diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2025-07-01 18:14:45 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-07-07 22:43:52 -0700 |
| commit | c8fcd2ff2c032b2de8cc1a57e075552d1cab35df (patch) | |
| tree | 7155f58049ecd0e948533f6b64cba1553dd33ae2 /src/link/MachO/dyld_info/Rebase.zig | |
| parent | f71d97e4cbb0e56213cb76657ad6c9edf6134868 (diff) | |
| download | zig-c8fcd2ff2c032b2de8cc1a57e075552d1cab35df.tar.gz zig-c8fcd2ff2c032b2de8cc1a57e075552d1cab35df.zip | |
MachO: update to new std.io APIs
Diffstat (limited to 'src/link/MachO/dyld_info/Rebase.zig')
| -rw-r--r-- | src/link/MachO/dyld_info/Rebase.zig | 95 |
1 files changed, 48 insertions, 47 deletions
diff --git a/src/link/MachO/dyld_info/Rebase.zig b/src/link/MachO/dyld_info/Rebase.zig index dc4fcbcc1d..5fdba220a7 100644 --- a/src/link/MachO/dyld_info/Rebase.zig +++ b/src/link/MachO/dyld_info/Rebase.zig @@ -3,7 +3,7 @@ buffer: std.ArrayListUnmanaged(u8) = .empty, pub const Entry = struct { offset: u64, - segment_id: u8, + segment_id: u4, pub fn lessThan(ctx: void, entry: Entry, other: Entry) bool { _ = ctx; @@ -110,33 +110,35 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void { fn finalize(rebase: *Rebase, gpa: Allocator) !void { if (rebase.entries.items.len == 0) return; - const writer = rebase.buffer.writer(gpa); + var aw: std.io.Writer.Allocating = .fromArrayList(gpa, &rebase.buffer); + const bw = &aw.writer; + defer rebase.buffer = aw.toArrayList(); log.debug("rebase opcodes", .{}); std.mem.sort(Entry, rebase.entries.items, {}, Entry.lessThan); - try setTypePointer(writer); + try setTypePointer(bw); var start: usize = 0; var seg_id: ?u8 = null; for (rebase.entries.items, 0..) |entry, i| { if (seg_id != null and seg_id.? == entry.segment_id) continue; - try finalizeSegment(rebase.entries.items[start..i], writer); + try finalizeSegment(rebase.entries.items[start..i], bw); seg_id = entry.segment_id; start = i; } - try finalizeSegment(rebase.entries.items[start..], writer); - try done(writer); + try finalizeSegment(rebase.entries.items[start..], bw); + try done(bw); } -fn finalizeSegment(entries: []const Entry, writer: anytype) !void { +fn finalizeSegment(entries: []const Entry, bw: *Writer) Writer.Error!void { if (entries.len == 0) return; const segment_id = entries[0].segment_id; var offset = entries[0].offset; - try setSegmentOffset(segment_id, offset, writer); + try setSegmentOffset(segment_id, offset, bw); var count: usize = 0; var skip: u64 = 0; @@ -155,7 +157,7 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void { .start => { if (offset < current_offset) { const delta = current_offset - offset; - try addAddr(delta, writer); + try addAddr(delta, bw); offset += delta; } state = .times; @@ -175,7 +177,7 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void { offset += skip; i -= 1; } else { - try rebaseTimes(count, writer); + try rebaseTimes(count, bw); state = .start; i -= 1; } @@ -184,9 +186,9 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void { if (current_offset < offset) { count -= 1; if (count == 1) { - try rebaseAddAddr(skip, writer); + try rebaseAddAddr(skip, bw); } else { - try rebaseTimesSkip(count, skip, writer); + try rebaseTimesSkip(count, skip, bw); } state = .start; offset = offset - (@sizeOf(u64) + skip); @@ -199,7 +201,7 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void { count += 1; offset += @sizeOf(u64) + skip; } else { - try rebaseTimesSkip(count, skip, writer); + try rebaseTimesSkip(count, skip, bw); state = .start; i -= 1; } @@ -210,68 +212,66 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void { switch (state) { .start => unreachable, .times => { - try rebaseTimes(count, writer); + try rebaseTimes(count, bw); }, .times_skip => { - try rebaseTimesSkip(count, skip, writer); + try rebaseTimesSkip(count, skip, bw); }, } } -fn setTypePointer(writer: anytype) !void { +fn setTypePointer(bw: *Writer) Writer.Error!void { log.debug(">>> set type: {d}", .{macho.REBASE_TYPE_POINTER}); - try writer.writeByte(macho.REBASE_OPCODE_SET_TYPE_IMM | @as(u4, @truncate(macho.REBASE_TYPE_POINTER))); + try bw.writeByte(macho.REBASE_OPCODE_SET_TYPE_IMM | @as(u4, @intCast(macho.REBASE_TYPE_POINTER))); } -fn setSegmentOffset(segment_id: u8, offset: u64, writer: anytype) !void { +fn setSegmentOffset(segment_id: u4, offset: u64, bw: *Writer) Writer.Error!void { log.debug(">>> set segment: {d} and offset: {x}", .{ segment_id, offset }); - try writer.writeByte(macho.REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | @as(u4, @truncate(segment_id))); - try std.leb.writeUleb128(writer, offset); + try bw.writeByte(macho.REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | @as(u4, @truncate(segment_id))); + try bw.writeLeb128(offset); } -fn rebaseAddAddr(addr: u64, writer: anytype) !void { +fn rebaseAddAddr(addr: u64, bw: *Writer) Writer.Error!void { log.debug(">>> rebase with add: {x}", .{addr}); - try writer.writeByte(macho.REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB); - try std.leb.writeUleb128(writer, addr); + try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB); + try bw.writeLeb128(addr); } -fn rebaseTimes(count: usize, writer: anytype) !void { +fn rebaseTimes(count: usize, bw: *Writer) Writer.Error!void { log.debug(">>> rebase with count: {d}", .{count}); if (count <= 0xf) { - try writer.writeByte(macho.REBASE_OPCODE_DO_REBASE_IMM_TIMES | @as(u4, @truncate(count))); + try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_IMM_TIMES | @as(u4, @truncate(count))); } else { - try writer.writeByte(macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES); - try std.leb.writeUleb128(writer, count); + try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES); + try bw.writeLeb128(count); } } -fn rebaseTimesSkip(count: usize, skip: u64, writer: anytype) !void { +fn rebaseTimesSkip(count: usize, skip: u64, bw: *Writer) Writer.Error!void { log.debug(">>> rebase with count: {d} and skip: {x}", .{ count, skip }); - try writer.writeByte(macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB); - try std.leb.writeUleb128(writer, count); - try std.leb.writeUleb128(writer, skip); + try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB); + try bw.writeLeb128(count); + try bw.writeLeb128(skip); } -fn addAddr(addr: u64, writer: anytype) !void { +fn addAddr(addr: u64, bw: *Writer) Writer.Error!void { log.debug(">>> add: {x}", .{addr}); - if (std.mem.isAlignedGeneric(u64, addr, @sizeOf(u64))) { - const imm = @divExact(addr, @sizeOf(u64)); - if (imm <= 0xf) { - try writer.writeByte(macho.REBASE_OPCODE_ADD_ADDR_IMM_SCALED | @as(u4, @truncate(imm))); - return; - } - } - try writer.writeByte(macho.REBASE_OPCODE_ADD_ADDR_ULEB); - try std.leb.writeUleb128(writer, addr); + if (std.math.divExact(u64, addr, @sizeOf(u64))) |scaled| { + if (std.math.cast(u4, scaled)) |imm_scaled| return bw.writeByte( + macho.REBASE_OPCODE_ADD_ADDR_IMM_SCALED | imm_scaled, + ); + } else |_| {} + try bw.writeByte(macho.REBASE_OPCODE_ADD_ADDR_ULEB); + try bw.writeLeb128(addr); } -fn done(writer: anytype) !void { +fn done(bw: *Writer) Writer.Error!void { log.debug(">>> done", .{}); - try writer.writeByte(macho.REBASE_OPCODE_DONE); + try bw.writeByte(macho.REBASE_OPCODE_DONE); } -pub fn write(rebase: Rebase, writer: anytype) !void { - try writer.writeAll(rebase.buffer.items); +pub fn write(rebase: Rebase, bw: *Writer) Writer.Error!void { + try bw.writeAll(rebase.buffer.items); } test "rebase - no entries" { @@ -654,9 +654,10 @@ const log = std.log.scoped(.link_dyld_info); const macho = std.macho; const mem = std.mem; const testing = std.testing; -const trace = @import("../../../tracy.zig").trace; - const Allocator = mem.Allocator; +const Writer = std.io.Writer; + +const trace = @import("../../../tracy.zig").trace; const File = @import("../file.zig").File; const MachO = @import("../../MachO.zig"); const Rebase = @This(); |
