mirror of
https://github.com/ziglang/zig.git
synced 2026-01-01 02:53:23 +00:00
macho: fix handling of lack of subsections and tracking of inner symbols
This commit is contained in:
parent
5edb8e0b8f
commit
2c2ff4558f
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user