| ... | ... | @@ -157,7 +157,6 @@ strtab: StringTable(.strtab) = .{}, |
| 157 | 157 | |
| 158 | 158 | got_table: TableSection(SymbolWithLoc) = .{}, |
| 159 | 159 | stub_table: TableSection(SymbolWithLoc) = .{}, |
| 160 | | tlv_table: SectionTable = .{}, |
| 161 | 160 | |
| 162 | 161 | error_flags: File.ErrorFlags = File.ErrorFlags{}, |
| 163 | 162 | |
| ... | ... | @@ -222,6 +221,10 @@ lazy_syms: LazySymbolTable = .{}, |
| 222 | 221 | /// Table of tracked Decls. |
| 223 | 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 | 228 | /// Hot-code swapping state. |
| 226 | 229 | hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{}, |
| 227 | 230 | |
| ... | ... | @@ -238,6 +241,8 @@ const LazySymbolMetadata = struct { |
| 238 | 241 | alignment: u32, |
| 239 | 242 | }; |
| 240 | 243 | |
| 244 | const TlvSymbolTable = std.AutoArrayHashMapUnmanaged(SymbolWithLoc, Atom.Index); |
| 245 | |
| 241 | 246 | const DeclMetadata = struct { |
| 242 | 247 | atom: Atom.Index, |
| 243 | 248 | section: u8, |
| ... | ... | @@ -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 | 274 | const BindingTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Binding)); |
| 386 | 275 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| 387 | 276 | const RebaseTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| ... | ... | @@ -1520,18 +1409,13 @@ fn createDyldPrivateAtom(self: *MachO) !void { |
| 1520 | 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 | 1413 | const gpa = self.base.allocator; |
| 1525 | 1414 | const size = 3 * @sizeOf(u64); |
| 1526 | 1415 | const required_alignment: u32 = 1; |
| 1527 | 1416 | const atom_index = try self.createAtom(); |
| 1528 | 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 | 1419 | const sym = self.getAtom(atom_index).getSymbolPtr(self); |
| 1536 | 1420 | sym.n_type = macho.N_SECT; |
| 1537 | 1421 | sym.n_sect = self.thread_vars_section_index.? + 1; |
| ... | ... | @@ -1706,7 +1590,6 @@ pub fn deinit(self: *MachO) void { |
| 1706 | 1590 | |
| 1707 | 1591 | self.got_table.deinit(gpa); |
| 1708 | 1592 | self.stub_table.deinit(gpa); |
| 1709 | | self.tlv_table.deinit(gpa); |
| 1710 | 1593 | self.strtab.deinit(gpa); |
| 1711 | 1594 | |
| 1712 | 1595 | self.locals.deinit(gpa); |
| ... | ... | @@ -1739,14 +1622,12 @@ pub fn deinit(self: *MachO) void { |
| 1739 | 1622 | |
| 1740 | 1623 | self.atoms.deinit(gpa); |
| 1741 | 1624 | |
| 1742 | | if (self.base.options.module) |_| { |
| 1743 | | for (self.decls.values()) |*m| { |
| 1744 | | m.exports.deinit(gpa); |
| 1745 | | } |
| 1746 | | self.decls.deinit(gpa); |
| 1747 | | } else { |
| 1748 | | assert(self.decls.count() == 0); |
| 1625 | for (self.decls.values()) |*m| { |
| 1626 | m.exports.deinit(gpa); |
| 1749 | 1627 | } |
| 1628 | self.decls.deinit(gpa); |
| 1629 | self.lazy_syms.deinit(gpa); |
| 1630 | self.tlv_table.deinit(gpa); |
| 1750 | 1631 | |
| 1751 | 1632 | for (self.unnamed_const_atoms.values()) |*atoms| { |
| 1752 | 1633 | atoms.deinit(gpa); |
| ... | ... | @@ -1926,15 +1807,6 @@ fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void { |
| 1926 | 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 | 1810 | pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void { |
| 1939 | 1811 | if (build_options.skip_non_native and builtin.object_format != .macho) { |
| 1940 | 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 | 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 | 1962 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 2085 | 1963 | const sym_index = self.getAtom(atom_index).getSymbolIndex().?; |
| 2086 | 1964 | Atom.freeRelocations(self, atom_index); |
| ... | ... | @@ -2229,6 +2107,101 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol, alignmen |
| 2229 | 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 | 2205 | pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index { |
| 2233 | 2206 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); |
| 2234 | 2207 | if (!gop.found_existing) { |
| ... | ... | @@ -2296,21 +2269,11 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 |
| 2296 | 2269 | const sect_id = decl_metadata.section; |
| 2297 | 2270 | const header = &self.sections.items(.header)[sect_id]; |
| 2298 | 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 | 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 | 2274 | if (atom.size != 0) { |
| 2312 | 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 | 2277 | sym.n_type = macho.N_SECT; |
| 2315 | 2278 | sym.n_sect = sect_id + 1; |
| 2316 | 2279 | sym.n_desc = 0; |
| ... | ... | @@ -2320,21 +2283,13 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 |
| 2320 | 2283 | |
| 2321 | 2284 | if (need_realloc) { |
| 2322 | 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 | 2287 | log.debug(" (required alignment 0x{x})", .{required_alignment}); |
| 2325 | 2288 | |
| 2326 | 2289 | if (vaddr != sym.n_value) { |
| 2327 | 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 | 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 | 2293 | try self.writeOffsetTableEntry(got_atom_index); |
| 2339 | 2294 | } |
| 2340 | 2295 | } else if (code_len < atom.size) { |
| ... | ... | @@ -2346,7 +2301,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 |
| 2346 | 2301 | self.getAtomPtr(atom_index).size = code_len; |
| 2347 | 2302 | } else { |
| 2348 | 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 | 2305 | sym.n_type = macho.N_SECT; |
| 2351 | 2306 | sym.n_sect = sect_id + 1; |
| 2352 | 2307 | sym.n_desc = 0; |
| ... | ... | @@ -2354,21 +2309,13 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 |
| 2354 | 2309 | const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment); |
| 2355 | 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 | 2313 | log.debug(" (required alignment 0x{x})", .{required_alignment}); |
| 2359 | 2314 | |
| 2360 | 2315 | self.getAtomPtr(atom_index).size = code_len; |
| 2361 | 2316 | sym.n_value = vaddr; |
| 2362 | 2317 | |
| 2363 | | if (is_threadlocal) { |
| 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); |
| 2318 | try self.addGotEntry(.{ .sym_index = sym_index }); |
| 2372 | 2319 | } |
| 2373 | 2320 | |
| 2374 | 2321 | try self.writeAtom(atom_index, code); |
| ... | ... | @@ -4169,8 +4116,8 @@ pub fn logSymtab(self: *MachO) void { |
| 4169 | 4116 | log.debug("stubs entries:", .{}); |
| 4170 | 4117 | log.debug("{}", .{self.stub_table}); |
| 4171 | 4118 | |
| 4172 | | log.debug("threadlocal entries:", .{}); |
| 4173 | | log.debug("{}", .{self.tlv_table.fmtDebug(self)}); |
| 4119 | // log.debug("threadlocal entries:", .{}); |
| 4120 | // log.debug("{}", .{self.tlv_table}); |
| 4174 | 4121 | } |
| 4175 | 4122 | |
| 4176 | 4123 | pub fn logAtoms(self: *MachO) void { |