diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/MachO/Object.zig | 19 | ||||
| -rw-r--r-- | src/link/MachO/ZldAtom.zig | 53 | ||||
| -rw-r--r-- | src/link/MachO/dead_strip.zig | 21 | ||||
| -rw-r--r-- | src/link/MachO/zld.zig | 24 |
4 files changed, 73 insertions, 44 deletions
diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 2309f7cfca..2c49108b82 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -316,6 +316,7 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u31) !void { object_id, sym_index, 0, + 0, sect.size, sect.@"align", out_sect_id, @@ -392,6 +393,7 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u31) !void { object_id, sym_index, 0, + 0, atom_size, sect.@"align", out_sect_id, @@ -429,6 +431,7 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u31) !void { zld, object_id, atom_sym_index, + atom_sym_index + 1, nsyms_trailing, atom_size, atom_align, @@ -447,19 +450,17 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u31) !void { zld.addAtomToSection(atom_index); } } else { - const sym_index = self.getSectionAliasSymbolIndex(sect_id); + const alias_index = self.getSectionAliasSymbolIndex(sect_id); const atom_index = try self.createAtomFromSubsection( zld, object_id, - sym_index, - 0, + alias_index, + sect_start_index, + sect_loc.len, sect.size, sect.@"align", out_sect_id, ); - // If there is no symbol to refer to this atom, we create - // a temp one, unless we already did that when working out the relocations - // of other atoms. zld.addAtomToSection(atom_index); } } @@ -470,7 +471,8 @@ fn createAtomFromSubsection( zld: *Zld, object_id: u31, sym_index: u32, - nsyms_trailing: u32, + inner_sym_index: u32, + inner_nsyms_trailing: u32, size: u64, alignment: u32, out_sect_id: u8, @@ -478,7 +480,8 @@ fn createAtomFromSubsection( const gpa = zld.gpa; const atom_index = try zld.createEmptyAtom(sym_index, size, alignment); const atom = zld.getAtomPtr(atom_index); - atom.nsyms_trailing = nsyms_trailing; + atom.inner_sym_index = inner_sym_index; + atom.inner_nsyms_trailing = inner_nsyms_trailing; atom.file = object_id; self.symtab[sym_index].n_sect = out_sect_id + 1; diff --git a/src/link/MachO/ZldAtom.zig b/src/link/MachO/ZldAtom.zig index 6326b122d8..44cc609b9a 100644 --- a/src/link/MachO/ZldAtom.zig +++ b/src/link/MachO/ZldAtom.zig @@ -28,7 +28,8 @@ sym_index: u32, /// If this Atom references a subsection in an Object file, `nsyms_trailing` /// tells how many symbols trailing `sym_index` fall within this Atom's address /// range. -nsyms_trailing: u32, +inner_sym_index: u32, +inner_nsyms_trailing: u32, /// -1 means symbol defined by the linker. /// Otherwise, it is the index into appropriate object file. @@ -52,7 +53,8 @@ prev_index: ?AtomIndex, pub const empty = Atom{ .sym_index = 0, - .nsyms_trailing = 0, + .inner_sym_index = 0, + .inner_nsyms_trailing = 0, .file = -1, .size = 0, .alignment = 0, @@ -81,9 +83,10 @@ const InnerSymIterator = struct { pub fn next(it: *@This()) ?SymbolWithLoc { if (it.count == 0) return null; + const res = SymbolWithLoc{ .sym_index = it.sym_index, .file = it.file }; it.sym_index += 1; it.count -= 1; - return SymbolWithLoc{ .sym_index = it.sym_index, .file = it.file }; + return res; } }; @@ -91,8 +94,8 @@ pub fn getInnerSymbolsIterator(zld: *Zld, atom_index: AtomIndex) InnerSymIterato const atom = zld.getAtom(atom_index); assert(atom.getFile() != null); return .{ - .sym_index = atom.sym_index, - .count = atom.nsyms_trailing, + .sym_index = atom.inner_sym_index, + .count = atom.inner_nsyms_trailing, .file = atom.file, }; } @@ -123,9 +126,16 @@ pub fn calcInnerSymbolOffset(zld: *Zld, atom_index: AtomIndex, sym_index: u32) u if (atom.sym_index == sym_index) return 0; const object = zld.objects.items[atom.getFile().?]; - const source_atom_sym = object.getSourceSymbol(atom.sym_index).?; const source_sym = object.getSourceSymbol(sym_index).?; - return source_sym.n_value - source_atom_sym.n_value; + const base_addr = if (object.getSourceSymbol(atom.sym_index)) |sym| + sym.n_value + else blk: { + const nbase = @intCast(u32, object.in_symtab.?.len); + const sect_id = @intCast(u16, atom.sym_index - nbase); + const source_sect = object.getSourceSection(sect_id); + break :blk source_sect.addr; + }; + return source_sym.n_value - base_addr; } pub fn scanAtomRelocs( @@ -383,13 +393,13 @@ pub fn resolveRelocs( .base_offset = @intCast(i32, source_sym.n_value - source_sect.addr), }; } - for (object.getSourceSections()) |source_sect, i| { - const sym_index = object.getSectionAliasSymbolIndex(@intCast(u8, i)); - if (sym_index == atom.sym_index) break :blk .{ - .base_addr = source_sect.addr, - .base_offset = 0, - }; - } else unreachable; + const nbase = @intCast(u32, object.in_symtab.?.len); + const sect_id = @intCast(u16, atom.sym_index - nbase); + const source_sect = object.getSourceSection(sect_id); + break :blk .{ + .base_addr = source_sect.addr, + .base_offset = 0, + }; }; log.debug("resolving relocations in ATOM(%{d}, '{s}')", .{ @@ -918,11 +928,9 @@ pub fn getAtomCode(zld: *Zld, atom_index: AtomIndex) []const u8 { // If there was no matching symbol present in the source symtab, this means // we are dealing with either an entire section, or part of it, but also // starting at the beginning. - const source_sect = for (object.getSourceSections()) |source_sect, sect_id| { - const sym_index = object.getSectionAliasSymbolIndex(@intCast(u8, sect_id)); - if (sym_index == atom.sym_index) break source_sect; - } else unreachable; - + const nbase = @intCast(u32, object.in_symtab.?.len); + const sect_id = @intCast(u16, atom.sym_index - nbase); + const source_sect = object.getSourceSection(sect_id); assert(!source_sect.isZerofill()); const code = object.getSectionContents(source_sect); const code_len = @intCast(usize, atom.size); @@ -949,10 +957,9 @@ pub fn getAtomRelocs(zld: *Zld, atom_index: AtomIndex) []align(1) const macho.re // If there was no matching symbol present in the source symtab, this means // we are dealing with either an entire section, or part of it, but also // starting at the beginning. - const source_sect = for (object.getSourceSections()) |source_sect, sect_id| { - const sym_index = object.getSectionAliasSymbolIndex(@intCast(u8, sect_id)); - if (sym_index == atom.sym_index) break source_sect; - } else unreachable; + const nbase = @intCast(u32, object.in_symtab.?.len); + const sect_id = @intCast(u16, atom.sym_index - nbase); + const source_sect = object.getSourceSection(sect_id); assert(!source_sect.isZerofill()); break :blk source_sect; }; diff --git a/src/link/MachO/dead_strip.zig b/src/link/MachO/dead_strip.zig index b329d6e547..8bcc6ca062 100644 --- a/src/link/MachO/dead_strip.zig +++ b/src/link/MachO/dead_strip.zig @@ -77,8 +77,15 @@ fn collectRoots(zld: *Zld, roots: *AtomTable) !void { for (zld.objects.items) |object| { for (object.atoms.items) |atom_index| { const atom = zld.getAtom(atom_index); - const source_sym = object.getSourceSymbol(atom.sym_index) orelse continue; - const source_sect = object.getSourceSection(source_sym.n_sect - 1); + + const sect_id = if (object.getSourceSymbol(atom.sym_index)) |source_sym| + source_sym.n_sect - 1 + else blk: { + const nbase = @intCast(u32, object.in_symtab.?.len); + const sect_id = @intCast(u16, atom.sym_index - nbase); + break :blk sect_id; + }; + const source_sect = object.getSourceSection(sect_id); const is_gc_root = blk: { if (source_sect.isDontDeadStrip()) break :blk true; if (mem.eql(u8, "__StaticInit", source_sect.sectName())) break :blk true; @@ -220,8 +227,14 @@ fn mark(zld: *Zld, roots: AtomTable, alive: *AtomTable, reverse_lookups: [][]u32 if (alive.contains(atom_index)) continue; const atom = zld.getAtom(atom_index); - const source_sym = object.getSourceSymbol(atom.sym_index) orelse continue; - const source_sect = object.getSourceSection(source_sym.n_sect - 1); + const sect_id = if (object.getSourceSymbol(atom.sym_index)) |source_sym| + source_sym.n_sect - 1 + else blk: { + const nbase = @intCast(u32, object.in_symtab.?.len); + const sect_id = @intCast(u16, atom.sym_index - nbase); + break :blk sect_id; + }; + const source_sect = object.getSourceSection(sect_id); if (source_sect.isDontDeadStripIfReferencesLive()) { if (try refersLive(zld, atom_index, alive.*, reverse_lookups)) { diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index 8caecd2465..bde418642a 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -1911,7 +1911,7 @@ pub const Zld = struct { sym.n_value, }); - if (atom.getFile()) |_| { + if (atom.getFile() != null) { // Update each symbol contained within the atom var it = Atom.getInnerSymbolsIterator(self, atom_index); while (it.next()) |sym_loc| { @@ -2160,8 +2160,11 @@ pub const Zld = struct { log.debug(" ATOM({d}, %{d}, '{s}')", .{ atom_index, atom.sym_index, self.getSymbolName(atom.getSymbolWithLoc()) }); const object = self.objects.items[atom.getFile().?]; - const source_sym = object.getSourceSymbol(atom.sym_index).?; - const source_sect = object.getSourceSection(source_sym.n_sect - 1); + const base_rel_offset: i32 = blk: { + const source_sym = object.getSourceSymbol(atom.sym_index) orelse break :blk 0; + const source_sect = object.getSourceSection(source_sym.n_sect - 1); + break :blk @intCast(i32, source_sym.n_value - source_sect.addr); + }; const relocs = Atom.getAtomRelocs(self, atom_index); for (relocs) |rel| { @@ -2180,7 +2183,7 @@ pub const Zld = struct { } const base_offset = @intCast(i32, sym.n_value - segment.vmaddr); - const rel_offset = rel.r_address - @intCast(i32, source_sym.n_value - source_sect.addr); + const rel_offset = rel.r_address - base_rel_offset; const offset = @intCast(u64, base_offset + rel_offset); log.debug(" | rebase at {x}", .{offset}); @@ -2288,8 +2291,11 @@ pub const Zld = struct { if (should_bind) { const object = self.objects.items[atom.getFile().?]; - const source_sym = object.getSourceSymbol(atom.sym_index).?; - const source_sect = object.getSourceSection(source_sym.n_sect - 1); + const base_rel_offset: i32 = blk: { + const source_sym = object.getSourceSymbol(atom.sym_index) orelse break :blk 0; + const source_sect = object.getSourceSection(source_sym.n_sect - 1); + break :blk @intCast(i32, source_sym.n_value - source_sect.addr); + }; const relocs = Atom.getAtomRelocs(self, atom_index); for (relocs) |rel| { @@ -2313,7 +2319,7 @@ pub const Zld = struct { if (!bind_sym.undf()) continue; const base_offset = @intCast(i32, sym.n_value - segment.vmaddr); - const rel_offset = rel.r_address - @intCast(i32, source_sym.n_value - source_sect.addr); + const rel_offset = rel.r_address - base_rel_offset; const offset = @intCast(u64, base_offset + rel_offset); const dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER); @@ -3491,7 +3497,7 @@ pub const Zld = struct { }); } } - scoped_log.debug(" object(null)", .{}); + scoped_log.debug(" object(-1)", .{}); for (self.locals.items) |sym, sym_id| { if (sym.undf()) continue; scoped_log.debug(" %{d}: {s} @{x} in sect({d}), {s}", .{ @@ -3635,7 +3641,7 @@ pub const Zld = struct { sym.n_sect, }); - if (atom.getFile()) |_| { + if (atom.getFile() != null) { var it = Atom.getInnerSymbolsIterator(self, atom_index); while (it.next()) |sym_loc| { const inner = self.getSymbol(sym_loc); |
