authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-20 21:49:11+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:42+01:00
log6ad4062bf2b5066808d728071b87d4084d710e5b
treed5326a678d8ea0c8837789d62c7de67574787333
parentc02a603b63611a3f7963fce64f48ed3d2c10f86d

macho: save TLS variables in ZigObject


1 files changed, 71 insertions(+), 2 deletions(-)

src/link/MachO/ZigObject.zig+71-2
...@@ -38,6 +38,9 @@ unnamed_consts: UnnamedConstTable = .{},...@@ -38,6 +38,9 @@ unnamed_consts: UnnamedConstTable = .{},
38/// Table of tracked AnonDecls.38/// Table of tracked AnonDecls.
39anon_decls: AnonDeclTable = .{},39anon_decls: AnonDeclTable = .{},
4040
41/// TLS variables indexed by Atom.Index.
42tls_variables: TlsTable = .{},
43
41/// A table of relocations.44/// A table of relocations.
42relocs: RelocationTable = .{},45relocs: RelocationTable = .{},
4346
...@@ -87,6 +90,11 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {...@@ -87,6 +90,11 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
87 list.deinit(allocator);90 list.deinit(allocator);
88 }91 }
89 self.relocs.deinit(allocator);92 self.relocs.deinit(allocator);
93
94 for (self.tls_variables.values()) |*tlv| {
95 tlv.deinit(allocator);
96 }
97 self.tls_variables.deinit(allocator);
90}98}
9199
92fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index {100fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index {
...@@ -612,8 +620,7 @@ pub fn updateDecl(...@@ -612,8 +620,7 @@ pub fn updateDecl(
612 else => false,620 else => false,
613 };621 };
614 if (is_threadlocal) {622 if (is_threadlocal) {
615 // TODO: emit TLV623 try self.updateTlv(macho_file, decl_index, sym_index, sect_index, code);
616 @panic("TODO updateDecl for TLS");
617 } else {624 } else {
618 try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code);625 try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code);
619 }626 }
...@@ -715,6 +722,58 @@ fn updateDeclCode(...@@ -715,6 +722,58 @@ fn updateDeclCode(
715 }722 }
716}723}
717724
725fn updateTlv(
726 self: *ZigObject,
727 macho_file: *MachO,
728 decl_index: InternPool.DeclIndex,
729 sym_index: Symbol.Index,
730 sect_index: u8,
731 code: []const u8,
732) !void {
733 const comp = macho_file.base.comp;
734 const gpa = comp.gpa;
735 const mod = comp.module.?;
736 const decl = mod.declPtr(decl_index);
737 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
738
739 log.debug("updateTlv {s} ({*})", .{ decl_name, decl });
740
741 const required_alignment = decl.getAlignment(mod);
742
743 const sym = macho_file.getSymbol(sym_index);
744 const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];
745 const atom = sym.getAtom(macho_file).?;
746
747 sym.out_n_sect = sect_index;
748 atom.out_n_sect = sect_index;
749
750 sym.name = try macho_file.strings.insert(gpa, decl_name);
751 atom.flags.alive = true;
752 atom.name = sym.name;
753 nlist.n_strx = sym.name;
754 nlist.n_sect = sect_index + 1;
755 nlist.n_type = macho.N_EXT;
756 self.symtab.items(.size)[sym.nlist_idx] = code.len;
757
758 atom.alignment = required_alignment;
759 atom.size = code.len;
760
761 const slice = macho_file.sections.slice();
762 const header = slice.items(.header)[sect_index];
763 const atoms = &slice.items(.atoms)[sect_index];
764
765 const gop = try self.tls_variables.getOrPut(gpa, atom.atom_index);
766 assert(!gop.found_existing); // TODO incremental updates
767 gop.value_ptr.* = .{ .symbol_index = sym_index };
768
769 // We only store the data for the TLV if it's non-zerofill.
770 if (!header.isZerofill()) {
771 gop.value_ptr.code = try gpa.dupe(u8, code);
772 }
773
774 try atoms.append(gpa, atom.atom_index);
775}
776
718fn getDeclOutputSection(777fn getDeclOutputSection(
719 self: *ZigObject,778 self: *ZigObject,
720 macho_file: *MachO,779 macho_file: *MachO,
...@@ -1244,11 +1303,21 @@ const LazySymbolMetadata = struct {...@@ -1244,11 +1303,21 @@ const LazySymbolMetadata = struct {
1244 const_state: State = .unused,1303 const_state: State = .unused,
1245};1304};
12461305
1306const TlsVariable = struct {
1307 symbol_index: Symbol.Index,
1308 code: []const u8 = &[0]u8{},
1309
1310 fn deinit(tlv: *TlsVariable, allocator: Allocator) void {
1311 allocator.free(tlv.code);
1312 }
1313};
1314
1247const DeclTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata);1315const DeclTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata);
1248const UnnamedConstTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Symbol.Index));1316const UnnamedConstTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Symbol.Index));
1249const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata);1317const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata);
1250const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata);1318const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata);
1251const RelocationTable = std.ArrayListUnmanaged(std.ArrayListUnmanaged(Relocation));1319const RelocationTable = std.ArrayListUnmanaged(std.ArrayListUnmanaged(Relocation));
1320const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable);
12521321
1253const assert = std.debug.assert;1322const assert = std.debug.assert;
1254const builtin = @import("builtin");1323const builtin = @import("builtin");