diff options
Diffstat (limited to 'src/link/MachO/Object.zig')
| -rw-r--r-- | src/link/MachO/Object.zig | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 32f33eeff0..401184da51 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -44,6 +44,10 @@ symtab: []macho.nlist_64 = undefined, /// Can be undefined as set together with in_symtab. source_symtab_lookup: []u32 = undefined, /// Can be undefined as set together with in_symtab. +source_address_lookup: []i64 = undefined, +/// Can be undefined as set together with in_symtab. +source_section_index_lookup: []i64 = undefined, +/// Can be undefined as set together with in_symtab. strtab_lookup: []u32 = undefined, /// Can be undefined as set together with in_symtab. atom_by_index_table: []AtomIndex = undefined, @@ -58,6 +62,8 @@ pub fn deinit(self: *Object, gpa: Allocator) void { gpa.free(self.contents); if (self.in_symtab) |_| { gpa.free(self.source_symtab_lookup); + gpa.free(self.source_address_lookup); + gpa.free(self.source_section_index_lookup); gpa.free(self.strtab_lookup); gpa.free(self.symtab); gpa.free(self.atom_by_index_table); @@ -116,6 +122,10 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) self.strtab_lookup = try allocator.alloc(u32, self.in_symtab.?.len); self.globals_lookup = try allocator.alloc(i64, self.in_symtab.?.len); self.atom_by_index_table = try allocator.alloc(AtomIndex, self.in_symtab.?.len + nsects); + // This is wasteful but we need to be able to lookup source symbol address after stripping and + // allocating of sections. + self.source_address_lookup = try allocator.alloc(i64, self.in_symtab.?.len); + self.source_section_index_lookup = try allocator.alloc(i64, nsects); for (self.symtab) |*sym| { sym.* = .{ @@ -129,6 +139,7 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) mem.set(i64, self.globals_lookup, -1); mem.set(AtomIndex, self.atom_by_index_table, 0); + mem.set(i64, self.source_section_index_lookup, -1); // You would expect that the symbol table is at least pre-sorted based on symbol's type: // local < extern defined < undefined. Unfortunately, this is not guaranteed! For instance, @@ -150,8 +161,13 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) for (sorted_all_syms.items) |sym_id, i| { const sym = sym_id.getSymbol(self); + if (sym.sect() and self.source_section_index_lookup[sym.n_sect - 1] == -1) { + self.source_section_index_lookup[sym.n_sect - 1] = @intCast(i64, i); + } + self.symtab[i] = sym; self.source_symtab_lookup[i] = sym_id.index; + self.source_address_lookup[i] = if (sym.undf()) -1 else @intCast(i64, sym.n_value); const sym_name_len = mem.sliceTo(@ptrCast([*:0]const u8, self.in_strtab.?.ptr + sym.n_strx), 0).len + 1; self.strtab_lookup[i] = @intCast(u32, sym_name_len); @@ -244,13 +260,12 @@ fn filterSymbolsBySection(symbols: []macho.nlist_64, n_sect: u8) struct { return .{ .index = @intCast(u32, index), .len = @intCast(u32, len) }; } -fn filterSymbolsByAddress(symbols: []macho.nlist_64, n_sect: u8, start_addr: u64, end_addr: u64) struct { +fn filterSymbolsByAddress(symbols: []macho.nlist_64, start_addr: u64, end_addr: u64) struct { index: u32, len: u32, } { const Predicate = struct { addr: u64, - n_sect: u8, pub fn predicate(pred: @This(), symbol: macho.nlist_64) bool { return symbol.n_value >= pred.addr; @@ -259,11 +274,9 @@ fn filterSymbolsByAddress(symbols: []macho.nlist_64, n_sect: u8, start_addr: u64 const index = @import("zld.zig").lsearch(macho.nlist_64, symbols, Predicate{ .addr = start_addr, - .n_sect = n_sect, }); const len = @import("zld.zig").lsearch(macho.nlist_64, symbols[index..], Predicate{ .addr = end_addr, - .n_sect = n_sect, }); return .{ .index = @intCast(u32, index), .len = @intCast(u32, len) }; @@ -412,12 +425,7 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u31) !void { while (next_sym_index < sect_start_index + sect_loc.len) { const next_sym = symtab[next_sym_index]; const addr = next_sym.n_value; - const atom_loc = filterSymbolsByAddress( - symtab[next_sym_index..], - sect_id + 1, - addr, - addr + 1, - ); + const atom_loc = filterSymbolsByAddress(symtab[next_sym_index..], addr, addr + 1); assert(atom_loc.len > 0); const atom_sym_index = atom_loc.index + next_sym_index; const nsyms_trailing = atom_loc.len - 1; |
