From c8fcd2ff2c032b2de8cc1a57e075552d1cab35df Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 1 Jul 2025 18:14:45 -0700 Subject: MachO: update to new std.io APIs --- src/link/MachO/UnwindInfo.zig | 143 ++++++++++++++---------------------------- 1 file changed, 46 insertions(+), 97 deletions(-) (limited to 'src/link/MachO/UnwindInfo.zig') diff --git a/src/link/MachO/UnwindInfo.zig b/src/link/MachO/UnwindInfo.zig index ffeeaddb23..17676fd826 100644 --- a/src/link/MachO/UnwindInfo.zig +++ b/src/link/MachO/UnwindInfo.zig @@ -133,7 +133,7 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { for (info.records.items) |ref| { const rec = ref.getUnwindRecord(macho_file); const atom = rec.getAtom(macho_file); - log.debug("@{x}-{x} : {s} : rec({d}) : object({d}) : {}", .{ + log.debug("@{x}-{x} : {s} : rec({d}) : object({d}) : {f}", .{ rec.getAtomAddress(macho_file), rec.getAtomAddress(macho_file) + rec.length, atom.getName(macho_file), @@ -202,7 +202,7 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { if (i >= max_common_encodings) break; if (slice[i].count < 2) continue; info.appendCommonEncoding(slice[i].enc); - log.debug("adding common encoding: {d} => {}", .{ i, slice[i].enc }); + log.debug("adding common encoding: {d} => {f}", .{ i, slice[i].enc }); } } @@ -255,7 +255,7 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { page.kind = .compressed; } - log.debug("{}", .{page.fmt(info.*)}); + log.debug("{f}", .{page.fmt(info.*)}); try info.pages.append(gpa, page); } @@ -289,13 +289,10 @@ pub fn calcSize(info: UnwindInfo) usize { return total_size; } -pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { +pub fn write(info: UnwindInfo, macho_file: *MachO, bw: *Writer) Writer.Error!void { const seg = macho_file.getTextSegment(); const header = macho_file.sections.items(.header)[macho_file.unwind_info_sect_index.?]; - var stream = std.io.fixedBufferStream(buffer); - const writer = stream.writer(); - const common_encodings_offset: u32 = @sizeOf(macho.unwind_info_section_header); const common_encodings_count: u32 = info.common_encodings_count; const personalities_offset: u32 = common_encodings_offset + common_encodings_count * @sizeOf(u32); @@ -303,7 +300,7 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { const indexes_offset: u32 = personalities_offset + personalities_count * @sizeOf(u32); const indexes_count: u32 = @as(u32, @intCast(info.pages.items.len + 1)); - try writer.writeStruct(macho.unwind_info_section_header{ + try bw.writeStruct(macho.unwind_info_section_header{ .commonEncodingsArraySectionOffset = common_encodings_offset, .commonEncodingsArrayCount = common_encodings_count, .personalityArraySectionOffset = personalities_offset, @@ -312,11 +309,11 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { .indexCount = indexes_count, }); - try writer.writeAll(mem.sliceAsBytes(info.common_encodings[0..info.common_encodings_count])); + try bw.writeAll(mem.sliceAsBytes(info.common_encodings[0..info.common_encodings_count])); for (info.personalities[0..info.personalities_count]) |ref| { const sym = ref.getSymbol(macho_file).?; - try writer.writeInt(u32, @intCast(sym.getGotAddress(macho_file) - seg.vmaddr), .little); + try bw.writeInt(u32, @intCast(sym.getGotAddress(macho_file) - seg.vmaddr), .little); } const pages_base_offset = @as(u32, @intCast(header.size - (info.pages.items.len * second_level_page_bytes))); @@ -325,7 +322,7 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { for (info.pages.items, 0..) |page, i| { assert(page.count > 0); const rec = info.records.items[page.start].getUnwindRecord(macho_file); - try writer.writeStruct(macho.unwind_info_section_header_index_entry{ + try bw.writeStruct(macho.unwind_info_section_header_index_entry{ .functionOffset = @as(u32, @intCast(rec.getAtomAddress(macho_file) - seg.vmaddr)), .secondLevelPagesSectionOffset = @as(u32, @intCast(pages_base_offset + i * second_level_page_bytes)), .lsdaIndexArraySectionOffset = lsda_base_offset + @@ -335,7 +332,7 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { const last_rec = info.records.items[info.records.items.len - 1].getUnwindRecord(macho_file); const sentinel_address = @as(u32, @intCast(last_rec.getAtomAddress(macho_file) + last_rec.length - seg.vmaddr)); - try writer.writeStruct(macho.unwind_info_section_header_index_entry{ + try bw.writeStruct(macho.unwind_info_section_header_index_entry{ .functionOffset = sentinel_address, .secondLevelPagesSectionOffset = 0, .lsdaIndexArraySectionOffset = lsda_base_offset + @@ -344,23 +341,20 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { for (info.lsdas.items) |index| { const rec = info.records.items[index].getUnwindRecord(macho_file); - try writer.writeStruct(macho.unwind_info_section_header_lsda_index_entry{ + try bw.writeStruct(macho.unwind_info_section_header_lsda_index_entry{ .functionOffset = @as(u32, @intCast(rec.getAtomAddress(macho_file) - seg.vmaddr)), .lsdaOffset = @as(u32, @intCast(rec.getLsdaAddress(macho_file) - seg.vmaddr)), }); } for (info.pages.items) |page| { - const start = stream.pos; - try page.write(info, macho_file, writer); - const nwritten = stream.pos - start; - if (nwritten < second_level_page_bytes) { - const padding = math.cast(usize, second_level_page_bytes - nwritten) orelse return error.Overflow; - try writer.writeByteNTimes(0, padding); - } + const start = bw.count; + try page.write(info, macho_file, bw); + const nwritten = bw.count - start; + try bw.splatByteAll(0, math.cast(usize, second_level_page_bytes - nwritten) orelse return error.Overflow); } - @memset(buffer[stream.pos..], 0); + @memset(bw.unusedCapacitySlice(), 0); } fn getOrPutPersonalityFunction(info: *UnwindInfo, ref: MachO.Ref) error{TooManyPersonalities}!u2 { @@ -455,15 +449,9 @@ pub const Encoding = extern struct { return enc.enc == other.enc; } - pub fn format( - enc: Encoding, - comptime unused_fmt_string: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, - ) !void { - _ = unused_fmt_string; - _ = options; - try writer.print("0x{x:0>8}", .{enc.enc}); + pub fn format(enc: Encoding, w: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void { + comptime assert(unused_fmt_string.len == 0); + try w.print("0x{x:0>8}", .{enc.enc}); } }; @@ -517,48 +505,28 @@ pub const Record = struct { return lsda.getAddress(macho_file) + rec.lsda_offset; } - pub fn format( - rec: Record, - comptime unused_fmt_string: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, - ) !void { - _ = rec; - _ = unused_fmt_string; - _ = options; - _ = writer; - @compileError("do not format UnwindInfo.Records directly"); - } - - pub fn fmt(rec: Record, macho_file: *MachO) std.fmt.Formatter(format2) { + pub fn fmt(rec: Record, macho_file: *MachO) std.fmt.Formatter(Format, Format.default) { return .{ .data = .{ .rec = rec, .macho_file = macho_file, } }; } - const FormatContext = struct { + const Format = struct { rec: Record, macho_file: *MachO, - }; - fn format2( - ctx: FormatContext, - comptime unused_fmt_string: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, - ) !void { - _ = unused_fmt_string; - _ = options; - const rec = ctx.rec; - const macho_file = ctx.macho_file; - try writer.print("{x} : len({x})", .{ - rec.enc.enc, rec.length, - }); - if (rec.enc.isDwarf(macho_file)) try writer.print(" : fde({d})", .{rec.fde}); - try writer.print(" : {s}", .{rec.getAtom(macho_file).getName(macho_file)}); - if (!rec.alive) try writer.writeAll(" : [*]"); - } + fn default(f: Format, w: *Writer) Writer.Error!void { + const rec = f.rec; + const macho_file = f.macho_file; + try w.print("{x} : len({x})", .{ + rec.enc.enc, rec.length, + }); + if (rec.enc.isDwarf(macho_file)) try w.print(" : fde({d})", .{rec.fde}); + try w.print(" : {s}", .{rec.getAtom(macho_file).getName(macho_file)}); + if (!rec.alive) try w.writeAll(" : [*]"); + } + }; pub const Index = u32; @@ -613,45 +581,25 @@ const Page = struct { return null; } - fn format( - page: *const Page, - comptime unused_format_string: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, - ) !void { - _ = page; - _ = unused_format_string; - _ = options; - _ = writer; - @compileError("do not format Page directly; use page.fmt()"); - } - - const FormatPageContext = struct { + const Format = struct { page: Page, info: UnwindInfo, - }; - fn format2( - ctx: FormatPageContext, - comptime unused_format_string: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, - ) @TypeOf(writer).Error!void { - _ = options; - _ = unused_format_string; - try writer.writeAll("Page:\n"); - try writer.print(" kind: {s}\n", .{@tagName(ctx.page.kind)}); - try writer.print(" entries: {d} - {d}\n", .{ - ctx.page.start, - ctx.page.start + ctx.page.count, - }); - try writer.print(" encodings (count = {d})\n", .{ctx.page.page_encodings_count}); - for (ctx.page.page_encodings[0..ctx.page.page_encodings_count], 0..) |enc, i| { - try writer.print(" {d}: {}\n", .{ ctx.info.common_encodings_count + i, enc }); + fn default(f: Format, w: *Writer) Writer.Error!void { + try w.writeAll("Page:\n"); + try w.print(" kind: {s}\n", .{@tagName(f.page.kind)}); + try w.print(" entries: {d} - {d}\n", .{ + f.page.start, + f.page.start + f.page.count, + }); + try w.print(" encodings (count = {d})\n", .{f.page.page_encodings_count}); + for (f.page.page_encodings[0..f.page.page_encodings_count], 0..) |enc, i| { + try w.print(" {d}: {f}\n", .{ f.info.common_encodings_count + i, enc }); + } } - } + }; - fn fmt(page: Page, info: UnwindInfo) std.fmt.Formatter(format2) { + fn fmt(page: Page, info: UnwindInfo) std.fmt.Formatter(Format, Format.default) { return .{ .data = .{ .page = page, .info = info, @@ -720,6 +668,7 @@ const macho = std.macho; const math = std.math; const mem = std.mem; const trace = @import("../../tracy.zig").trace; +const Writer = std.io.Writer; const Allocator = mem.Allocator; const Atom = @import("Atom.zig"); -- cgit v1.2.3