| ... | @@ -157,7 +157,6 @@ strtab: StringTable(.strtab) = .{}, | ... | @@ -157,7 +157,6 @@ strtab: StringTable(.strtab) = .{}, |
| 157 | | 157 | |
| 158 | got_table: TableSection(SymbolWithLoc) = .{}, | 158 | got_table: TableSection(SymbolWithLoc) = .{}, |
| 159 | stub_table: TableSection(SymbolWithLoc) = .{}, | 159 | stub_table: TableSection(SymbolWithLoc) = .{}, |
| 160 | tlv_table: SectionTable = .{}, | | |
| 161 | | 160 | |
| 162 | error_flags: File.ErrorFlags = File.ErrorFlags{}, | 161 | error_flags: File.ErrorFlags = File.ErrorFlags{}, |
| 163 | | 162 | |
| ... | @@ -222,6 +221,10 @@ lazy_syms: LazySymbolTable = .{}, | ... | @@ -222,6 +221,10 @@ lazy_syms: LazySymbolTable = .{}, |
| 222 | /// Table of tracked Decls. | 221 | /// Table of tracked Decls. |
| 223 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, | 222 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, |
| 224 | | 223 | |
| | 224 | /// Table of threadlocal variables descriptors. |
| | 225 | /// They are emitted in the `__thread_vars` section. |
| | 226 | tlv_table: TlvSymbolTable = .{}, |
| | 227 | |
| 225 | /// Hot-code swapping state. | 228 | /// Hot-code swapping state. |
| 226 | hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{}, | 229 | hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{}, |
| 227 | | 230 | |
| ... | @@ -238,6 +241,8 @@ const LazySymbolMetadata = struct { | ... | @@ -238,6 +241,8 @@ const LazySymbolMetadata = struct { |
| 238 | alignment: u32, | 241 | alignment: u32, |
| 239 | }; | 242 | }; |
| 240 | | 243 | |
| | 244 | const TlvSymbolTable = std.AutoArrayHashMapUnmanaged(SymbolWithLoc, Atom.Index); |
| | 245 | |
| 241 | const DeclMetadata = struct { | 246 | const DeclMetadata = struct { |
| 242 | atom: Atom.Index, | 247 | atom: Atom.Index, |
| 243 | section: u8, | 248 | section: u8, |
| ... | @@ -266,122 +271,6 @@ const DeclMetadata = struct { | ... | @@ -266,122 +271,6 @@ const DeclMetadata = struct { |
| 266 | } | 271 | } |
| 267 | }; | 272 | }; |
| 268 | | 273 | |
| 269 | const SectionTable = struct { | | |
| 270 | entries: std.ArrayListUnmanaged(Entry) = .{}, | | |
| 271 | free_list: std.ArrayListUnmanaged(u32) = .{}, | | |
| 272 | lookup: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, | | |
| 273 | | | |
| 274 | pub fn deinit(st: *ST, allocator: Allocator) void { | | |
| 275 | st.entries.deinit(allocator); | | |
| 276 | st.free_list.deinit(allocator); | | |
| 277 | st.lookup.deinit(allocator); | | |
| 278 | } | | |
| 279 | | | |
| 280 | pub fn allocateEntry(st: *ST, allocator: Allocator, target: SymbolWithLoc) !u32 { | | |
| 281 | try st.entries.ensureUnusedCapacity(allocator, 1); | | |
| 282 | const index = blk: { | | |
| 283 | if (st.free_list.popOrNull()) |index| { | | |
| 284 | log.debug(" (reusing entry index {d})", .{index}); | | |
| 285 | break :blk index; | | |
| 286 | } else { | | |
| 287 | log.debug(" (allocating entry at index {d})", .{st.entries.items.len}); | | |
| 288 | const index = @intCast(u32, st.entries.items.len); | | |
| 289 | _ = st.entries.addOneAssumeCapacity(); | | |
| 290 | break :blk index; | | |
| 291 | } | | |
| 292 | }; | | |
| 293 | st.entries.items[index] = .{ .target = target, .sym_index = 0 }; | | |
| 294 | try st.lookup.putNoClobber(allocator, target, index); | | |
| 295 | return index; | | |
| 296 | } | | |
| 297 | | | |
| 298 | pub fn freeEntry(st: *ST, allocator: Allocator, target: SymbolWithLoc) void { | | |
| 299 | const index = st.lookup.get(target) orelse return; | | |
| 300 | st.free_list.append(allocator, index) catch {}; | | |
| 301 | st.entries.items[index] = .{ | | |
| 302 | .target = .{ .sym_index = 0 }, | | |
| 303 | .sym_index = 0, | | |
| 304 | }; | | |
| 305 | _ = st.lookup.remove(target); | | |
| 306 | } | | |
| 307 | | | |
| 308 | pub fn getAtomIndex(st: *const ST, macho_file: *MachO, target: SymbolWithLoc) ?Atom.Index { | | |
| 309 | const index = st.lookup.get(target) orelse return null; | | |
| 310 | return st.entries.items[index].getAtomIndex(macho_file); | | |
| 311 | } | | |
| 312 | | | |
| 313 | const FormatContext = struct { | | |
| 314 | macho_file: *MachO, | | |
| 315 | st: *const ST, | | |
| 316 | }; | | |
| 317 | | | |
| 318 | fn fmt( | | |
| 319 | ctx: FormatContext, | | |
| 320 | comptime unused_format_string: []const u8, | | |
| 321 | options: std.fmt.FormatOptions, | | |
| 322 | writer: anytype, | | |
| 323 | ) @TypeOf(writer).Error!void { | | |
| 324 | _ = options; | | |
| 325 | comptime assert(unused_format_string.len == 0); | | |
| 326 | try writer.writeAll("SectionTable:\n"); | | |
| 327 | for (ctx.st.entries.items, 0..) |entry, i| { | | |
| 328 | const atom_sym = entry.getSymbol(ctx.macho_file); | | |
| 329 | const target_sym = ctx.macho_file.getSymbol(entry.target); | | |
| 330 | try writer.print(" {d}@{x} => ", .{ i, atom_sym.n_value }); | | |
| 331 | if (target_sym.undf()) { | | |
| 332 | try writer.print("import('{s}')", .{ | | |
| 333 | ctx.macho_file.getSymbolName(entry.target), | | |
| 334 | }); | | |
| 335 | } else { | | |
| 336 | try writer.print("local(%{d}) in object({?d})", .{ | | |
| 337 | entry.target.sym_index, | | |
| 338 | entry.target.file, | | |
| 339 | }); | | |
| 340 | } | | |
| 341 | try writer.writeByte('\n'); | | |
| 342 | } | | |
| 343 | } | | |
| 344 | | | |
| 345 | fn format(st: *const ST, comptime unused_format_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { | | |
| 346 | _ = st; | | |
| 347 | _ = unused_format_string; | | |
| 348 | _ = options; | | |
| 349 | _ = writer; | | |
| 350 | @compileError("do not format SectionTable directly; use st.fmtDebug()"); | | |
| 351 | } | | |
| 352 | | | |
| 353 | pub fn fmtDebug(st: *const ST, macho_file: *MachO) std.fmt.Formatter(fmt) { | | |
| 354 | return .{ .data = .{ | | |
| 355 | .macho_file = macho_file, | | |
| 356 | .st = st, | | |
| 357 | } }; | | |
| 358 | } | | |
| 359 | | | |
| 360 | const ST = @This(); | | |
| 361 | | | |
| 362 | const Entry = struct { | | |
| 363 | target: SymbolWithLoc, | | |
| 364 | // Index into the synthetic symbol table (i.e., file == null). | | |
| 365 | sym_index: u32, | | |
| 366 | | | |
| 367 | pub fn getSymbol(entry: Entry, macho_file: *MachO) macho.nlist_64 { | | |
| 368 | return macho_file.getSymbol(.{ .sym_index = entry.sym_index }); | | |
| 369 | } | | |
| 370 | | | |
| 371 | pub fn getSymbolPtr(entry: Entry, macho_file: *MachO) *macho.nlist_64 { | | |
| 372 | return macho_file.getSymbolPtr(.{ .sym_index = entry.sym_index }); | | |
| 373 | } | | |
| 374 | | | |
| 375 | pub fn getAtomIndex(entry: Entry, macho_file: *MachO) ?Atom.Index { | | |
| 376 | return macho_file.getAtomIndexForSymbol(.{ .sym_index = entry.sym_index }); | | |
| 377 | } | | |
| 378 | | | |
| 379 | pub fn getName(entry: Entry, macho_file: *MachO) []const u8 { | | |
| 380 | return macho_file.getSymbolName(.{ .sym_index = entry.sym_index }); | | |
| 381 | } | | |
| 382 | }; | | |
| 383 | }; | | |
| 384 | | | |
| 385 | const BindingTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Binding)); | 274 | const BindingTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Binding)); |
| 386 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); | 275 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| 387 | const RebaseTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); | 276 | const RebaseTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| ... | @@ -1520,18 +1409,13 @@ fn createDyldPrivateAtom(self: *MachO) !void { | ... | @@ -1520,18 +1409,13 @@ fn createDyldPrivateAtom(self: *MachO) !void { |
| 1520 | try self.writeAtom(atom_index, &buffer); | 1409 | try self.writeAtom(atom_index, &buffer); |
| 1521 | } | 1410 | } |
| 1522 | | 1411 | |
| 1523 | fn createThreadLocalDescriptorAtom(self: *MachO, target: SymbolWithLoc) !Atom.Index { | 1412 | fn createThreadLocalDescriptorAtom(self: *MachO, sym_name: []const u8, target: SymbolWithLoc) !Atom.Index { |
| 1524 | const gpa = self.base.allocator; | 1413 | const gpa = self.base.allocator; |
| 1525 | const size = 3 * @sizeOf(u64); | 1414 | const size = 3 * @sizeOf(u64); |
| 1526 | const required_alignment: u32 = 1; | 1415 | const required_alignment: u32 = 1; |
| 1527 | const atom_index = try self.createAtom(); | 1416 | const atom_index = try self.createAtom(); |
| 1528 | self.getAtomPtr(atom_index).size = size; | 1417 | self.getAtomPtr(atom_index).size = size; |
| 1529 | | 1418 | |
| 1530 | const target_sym_name = self.getSymbolName(target); | | |
| 1531 | const name_delimiter = mem.indexOf(u8, target_sym_name, "$").?; | | |
| 1532 | const sym_name = try gpa.dupe(u8, target_sym_name[0..name_delimiter]); | | |
| 1533 | defer gpa.free(sym_name); | | |
| 1534 | | | |
| 1535 | const sym = self.getAtom(atom_index).getSymbolPtr(self); | 1419 | const sym = self.getAtom(atom_index).getSymbolPtr(self); |
| 1536 | sym.n_type = macho.N_SECT; | 1420 | sym.n_type = macho.N_SECT; |
| 1537 | sym.n_sect = self.thread_vars_section_index.? + 1; | 1421 | sym.n_sect = self.thread_vars_section_index.? + 1; |
| ... | @@ -1706,7 +1590,6 @@ pub fn deinit(self: *MachO) void { | ... | @@ -1706,7 +1590,6 @@ pub fn deinit(self: *MachO) void { |
| 1706 | | 1590 | |
| 1707 | self.got_table.deinit(gpa); | 1591 | self.got_table.deinit(gpa); |
| 1708 | self.stub_table.deinit(gpa); | 1592 | self.stub_table.deinit(gpa); |
| 1709 | self.tlv_table.deinit(gpa); | | |
| 1710 | self.strtab.deinit(gpa); | 1593 | self.strtab.deinit(gpa); |
| 1711 | | 1594 | |
| 1712 | self.locals.deinit(gpa); | 1595 | self.locals.deinit(gpa); |
| ... | @@ -1739,14 +1622,12 @@ pub fn deinit(self: *MachO) void { | ... | @@ -1739,14 +1622,12 @@ pub fn deinit(self: *MachO) void { |
| 1739 | | 1622 | |
| 1740 | self.atoms.deinit(gpa); | 1623 | self.atoms.deinit(gpa); |
| 1741 | | 1624 | |
| 1742 | if (self.base.options.module) |_| { | 1625 | for (self.decls.values()) |*m| { |
| 1743 | for (self.decls.values()) |*m| { | 1626 | m.exports.deinit(gpa); |
| 1744 | m.exports.deinit(gpa); | | |
| 1745 | } | | |
| 1746 | self.decls.deinit(gpa); | | |
| 1747 | } else { | | |
| 1748 | assert(self.decls.count() == 0); | | |
| 1749 | } | 1627 | } |
| | 1628 | self.decls.deinit(gpa); |
| | 1629 | self.lazy_syms.deinit(gpa); |
| | 1630 | self.tlv_table.deinit(gpa); |
| 1750 | | 1631 | |
| 1751 | for (self.unnamed_const_atoms.values()) |*atoms| { | 1632 | for (self.unnamed_const_atoms.values()) |*atoms| { |
| 1752 | atoms.deinit(gpa); | 1633 | atoms.deinit(gpa); |
| ... | @@ -1926,15 +1807,6 @@ fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void { | ... | @@ -1926,15 +1807,6 @@ fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void { |
| 1926 | self.stub_table_count_dirty = true; | 1807 | self.stub_table_count_dirty = true; |
| 1927 | } | 1808 | } |
| 1928 | | 1809 | |
| 1929 | fn addTlvEntry(self: *MachO, target: SymbolWithLoc) !void { | | |
| 1930 | if (self.tlv_table.lookup.contains(target)) return; | | |
| 1931 | const tlv_index = try self.tlv_table.allocateEntry(self.base.allocator, target); | | |
| 1932 | const tlv_atom_index = try self.createThreadLocalDescriptorAtom(target); | | |
| 1933 | const tlv_atom = self.getAtom(tlv_atom_index); | | |
| 1934 | self.tlv_table.entries.items[tlv_index].sym_index = tlv_atom.getSymbolIndex().?; | | |
| 1935 | self.markRelocsDirtyByTarget(target); | | |
| 1936 | } | | |
| 1937 | | | |
| 1938 | pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void { | 1810 | pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void { |
| 1939 | if (build_options.skip_non_native and builtin.object_format != .macho) { | 1811 | if (build_options.skip_non_native and builtin.object_format != .macho) { |
| 1940 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 1812 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| ... | @@ -2081,6 +1953,12 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index) | ... | @@ -2081,6 +1953,12 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index) |
| 2081 | } | 1953 | } |
| 2082 | } | 1954 | } |
| 2083 | | 1955 | |
| | 1956 | const is_threadlocal = if (decl.val.castTag(.variable)) |payload| |
| | 1957 | payload.data.is_threadlocal and !self.base.options.single_threaded |
| | 1958 | else |
| | 1959 | false; |
| | 1960 | if (is_threadlocal) return self.updateThreadlocalVariable(module, decl_index); |
| | 1961 | |
| 2084 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); | 1962 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 2085 | const sym_index = self.getAtom(atom_index).getSymbolIndex().?; | 1963 | const sym_index = self.getAtom(atom_index).getSymbolIndex().?; |
| 2086 | Atom.freeRelocations(self, atom_index); | 1964 | Atom.freeRelocations(self, atom_index); |
| ... | @@ -2229,6 +2107,101 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol, alignmen | ... | @@ -2229,6 +2107,101 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol, alignmen |
| 2229 | return atom.*.?; | 2107 | return atom.*.?; |
| 2230 | } | 2108 | } |
| 2231 | | 2109 | |
| | 2110 | fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.Decl.Index) !void { |
| | 2111 | // Lowering a TLV on macOS involves two stages: |
| | 2112 | // 1. first we lower the initializer into appopriate section (__thread_data or __thread_bss) |
| | 2113 | // 2. next, we create a corresponding threadlocal variable descriptor in __thread_vars |
| | 2114 | |
| | 2115 | // 1. Lower the initializer value. |
| | 2116 | const init_atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| | 2117 | const init_atom = self.getAtomPtr(init_atom_index); |
| | 2118 | const init_sym_index = init_atom.getSymbolIndex().?; |
| | 2119 | Atom.freeRelocations(self, init_atom_index); |
| | 2120 | |
| | 2121 | const gpa = self.base.allocator; |
| | 2122 | |
| | 2123 | var code_buffer = std.ArrayList(u8).init(gpa); |
| | 2124 | defer code_buffer.deinit(); |
| | 2125 | |
| | 2126 | var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym| |
| | 2127 | try d_sym.dwarf.initDeclState(module, decl_index) |
| | 2128 | else |
| | 2129 | null; |
| | 2130 | defer if (decl_state) |*ds| ds.deinit(); |
| | 2131 | |
| | 2132 | const decl = module.declPtr(decl_index); |
| | 2133 | const decl_metadata = self.decls.get(decl_index).?; |
| | 2134 | const decl_val = decl.val.castTag(.variable).?.data.init; |
| | 2135 | const res = if (decl_state) |*ds| |
| | 2136 | try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ |
| | 2137 | .ty = decl.ty, |
| | 2138 | .val = decl_val, |
| | 2139 | }, &code_buffer, .{ |
| | 2140 | .dwarf = ds, |
| | 2141 | }, .{ |
| | 2142 | .parent_atom_index = init_sym_index, |
| | 2143 | }) |
| | 2144 | else |
| | 2145 | try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ |
| | 2146 | .ty = decl.ty, |
| | 2147 | .val = decl_val, |
| | 2148 | }, &code_buffer, .none, .{ |
| | 2149 | .parent_atom_index = init_sym_index, |
| | 2150 | }); |
| | 2151 | |
| | 2152 | var code = switch (res) { |
| | 2153 | .ok => code_buffer.items, |
| | 2154 | .fail => |em| { |
| | 2155 | decl.analysis = .codegen_failure; |
| | 2156 | try module.failed_decls.put(module.gpa, decl_index, em); |
| | 2157 | return; |
| | 2158 | }, |
| | 2159 | }; |
| | 2160 | |
| | 2161 | const required_alignment = decl.getAlignment(self.base.options.target); |
| | 2162 | |
| | 2163 | const decl_name = try decl.getFullyQualifiedName(module); |
| | 2164 | defer gpa.free(decl_name); |
| | 2165 | |
| | 2166 | const init_sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{decl_name}); |
| | 2167 | defer gpa.free(init_sym_name); |
| | 2168 | |
| | 2169 | const sect_id = decl_metadata.section; |
| | 2170 | const init_sym = init_atom.getSymbolPtr(self); |
| | 2171 | init_sym.n_strx = try self.strtab.insert(gpa, init_sym_name); |
| | 2172 | init_sym.n_type = macho.N_SECT; |
| | 2173 | init_sym.n_sect = sect_id + 1; |
| | 2174 | init_sym.n_desc = 0; |
| | 2175 | init_atom.size = code.len; |
| | 2176 | |
| | 2177 | init_sym.n_value = try self.allocateAtom(init_atom_index, code.len, required_alignment); |
| | 2178 | errdefer self.freeAtom(init_atom_index); |
| | 2179 | |
| | 2180 | log.debug("allocated atom for {s} at 0x{x}", .{ init_sym_name, init_sym.n_value }); |
| | 2181 | log.debug(" (required alignment 0x{x})", .{required_alignment}); |
| | 2182 | |
| | 2183 | try self.writeAtom(init_atom_index, code); |
| | 2184 | |
| | 2185 | if (decl_state) |*ds| { |
| | 2186 | try self.d_sym.?.dwarf.commitDeclState( |
| | 2187 | module, |
| | 2188 | decl_index, |
| | 2189 | init_sym.n_value, |
| | 2190 | self.getAtom(init_atom_index).size, |
| | 2191 | ds, |
| | 2192 | ); |
| | 2193 | } |
| | 2194 | |
| | 2195 | try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); |
| | 2196 | |
| | 2197 | // 2. Create a TLV descriptor. |
| | 2198 | const init_atom_sym_loc = init_atom.getSymbolWithLoc(); |
| | 2199 | const gop = try self.tlv_table.getOrPut(gpa, init_atom_sym_loc); |
| | 2200 | assert(!gop.found_existing); |
| | 2201 | gop.value_ptr.* = try self.createThreadLocalDescriptorAtom(decl_name, init_atom_sym_loc); |
| | 2202 | self.markRelocsDirtyByTarget(init_atom_sym_loc); |
| | 2203 | } |
| | 2204 | |
| 2232 | pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index { | 2205 | pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index { |
| 2233 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); | 2206 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); |
| 2234 | if (!gop.found_existing) { | 2207 | if (!gop.found_existing) { |
| ... | @@ -2296,21 +2269,11 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 | ... | @@ -2296,21 +2269,11 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 |
| 2296 | const sect_id = decl_metadata.section; | 2269 | const sect_id = decl_metadata.section; |
| 2297 | const header = &self.sections.items(.header)[sect_id]; | 2270 | const header = &self.sections.items(.header)[sect_id]; |
| 2298 | const segment = self.getSegment(sect_id); | 2271 | const segment = self.getSegment(sect_id); |
| 2299 | const is_threadlocal = if (!self.base.options.single_threaded) | | |
| 2300 | header.flags == macho.S_THREAD_LOCAL_REGULAR or header.flags == macho.S_THREAD_LOCAL_ZEROFILL | | |
| 2301 | else | | |
| 2302 | false; | | |
| 2303 | const code_len = code.len; | 2272 | const code_len = code.len; |
| 2304 | | 2273 | |
| 2305 | const sym_name = if (is_threadlocal) | | |
| 2306 | try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{decl_name}) | | |
| 2307 | else | | |
| 2308 | decl_name; | | |
| 2309 | defer if (is_threadlocal) gpa.free(sym_name); | | |
| 2310 | | | |
| 2311 | if (atom.size != 0) { | 2274 | if (atom.size != 0) { |
| 2312 | const sym = atom.getSymbolPtr(self); | 2275 | const sym = atom.getSymbolPtr(self); |
| 2313 | sym.n_strx = try self.strtab.insert(gpa, sym_name); | 2276 | sym.n_strx = try self.strtab.insert(gpa, decl_name); |
| 2314 | sym.n_type = macho.N_SECT; | 2277 | sym.n_type = macho.N_SECT; |
| 2315 | sym.n_sect = sect_id + 1; | 2278 | sym.n_sect = sect_id + 1; |
| 2316 | sym.n_desc = 0; | 2279 | sym.n_desc = 0; |
| ... | @@ -2320,21 +2283,13 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 | ... | @@ -2320,21 +2283,13 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 |
| 2320 | | 2283 | |
| 2321 | if (need_realloc) { | 2284 | if (need_realloc) { |
| 2322 | const vaddr = try self.growAtom(atom_index, code_len, required_alignment); | 2285 | const vaddr = try self.growAtom(atom_index, code_len, required_alignment); |
| 2323 | log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ sym_name, sym.n_value, vaddr }); | 2286 | log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ decl_name, sym.n_value, vaddr }); |
| 2324 | log.debug(" (required alignment 0x{x})", .{required_alignment}); | 2287 | log.debug(" (required alignment 0x{x})", .{required_alignment}); |
| 2325 | | 2288 | |
| 2326 | if (vaddr != sym.n_value) { | 2289 | if (vaddr != sym.n_value) { |
| 2327 | sym.n_value = vaddr; | 2290 | sym.n_value = vaddr; |
| 2328 | // TODO: I think we should update the offset to the initializer here too. | | |
| 2329 | const target: SymbolWithLoc = if (is_threadlocal) blk: { | | |
| 2330 | const tlv_atom_index = self.tlv_table.getAtomIndex(self, .{ | | |
| 2331 | .sym_index = sym_index, | | |
| 2332 | }).?; | | |
| 2333 | const tlv_atom = self.getAtom(tlv_atom_index); | | |
| 2334 | break :blk tlv_atom.getSymbolWithLoc(); | | |
| 2335 | } else .{ .sym_index = sym_index }; | | |
| 2336 | log.debug(" (updating GOT entry)", .{}); | 2291 | log.debug(" (updating GOT entry)", .{}); |
| 2337 | const got_atom_index = self.got_table.lookup.get(target).?; | 2292 | const got_atom_index = self.got_table.lookup.get(.{ .sym_index = sym_index }).?; |
| 2338 | try self.writeOffsetTableEntry(got_atom_index); | 2293 | try self.writeOffsetTableEntry(got_atom_index); |
| 2339 | } | 2294 | } |
| 2340 | } else if (code_len < atom.size) { | 2295 | } else if (code_len < atom.size) { |
| ... | @@ -2346,7 +2301,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 | ... | @@ -2346,7 +2301,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 |
| 2346 | self.getAtomPtr(atom_index).size = code_len; | 2301 | self.getAtomPtr(atom_index).size = code_len; |
| 2347 | } else { | 2302 | } else { |
| 2348 | const sym = atom.getSymbolPtr(self); | 2303 | const sym = atom.getSymbolPtr(self); |
| 2349 | sym.n_strx = try self.strtab.insert(gpa, sym_name); | 2304 | sym.n_strx = try self.strtab.insert(gpa, decl_name); |
| 2350 | sym.n_type = macho.N_SECT; | 2305 | sym.n_type = macho.N_SECT; |
| 2351 | sym.n_sect = sect_id + 1; | 2306 | sym.n_sect = sect_id + 1; |
| 2352 | sym.n_desc = 0; | 2307 | sym.n_desc = 0; |
| ... | @@ -2354,21 +2309,13 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 | ... | @@ -2354,21 +2309,13 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 |
| 2354 | const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment); | 2309 | const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment); |
| 2355 | errdefer self.freeAtom(atom_index); | 2310 | errdefer self.freeAtom(atom_index); |
| 2356 | | 2311 | |
| 2357 | log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, vaddr }); | 2312 | log.debug("allocated atom for {s} at 0x{x}", .{ decl_name, vaddr }); |
| 2358 | log.debug(" (required alignment 0x{x})", .{required_alignment}); | 2313 | log.debug(" (required alignment 0x{x})", .{required_alignment}); |
| 2359 | | 2314 | |
| 2360 | self.getAtomPtr(atom_index).size = code_len; | 2315 | self.getAtomPtr(atom_index).size = code_len; |
| 2361 | sym.n_value = vaddr; | 2316 | sym.n_value = vaddr; |
| 2362 | | 2317 | |
| 2363 | if (is_threadlocal) { | 2318 | try self.addGotEntry(.{ .sym_index = sym_index }); |
| 2364 | try self.addTlvEntry(.{ .sym_index = sym_index }); | | |
| 2365 | } | | |
| 2366 | const target: SymbolWithLoc = if (is_threadlocal) blk: { | | |
| 2367 | const tlv_atom_index = self.tlv_table.getAtomIndex(self, .{ .sym_index = sym_index }).?; | | |
| 2368 | const tlv_atom = self.getAtom(tlv_atom_index); | | |
| 2369 | break :blk tlv_atom.getSymbolWithLoc(); | | |
| 2370 | } else .{ .sym_index = sym_index }; | | |
| 2371 | try self.addGotEntry(target); | | |
| 2372 | } | 2319 | } |
| 2373 | | 2320 | |
| 2374 | try self.writeAtom(atom_index, code); | 2321 | try self.writeAtom(atom_index, code); |
| ... | @@ -4169,8 +4116,8 @@ pub fn logSymtab(self: *MachO) void { | ... | @@ -4169,8 +4116,8 @@ pub fn logSymtab(self: *MachO) void { |
| 4169 | log.debug("stubs entries:", .{}); | 4116 | log.debug("stubs entries:", .{}); |
| 4170 | log.debug("{}", .{self.stub_table}); | 4117 | log.debug("{}", .{self.stub_table}); |
| 4171 | | 4118 | |
| 4172 | log.debug("threadlocal entries:", .{}); | 4119 | // log.debug("threadlocal entries:", .{}); |
| 4173 | log.debug("{}", .{self.tlv_table.fmtDebug(self)}); | 4120 | // log.debug("{}", .{self.tlv_table}); |
| 4174 | } | 4121 | } |
| 4175 | | 4122 | |
| 4176 | pub fn logAtoms(self: *MachO) void { | 4123 | pub fn logAtoms(self: *MachO) void { |