aboutsummaryrefslogtreecommitdiff
path: root/src/link/MachO/dyld_info/Rebase.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2025-07-01 18:14:45 -0700
committerAndrew Kelley <andrew@ziglang.org>2025-07-07 22:43:52 -0700
commitc8fcd2ff2c032b2de8cc1a57e075552d1cab35df (patch)
tree7155f58049ecd0e948533f6b64cba1553dd33ae2 /src/link/MachO/dyld_info/Rebase.zig
parentf71d97e4cbb0e56213cb76657ad6c9edf6134868 (diff)
downloadzig-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.zig95
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();