diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-01-20 21:49:11 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-01-24 12:34:42 +0100 |
| commit | 6ad4062bf2b5066808d728071b87d4084d710e5b (patch) | |
| tree | d5326a678d8ea0c8837789d62c7de67574787333 /src | |
| parent | c02a603b63611a3f7963fce64f48ed3d2c10f86d (diff) | |
| download | zig-6ad4062bf2b5066808d728071b87d4084d710e5b.tar.gz zig-6ad4062bf2b5066808d728071b87d4084d710e5b.zip | |
macho: save TLS variables in ZigObject
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/MachO/ZigObject.zig | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index 930d500e29..976a3236ae 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -38,6 +38,9 @@ unnamed_consts: UnnamedConstTable = .{}, /// Table of tracked AnonDecls. anon_decls: AnonDeclTable = .{}, +/// TLS variables indexed by Atom.Index. +tls_variables: TlsTable = .{}, + /// A table of relocations. relocs: RelocationTable = .{}, @@ -87,6 +90,11 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { list.deinit(allocator); } self.relocs.deinit(allocator); + + for (self.tls_variables.values()) |*tlv| { + tlv.deinit(allocator); + } + self.tls_variables.deinit(allocator); } fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index { @@ -612,8 +620,7 @@ pub fn updateDecl( else => false, }; if (is_threadlocal) { - // TODO: emit TLV - @panic("TODO updateDecl for TLS"); + try self.updateTlv(macho_file, decl_index, sym_index, sect_index, code); } else { try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code); } @@ -715,6 +722,58 @@ fn updateDeclCode( } } +fn updateTlv( + self: *ZigObject, + macho_file: *MachO, + decl_index: InternPool.DeclIndex, + sym_index: Symbol.Index, + sect_index: u8, + code: []const u8, +) !void { + const comp = macho_file.base.comp; + const gpa = comp.gpa; + const mod = comp.module.?; + const decl = mod.declPtr(decl_index); + const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); + + log.debug("updateTlv {s} ({*})", .{ decl_name, decl }); + + const required_alignment = decl.getAlignment(mod); + + const sym = macho_file.getSymbol(sym_index); + const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; + const atom = sym.getAtom(macho_file).?; + + sym.out_n_sect = sect_index; + atom.out_n_sect = sect_index; + + sym.name = try macho_file.strings.insert(gpa, decl_name); + atom.flags.alive = true; + atom.name = sym.name; + nlist.n_strx = sym.name; + nlist.n_sect = sect_index + 1; + nlist.n_type = macho.N_EXT; + self.symtab.items(.size)[sym.nlist_idx] = code.len; + + atom.alignment = required_alignment; + atom.size = code.len; + + const slice = macho_file.sections.slice(); + const header = slice.items(.header)[sect_index]; + const atoms = &slice.items(.atoms)[sect_index]; + + const gop = try self.tls_variables.getOrPut(gpa, atom.atom_index); + assert(!gop.found_existing); // TODO incremental updates + gop.value_ptr.* = .{ .symbol_index = sym_index }; + + // We only store the data for the TLV if it's non-zerofill. + if (!header.isZerofill()) { + gop.value_ptr.code = try gpa.dupe(u8, code); + } + + try atoms.append(gpa, atom.atom_index); +} + fn getDeclOutputSection( self: *ZigObject, macho_file: *MachO, @@ -1244,11 +1303,21 @@ const LazySymbolMetadata = struct { const_state: State = .unused, }; +const TlsVariable = struct { + symbol_index: Symbol.Index, + code: []const u8 = &[0]u8{}, + + fn deinit(tlv: *TlsVariable, allocator: Allocator) void { + allocator.free(tlv.code); + } +}; + const DeclTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata); const UnnamedConstTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Symbol.Index)); const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata); const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata); const RelocationTable = std.ArrayListUnmanaged(std.ArrayListUnmanaged(Relocation)); +const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable); const assert = std.debug.assert; const builtin = @import("builtin"); |
