aboutsummaryrefslogtreecommitdiff
path: root/src/link/MachO.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2023-04-19 16:38:44 +0200
committerJakub Konka <kubkon@jakubkonka.com>2023-04-21 22:44:27 +0200
commitfa40267b04e29fa8e36e73cb54eb68d58d26fa8d (patch)
treec6f77455c305e37e13d66eda48da736c93b4c9d6 /src/link/MachO.zig
parentc55e821df6d6adca449720e052f40463eef8174b (diff)
downloadzig-fa40267b04e29fa8e36e73cb54eb68d58d26fa8d.tar.gz
zig-fa40267b04e29fa8e36e73cb54eb68d58d26fa8d.zip
macho: do not allocate atoms for stub entries
Diffstat (limited to 'src/link/MachO.zig')
-rw-r--r--src/link/MachO.zig453
1 files changed, 160 insertions, 293 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 43614e4039..2749cfe095 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -19,6 +19,7 @@ const fat = @import("MachO/fat.zig");
const link = @import("../link.zig");
const llvm_backend = @import("../codegen/llvm.zig");
const load_commands = @import("MachO/load_commands.zig");
+const stubs = @import("MachO/stubs.zig");
const target_util = @import("../target.zig");
const trace = @import("../tracy.zig").trace;
const zld = @import("MachO/zld.zig");
@@ -156,7 +157,7 @@ stub_helper_preamble_atom_index: ?Atom.Index = null,
strtab: StringTable(.strtab) = .{},
got_table: TableSection(SymbolWithLoc) = .{},
-stubs_table: SectionTable = .{},
+stub_table: TableSection(SymbolWithLoc) = .{},
tlv_table: SectionTable = .{},
error_flags: File.ErrorFlags = File.ErrorFlags{},
@@ -164,6 +165,8 @@ error_flags: File.ErrorFlags = File.ErrorFlags{},
segment_table_dirty: bool = false,
got_table_count_dirty: bool = false,
got_table_contents_dirty: bool = false,
+stub_table_count_dirty: bool = false,
+stub_table_contents_dirty: bool = false,
/// A helper var to indicate if we are at the start of the incremental updates, or
/// already somewhere further along the update-and-run chain.
@@ -213,11 +216,6 @@ rebases: RebaseTable = .{},
/// this will be a table indexed by index into the list of Atoms.
bindings: BindingTable = .{},
-/// A table of lazy bindings indexed by the owning them `Atom`.
-/// Note that once we refactor `Atom`'s lifetime and ownership rules,
-/// this will be a table indexed by index into the list of Atoms.
-lazy_bindings: BindingTable = .{},
-
/// Table of tracked LazySymbols.
lazy_syms: LazySymbolTable = .{},
@@ -763,11 +761,23 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
if (self.got_table_contents_dirty) {
for (self.got_table.entries.items, 0..) |entry, i| {
if (!self.got_table.lookup.contains(entry)) continue;
+ // TODO: write all in one go rather than incrementally.
try self.writeOffsetTableEntry(i);
}
self.got_table_contents_dirty = false;
}
+ // Update stubs if we moved any section in memory.
+ // TODO: we probably don't need to update all sections if only one got moved.
+ if (self.stub_table_contents_dirty) {
+ for (self.stub_table.entries.items, 0..) |entry, i| {
+ if (!self.stub_table.lookup.contains(entry)) continue;
+ // TODO: write all in one go rather than incrementally.
+ try self.writeStubTableEntry(i);
+ }
+ self.stub_table_contents_dirty = false;
+ }
+
if (build_options.enable_logging) {
self.logSymtab();
self.logSections();
@@ -1311,6 +1321,86 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void {
}
}
+fn writeStubTableEntry(self: *MachO, index: usize) !void {
+ const stubs_sect_id = self.stubs_section_index.?;
+ const stub_helper_sect_id = self.stub_helper_section_index.?;
+ const laptr_sect_id = self.la_symbol_ptr_section_index.?;
+
+ const cpu_arch = self.base.options.target.cpu.arch;
+ const stub_entry_size = stubs.calcStubEntrySize(cpu_arch);
+ const stub_helper_entry_size = stubs.calcStubHelperEntrySize(cpu_arch);
+ const stub_helper_preamble_size = stubs.calcStubHelperPreambleSize(cpu_arch);
+
+ if (self.stub_table_count_dirty) {
+ // We grow all 3 sections one by one.
+ {
+ const needed_size = stub_entry_size * self.stub_table.entries.items.len;
+ try self.growSection(stubs_sect_id, needed_size);
+ }
+ {
+ const needed_size = stub_helper_preamble_size + stub_helper_entry_size * self.stub_table.entries.items.len;
+ try self.growSection(stub_helper_sect_id, needed_size);
+ }
+ {
+ const needed_size = @sizeOf(u64) * self.stub_table.entries.items.len;
+ try self.growSection(laptr_sect_id, needed_size);
+ }
+ self.stub_table_count_dirty = false;
+ }
+
+ const gpa = self.base.allocator;
+
+ const stubs_header = self.sections.items(.header)[stubs_sect_id];
+ const stub_helper_header = self.sections.items(.header)[stub_helper_sect_id];
+ const laptr_header = self.sections.items(.header)[laptr_sect_id];
+
+ const entry = self.stub_table.entries.items[index];
+ const stub_addr: u64 = stubs_header.addr + stub_entry_size * index;
+ const stub_helper_addr: u64 = stub_helper_header.addr + stub_helper_preamble_size + stub_helper_entry_size * index;
+ const laptr_addr: u64 = laptr_header.addr + @sizeOf(u64) * index;
+
+ log.debug("writing stub entry {d}: @{x} => '{s}'", .{ index, stub_addr, self.getSymbolName(entry) });
+
+ {
+ var buf = try std.ArrayList(u8).initCapacity(gpa, stub_entry_size);
+ defer buf.deinit();
+ try stubs.writeStubCode(.{
+ .cpu_arch = cpu_arch,
+ .source_addr = stub_addr,
+ .target_addr = laptr_addr,
+ }, buf.writer());
+ const off = stubs_header.offset + stub_entry_size * index;
+ try self.base.file.?.pwriteAll(buf.items, off);
+ }
+
+ {
+ var buf = try std.ArrayList(u8).initCapacity(gpa, stub_helper_entry_size);
+ defer buf.deinit();
+ try stubs.writeStubHelperCode(.{
+ .cpu_arch = cpu_arch,
+ .source_addr = stub_helper_addr,
+ .target_addr = stub_helper_header.addr,
+ }, buf.writer());
+ const off = stub_helper_header.offset + stub_helper_preamble_size + stub_helper_entry_size * index;
+ try self.base.file.?.pwriteAll(buf.items, off);
+ }
+
+ {
+ var buf: [@sizeOf(u64)]u8 = undefined;
+ mem.writeIntLittle(u64, &buf, stub_helper_addr);
+ const off = laptr_header.offset + @sizeOf(u64) * index;
+ try self.base.file.?.pwriteAll(&buf, off);
+ }
+
+ // TODO: generating new stub entry will require pulling the address of the symbol from the
+ // target dylib when updating directly in memory.
+ if (is_hot_update_compatible) {
+ if (self.hot_state.mach_task) |_| {
+ @panic("TODO: update a stub entry in memory");
+ }
+ }
+}
+
fn writePtrWidthAtom(self: *MachO, atom_index: Atom.Index) !void {
var buffer: [@sizeOf(u64)]u8 = [_]u8{0} ** @sizeOf(u64);
try self.writeAtom(atom_index, &buffer);
@@ -1339,12 +1429,16 @@ fn markRelocsDirtyByAddress(self: *MachO, addr: u64) void {
}
// Dirty synthetic table sections if necessary
- for (&[_]u8{self.got_section_index.?}, &[_]*bool{&self.got_table_contents_dirty}) |sect_id, dirty| {
- if (dirty.*) continue;
- const segment_index = self.sections.items(.segment_index)[sect_id];
- const segment = self.segments.items[segment_index];
- if (segment.vmaddr < addr) continue;
- dirty.* = true;
+ {
+ const target_addr = self.getSegment(self.got_section_index.?).vmaddr;
+ if (target_addr >= addr) self.got_table_contents_dirty = true;
+ }
+ {
+ const stubs_addr = self.getSegment(self.stubs_section_index.?).vmaddr;
+ const stub_helper_addr = self.getSegment(self.stub_helper_section_index.?).vmaddr;
+ const laptr_addr = self.getSegment(self.la_symbol_ptr_section_index.?).vmaddr;
+ if (stubs_addr >= addr or stub_helper_addr >= addr or laptr_addr >= addr)
+ self.stub_table_contents_dirty = true;
}
}
@@ -1525,200 +1619,6 @@ fn createStubHelperPreambleAtom(self: *MachO) !void {
try self.writeAtom(atom_index, code);
}
-fn createStubHelperAtom(self: *MachO) !Atom.Index {
- const gpa = self.base.allocator;
- const arch = self.base.options.target.cpu.arch;
- const size: u4 = switch (arch) {
- .x86_64 => 10,
- .aarch64 => 3 * @sizeOf(u32),
- else => unreachable,
- };
- const atom_index = try self.createAtom();
- const atom = self.getAtomPtr(atom_index);
- atom.size = size;
-
- const required_alignment: u32 = switch (arch) {
- .x86_64 => 1,
- .aarch64 => @alignOf(u32),
- else => unreachable,
- };
-
- const sym = atom.getSymbolPtr(self);
- sym.n_type = macho.N_SECT;
- sym.n_sect = self.stub_helper_section_index.? + 1;
-
- const code = try gpa.alloc(u8, size);
- defer gpa.free(code);
- mem.set(u8, code, 0);
-
- const stub_helper_preamble_atom_sym_index = if (self.stub_helper_preamble_atom_index) |stub_index|
- self.getAtom(stub_index).getSymbolIndex().?
- else
- unreachable;
-
- switch (arch) {
- .x86_64 => {
- // pushq
- code[0] = 0x68;
- // Next 4 bytes 1..4 are just a placeholder populated in `populateLazyBindOffsetsInStubHelper`.
- // jmpq
- code[5] = 0xe9;
-
- try Atom.addRelocation(self, atom_index, .{
- .type = .branch,
- .target = .{ .sym_index = stub_helper_preamble_atom_sym_index },
- .offset = 6,
- .addend = 0,
- .pcrel = true,
- .length = 2,
- });
- },
- .aarch64 => {
- const literal = blk: {
- const div_res = try math.divExact(u64, size - @sizeOf(u32), 4);
- break :blk math.cast(u18, div_res) orelse return error.Overflow;
- };
- // ldr w16, literal
- mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.ldrLiteral(
- .w16,
- literal,
- ).toU32());
- // b disp
- mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.b(0).toU32());
- // Next 4 bytes 8..12 are just a placeholder populated in `populateLazyBindOffsetsInStubHelper`.
-
- try Atom.addRelocation(self, atom_index, .{
- .type = .branch,
- .target = .{ .sym_index = stub_helper_preamble_atom_sym_index },
- .offset = 4,
- .addend = 0,
- .pcrel = true,
- .length = 2,
- });
- },
- else => unreachable,
- }
-
- sym.n_value = try self.allocateAtom(atom_index, size, required_alignment);
- log.debug("allocated stub helper atom at 0x{x}", .{sym.n_value});
- try self.writeAtom(atom_index, code);
-
- return atom_index;
-}
-
-fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWithLoc) !Atom.Index {
- const atom_index = try self.createAtom();
- const atom = self.getAtomPtr(atom_index);
- atom.size = @sizeOf(u64);
-
- const sym = atom.getSymbolPtr(self);
- sym.n_type = macho.N_SECT;
- sym.n_sect = self.la_symbol_ptr_section_index.? + 1;
-
- try Atom.addRelocation(self, atom_index, .{
- .type = .unsigned,
- .target = .{ .sym_index = stub_sym_index },
- .offset = 0,
- .addend = 0,
- .pcrel = false,
- .length = 3,
- });
- try Atom.addRebase(self, atom_index, 0);
- try Atom.addLazyBinding(self, atom_index, .{
- .target = self.getGlobal(self.getSymbolName(target)).?,
- .offset = 0,
- });
-
- sym.n_value = try self.allocateAtom(atom_index, atom.size, @alignOf(u64));
- log.debug("allocated lazy pointer atom at 0x{x} ({s})", .{ sym.n_value, self.getSymbolName(target) });
- try self.writePtrWidthAtom(atom_index);
-
- return atom_index;
-}
-
-fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index {
- const gpa = self.base.allocator;
- const arch = self.base.options.target.cpu.arch;
- const size: u4 = switch (arch) {
- .x86_64 => 6,
- .aarch64 => 3 * @sizeOf(u32),
- else => unreachable, // unhandled architecture type
- };
- const atom_index = try self.createAtom();
- const atom = self.getAtomPtr(atom_index);
- atom.size = size;
-
- const required_alignment: u32 = switch (arch) {
- .x86_64 => 1,
- .aarch64 => @alignOf(u32),
- else => unreachable, // unhandled architecture type
-
- };
-
- const sym = atom.getSymbolPtr(self);
- sym.n_type = macho.N_SECT;
- sym.n_sect = self.stubs_section_index.? + 1;
-
- const code = try gpa.alloc(u8, size);
- defer gpa.free(code);
- mem.set(u8, code, 0);
-
- switch (arch) {
- .x86_64 => {
- // jmp
- code[0] = 0xff;
- code[1] = 0x25;
-
- try Atom.addRelocation(self, atom_index, .{
- .type = .branch,
- .target = .{ .sym_index = laptr_sym_index },
- .offset = 2,
- .addend = 0,
- .pcrel = true,
- .length = 2,
- });
- },
- .aarch64 => {
- // adrp x16, pages
- mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adrp(.x16, 0).toU32());
- // ldr x16, x16, offset
- mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.ldr(
- .x16,
- .x16,
- aarch64.Instruction.LoadStoreOffset.imm(0),
- ).toU32());
- // br x16
- mem.writeIntLittle(u32, code[8..12], aarch64.Instruction.br(.x16).toU32());
-
- try Atom.addRelocations(self, atom_index, &[_]Relocation{
- .{
- .type = .page,
- .target = .{ .sym_index = laptr_sym_index },
- .offset = 0,
- .addend = 0,
- .pcrel = true,
- .length = 2,
- },
- .{
- .type = .pageoff,
- .target = .{ .sym_index = laptr_sym_index },
- .offset = 4,
- .addend = 0,
- .pcrel = false,
- .length = 2,
- },
- });
- },
- else => unreachable,
- }
-
- sym.n_value = try self.allocateAtom(atom_index, size, required_alignment);
- log.debug("allocated stub atom at 0x{x}", .{sym.n_value});
- try self.writeAtom(atom_index, code);
-
- return atom_index;
-}
-
fn createThreadLocalDescriptorAtom(self: *MachO, target: SymbolWithLoc) !Atom.Index {
const gpa = self.base.allocator;
const size = 3 * @sizeOf(u64);
@@ -1904,7 +1804,7 @@ pub fn deinit(self: *MachO) void {
}
self.got_table.deinit(gpa);
- self.stubs_table.deinit(gpa);
+ self.stub_table.deinit(gpa);
self.tlv_table.deinit(gpa);
self.strtab.deinit(gpa);
@@ -1968,11 +1868,6 @@ pub fn deinit(self: *MachO) void {
bindings.deinit(gpa);
}
self.bindings.deinit(gpa);
-
- for (self.lazy_bindings.values()) |*bindings| {
- bindings.deinit(gpa);
- }
- self.lazy_bindings.deinit(gpa);
}
fn freeAtom(self: *MachO, atom_index: Atom.Index) void {
@@ -2124,16 +2019,10 @@ fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void {
}
fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {
- if (self.stubs_table.lookup.contains(target)) return;
- const stub_index = try self.stubs_table.allocateEntry(self.base.allocator, target);
- const stub_helper_atom_index = try self.createStubHelperAtom();
- const stub_helper_atom = self.getAtom(stub_helper_atom_index);
- const laptr_atom_index = try self.createLazyPointerAtom(stub_helper_atom.getSymbolIndex().?, target);
- const laptr_atom = self.getAtom(laptr_atom_index);
- const stub_atom_index = try self.createStubAtom(laptr_atom.getSymbolIndex().?);
- const stub_atom = self.getAtom(stub_atom_index);
- self.stubs_table.entries.items[stub_index].sym_index = stub_atom.getSymbolIndex().?;
- self.markRelocsDirtyByTarget(target);
+ if (self.stub_table.lookup.contains(target)) return;
+ const stub_index = try self.stub_table.allocateEntry(self.base.allocator, target);
+ try self.writeStubTableEntry(stub_index);
+ self.stub_table_count_dirty = true;
}
fn addTlvEntry(self: *MachO, target: SymbolWithLoc) !void {
@@ -2840,11 +2729,7 @@ fn populateMissingMetadata(self: *MachO) !void {
}
if (self.stubs_section_index == null) {
- const stub_size: u32 = switch (cpu_arch) {
- .x86_64 => 6,
- .aarch64 => 3 * @sizeOf(u32),
- else => unreachable, // unhandled architecture type
- };
+ const stub_size = stubs.calcStubEntrySize(cpu_arch);
self.stubs_section_index = try self.allocateSection("__TEXT2", "__stubs", .{
.size = stub_size,
.alignment = switch (cpu_arch) {
@@ -3377,45 +3262,35 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {
try bind.finalize(gpa, self);
}
-fn collectLazyBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {
+fn collectLazyBindData(self: *MachO, bind: anytype) !void {
const gpa = self.base.allocator;
- const slice = self.sections.slice();
- for (raw_bindings.keys(), 0..) |atom_index, i| {
- const atom = self.getAtom(atom_index);
- log.debug(" ATOM(%{?d}, '{s}')", .{ atom.getSymbolIndex(), atom.getName(self) });
-
- const sym = atom.getSymbol(self);
- const segment_index = slice.items(.segment_index)[sym.n_sect - 1];
- const seg = self.getSegment(sym.n_sect - 1);
-
- const base_offset = sym.n_value - seg.vmaddr;
-
- const bindings = raw_bindings.values()[i];
- try bind.entries.ensureUnusedCapacity(gpa, bindings.items.len);
-
- for (bindings.items) |binding| {
- const bind_sym = self.getSymbol(binding.target);
- const bind_sym_name = self.getSymbolName(binding.target);
- const dylib_ordinal = @divTrunc(
- @bitCast(i16, bind_sym.n_desc),
- macho.N_SYMBOL_RESOLVER,
- );
- log.debug(" | bind at {x}, import('{s}') in dylib({d})", .{
- binding.offset + base_offset,
- bind_sym_name,
- dylib_ordinal,
- });
- if (bind_sym.weakRef()) {
- log.debug(" | marking as weak ref ", .{});
- }
- bind.entries.appendAssumeCapacity(.{
- .target = binding.target,
- .offset = binding.offset + base_offset,
- .segment_id = segment_index,
- .addend = 0,
- });
+ try bind.entries.ensureUnusedCapacity(gpa, self.stub_table.entries.items.len);
+ const segment_index = self.sections.items(.segment_index)[self.la_symbol_ptr_section_index.?];
+ for (self.stub_table.entries.items, 0..) |entry, i| {
+ if (!self.stub_table.lookup.contains(entry)) continue;
+ const bind_sym = self.getSymbol(entry);
+ assert(bind_sym.undf());
+ const bind_sym_name = self.getSymbolName(entry);
+ const offset = i * @sizeOf(u64);
+ const dylib_ordinal = @divTrunc(
+ @bitCast(i16, bind_sym.n_desc),
+ macho.N_SYMBOL_RESOLVER,
+ );
+ log.debug(" | bind at {x}, import('{s}') in dylib({d})", .{
+ offset,
+ bind_sym_name,
+ dylib_ordinal,
+ });
+ if (bind_sym.weakRef()) {
+ log.debug(" | marking as weak ref ", .{});
}
+ bind.entries.appendAssumeCapacity(.{
+ .target = entry,
+ .offset = offset,
+ .segment_id = segment_index,
+ .addend = 0,
+ });
}
try bind.finalize(gpa, self);
@@ -3464,7 +3339,7 @@ fn writeDyldInfoData(self: *MachO) !void {
var lazy_bind = LazyBind{};
defer lazy_bind.deinit(gpa);
- try self.collectLazyBindData(&lazy_bind, self.lazy_bindings);
+ try self.collectLazyBindData(&lazy_bind);
var trie: Trie = .{};
defer trie.deinit(gpa);
@@ -3542,32 +3417,24 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: LazyBind) !void
const stub_helper_section_index = self.stub_helper_section_index.?;
assert(self.stub_helper_preamble_atom_index != null);
- const section = self.sections.get(stub_helper_section_index);
+ const header = self.sections.items(.header)[stub_helper_section_index];
- const stub_offset: u4 = switch (self.base.options.target.cpu.arch) {
- .x86_64 => 1,
- .aarch64 => 2 * @sizeOf(u32),
- else => unreachable,
- };
- const header = section.header;
- var atom_index = section.last_atom_index.?;
+ const cpu_arch = self.base.options.target.cpu.arch;
+ const preamble_size = stubs.calcStubHelperPreambleSize(cpu_arch);
+ const stub_size = stubs.calcStubHelperEntrySize(cpu_arch);
+ const stub_offset = stubs.calcStubOffsetInStubHelper(cpu_arch);
+ const base_offset = header.offset + preamble_size;
- var index: usize = lazy_bind.offsets.items.len;
- while (index > 0) : (index -= 1) {
- const atom = self.getAtom(atom_index);
- const sym = atom.getSymbol(self);
- const file_offset = header.offset + sym.n_value - header.addr + stub_offset;
- const bind_offset = lazy_bind.offsets.items[index - 1];
+ for (lazy_bind.offsets.items, 0..) |bind_offset, index| {
+ const file_offset = base_offset + index * stub_size + stub_offset;
log.debug("writing lazy bind offset 0x{x} ({s}) in stub helper at 0x{x}", .{
bind_offset,
- self.getSymbolName(lazy_bind.entries.items[index - 1].target),
+ self.getSymbolName(lazy_bind.entries.items[index].target),
file_offset,
});
try self.base.file.?.pwriteAll(mem.asBytes(&bind_offset), file_offset);
-
- atom_index = atom.prev_index.?;
}
}
@@ -3683,7 +3550,7 @@ const SymtabCtx = struct {
fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
const gpa = self.base.allocator;
- const nstubs = @intCast(u32, self.stubs_table.lookup.count());
+ const nstubs = @intCast(u32, self.stub_table.lookup.count());
const ngot_entries = @intCast(u32, self.got_table.lookup.count());
const nindirectsyms = nstubs * 2 + ngot_entries;
const iextdefsym = ctx.nlocalsym;
@@ -3704,13 +3571,13 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
const writer = buf.writer();
if (self.stubs_section_index) |sect_id| {
- const stubs = &self.sections.items(.header)[sect_id];
- stubs.reserved1 = 0;
- for (self.stubs_table.entries.items) |entry| {
- if (entry.sym_index == 0) continue;
- const target_sym = self.getSymbol(entry.target);
+ const stubs_header = &self.sections.items(.header)[sect_id];
+ stubs_header.reserved1 = 0;
+ for (self.stub_table.entries.items) |entry| {
+ if (!self.stub_table.lookup.contains(entry)) continue;
+ const target_sym = self.getSymbol(entry);
assert(target_sym.undf());
- try writer.writeIntLittle(u32, iundefsym + ctx.imports_table.get(entry.target).?);
+ try writer.writeIntLittle(u32, iundefsym + ctx.imports_table.get(entry).?);
}
}
@@ -3731,11 +3598,11 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
if (self.la_symbol_ptr_section_index) |sect_id| {
const la_symbol_ptr = &self.sections.items(.header)[sect_id];
la_symbol_ptr.reserved1 = nstubs + ngot_entries;
- for (self.stubs_table.entries.items) |entry| {
- if (entry.sym_index == 0) continue;
- const target_sym = self.getSymbol(entry.target);
+ for (self.stub_table.entries.items) |entry| {
+ if (!self.stub_table.lookup.contains(entry)) continue;
+ const target_sym = self.getSymbol(entry);
assert(target_sym.undf());
- try writer.writeIntLittle(u32, iundefsym + ctx.imports_table.get(entry.target).?);
+ try writer.writeIntLittle(u32, iundefsym + ctx.imports_table.get(entry).?);
}
}
@@ -4422,7 +4289,7 @@ pub fn logSymtab(self: *MachO) void {
log.debug("{}", .{self.got_table});
log.debug("stubs entries:", .{});
- log.debug("{}", .{self.stubs_table.fmtDebug(self)});
+ log.debug("{}", .{self.stub_table});
log.debug("threadlocal entries:", .{});
log.debug("{}", .{self.tlv_table.fmtDebug(self)});