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