Commit 2c2ff4558f
Changed files (4)
src
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)) {
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;
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);
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;
};