diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2023-04-18 23:00:55 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2023-04-21 22:44:27 +0200 |
| commit | c6e916d7fe4234c821eeeff19a73b334129c00de (patch) | |
| tree | 78bd853d86c12e8c06b58f7cc6a7e612bc78a6e0 /src | |
| parent | 711bc2cf3919a2010503610574e7dfcad8a17929 (diff) | |
| download | zig-c6e916d7fe4234c821eeeff19a73b334129c00de.tar.gz zig-c6e916d7fe4234c821eeeff19a73b334129c00de.zip | |
macho: fix runtime panics
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/MachO.zig | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 0efbf3b270..78b6a6c9a1 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3266,6 +3266,7 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { } // Gather GOT pointers + try rebase.entries.ensureUnusedCapacity(gpa, self.got_table.entries.items.len); const segment_index = self.sections.items(.segment_index)[self.got_section_index.?]; for (self.got_table.entries.items, 0..) |entry, i| { if (!self.got_table.lookup.contains(entry)) continue; @@ -3324,6 +3325,7 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void { } // Gather GOT pointers + try bind.entries.ensureUnusedCapacity(gpa, self.got_table.entries.items.len); const segment_index = self.sections.items(.segment_index)[self.got_section_index.?]; for (self.got_table.entries.items, 0..) |entry, i| { if (!self.got_table.lookup.contains(entry)) continue; @@ -3352,6 +3354,50 @@ 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 { + 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.finalize(gpa, self); +} + fn collectExportData(self: *MachO, trie: *Trie) !void { const gpa = self.base.allocator; @@ -3395,7 +3441,7 @@ fn writeDyldInfoData(self: *MachO) !void { var lazy_bind = LazyBind{}; defer lazy_bind.deinit(gpa); - try self.collectBindData(&lazy_bind, self.lazy_bindings); + try self.collectLazyBindData(&lazy_bind, self.lazy_bindings); var trie: Trie = .{}; defer trie.deinit(gpa); |
