authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-17 08:33:58+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:41+01:00
logbd9d8bd462799c552eed9812484add68e498a3ee
tree34bf18252080820f36a5645b065096cda403e091
parent9509fadbe38e77bc0f8b079c4d9def2937d81322

macho: create Atom for Decl in ZigObject


4 files changed, 135 insertions(+), 58 deletions(-)

src/link/MachO/Atom.zig+3-3
......@@ -55,7 +55,7 @@ pub fn getData(self: Atom, macho_file: *MachO) []const u8 {
5555
5656pub fn getRelocs(self: Atom, macho_file: *MachO) []const Relocation {
5757 return switch (self.getFile(macho_file)) {
58 .zig_object => @panic("TODO Atom.getRelocs"),
58 .zig_object => |x| x.getAtomRelocs(self),
5959 .object => |x| x.getAtomRelocs(self),
6060 else => unreachable,
6161 };
......@@ -890,8 +890,8 @@ pub const Flags = packed struct {
890890};
891891
892892pub const Loc = struct {
893 pos: usize = 0,
894 len: usize = 0,
893 pos: u32 = 0,
894 len: u32 = 0,
895895};
896896
897897pub const Alignment = @import("../../InternPool.zig").Alignment;
src/link/MachO/Object.zig+2-2
......@@ -608,7 +608,7 @@ fn initRelocs(self: *Object, macho_file: *MachO) !void {
608608 for (slice.items(.header), slice.items(.relocs), slice.items(.subsections)) |sect, relocs, subsections| {
609609 if (sect.isZerofill()) continue;
610610
611 var next_reloc: usize = 0;
611 var next_reloc: u32 = 0;
612612 for (subsections.items) |subsection| {
613613 const atom = macho_file.getAtom(subsection.atom).?;
614614 if (!atom.flags.alive) continue;
......@@ -1767,7 +1767,7 @@ const Subsection = struct {
17671767 off: u64,
17681768};
17691769
1770const Nlist = struct {
1770pub const Nlist = struct {
17711771 nlist: macho.nlist_64,
17721772 size: u64,
17731773 atom: Atom.Index,
src/link/MachO/Symbol.zig+6-1
......@@ -19,7 +19,7 @@ out_n_sect: u16 = 0,
1919
2020/// Index of the source nlist this symbol references.
2121/// Use `getNlist` to pull the nlist from the relevant file.
22nlist_idx: u32 = 0,
22nlist_idx: Index = 0,
2323
2424/// Misc flags for the symbol packaged as packed struct for compression.
2525flags: Flags = .{},
......@@ -352,6 +352,10 @@ pub const Flags = packed struct {
352352 needs_got: bool = false,
353353 has_got: bool = false,
354354
355 /// Whether the symbol contains __got_zig indirection.
356 needs_zig_got: bool = false,
357 has_zig_got: bool = false,
358
355359 /// Whether the symbols contains __stubs indirection.
356360 stubs: bool = false,
357361
......@@ -386,5 +390,6 @@ const std = @import("std");
386390const Atom = @import("Atom.zig");
387391const File = @import("file.zig").File;
388392const MachO = @import("../MachO.zig");
393const Nlist = Object.Nlist;
389394const Object = @import("Object.zig");
390395const Symbol = @This();
src/link/MachO/ZigObject.zig+124-52
......@@ -7,6 +7,12 @@ symtab: std.MultiArrayList(Nlist) = .{},
77symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
88atoms: std.ArrayListUnmanaged(Atom.Index) = .{},
99
10/// Table of tracked Decls.
11decls: DeclTable = .{},
12
13/// A table of relocations.
14relocs: RelocationTable = .{},
15
1016output_symtab_ctx: MachO.SymtabCtx = .{},
1117
1218pub fn init(self: *ZigObject, macho_file: *MachO) !void {
......@@ -20,6 +26,19 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
2026 self.symtab.deinit(allocator);
2127 self.symbols.deinit(allocator);
2228 self.atoms.deinit(allocator);
29
30 {
31 var it = self.decls.iterator();
32 while (it.next()) |entry| {
33 entry.value_ptr.exports.deinit(allocator);
34 }
35 self.decls.deinit(allocator);
36 }
37
38 for (self.relocs.items) |*list| {
39 list.deinit(allocator);
40 }
41 self.relocs.deinit(allocator);
2342}
2443
2544fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index {
......@@ -33,6 +52,38 @@ fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index {
3352 return index;
3453}
3554
55pub fn addAtom(self: *ZigObject, macho_file: *MachO) !Symbol.Index {
56 const gpa = macho_file.base.comp.gpa;
57 const atom_index = try macho_file.addAtom();
58 const symbol_index = try macho_file.addSymbol();
59 const nlist_index = try self.addNlist(gpa);
60
61 try self.atoms.append(gpa, atom_index);
62 try self.symbols.append(gpa, symbol_index);
63
64 const atom = macho_file.getAtom(atom_index).?;
65 atom.file = self.index;
66
67 const symbol = macho_file.getSymbol(symbol_index);
68 symbol.file = self.index;
69 symbol.atom = atom_index;
70
71 self.symtab.items(.atom)[nlist_index] = atom_index;
72 symbol.nlist_idx = nlist_index;
73
74 const relocs_index = @as(u32, @intCast(self.relocs.items.len));
75 const relocs = try self.relocs.addOne(gpa);
76 relocs.* = .{};
77 atom.relocs = .{ .pos = relocs_index, .len = 0 };
78
79 return symbol_index;
80}
81
82pub fn getAtomRelocs(self: *ZigObject, atom: Atom) []const Relocation {
83 const relocs = self.relocs.items[atom.relocs.pos];
84 return relocs.items[0..atom.relocs.len];
85}
86
3687pub fn resolveSymbols(self: *ZigObject, macho_file: *MachO) void {
3788 _ = self;
3889 _ = macho_file;
......@@ -216,54 +267,35 @@ pub fn updateDecl(
216267 return;
217268 }
218269
219 // const is_threadlocal = if (decl.val.getVariable(mod)) |variable|
220 // variable.is_threadlocal and comp.config.any_non_single_threaded
221 // else
222 // false;
223 // if (is_threadlocal) return self.updateThreadlocalVariable(mod, decl_index);
224
225 // const atom_index = try self.getOrCreateAtomForDecl(decl_index);
226 // const sym_index = self.getAtom(atom_index).getSymbolIndex().?;
227 // Atom.freeRelocations(self, atom_index);
228
229 // const comp = macho_file.base.comp;
230 // const gpa = comp.gpa;
231
232 // var code_buffer = std.ArrayList(u8).init(gpa);
233 // defer code_buffer.deinit();
234
235 // var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym|
236 // try d_sym.dwarf.initDeclState(mod, decl_index)
237 // else
238 // null;
239 // defer if (decl_state) |*ds| ds.deinit();
240
241 // const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
242 // const res = if (decl_state) |*ds|
243 // try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
244 // .ty = decl.ty,
245 // .val = decl_val,
246 // }, &code_buffer, .{
247 // .dwarf = ds,
248 // }, .{
249 // .parent_atom_index = sym_index,
250 // })
251 // else
252 // try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
253 // .ty = decl.ty,
254 // .val = decl_val,
255 // }, &code_buffer, .none, .{
256 // .parent_atom_index = sym_index,
257 // });
258
259 // const code = switch (res) {
260 // .ok => code_buffer.items,
261 // .fail => |em| {
262 // decl.analysis = .codegen_failure;
263 // try mod.failed_decls.put(mod.gpa, decl_index, em);
264 // return;
265 // },
266 // };
270 const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index);
271 // TODO: free relocs if any
272
273 const gpa = macho_file.base.comp.gpa;
274 var code_buffer = std.ArrayList(u8).init(gpa);
275 defer code_buffer.deinit();
276
277 var decl_state: ?Dwarf.DeclState = null; // TODO: Dwarf
278 defer if (decl_state) |*ds| ds.deinit();
279
280 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
281 const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;
282 const res =
283 try codegen.generateSymbol(&macho_file.base, decl.srcLoc(mod), .{
284 .ty = decl.ty,
285 .val = decl_val,
286 }, &code_buffer, dio, .{
287 .parent_atom_index = sym_index,
288 });
289
290 const code = switch (res) {
291 .ok => code_buffer.items,
292 .fail => |em| {
293 decl.analysis = .codegen_failure;
294 try mod.failed_decls.put(mod.gpa, decl_index, em);
295 return;
296 },
297 };
298 _ = code;
267299 // const addr = try self.updateDeclCode(decl_index, code);
268300
269301 // if (decl_state) |*ds| {
......@@ -342,6 +374,32 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l
342374 @panic("TODO getGlobalSymbol");
343375}
344376
377pub fn getOrCreateMetadataForDecl(
378 self: *ZigObject,
379 macho_file: *MachO,
380 decl_index: InternPool.DeclIndex,
381) !Symbol.Index {
382 const gpa = macho_file.base.comp.gpa;
383 const gop = try self.decls.getOrPut(gpa, decl_index);
384 if (!gop.found_existing) {
385 const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;
386 const sym_index = try self.addAtom(macho_file);
387 const mod = macho_file.base.comp.module.?;
388 const decl = mod.declPtr(decl_index);
389 const sym = macho_file.getSymbol(self.symbols.items[sym_index]);
390 if (decl.getOwnedVariable(mod)) |variable| {
391 if (variable.is_threadlocal and any_non_single_threaded) {
392 sym.flags.tlv = true;
393 }
394 }
395 if (!sym.flags.tlv) {
396 sym.flags.needs_zig_got = true;
397 }
398 gop.value_ptr.* = .{ .symbol_index = sym_index };
399 }
400 return gop.value_ptr.symbol_index;
401}
402
345403pub fn asFile(self: *ZigObject) File {
346404 return .{ .zig_object = self };
347405}
......@@ -395,11 +453,23 @@ fn formatAtoms(
395453 }
396454}
397455
398const Nlist = struct {
399 nlist: macho.nlist_64,
400 size: u64,
401 atom: Atom.Index,
456const DeclMetadata = struct {
457 symbol_index: Symbol.Index,
458 /// A list of all exports aliases of this Decl.
459 exports: std.ArrayListUnmanaged(Symbol.Index) = .{},
460
461 fn @"export"(m: DeclMetadata, zig_object: *ZigObject, macho_file: *MachO, name: []const u8) ?*u32 {
462 for (m.exports.items) |*exp| {
463 const nlist = zig_object.symtab.items(.nlist)[exp.*];
464 const exp_name = macho_file.strings.getAssumeExists(nlist.n_strx);
465 if (mem.eql(u8, name, exp_name)) return exp;
466 }
467 return null;
468 }
402469};
470const DeclTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata);
471
472const RelocationTable = std.ArrayListUnmanaged(std.ArrayListUnmanaged(Relocation));
403473
404474const assert = std.debug.assert;
405475const builtin = @import("builtin");
......@@ -420,8 +490,10 @@ const File = @import("file.zig").File;
420490const InternPool = @import("../../InternPool.zig");
421491const Liveness = @import("../../Liveness.zig");
422492const MachO = @import("../MachO.zig");
493const Nlist = Object.Nlist;
423494const Module = @import("../../Module.zig");
424495const Object = @import("Object.zig");
496const Relocation = @import("Relocation.zig");
425497const Symbol = @import("Symbol.zig");
426498const StringTable = @import("../StringTable.zig");
427499const Type = @import("../../type.zig").Type;