macho: implement resolveSymbols in ZigObject

This commit is contained in:
Jakub Konka 2024-01-18 21:23:00 +01:00
parent 5ef63e333a
commit 30b7d3e45f
2 changed files with 74 additions and 6 deletions

View File

@ -564,7 +564,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
},
};
self.markImportsAndExports();
try self.markImportsAndExports();
self.deadStripDylibs();
for (self.dylibs.items, 1..) |index, ord| {
@ -1533,6 +1533,10 @@ fn checkDuplicates(self: *MachO) !void {
dupes.deinit();
}
if (self.getZigObject()) |zo| {
try zo.checkDuplicates(&dupes, self);
}
for (self.objects.items) |index| {
try self.getFile(index).?.object.checkDuplicates(&dupes, self);
}
@ -1540,8 +1544,14 @@ fn checkDuplicates(self: *MachO) !void {
try self.reportDuplicates(dupes);
}
fn markImportsAndExports(self: *MachO) void {
for (self.objects.items) |index| {
fn markImportsAndExports(self: *MachO) error{OutOfMemory}!void {
const gpa = self.base.comp.gpa;
var objects = try std.ArrayList(File.Index).initCapacity(gpa, self.objects.items.len + 1);
defer objects.deinit();
if (self.getZigObject()) |zo| objects.appendAssumeCapacity(zo.index);
objects.appendSliceAssumeCapacity(self.objects.items);
for (objects.items) |index| {
for (self.getFile(index).?.getSymbols()) |sym_index| {
const sym = self.getSymbol(sym_index);
const file = sym.getFile(self) orelse continue;

View File

@ -137,9 +137,60 @@ pub fn freeAtomRelocs(self: *ZigObject, atom: Atom) void {
}
pub fn resolveSymbols(self: *ZigObject, macho_file: *MachO) void {
_ = self;
_ = macho_file;
@panic("TODO resolveSymbols");
const tracy = trace(@src());
defer tracy.end();
for (self.symbols.items, 0..) |index, i| {
const nlist_idx = @as(Symbol.Index, @intCast(i));
const nlist = self.symtab.items(.nlist)[nlist_idx];
const atom_index = self.symtab.items(.atom)[nlist_idx];
if (!nlist.ext()) continue;
if (nlist.undf() and !nlist.tentative()) continue;
if (nlist.sect()) {
const atom = macho_file.getAtom(atom_index).?;
if (!atom.flags.alive) continue;
}
const symbol = macho_file.getSymbol(index);
if (self.asFile().getSymbolRank(.{
.archive = false,
.weak = nlist.weakDef(),
.tentative = nlist.tentative(),
}) < symbol.getSymbolRank(macho_file)) {
const value = if (nlist.sect()) blk: {
const atom = macho_file.getAtom(atom_index).?;
break :blk nlist.n_value - atom.getInputAddress(macho_file);
} else nlist.n_value;
symbol.value = value;
symbol.atom = atom_index;
symbol.nlist_idx = nlist_idx;
symbol.file = self.index;
symbol.flags.weak = nlist.weakDef();
symbol.flags.abs = nlist.abs();
symbol.flags.tentative = nlist.tentative();
symbol.flags.weak_ref = false;
symbol.flags.dyn_ref = nlist.n_desc & macho.REFERENCED_DYNAMICALLY != 0;
symbol.flags.no_dead_strip = symbol.flags.no_dead_strip or nlist.noDeadStrip();
// TODO: symbol.flags.interposable = macho_file.base.isDynLib() and macho_file.options.namespace == .flat and !nlist.pext();
symbol.flags.interposable = false;
if (nlist.sect() and
macho_file.sections.items(.header)[nlist.n_sect - 1].type() == macho.S_THREAD_LOCAL_VARIABLES)
{
symbol.flags.tlv = true;
}
}
// Regardless of who the winner is, we still merge symbol visibility here.
if (nlist.pext() or (nlist.weakDef() and nlist.weakRef())) {
if (symbol.visibility != .global) {
symbol.visibility = .hidden;
}
} else {
symbol.visibility = .global;
}
}
}
pub fn resetGlobals(self: *ZigObject, macho_file: *MachO) void {
@ -170,6 +221,13 @@ pub fn markLive(self: *ZigObject, macho_file: *MachO) void {
}
}
pub fn checkDuplicates(self: *ZigObject, dupes: anytype, macho_file: *MachO) !void {
_ = self;
_ = dupes;
_ = macho_file;
@panic("TODO checkDuplicates");
}
pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) !void {
const tracy = trace(@src());
defer tracy.end();