Commit 30b7d3e45f
Changed files (2)
src
link
src/link/MachO/ZigObject.zig
@@ -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();
src/link/MachO.zig
@@ -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;