| ... | ... | @@ -50,7 +50,7 @@ reverse_symtab_lookup: []u32 = undefined, |
| 50 | 50 | /// Can be undefined as set together with in_symtab. |
| 51 | 51 | source_address_lookup: []i64 = undefined, |
| 52 | 52 | /// Can be undefined as set together with in_symtab. |
| 53 | | source_section_index_lookup: []i64 = undefined, |
| 53 | source_section_index_lookup: []Entry = undefined, |
| 54 | 54 | /// Can be undefined as set together with in_symtab. |
| 55 | 55 | strtab_lookup: []u32 = undefined, |
| 56 | 56 | /// Can be undefined as set together with in_symtab. |
| ... | ... | @@ -58,7 +58,7 @@ atom_by_index_table: []AtomIndex = undefined, |
| 58 | 58 | /// Can be undefined as set together with in_symtab. |
| 59 | 59 | globals_lookup: []i64 = undefined, |
| 60 | 60 | /// Can be undefined as set together with in_symtab. |
| 61 | | relocs_lookup: []RelocEntry = undefined, |
| 61 | relocs_lookup: []Entry = undefined, |
| 62 | 62 | |
| 63 | 63 | /// All relocations sorted and flatened, sorted by address descending |
| 64 | 64 | /// per section. |
| ... | ... | @@ -81,11 +81,14 @@ unwind_info_sect_id: ?u8 = null, |
| 81 | 81 | unwind_relocs_lookup: []Record = undefined, |
| 82 | 82 | unwind_records_lookup: std.AutoHashMapUnmanaged(AtomIndex, u32) = .{}, |
| 83 | 83 | |
| 84 | | const RelocEntry = struct { start: u32, len: u32 }; |
| 84 | const Entry = struct { |
| 85 | start: u32 = 0, |
| 86 | len: u32 = 0, |
| 87 | }; |
| 85 | 88 | |
| 86 | 89 | const Record = struct { |
| 87 | 90 | dead: bool, |
| 88 | | reloc: RelocEntry, |
| 91 | reloc: Entry, |
| 89 | 92 | }; |
| 90 | 93 | |
| 91 | 94 | pub fn deinit(self: *Object, gpa: Allocator) void { |
| ... | ... | @@ -170,11 +173,11 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) |
| 170 | 173 | self.strtab_lookup = try allocator.alloc(u32, self.in_symtab.?.len); |
| 171 | 174 | self.globals_lookup = try allocator.alloc(i64, self.in_symtab.?.len); |
| 172 | 175 | self.atom_by_index_table = try allocator.alloc(AtomIndex, self.in_symtab.?.len + nsects); |
| 173 | | self.relocs_lookup = try allocator.alloc(RelocEntry, self.in_symtab.?.len + nsects); |
| 176 | self.relocs_lookup = try allocator.alloc(Entry, self.in_symtab.?.len + nsects); |
| 174 | 177 | // This is wasteful but we need to be able to lookup source symbol address after stripping and |
| 175 | 178 | // allocating of sections. |
| 176 | 179 | self.source_address_lookup = try allocator.alloc(i64, self.in_symtab.?.len); |
| 177 | | self.source_section_index_lookup = try allocator.alloc(i64, nsects); |
| 180 | self.source_section_index_lookup = try allocator.alloc(Entry, nsects); |
| 178 | 181 | |
| 179 | 182 | for (self.symtab) |*sym| { |
| 180 | 183 | sym.* = .{ |
| ... | ... | @@ -188,11 +191,8 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) |
| 188 | 191 | |
| 189 | 192 | mem.set(i64, self.globals_lookup, -1); |
| 190 | 193 | mem.set(AtomIndex, self.atom_by_index_table, 0); |
| 191 | | mem.set(i64, self.source_section_index_lookup, -1); |
| 192 | | mem.set(RelocEntry, self.relocs_lookup, .{ |
| 193 | | .start = 0, |
| 194 | | .len = 0, |
| 195 | | }); |
| 194 | mem.set(Entry, self.source_section_index_lookup, .{}); |
| 195 | mem.set(Entry, self.relocs_lookup, .{}); |
| 196 | 196 | |
| 197 | 197 | // You would expect that the symbol table is at least pre-sorted based on symbol's type: |
| 198 | 198 | // local < extern defined < undefined. Unfortunately, this is not guaranteed! For instance, |
| ... | ... | @@ -211,13 +211,25 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) |
| 211 | 211 | // is kind enough to specify the symbols in the correct order. |
| 212 | 212 | sort.sort(SymbolAtIndex, sorted_all_syms.items, self, SymbolAtIndex.lessThan); |
| 213 | 213 | |
| 214 | var prev_sect_id: u8 = 0; |
| 215 | var section_index_lookup: ?Entry = null; |
| 214 | 216 | for (sorted_all_syms.items, 0..) |sym_id, i| { |
| 215 | 217 | const sym = sym_id.getSymbol(self); |
| 216 | 218 | |
| 217 | | if (sym.sect() and self.source_section_index_lookup[sym.n_sect - 1] == -1) { |
| 218 | | self.source_section_index_lookup[sym.n_sect - 1] = @intCast(i64, i); |
| 219 | if (section_index_lookup) |*lookup| { |
| 220 | if (sym.n_sect != prev_sect_id or sym.undf()) { |
| 221 | self.source_section_index_lookup[prev_sect_id - 1] = lookup.*; |
| 222 | section_index_lookup = null; |
| 223 | } else { |
| 224 | lookup.len += 1; |
| 225 | } |
| 226 | } |
| 227 | if (sym.sect() and section_index_lookup == null) { |
| 228 | section_index_lookup = .{ .start = @intCast(u32, i), .len = 1 }; |
| 219 | 229 | } |
| 220 | 230 | |
| 231 | prev_sect_id = sym.n_sect; |
| 232 | |
| 221 | 233 | self.symtab[i] = sym; |
| 222 | 234 | self.source_symtab_lookup[i] = sym_id.index; |
| 223 | 235 | self.reverse_symtab_lookup[sym_id.index] = @intCast(u32, i); |
| ... | ... | @@ -234,13 +246,7 @@ pub fn parse(self: *Object, allocator: Allocator, cpu_arch: std.Target.Cpu.Arch) |
| 234 | 246 | self.unwind_info_sect_id = self.getSourceSectionIndexByName("__LD", "__compact_unwind"); |
| 235 | 247 | if (self.hasUnwindRecords()) { |
| 236 | 248 | self.unwind_relocs_lookup = try allocator.alloc(Record, self.getUnwindRecords().len); |
| 237 | | mem.set(Record, self.unwind_relocs_lookup, .{ |
| 238 | | .dead = true, |
| 239 | | .reloc = .{ |
| 240 | | .start = 0, |
| 241 | | .len = 0, |
| 242 | | }, |
| 243 | | }); |
| 249 | mem.set(Record, self.unwind_relocs_lookup, .{ .dead = true, .reloc = .{} }); |
| 244 | 250 | } |
| 245 | 251 | } |
| 246 | 252 | |
| ... | ... | @@ -620,7 +626,7 @@ fn filterRelocs( |
| 620 | 626 | relocs: []align(1) const macho.relocation_info, |
| 621 | 627 | start_addr: u64, |
| 622 | 628 | end_addr: u64, |
| 623 | | ) RelocEntry { |
| 629 | ) Entry { |
| 624 | 630 | const Predicate = struct { |
| 625 | 631 | addr: u64, |
| 626 | 632 | |
| ... | ... | @@ -712,9 +718,9 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void { |
| 712 | 718 | |
| 713 | 719 | while (try it.next()) |record| { |
| 714 | 720 | const offset = it.pos - record.getSize(); |
| 715 | | const rel_pos = switch (cpu_arch) { |
| 721 | const rel_pos: Entry = switch (cpu_arch) { |
| 716 | 722 | .aarch64 => filterRelocs(relocs, offset, offset + record.getSize()), |
| 717 | | .x86_64 => RelocEntry{ .start = 0, .len = 0 }, |
| 723 | .x86_64 => .{}, |
| 718 | 724 | else => unreachable, |
| 719 | 725 | }; |
| 720 | 726 | self.eh_frame_relocs_lookup.putAssumeCapacityNoClobber(offset, .{ |
| ... | ... | @@ -990,13 +996,15 @@ pub fn getSymbolByAddress(self: Object, addr: u64, sect_hint: ?u8) u32 { |
| 990 | 996 | }; |
| 991 | 997 | |
| 992 | 998 | if (sect_hint) |sect_id| { |
| 993 | | if (self.source_section_index_lookup[sect_id] > -1) { |
| 994 | | const first_sym_index = @intCast(usize, self.source_section_index_lookup[sect_id]); |
| 995 | | const target_sym_index = @import("zld.zig").lsearch(i64, self.source_address_lookup[first_sym_index..], Predicate{ |
| 996 | | .addr = @intCast(i64, addr), |
| 997 | | }); |
| 999 | if (self.source_section_index_lookup[sect_id].len > 0) { |
| 1000 | const lookup = self.source_section_index_lookup[sect_id]; |
| 1001 | const target_sym_index = @import("zld.zig").lsearch( |
| 1002 | i64, |
| 1003 | self.source_address_lookup[lookup.start..][0..lookup.len], |
| 1004 | Predicate{ .addr = @intCast(i64, addr) }, |
| 1005 | ); |
| 998 | 1006 | if (target_sym_index > 0) { |
| 999 | | return @intCast(u32, first_sym_index + target_sym_index - 1); |
| 1007 | return @intCast(u32, lookup.start + target_sym_index - 1); |
| 1000 | 1008 | } |
| 1001 | 1009 | } |
| 1002 | 1010 | return self.getSectionAliasSymbolIndex(sect_id); |