authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-30 22:40:27+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-09-04 13:34:25+02:00
log6ec5df3898d594dd97d1b557aa7bdde38a9998b6
tree167cb016ef4cad4d83ea7b98a01c1de746a3da57
parent3e100c5daba0f64695eab0bb4216b9d242229ba6

elf: allocate .tdata and .tbss using allocateAtom mechanics


2 files changed, 43 insertions(+), 54 deletions(-)

src/link/Elf.zig+3-16
......@@ -3556,24 +3556,9 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
35563556
35573557fn updateSectionSizes(self: *Elf) !void {
35583558 const slice = self.sections.slice();
3559 for (slice.items(.shdr), slice.items(.atom_list), 0..) |*shdr, atom_list, shndx| {
3559 for (slice.items(.shdr), slice.items(.atom_list)) |*shdr, atom_list| {
35603560 if (atom_list.items.len == 0) continue;
35613561 if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue;
3562 if (self.zigObjectPtr()) |zo| blk: {
3563 const sym_index = for ([_]?Symbol.Index{
3564 zo.text_index,
3565 zo.rodata_index,
3566 zo.data_relro_index,
3567 zo.data_index,
3568 zo.bss_index,
3569 }) |maybe_idx| {
3570 if (maybe_idx) |idx| break idx;
3571 } else break :blk;
3572 const atom_ptr = zo.symbol(sym_index).atom(self).?;
3573 if (shndx == atom_ptr.output_section_index) {
3574 shdr.sh_size = atom_ptr.size;
3575 }
3576 }
35773562 for (atom_list.items) |ref| {
35783563 const atom_ptr = self.atom(ref) orelse continue;
35793564 if (!atom_ptr.alive) continue;
......@@ -3908,6 +3893,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
39083893 zo.rodata_index,
39093894 zo.data_relro_index,
39103895 zo.data_index,
3896 zo.tdata_index,
39113897 zo.eh_frame_index,
39123898 }) |maybe_sym_index| {
39133899 const sect_sym_index = maybe_sym_index orelse continue;
......@@ -4067,6 +4053,7 @@ fn writeAtoms(self: *Elf) !void {
40674053 zo.rodata_index,
40684054 zo.data_relro_index,
40694055 zo.data_index,
4056 zo.tdata_index,
40704057 zo.eh_frame_index,
40714058 zo.debug_info_index,
40724059 zo.debug_abbrev_index,
src/link/Elf/ZigObject.zig+40-38
......@@ -56,6 +56,8 @@ rodata_index: ?Symbol.Index = null,
5656data_relro_index: ?Symbol.Index = null,
5757data_index: ?Symbol.Index = null,
5858bss_index: ?Symbol.Index = null,
59tdata_index: ?Symbol.Index = null,
60tbss_index: ?Symbol.Index = null,
5961eh_frame_index: ?Symbol.Index = null,
6062debug_info_index: ?Symbol.Index = null,
6163debug_abbrev_index: ?Symbol.Index = null,
......@@ -233,10 +235,6 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
233235 meta.exports.deinit(allocator);
234236 }
235237 self.uavs.deinit(allocator);
236
237 for (self.tls_variables.values()) |*tlv| {
238 tlv.deinit(allocator);
239 }
240238 self.tls_variables.deinit(allocator);
241239
242240 if (self.dwarf) |*dwarf| {
......@@ -898,14 +896,6 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void {
898896pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 {
899897 const gpa = elf_file.base.comp.gpa;
900898 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
909899 const file_offset = atom_ptr.offset(elf_file);
910900 const size = std.math.cast(usize, atom_ptr.size) orelse return error.Overflow;
911901 const code = try gpa.alloc(u8, size);
......@@ -1161,18 +1151,29 @@ fn getNavShdrIndex(
11611151 const is_bss = !has_relocs and for (code) |byte| {
11621152 if (byte != 0) break false;
11631153 } 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(.{
11711169 .type = elf.SHT_PROGBITS,
11721170 .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS,
11731171 .name = try elf_file.insertShString(".tdata"),
1172 .addralign = 1,
11741173 .offset = std.math.maxInt(u64),
11751174 });
1175 self.tdata_index = try self.addSectionSymbol(gpa, ".tdata", .@"1", osec);
1176 return osec;
11761177 }
11771178 if (is_const) {
11781179 if (self.data_relro_index) |symbol_index|
......@@ -1367,15 +1368,11 @@ fn updateTlv(
13671368 const atom_ptr = sym.atom(elf_file).?;
13681369 const name_offset = try self.strtab.insert(gpa, nav.fqn.toSlice(ip));
13691370
1370 sym.value = 0;
1371 sym.name_offset = name_offset;
1372
1373 atom_ptr.output_section_index = shndx;
13741371 atom_ptr.alive = true;
13751372 atom_ptr.name_offset = name_offset;
1373 atom_ptr.output_section_index = shndx;
13761374
13771375 sym.name_offset = name_offset;
1378 esym.st_value = 0;
13791376 esym.st_name = name_offset;
13801377 esym.st_info = elf.STT_TLS;
13811378 esym.st_size = code.len;
......@@ -1383,21 +1380,25 @@ fn updateTlv(
13831380 atom_ptr.alignment = required_alignment;
13841381 atom_ptr.size = code.len;
13851382
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
13871385
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;
13921389
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;
13981391
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 }
14011402}
14021403
14031404pub fn updateFunc(
......@@ -1994,8 +1995,9 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {
19941995 const sect_atom_ptr = for ([_]?Symbol.Index{
19951996 self.text_index,
19961997 self.rodata_index,
1997 self.data_index,
19981998 self.data_relro_index,
1999 self.data_index,
2000 self.tdata_index,
19992001 }) |maybe_sym_index| {
20002002 const sect_sym_index = maybe_sym_index orelse continue;
20012003 const sect_atom_ptr = self.symbol(sect_sym_index).atom(elf_file).?;
......@@ -2305,7 +2307,7 @@ const AtomList = std.ArrayListUnmanaged(Atom.Index);
23052307const NavTable = std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);
23062308const UavTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, AvMetadata);
23072309const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);
2308const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable);
2310const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, void);
23092311
23102312const x86_64 = struct {
23112313 fn writeTrampolineCode(source_addr: i64, target_addr: i64, buf: *[max_trampoline_len]u8) ![]u8 {