aboutsummaryrefslogtreecommitdiff
path: root/src/link/MachO/Object.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/link/MachO/Object.zig')
-rw-r--r--src/link/MachO/Object.zig28
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;