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