authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-18 21:23:00+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:41+01:00
log30b7d3e45f25195791f8eba74a2f89d41b325049
tree7dd6114f1daf548a297e93fa6a3a08c5d194dbe5
parent5ef63e333ad47c63ac648da48c25078bba0cccbb

macho: implement resolveSymbols in ZigObject


2 files changed, 74 insertions(+), 6 deletions(-)

src/link/MachO.zig+13-3
...@@ -564,7 +564,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node...@@ -564,7 +564,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
564 },564 },
565 };565 };
566566
567 self.markImportsAndExports();567 try self.markImportsAndExports();
568 self.deadStripDylibs();568 self.deadStripDylibs();
569569
570 for (self.dylibs.items, 1..) |index, ord| {570 for (self.dylibs.items, 1..) |index, ord| {
...@@ -1533,6 +1533,10 @@ fn checkDuplicates(self: *MachO) !void {...@@ -1533,6 +1533,10 @@ fn checkDuplicates(self: *MachO) !void {
1533 dupes.deinit();1533 dupes.deinit();
1534 }1534 }
15351535
1536 if (self.getZigObject()) |zo| {
1537 try zo.checkDuplicates(&dupes, self);
1538 }
1539
1536 for (self.objects.items) |index| {1540 for (self.objects.items) |index| {
1537 try self.getFile(index).?.object.checkDuplicates(&dupes, self);1541 try self.getFile(index).?.object.checkDuplicates(&dupes, self);
1538 }1542 }
...@@ -1540,8 +1544,14 @@ fn checkDuplicates(self: *MachO) !void {...@@ -1540,8 +1544,14 @@ fn checkDuplicates(self: *MachO) !void {
1540 try self.reportDuplicates(dupes);1544 try self.reportDuplicates(dupes);
1541}1545}
15421546
1543fn markImportsAndExports(self: *MachO) void {1547fn markImportsAndExports(self: *MachO) error{OutOfMemory}!void {
1544 for (self.objects.items) |index| {1548 const gpa = self.base.comp.gpa;
1549 var objects = try std.ArrayList(File.Index).initCapacity(gpa, self.objects.items.len + 1);
1550 defer objects.deinit();
1551 if (self.getZigObject()) |zo| objects.appendAssumeCapacity(zo.index);
1552 objects.appendSliceAssumeCapacity(self.objects.items);
1553
1554 for (objects.items) |index| {
1545 for (self.getFile(index).?.getSymbols()) |sym_index| {1555 for (self.getFile(index).?.getSymbols()) |sym_index| {
1546 const sym = self.getSymbol(sym_index);1556 const sym = self.getSymbol(sym_index);
1547 const file = sym.getFile(self) orelse continue;1557 const file = sym.getFile(self) orelse continue;
src/link/MachO/ZigObject.zig+61-3
...@@ -137,9 +137,60 @@ pub fn freeAtomRelocs(self: *ZigObject, atom: Atom) void {...@@ -137,9 +137,60 @@ pub fn freeAtomRelocs(self: *ZigObject, atom: Atom) void {
137}137}
138138
139pub fn resolveSymbols(self: *ZigObject, macho_file: *MachO) void {139pub fn resolveSymbols(self: *ZigObject, macho_file: *MachO) void {
140 _ = self;140 const tracy = trace(@src());
141 _ = macho_file;141 defer tracy.end();
142 @panic("TODO resolveSymbols");142
143 for (self.symbols.items, 0..) |index, i| {
144 const nlist_idx = @as(Symbol.Index, @intCast(i));
145 const nlist = self.symtab.items(.nlist)[nlist_idx];
146 const atom_index = self.symtab.items(.atom)[nlist_idx];
147
148 if (!nlist.ext()) continue;
149 if (nlist.undf() and !nlist.tentative()) continue;
150 if (nlist.sect()) {
151 const atom = macho_file.getAtom(atom_index).?;
152 if (!atom.flags.alive) continue;
153 }
154
155 const symbol = macho_file.getSymbol(index);
156 if (self.asFile().getSymbolRank(.{
157 .archive = false,
158 .weak = nlist.weakDef(),
159 .tentative = nlist.tentative(),
160 }) < symbol.getSymbolRank(macho_file)) {
161 const value = if (nlist.sect()) blk: {
162 const atom = macho_file.getAtom(atom_index).?;
163 break :blk nlist.n_value - atom.getInputAddress(macho_file);
164 } else nlist.n_value;
165 symbol.value = value;
166 symbol.atom = atom_index;
167 symbol.nlist_idx = nlist_idx;
168 symbol.file = self.index;
169 symbol.flags.weak = nlist.weakDef();
170 symbol.flags.abs = nlist.abs();
171 symbol.flags.tentative = nlist.tentative();
172 symbol.flags.weak_ref = false;
173 symbol.flags.dyn_ref = nlist.n_desc & macho.REFERENCED_DYNAMICALLY != 0;
174 symbol.flags.no_dead_strip = symbol.flags.no_dead_strip or nlist.noDeadStrip();
175 // TODO: symbol.flags.interposable = macho_file.base.isDynLib() and macho_file.options.namespace == .flat and !nlist.pext();
176 symbol.flags.interposable = false;
177
178 if (nlist.sect() and
179 macho_file.sections.items(.header)[nlist.n_sect - 1].type() == macho.S_THREAD_LOCAL_VARIABLES)
180 {
181 symbol.flags.tlv = true;
182 }
183 }
184
185 // Regardless of who the winner is, we still merge symbol visibility here.
186 if (nlist.pext() or (nlist.weakDef() and nlist.weakRef())) {
187 if (symbol.visibility != .global) {
188 symbol.visibility = .hidden;
189 }
190 } else {
191 symbol.visibility = .global;
192 }
193 }
143}194}
144195
145pub fn resetGlobals(self: *ZigObject, macho_file: *MachO) void {196pub fn resetGlobals(self: *ZigObject, macho_file: *MachO) void {
...@@ -170,6 +221,13 @@ pub fn markLive(self: *ZigObject, macho_file: *MachO) void {...@@ -170,6 +221,13 @@ pub fn markLive(self: *ZigObject, macho_file: *MachO) void {
170 }221 }
171}222}
172223
224pub fn checkDuplicates(self: *ZigObject, dupes: anytype, macho_file: *MachO) !void {
225 _ = self;
226 _ = dupes;
227 _ = macho_file;
228 @panic("TODO checkDuplicates");
229}
230
173pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) !void {231pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) !void {
174 const tracy = trace(@src());232 const tracy = trace(@src());
175 defer tracy.end();233 defer tracy.end();