| ... | ... | @@ -56,6 +56,8 @@ rodata_index: ?Symbol.Index = null, |
| 56 | 56 | data_relro_index: ?Symbol.Index = null, |
| 57 | 57 | data_index: ?Symbol.Index = null, |
| 58 | 58 | bss_index: ?Symbol.Index = null, |
| 59 | tdata_index: ?Symbol.Index = null, |
| 60 | tbss_index: ?Symbol.Index = null, |
| 59 | 61 | eh_frame_index: ?Symbol.Index = null, |
| 60 | 62 | debug_info_index: ?Symbol.Index = null, |
| 61 | 63 | debug_abbrev_index: ?Symbol.Index = null, |
| ... | ... | @@ -233,10 +235,6 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { |
| 233 | 235 | meta.exports.deinit(allocator); |
| 234 | 236 | } |
| 235 | 237 | self.uavs.deinit(allocator); |
| 236 | | |
| 237 | | for (self.tls_variables.values()) |*tlv| { |
| 238 | | tlv.deinit(allocator); |
| 239 | | } |
| 240 | 238 | self.tls_variables.deinit(allocator); |
| 241 | 239 | |
| 242 | 240 | if (self.dwarf) |*dwarf| { |
| ... | ... | @@ -898,14 +896,6 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void { |
| 898 | 896 | pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 { |
| 899 | 897 | const gpa = elf_file.base.comp.gpa; |
| 900 | 898 | const atom_ptr = self.atom(atom_index).?; |
| 901 | | const shdr = &elf_file.sections.items(.shdr)[atom_ptr.output_section_index]; |
| 902 | | |
| 903 | | if (shdr.sh_flags & elf.SHF_TLS != 0) { |
| 904 | | const tlv = self.tls_variables.get(atom_index).?; |
| 905 | | const code = try gpa.dupe(u8, tlv.code); |
| 906 | | return code; |
| 907 | | } |
| 908 | | |
| 909 | 899 | const file_offset = atom_ptr.offset(elf_file); |
| 910 | 900 | const size = std.math.cast(usize, atom_ptr.size) orelse return error.Overflow; |
| 911 | 901 | const code = try gpa.alloc(u8, size); |
| ... | ... | @@ -1161,18 +1151,29 @@ fn getNavShdrIndex( |
| 1161 | 1151 | const is_bss = !has_relocs and for (code) |byte| { |
| 1162 | 1152 | if (byte != 0) break false; |
| 1163 | 1153 | } else true; |
| 1164 | | if (is_bss) return elf_file.sectionByName(".tbss") orelse try elf_file.addSection(.{ |
| 1165 | | .type = elf.SHT_NOBITS, |
| 1166 | | .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS, |
| 1167 | | .name = try elf_file.insertShString(".tbss"), |
| 1168 | | .offset = std.math.maxInt(u64), |
| 1169 | | }); |
| 1170 | | return elf_file.sectionByName(".tdata") orelse try elf_file.addSection(.{ |
| 1154 | if (is_bss) { |
| 1155 | if (self.tbss_index) |symbol_index| |
| 1156 | return self.symbol(symbol_index).atom(elf_file).?.output_section_index; |
| 1157 | const osec = try elf_file.addSection(.{ |
| 1158 | .name = try elf_file.insertShString(".tbss"), |
| 1159 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS, |
| 1160 | .type = elf.SHT_NOBITS, |
| 1161 | .addralign = 1, |
| 1162 | }); |
| 1163 | self.tbss_index = try self.addSectionSymbol(gpa, ".tbss", .@"1", osec); |
| 1164 | return osec; |
| 1165 | } |
| 1166 | if (self.tdata_index) |symbol_index| |
| 1167 | return self.symbol(symbol_index).atom(elf_file).?.output_section_index; |
| 1168 | const osec = try elf_file.addSection(.{ |
| 1171 | 1169 | .type = elf.SHT_PROGBITS, |
| 1172 | 1170 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS, |
| 1173 | 1171 | .name = try elf_file.insertShString(".tdata"), |
| 1172 | .addralign = 1, |
| 1174 | 1173 | .offset = std.math.maxInt(u64), |
| 1175 | 1174 | }); |
| 1175 | self.tdata_index = try self.addSectionSymbol(gpa, ".tdata", .@"1", osec); |
| 1176 | return osec; |
| 1176 | 1177 | } |
| 1177 | 1178 | if (is_const) { |
| 1178 | 1179 | if (self.data_relro_index) |symbol_index| |
| ... | ... | @@ -1367,15 +1368,11 @@ fn updateTlv( |
| 1367 | 1368 | const atom_ptr = sym.atom(elf_file).?; |
| 1368 | 1369 | const name_offset = try self.strtab.insert(gpa, nav.fqn.toSlice(ip)); |
| 1369 | 1370 | |
| 1370 | | sym.value = 0; |
| 1371 | | sym.name_offset = name_offset; |
| 1372 | | |
| 1373 | | atom_ptr.output_section_index = shndx; |
| 1374 | 1371 | atom_ptr.alive = true; |
| 1375 | 1372 | atom_ptr.name_offset = name_offset; |
| 1373 | atom_ptr.output_section_index = shndx; |
| 1376 | 1374 | |
| 1377 | 1375 | sym.name_offset = name_offset; |
| 1378 | | esym.st_value = 0; |
| 1379 | 1376 | esym.st_name = name_offset; |
| 1380 | 1377 | esym.st_info = elf.STT_TLS; |
| 1381 | 1378 | esym.st_size = code.len; |
| ... | ... | @@ -1383,21 +1380,25 @@ fn updateTlv( |
| 1383 | 1380 | atom_ptr.alignment = required_alignment; |
| 1384 | 1381 | atom_ptr.size = code.len; |
| 1385 | 1382 | |
| 1386 | | self.navs.getPtr(nav_index).?.allocated = true; |
| 1383 | const gop = try self.tls_variables.getOrPut(gpa, atom_ptr.atom_index); |
| 1384 | assert(!gop.found_existing); // TODO incremental updates |
| 1387 | 1385 | |
| 1388 | | { |
| 1389 | | const gop = try self.tls_variables.getOrPut(gpa, atom_ptr.atom_index); |
| 1390 | | assert(!gop.found_existing); // TODO incremental updates |
| 1391 | | gop.value_ptr.* = .{ .symbol_index = sym_index }; |
| 1386 | try self.allocateAtom(atom_ptr, elf_file); |
| 1387 | sym.value = 0; |
| 1388 | esym.st_value = 0; |
| 1392 | 1389 | |
| 1393 | | // We only store the data for the TLV if it's non-zerofill. |
| 1394 | | if (elf_file.sections.items(.shdr)[shndx].sh_type != elf.SHT_NOBITS) { |
| 1395 | | gop.value_ptr.code = try gpa.dupe(u8, code); |
| 1396 | | } |
| 1397 | | } |
| 1390 | self.navs.getPtr(nav_index).?.allocated = true; |
| 1398 | 1391 | |
| 1399 | | const atom_list = &elf_file.sections.items(.atom_list)[atom_ptr.output_section_index]; |
| 1400 | | try atom_list.append(gpa, .{ .index = atom_ptr.atom_index, .file = self.index }); |
| 1392 | const shdr = elf_file.sections.items(.shdr)[shndx]; |
| 1393 | if (shdr.sh_type != elf.SHT_NOBITS) { |
| 1394 | const file_offset = atom_ptr.offset(elf_file); |
| 1395 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 1396 | log.debug("writing TLV {s} from 0x{x} to 0x{x}", .{ |
| 1397 | atom_ptr.name(elf_file), |
| 1398 | file_offset, |
| 1399 | file_offset + code.len, |
| 1400 | }); |
| 1401 | } |
| 1401 | 1402 | } |
| 1402 | 1403 | |
| 1403 | 1404 | pub fn updateFunc( |
| ... | ... | @@ -1994,8 +1995,9 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void { |
| 1994 | 1995 | const sect_atom_ptr = for ([_]?Symbol.Index{ |
| 1995 | 1996 | self.text_index, |
| 1996 | 1997 | self.rodata_index, |
| 1997 | | self.data_index, |
| 1998 | 1998 | self.data_relro_index, |
| 1999 | self.data_index, |
| 2000 | self.tdata_index, |
| 1999 | 2001 | }) |maybe_sym_index| { |
| 2000 | 2002 | const sect_sym_index = maybe_sym_index orelse continue; |
| 2001 | 2003 | const sect_atom_ptr = self.symbol(sect_sym_index).atom(elf_file).?; |
| ... | ... | @@ -2305,7 +2307,7 @@ const AtomList = std.ArrayListUnmanaged(Atom.Index); |
| 2305 | 2307 | const NavTable = std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvMetadata); |
| 2306 | 2308 | const UavTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, AvMetadata); |
| 2307 | 2309 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata); |
| 2308 | | const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable); |
| 2310 | const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, void); |
| 2309 | 2311 | |
| 2310 | 2312 | const x86_64 = struct { |
| 2311 | 2313 | fn writeTrampolineCode(source_addr: i64, target_addr: i64, buf: *[max_trampoline_len]u8) ![]u8 { |