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 {...@@ -3556,24 +3556,9 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
35563556
3557fn updateSectionSizes(self: *Elf) !void {3557fn updateSectionSizes(self: *Elf) !void {
3558 const slice = self.sections.slice();3558 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| {
3560 if (atom_list.items.len == 0) continue;3560 if (atom_list.items.len == 0) continue;
3561 if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue;3561 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 }
3577 for (atom_list.items) |ref| {3562 for (atom_list.items) |ref| {
3578 const atom_ptr = self.atom(ref) orelse continue;3563 const atom_ptr = self.atom(ref) orelse continue;
3579 if (!atom_ptr.alive) continue;3564 if (!atom_ptr.alive) continue;
...@@ -3908,6 +3893,7 @@ pub fn allocateAllocSections(self: *Elf) !void {...@@ -3908,6 +3893,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
3908 zo.rodata_index,3893 zo.rodata_index,
3909 zo.data_relro_index,3894 zo.data_relro_index,
3910 zo.data_index,3895 zo.data_index,
3896 zo.tdata_index,
3911 zo.eh_frame_index,3897 zo.eh_frame_index,
3912 }) |maybe_sym_index| {3898 }) |maybe_sym_index| {
3913 const sect_sym_index = maybe_sym_index orelse continue;3899 const sect_sym_index = maybe_sym_index orelse continue;
...@@ -4067,6 +4053,7 @@ fn writeAtoms(self: *Elf) !void {...@@ -4067,6 +4053,7 @@ fn writeAtoms(self: *Elf) !void {
4067 zo.rodata_index,4053 zo.rodata_index,
4068 zo.data_relro_index,4054 zo.data_relro_index,
4069 zo.data_index,4055 zo.data_index,
4056 zo.tdata_index,
4070 zo.eh_frame_index,4057 zo.eh_frame_index,
4071 zo.debug_info_index,4058 zo.debug_info_index,
4072 zo.debug_abbrev_index,4059 zo.debug_abbrev_index,
src/link/Elf/ZigObject.zig+40-38
...@@ -56,6 +56,8 @@ rodata_index: ?Symbol.Index = null,...@@ -56,6 +56,8 @@ rodata_index: ?Symbol.Index = null,
56data_relro_index: ?Symbol.Index = null,56data_relro_index: ?Symbol.Index = null,
57data_index: ?Symbol.Index = null,57data_index: ?Symbol.Index = null,
58bss_index: ?Symbol.Index = null,58bss_index: ?Symbol.Index = null,
59tdata_index: ?Symbol.Index = null,
60tbss_index: ?Symbol.Index = null,
59eh_frame_index: ?Symbol.Index = null,61eh_frame_index: ?Symbol.Index = null,
60debug_info_index: ?Symbol.Index = null,62debug_info_index: ?Symbol.Index = null,
61debug_abbrev_index: ?Symbol.Index = null,63debug_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);
241239
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 {
898pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 {896pub 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));
13691370
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;
13761374
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;
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 {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 updates1388 esym.st_value = 0;
1391 gop.value_ptr.* = .{ .symbol_index = sym_index };
13921389
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 }
13981391
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}
14021403
1403pub fn updateFunc(1404pub 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);
2305const NavTable = std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);2307const NavTable = std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);
2306const UavTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, AvMetadata);2308const UavTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, AvMetadata);
2307const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);2309const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);
2308const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable);2310const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, void);
23092311
2310const x86_64 = struct {2312const 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 {