diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-01-18 21:23:00 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-01-24 12:34:41 +0100 |
| commit | 30b7d3e45f25195791f8eba74a2f89d41b325049 (patch) | |
| tree | 7dd6114f1daf548a297e93fa6a3a08c5d194dbe5 /src | |
| parent | 5ef63e333ad47c63ac648da48c25078bba0cccbb (diff) | |
| download | zig-30b7d3e45f25195791f8eba74a2f89d41b325049.tar.gz zig-30b7d3e45f25195791f8eba74a2f89d41b325049.zip | |
macho: implement resolveSymbols in ZigObject
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/MachO.zig | 16 | ||||
| -rw-r--r-- | src/link/MachO/ZigObject.zig | 64 |
2 files changed, 74 insertions, 6 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 7af13ca8d2..6763d21fdf 100644 --- a/src/link/MachO.zig +++ b/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; diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index aa29dc59e1..b6a8f5448b 100644 --- a/src/link/MachO/ZigObject.zig +++ b/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(); |
