mirror of
https://github.com/ziglang/zig.git
synced 2026-01-11 09:55:12 +00:00
macho: properly populate offset into lazy bind info
This commit is contained in:
parent
f0d7ec6f33
commit
2ea0901dd6
@ -2505,7 +2505,7 @@ fn writeStubInStubHelper(self: *MachO, index: u32) !void {
|
||||
const displacement = @intCast(i32, @intCast(i64, stub_helper.offset) - @intCast(i64, stub_off) - stub_size);
|
||||
// pushq
|
||||
code[0] = 0x68;
|
||||
mem.writeIntLittle(u32, code[1..][0..4], index * 0xd); // TODO
|
||||
mem.writeIntLittle(u32, code[1..][0..4], 0x0); // Just a placeholder populated in `populateLazyBindOffsetsInStubHelper`.
|
||||
// jmpq
|
||||
code[5] = 0xe9;
|
||||
mem.writeIntLittle(u32, code[6..][0..4], @bitCast(u32, displacement));
|
||||
@ -2516,7 +2516,7 @@ fn writeStubInStubHelper(self: *MachO, index: u32) !void {
|
||||
.literal = 0x2,
|
||||
}).toU32());
|
||||
mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.b(@intCast(i28, displacement)).toU32());
|
||||
mem.writeIntLittle(u32, code[8..12], index * 0xd); // TODO This is the size of lazy binding opcode block.
|
||||
mem.writeIntLittle(u32, code[8..12], 0x0); // Just a placeholder populated in `populateLazyBindOffsetsInStubHelper`.
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
@ -2630,6 +2630,7 @@ fn writeIndirectSymbolTable(self: *MachO) !void {
|
||||
const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?];
|
||||
const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;
|
||||
dysymtab.nindirectsyms = 0;
|
||||
// TODO check if we have allocated enough size.
|
||||
|
||||
var buf: [@sizeOf(u32)]u8 = undefined;
|
||||
var off = dysymtab.indirectsymoff;
|
||||
@ -2868,10 +2869,78 @@ fn writeLazyBindingInfoTable(self: *MachO) !void {
|
||||
log.debug("writing lazy binding info from 0x{x} to 0x{x}", .{ dyld_info.lazy_bind_off, dyld_info.lazy_bind_off + dyld_info.lazy_bind_size });
|
||||
|
||||
try self.base.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off);
|
||||
try self.populateLazyBindOffsetsInStubHelper(buffer);
|
||||
self.load_commands_dirty = true;
|
||||
self.lazy_binding_info_dirty = false;
|
||||
}
|
||||
|
||||
fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void {
|
||||
if (self.extern_lazy_symbols.items().len == 0) return;
|
||||
|
||||
var stream = std.io.fixedBufferStream(buffer);
|
||||
var reader = stream.reader();
|
||||
var offsets = std.ArrayList(u32).init(self.base.allocator);
|
||||
try offsets.append(0);
|
||||
defer offsets.deinit();
|
||||
var valid_block = false;
|
||||
|
||||
while (true) {
|
||||
const inst = reader.readByte() catch |err| switch (err) {
|
||||
error.EndOfStream => break,
|
||||
else => return err,
|
||||
};
|
||||
const imm: u8 = inst & macho.BIND_IMMEDIATE_MASK;
|
||||
const opcode: u8 = inst & macho.BIND_OPCODE_MASK;
|
||||
|
||||
switch (opcode) {
|
||||
macho.BIND_OPCODE_DO_BIND => {
|
||||
valid_block = true;
|
||||
},
|
||||
macho.BIND_OPCODE_DONE => {
|
||||
if (valid_block) {
|
||||
const offset = try stream.getPos();
|
||||
try offsets.append(@intCast(u32, offset));
|
||||
}
|
||||
valid_block = false;
|
||||
},
|
||||
macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM => {
|
||||
var next = try reader.readByte();
|
||||
while (next != @as(u8, 0)) {
|
||||
next = try reader.readByte();
|
||||
}
|
||||
},
|
||||
macho.BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB => {
|
||||
_ = try std.leb.readULEB128(u64, reader);
|
||||
},
|
||||
macho.BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB => {
|
||||
_ = try std.leb.readULEB128(u64, reader);
|
||||
},
|
||||
macho.BIND_OPCODE_SET_ADDEND_SLEB => {
|
||||
_ = try std.leb.readILEB128(i64, reader);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
assert(self.extern_lazy_symbols.items().len <= offsets.items.len);
|
||||
|
||||
const stub_size: u4 = switch (self.base.options.target.cpu.arch) {
|
||||
.x86_64 => 10,
|
||||
.aarch64 => 3 * @sizeOf(u32),
|
||||
else => unreachable,
|
||||
};
|
||||
const off: u4 = switch (self.base.options.target.cpu.arch) {
|
||||
.x86_64 => 1,
|
||||
.aarch64 => 2 * @sizeOf(u32),
|
||||
else => unreachable,
|
||||
};
|
||||
var buf: [@sizeOf(u32)]u8 = undefined;
|
||||
for (self.extern_lazy_symbols.items()) |_, i| {
|
||||
const placeholder_off = self.stub_helper_stubs_start_off.? + i * stub_size + off;
|
||||
mem.writeIntLittle(u32, &buf, offsets.items[i]);
|
||||
try self.base.file.?.pwriteAll(&buf, placeholder_off);
|
||||
}
|
||||
}
|
||||
|
||||
fn writeStringTable(self: *MachO) !void {
|
||||
if (!self.string_table_dirty) return;
|
||||
|
||||
@ -2979,8 +3048,6 @@ fn writeHeader(self: *MachO) !void {
|
||||
}
|
||||
|
||||
/// Parse MachO contents from existing binary file.
|
||||
/// TODO This method is incomplete and currently parses only the header
|
||||
/// plus the load commands.
|
||||
fn parseFromFile(self: *MachO, file: fs.File) !void {
|
||||
self.base.file = file;
|
||||
var reader = file.reader();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user