authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-21 20:42:39+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-25 10:20:14+02:00
loga9d3885ac7529e3b1dde3def42ac3da2874dd774
tree85be0fe31caf963c7d61c6c34c33514233558709
parenta6bf762a8ba3672c40e369f832d38f864d86fbd9

elf: streamline sections container


12 files changed, 336 insertions(+), 455 deletions(-)

src/link/Dwarf.zig+4-4
......@@ -317,7 +317,7 @@ pub const Section = struct {
317317 fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void {
318318 if (dwarf.bin_file.cast(.elf)) |elf_file| {
319319 try elf_file.growNonAllocSection(sec.index, len, @intCast(sec.alignment.toByteUnits().?), true);
320 const shdr = &elf_file.shdrs.items[sec.index];
320 const shdr = &elf_file.sections.items(.shdr)[sec.index];
321321 sec.off = shdr.sh_offset;
322322 sec.len = shdr.sh_size;
323323 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {
......@@ -340,7 +340,7 @@ pub const Section = struct {
340340 sec.off += len;
341341 sec.len -= len;
342342 if (dwarf.bin_file.cast(.elf)) |elf_file| {
343 const shdr = &elf_file.shdrs.items[sec.index];
343 const shdr = &elf_file.sections.items(.shdr)[sec.index];
344344 shdr.sh_offset = sec.off;
345345 shdr.sh_size = sec.len;
346346 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {
......@@ -771,7 +771,7 @@ const Entry = struct {
771771 log.err("missing {} from {s}", .{
772772 @as(Entry.Index, @enumFromInt(entry - unit.entries.items.ptr)),
773773 std.mem.sliceTo(if (dwarf.bin_file.cast(.elf)) |elf_file|
774 elf_file.shstrtab.items[elf_file.shdrs.items[sec.index].sh_name..]
774 elf_file.shstrtab.items[elf_file.sections.items(.shdr)[sec.index].sh_name..]
775775 else if (dwarf.bin_file.cast(.macho)) |macho_file|
776776 if (macho_file.d_sym) |*d_sym|
777777 &d_sym.sections.items[sec.index].segname
......@@ -1529,7 +1529,7 @@ pub fn reloadSectionMetadata(dwarf: *Dwarf) void {
15291529 elf_file.debug_rnglists_section_index.?,
15301530 elf_file.debug_str_section_index.?,
15311531 }) |sec, section_index| {
1532 const shdr = &elf_file.shdrs.items[section_index];
1532 const shdr = &elf_file.sections.items(.shdr)[section_index];
15331533 sec.index = section_index;
15341534 sec.off = shdr.sh_offset;
15351535 sec.len = shdr.sh_size;
src/link/Elf.zig+168-256
......@@ -45,17 +45,10 @@ linker_defined_index: ?File.Index = null,
4545objects: std.ArrayListUnmanaged(File.Index) = .{},
4646shared_objects: std.ArrayListUnmanaged(File.Index) = .{},
4747
48/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.
49/// Same order as in the file.
50shdrs: std.ArrayListUnmanaged(elf.Elf64_Shdr) = .{},
51/// Given index to a section, pulls index of containing phdr if any.
52phdr_to_shdr_table: std.AutoHashMapUnmanaged(u32, u32) = .{},
48/// List of all output sections and their associated metadata.
49sections: std.MultiArrayList(Section) = .{},
5350/// File offset into the shdr table.
5451shdr_table_offset: ?u64 = null,
55/// Table of lists of atoms per output section.
56/// This table is not used to track incrementally generated atoms.
57output_sections: std.AutoArrayHashMapUnmanaged(u32, std.ArrayListUnmanaged(Ref)) = .{},
58output_rela_sections: std.AutoArrayHashMapUnmanaged(u32, RelaSection) = .{},
5952
6053/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.
6154/// Same order as in the file.
......@@ -181,9 +174,6 @@ thunks: std.ArrayListUnmanaged(Thunk) = .{},
181174/// List of output merge sections with deduped contents.
182175merge_sections: std.ArrayListUnmanaged(MergeSection) = .{},
183176
184/// Table of last atom index in a section and matching atom free list if any.
185last_atom_and_free_list_table: LastAtomAndFreeListTable = .{},
186
187177first_eflags: ?elf.Elf64_Word = null,
188178
189179/// When allocating, the ideal_capacity is calculated by
......@@ -429,17 +419,12 @@ pub fn deinit(self: *Elf) void {
429419 self.objects.deinit(gpa);
430420 self.shared_objects.deinit(gpa);
431421
432 self.shdrs.deinit(gpa);
433 self.phdr_to_shdr_table.deinit(gpa);
434 self.phdrs.deinit(gpa);
435 for (self.output_sections.values()) |*list| {
436 list.deinit(gpa);
422 for (self.sections.items(.atom_list), self.sections.items(.free_list)) |*atoms, *free_list| {
423 atoms.deinit(gpa);
424 free_list.deinit(gpa);
437425 }
438 self.output_sections.deinit(gpa);
439 for (self.output_rela_sections.values()) |*sec| {
440 sec.atom_list.deinit(gpa);
441 }
442 self.output_rela_sections.deinit(gpa);
426 self.sections.deinit(gpa);
427 self.phdrs.deinit(gpa);
443428 self.shstrtab.deinit(gpa);
444429 self.symtab.deinit(gpa);
445430 self.strtab.deinit(gpa);
......@@ -453,10 +438,6 @@ pub fn deinit(self: *Elf) void {
453438 sect.deinit(gpa);
454439 }
455440 self.merge_sections.deinit(gpa);
456 for (self.last_atom_and_free_list_table.values()) |*value| {
457 value.free_list.deinit(gpa);
458 }
459 self.last_atom_and_free_list_table.deinit(gpa);
460441
461442 self.got.deinit(gpa);
462443 self.plt.deinit(gpa);
......@@ -505,7 +486,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 {
505486
506487 if (self.shdr_table_offset) |off| {
507488 const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr);
508 const tight_size = self.shdrs.items.len * shdr_size;
489 const tight_size = self.sections.items(.shdr).len * shdr_size;
509490 const increased_size = padToIdeal(tight_size);
510491 const test_end = off +| increased_size;
511492 if (start < test_end) {
......@@ -514,7 +495,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 {
514495 }
515496 }
516497
517 for (self.shdrs.items) |shdr| {
498 for (self.sections.items(.shdr)) |shdr| {
518499 if (shdr.sh_type == elf.SHT_NOBITS) continue;
519500 const increased_size = padToIdeal(shdr.sh_size);
520501 const test_end = shdr.sh_offset +| increased_size;
......@@ -544,7 +525,7 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 {
544525 if (self.shdr_table_offset) |off| {
545526 if (off > start and off < min_pos) min_pos = off;
546527 }
547 for (self.shdrs.items) |section| {
528 for (self.sections.items(.shdr)) |section| {
548529 if (section.sh_offset <= start) continue;
549530 if (section.sh_offset < min_pos) min_pos = section.sh_offset;
550531 }
......@@ -574,8 +555,12 @@ pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) !u64 {
574555}
575556
576557pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void {
577 const shdr = &self.shdrs.items[shdr_index];
578 const maybe_phdr = if (self.phdr_to_shdr_table.get(shdr_index)) |phndx| &self.phdrs.items[phndx] else null;
558 const slice = self.sections.slice();
559 const shdr = &slice.items(.shdr)[shdr_index];
560 assert(shdr.sh_flags & elf.SHF_ALLOC != 0);
561 const phndx = slice.items(.phndx)[shdr_index];
562 const phdr = &self.phdrs.items[phndx];
563
579564 log.debug("allocated size {x} of {s}, needed size {x}", .{
580565 self.allocatedSize(shdr.sh_offset),
581566 self.getShString(shdr.sh_name),
......@@ -590,7 +575,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void {
590575 const existing_size = shdr.sh_size;
591576 shdr.sh_size = 0;
592577 // Must move the entire section.
593 const alignment = if (maybe_phdr) |phdr| phdr.p_align else shdr.sh_addralign;
578 const alignment = if (phdr.p_type == elf.PT_NULL) shdr.sh_addralign else phdr.p_align;
594579 const new_offset = try self.findFreeSpace(needed_size, alignment);
595580
596581 log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{
......@@ -604,19 +589,17 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void {
604589 if (amt != existing_size) return error.InputOutput;
605590
606591 shdr.sh_offset = new_offset;
607 if (maybe_phdr) |phdr| phdr.p_offset = new_offset;
592 if (phdr.p_type != elf.PT_NULL) phdr.p_offset = new_offset;
608593 }
609 if (maybe_phdr) |phdr| phdr.p_filesz = needed_size;
594 if (phdr.p_type != elf.PT_NULL) phdr.p_filesz = needed_size;
610595 }
611596 shdr.sh_size = needed_size;
612597
613 if (maybe_phdr) |phdr| {
598 if (phdr.p_type != elf.PT_NULL) {
614599 const mem_capacity = self.allocatedVirtualSize(phdr.p_vaddr);
615600 if (needed_size > mem_capacity) {
616601 var err = try self.base.addErrorWithNotes(2);
617 try err.addMsg("fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{
618 self.phdr_to_shdr_table.get(shdr_index).?,
619 });
602 try err.addMsg("fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{phndx});
620603 try err.addNote("TODO: emit relocations to memory locations in self-hosted backends", .{});
621604 try err.addNote("as a workaround, try increasing pre-allocated virtual memory of each segment", .{});
622605 }
......@@ -634,7 +617,8 @@ pub fn growNonAllocSection(
634617 min_alignment: u32,
635618 requires_file_copy: bool,
636619) !void {
637 const shdr = &self.shdrs.items[shdr_index];
620 const shdr = &self.sections.items(.shdr)[shdr_index];
621 assert(shdr.sh_flags & elf.SHF_ALLOC == 0);
638622
639623 const allocated_size = self.allocatedSize(shdr.sh_offset);
640624 if (shdr.sh_offset + allocated_size == std.math.maxInt(u64)) {
......@@ -1018,7 +1002,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
10181002 const atom_ptr = zo.atom(atom_index) orelse continue;
10191003 if (!atom_ptr.alive) continue;
10201004 const out_shndx = atom_ptr.output_section_index;
1021 const shdr = &self.shdrs.items[out_shndx];
1005 const shdr = &self.sections.items(.shdr)[out_shndx];
10221006 if (shdr.sh_type == elf.SHT_NOBITS) continue;
10231007 const code = try zo.codeAlloc(self, atom_index);
10241008 defer gpa.free(code);
......@@ -2382,7 +2366,7 @@ pub fn writeShdrTable(self: *Elf) !void {
23822366 };
23832367
23842368 const shoff = self.shdr_table_offset orelse 0;
2385 const needed_size = self.shdrs.items.len * shsize;
2369 const needed_size = self.sections.items(.shdr).len * shsize;
23862370
23872371 if (needed_size > self.allocatedSize(shoff)) {
23882372 self.shdr_table_offset = null;
......@@ -2396,12 +2380,12 @@ pub fn writeShdrTable(self: *Elf) !void {
23962380
23972381 switch (self.ptr_width) {
23982382 .p32 => {
2399 const buf = try gpa.alloc(elf.Elf32_Shdr, self.shdrs.items.len);
2383 const buf = try gpa.alloc(elf.Elf32_Shdr, self.sections.items(.shdr).len);
24002384 defer gpa.free(buf);
24012385
24022386 for (buf, 0..) |*shdr, i| {
2403 assert(self.shdrs.items[i].sh_offset != math.maxInt(u64));
2404 shdr.* = shdrTo32(self.shdrs.items[i]);
2387 assert(self.sections.items(.shdr)[i].sh_offset != math.maxInt(u64));
2388 shdr.* = shdrTo32(self.sections.items(.shdr)[i]);
24052389 if (foreign_endian) {
24062390 mem.byteSwapAllFields(elf.Elf32_Shdr, shdr);
24072391 }
......@@ -2409,12 +2393,12 @@ pub fn writeShdrTable(self: *Elf) !void {
24092393 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?);
24102394 },
24112395 .p64 => {
2412 const buf = try gpa.alloc(elf.Elf64_Shdr, self.shdrs.items.len);
2396 const buf = try gpa.alloc(elf.Elf64_Shdr, self.sections.items(.shdr).len);
24132397 defer gpa.free(buf);
24142398
24152399 for (buf, 0..) |*shdr, i| {
2416 assert(self.shdrs.items[i].sh_offset != math.maxInt(u64));
2417 shdr.* = self.shdrs.items[i];
2400 assert(self.sections.items(.shdr)[i].sh_offset != math.maxInt(u64));
2401 shdr.* = self.sections.items(.shdr)[i];
24182402 if (foreign_endian) {
24192403 mem.byteSwapAllFields(elf.Elf64_Shdr, shdr);
24202404 }
......@@ -2582,7 +2566,7 @@ pub fn writeElfHeader(self: *Elf) !void {
25822566 mem.writeInt(u16, hdr_buf[index..][0..2], e_shentsize, endian);
25832567 index += 2;
25842568
2585 const e_shnum = @as(u16, @intCast(self.shdrs.items.len));
2569 const e_shnum = @as(u16, @intCast(self.sections.items(.shdr).len));
25862570 mem.writeInt(u16, hdr_buf[index..][0..2], e_shnum, endian);
25872571 index += 2;
25882572
......@@ -2741,7 +2725,7 @@ pub fn updateMergeSectionSizes(self: *Elf) !void {
27412725 msec.updateSize();
27422726 }
27432727 for (self.merge_sections.items) |*msec| {
2744 const shdr = &self.shdrs.items[msec.output_section_index];
2728 const shdr = &self.sections.items(.shdr)[msec.output_section_index];
27452729 const offset = msec.alignment.forward(shdr.sh_size);
27462730 const padding = offset - shdr.sh_size;
27472731 msec.value = @intCast(offset);
......@@ -2757,7 +2741,7 @@ pub fn writeMergeSections(self: *Elf) !void {
27572741 defer buffer.deinit();
27582742
27592743 for (self.merge_sections.items) |*msec| {
2760 const shdr = self.shdrs.items[msec.output_section_index];
2744 const shdr = self.sections.items(.shdr)[msec.output_section_index];
27612745 const fileoff = math.cast(usize, msec.value + shdr.sh_offset) orelse return error.Overflow;
27622746 const size = math.cast(usize, msec.size) orelse return error.Overflow;
27632747 try buffer.ensureTotalCapacity(size);
......@@ -3045,7 +3029,7 @@ fn initSpecialPhdrs(self: *Elf) !void {
30453029 .@"align" = 1,
30463030 });
30473031
3048 const has_tls = for (self.shdrs.items) |shdr| {
3032 const has_tls = for (self.sections.items(.shdr)) |shdr| {
30493033 if (shdr.sh_flags & elf.SHF_TLS != 0) break true;
30503034 } else false;
30513035 if (has_tls) {
......@@ -3074,6 +3058,7 @@ fn initSpecialPhdrs(self: *Elf) !void {
30743058/// we are about to sort.
30753059fn sortInitFini(self: *Elf) !void {
30763060 const gpa = self.base.comp.gpa;
3061 const slice = self.sections.slice();
30773062
30783063 const Entry = struct {
30793064 priority: i32,
......@@ -3087,7 +3072,7 @@ fn sortInitFini(self: *Elf) !void {
30873072 }
30883073 };
30893074
3090 for (self.shdrs.items, 0..) |shdr, shndx| {
3075 for (slice.items(.shdr), slice.items(.atom_list)) |shdr, *atom_list| {
30913076 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
30923077
30933078 var is_init_fini = false;
......@@ -3104,8 +3089,6 @@ fn sortInitFini(self: *Elf) !void {
31043089 }
31053090
31063091 if (!is_init_fini and !is_ctor_dtor) continue;
3107
3108 const atom_list = self.output_sections.getPtr(@intCast(shndx)).?;
31093092 if (atom_list.items.len == 0) continue;
31103093
31113094 var entries = std.ArrayList(Entry).init(gpa);
......@@ -3173,7 +3156,7 @@ fn setVersionSymtab(self: *Elf) !void {
31733156
31743157 if (self.verneed_section_index) |shndx| {
31753158 try self.verneed.generate(self);
3176 const shdr = &self.shdrs.items[shndx];
3159 const shdr = &self.sections.items(.shdr)[shndx];
31773160 shdr.sh_info = @as(u32, @intCast(self.verneed.verneed.items.len));
31783161 }
31793162}
......@@ -3252,17 +3235,10 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {
32523235 index.* = backlinks[index.*];
32533236 }
32543237 }
3255
3256 {
3257 var it = self.phdr_to_shdr_table.iterator();
3258 while (it.next()) |entry| {
3259 entry.value_ptr.* = backlinks[entry.value_ptr.*];
3260 }
3261 }
32623238}
32633239
32643240fn shdrRank(self: *Elf, shndx: u32) u8 {
3265 const shdr = self.shdrs.items[shndx];
3241 const shdr = self.sections.items(.shdr)[shndx];
32663242 const name = self.getShString(shdr.sh_name);
32673243 const flags = shdr.sh_flags;
32683244
......@@ -3319,9 +3295,9 @@ pub fn sortShdrs(self: *Elf) !void {
33193295 };
33203296
33213297 const gpa = self.base.comp.gpa;
3322 var entries = try std.ArrayList(Entry).initCapacity(gpa, self.shdrs.items.len);
3298 var entries = try std.ArrayList(Entry).initCapacity(gpa, self.sections.items(.shdr).len);
33233299 defer entries.deinit();
3324 for (0..self.shdrs.items.len) |shndx| {
3300 for (0..self.sections.items(.shdr).len) |shndx| {
33253301 entries.appendAssumeCapacity(.{ .shndx = @intCast(shndx) });
33263302 }
33273303
......@@ -3333,20 +3309,18 @@ pub fn sortShdrs(self: *Elf) !void {
33333309 backlinks[entry.shndx] = @intCast(i);
33343310 }
33353311
3336 const slice = try self.shdrs.toOwnedSlice(gpa);
3337 defer gpa.free(slice);
3312 var slice = self.sections.toOwnedSlice();
3313 defer slice.deinit(gpa);
33383314
3339 try self.shdrs.ensureTotalCapacityPrecise(gpa, slice.len);
3315 try self.sections.ensureTotalCapacity(gpa, slice.len);
33403316 for (entries.items) |sorted| {
3341 self.shdrs.appendAssumeCapacity(slice[sorted.shndx]);
3317 self.sections.appendAssumeCapacity(slice.get(sorted.shndx));
33423318 }
33433319
3344 try self.resetShdrIndexes(backlinks);
3320 self.resetShdrIndexes(backlinks);
33453321}
33463322
3347fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {
3348 const gpa = self.base.comp.gpa;
3349
3323fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
33503324 for (&[_]*?u32{
33513325 &self.eh_frame_section_index,
33523326 &self.eh_frame_rela_section_index,
......@@ -3388,116 +3362,65 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {
33883362 }
33893363
33903364 if (self.symtab_section_index) |index| {
3391 const shdr = &self.shdrs.items[index];
3365 const shdr = &self.sections.items(.shdr)[index];
33923366 shdr.sh_link = self.strtab_section_index.?;
33933367 }
33943368
33953369 if (self.dynamic_section_index) |index| {
3396 const shdr = &self.shdrs.items[index];
3370 const shdr = &self.sections.items(.shdr)[index];
33973371 shdr.sh_link = self.dynstrtab_section_index.?;
33983372 }
33993373
34003374 if (self.dynsymtab_section_index) |index| {
3401 const shdr = &self.shdrs.items[index];
3375 const shdr = &self.sections.items(.shdr)[index];
34023376 shdr.sh_link = self.dynstrtab_section_index.?;
34033377 }
34043378
34053379 if (self.hash_section_index) |index| {
3406 const shdr = &self.shdrs.items[index];
3380 const shdr = &self.sections.items(.shdr)[index];
34073381 shdr.sh_link = self.dynsymtab_section_index.?;
34083382 }
34093383
34103384 if (self.gnu_hash_section_index) |index| {
3411 const shdr = &self.shdrs.items[index];
3385 const shdr = &self.sections.items(.shdr)[index];
34123386 shdr.sh_link = self.dynsymtab_section_index.?;
34133387 }
34143388
34153389 if (self.versym_section_index) |index| {
3416 const shdr = &self.shdrs.items[index];
3390 const shdr = &self.sections.items(.shdr)[index];
34173391 shdr.sh_link = self.dynsymtab_section_index.?;
34183392 }
34193393
34203394 if (self.verneed_section_index) |index| {
3421 const shdr = &self.shdrs.items[index];
3395 const shdr = &self.sections.items(.shdr)[index];
34223396 shdr.sh_link = self.dynstrtab_section_index.?;
34233397 }
34243398
34253399 if (self.rela_dyn_section_index) |index| {
3426 const shdr = &self.shdrs.items[index];
3400 const shdr = &self.sections.items(.shdr)[index];
34273401 shdr.sh_link = self.dynsymtab_section_index orelse 0;
34283402 }
34293403
34303404 if (self.rela_plt_section_index) |index| {
3431 const shdr = &self.shdrs.items[index];
3405 const shdr = &self.sections.items(.shdr)[index];
34323406 shdr.sh_link = self.dynsymtab_section_index.?;
34333407 shdr.sh_info = self.plt_section_index.?;
34343408 }
34353409
34363410 if (self.eh_frame_rela_section_index) |index| {
3437 const shdr = &self.shdrs.items[index];
3411 const shdr = &self.sections.items(.shdr)[index];
34383412 shdr.sh_link = self.symtab_section_index.?;
34393413 shdr.sh_info = self.eh_frame_section_index.?;
34403414 }
34413415
3442 {
3443 var output_sections = try self.output_sections.clone(gpa);
3444 defer output_sections.deinit(gpa);
3445
3446 self.output_sections.clearRetainingCapacity();
3447
3448 var it = output_sections.iterator();
3449 while (it.next()) |entry| {
3450 const shndx = entry.key_ptr.*;
3451 const meta = entry.value_ptr.*;
3452 self.output_sections.putAssumeCapacityNoClobber(backlinks[shndx], meta);
3453 }
3454 }
3455
34563416 for (self.merge_sections.items) |*msec| {
34573417 msec.output_section_index = backlinks[msec.output_section_index];
34583418 }
34593419
3460 {
3461 var output_rela_sections = try self.output_rela_sections.clone(gpa);
3462 defer output_rela_sections.deinit(gpa);
3463
3464 self.output_rela_sections.clearRetainingCapacity();
3465
3466 var it = output_rela_sections.iterator();
3467 while (it.next()) |entry| {
3468 const shndx = entry.key_ptr.*;
3469 var meta = entry.value_ptr.*;
3470 meta.shndx = backlinks[meta.shndx];
3471 self.output_rela_sections.putAssumeCapacityNoClobber(backlinks[shndx], meta);
3472 }
3473 }
3474
3475 {
3476 var last_atom_and_free_list_table = try self.last_atom_and_free_list_table.clone(gpa);
3477 defer last_atom_and_free_list_table.deinit(gpa);
3478
3479 self.last_atom_and_free_list_table.clearRetainingCapacity();
3480
3481 var it = last_atom_and_free_list_table.iterator();
3482 while (it.next()) |entry| {
3483 const shndx = entry.key_ptr.*;
3484 const meta = entry.value_ptr.*;
3485 self.last_atom_and_free_list_table.putAssumeCapacityNoClobber(backlinks[shndx], meta);
3486 }
3487 }
3488
3489 {
3490 var phdr_to_shdr_table = try self.phdr_to_shdr_table.clone(gpa);
3491 defer phdr_to_shdr_table.deinit(gpa);
3492
3493 self.phdr_to_shdr_table.clearRetainingCapacity();
3494
3495 var it = phdr_to_shdr_table.iterator();
3496 while (it.next()) |entry| {
3497 const shndx = entry.key_ptr.*;
3498 const phndx = entry.value_ptr.*;
3499 self.phdr_to_shdr_table.putAssumeCapacityNoClobber(backlinks[shndx], phndx);
3500 }
3420 for (self.sections.items(.shdr)) |*shdr| {
3421 if (shdr.sh_type != elf.SHT_RELA) continue;
3422 shdr.sh_link = backlinks[shdr.sh_link];
3423 shdr.sh_info = backlinks[shdr.sh_info];
35013424 }
35023425
35033426 if (self.zigObjectPtr()) |zo| {
......@@ -3508,12 +3431,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {
35083431 if (zo.dwarf) |*dwarf| dwarf.reloadSectionMetadata();
35093432 }
35103433
3511 for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, sec| {
3512 const shdr = &self.shdrs.items[sec.shndx];
3513 shdr.sh_link = self.symtab_section_index.?;
3514 shdr.sh_info = shndx;
3515 }
3516
35173434 for (self.comdat_group_sections.items) |*cg| {
35183435 cg.shndx = backlinks[cg.shndx];
35193436 }
......@@ -3521,8 +3438,8 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {
35213438
35223439fn updateSectionSizes(self: *Elf) !void {
35233440 const target = self.base.comp.root_mod.resolved_target.result;
3524 for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| {
3525 const shdr = &self.shdrs.items[shndx];
3441 const slice = self.sections.slice();
3442 for (slice.items(.shdr), slice.items(.atom_list)) |*shdr, atom_list| {
35263443 if (atom_list.items.len == 0) continue;
35273444 if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue;
35283445 for (atom_list.items) |ref| {
......@@ -3537,38 +3454,38 @@ fn updateSectionSizes(self: *Elf) !void {
35373454 }
35383455
35393456 if (self.requiresThunks()) {
3540 for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| {
3541 const shdr = self.shdrs.items[shndx];
3457 for (slice.items(.shdr), slice.items(.atom_list), 0..) |*shdr, atom_list, shndx| {
35423458 if (shdr.sh_flags & elf.SHF_EXECINSTR == 0) continue;
35433459 if (atom_list.items.len == 0) continue;
35443460
35453461 // Create jump/branch range extenders if needed.
3546 try thunks.createThunks(shndx, self);
3462 try thunks.createThunks(shdr, @intCast(shndx), self);
35473463 }
35483464 }
35493465
3466 const shdrs = slice.items(.shdr);
35503467 if (self.eh_frame_section_index) |index| {
3551 self.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(self);
3468 shdrs[index].sh_size = try eh_frame.calcEhFrameSize(self);
35523469 }
35533470
35543471 if (self.eh_frame_hdr_section_index) |index| {
3555 self.shdrs.items[index].sh_size = eh_frame.calcEhFrameHdrSize(self);
3472 shdrs[index].sh_size = eh_frame.calcEhFrameHdrSize(self);
35563473 }
35573474
35583475 if (self.got_section_index) |index| {
3559 self.shdrs.items[index].sh_size = self.got.size(self);
3476 shdrs[index].sh_size = self.got.size(self);
35603477 }
35613478
35623479 if (self.plt_section_index) |index| {
3563 self.shdrs.items[index].sh_size = self.plt.size(self);
3480 shdrs[index].sh_size = self.plt.size(self);
35643481 }
35653482
35663483 if (self.got_plt_section_index) |index| {
3567 self.shdrs.items[index].sh_size = self.got_plt.size(self);
3484 shdrs[index].sh_size = self.got_plt.size(self);
35683485 }
35693486
35703487 if (self.plt_got_section_index) |index| {
3571 self.shdrs.items[index].sh_size = self.plt_got.size(self);
3488 shdrs[index].sh_size = self.plt_got.size(self);
35723489 }
35733490
35743491 if (self.rela_dyn_section_index) |shndx| {
......@@ -3579,11 +3496,11 @@ fn updateSectionSizes(self: *Elf) !void {
35793496 for (self.objects.items) |index| {
35803497 num += self.file(index).?.object.num_dynrelocs;
35813498 }
3582 self.shdrs.items[shndx].sh_size = num * @sizeOf(elf.Elf64_Rela);
3499 shdrs[shndx].sh_size = num * @sizeOf(elf.Elf64_Rela);
35833500 }
35843501
35853502 if (self.rela_plt_section_index) |index| {
3586 self.shdrs.items[index].sh_size = self.plt.numRela() * @sizeOf(elf.Elf64_Rela);
3503 shdrs[index].sh_size = self.plt.numRela() * @sizeOf(elf.Elf64_Rela);
35873504 }
35883505
35893506 if (self.copy_rel_section_index) |index| {
......@@ -3591,44 +3508,45 @@ fn updateSectionSizes(self: *Elf) !void {
35913508 }
35923509
35933510 if (self.interp_section_index) |index| {
3594 self.shdrs.items[index].sh_size = target.dynamic_linker.get().?.len + 1;
3511 shdrs[index].sh_size = target.dynamic_linker.get().?.len + 1;
35953512 }
35963513
35973514 if (self.hash_section_index) |index| {
3598 self.shdrs.items[index].sh_size = self.hash.size();
3515 shdrs[index].sh_size = self.hash.size();
35993516 }
36003517
36013518 if (self.gnu_hash_section_index) |index| {
3602 self.shdrs.items[index].sh_size = self.gnu_hash.size();
3519 shdrs[index].sh_size = self.gnu_hash.size();
36033520 }
36043521
36053522 if (self.dynamic_section_index) |index| {
3606 self.shdrs.items[index].sh_size = self.dynamic.size(self);
3523 shdrs[index].sh_size = self.dynamic.size(self);
36073524 }
36083525
36093526 if (self.dynsymtab_section_index) |index| {
3610 self.shdrs.items[index].sh_size = self.dynsym.size();
3527 shdrs[index].sh_size = self.dynsym.size();
36113528 }
36123529
36133530 if (self.dynstrtab_section_index) |index| {
3614 self.shdrs.items[index].sh_size = self.dynstrtab.items.len;
3531 shdrs[index].sh_size = self.dynstrtab.items.len;
36153532 }
36163533
36173534 if (self.versym_section_index) |index| {
3618 self.shdrs.items[index].sh_size = self.versym.items.len * @sizeOf(elf.Elf64_Versym);
3535 shdrs[index].sh_size = self.versym.items.len * @sizeOf(elf.Elf64_Versym);
36193536 }
36203537
36213538 if (self.verneed_section_index) |index| {
3622 self.shdrs.items[index].sh_size = self.verneed.size();
3539 shdrs[index].sh_size = self.verneed.size();
36233540 }
36243541
36253542 try self.updateSymtabSize();
36263543 self.updateShStrtabSize();
36273544}
36283545
3546// FIXME:JK this is very much obsolete, remove!
36293547pub fn updateShStrtabSize(self: *Elf) void {
36303548 if (self.shstrtab_section_index) |index| {
3631 self.shdrs.items[index].sh_size = self.shstrtab.items.len;
3549 self.sections.items(.shdr)[index].sh_size = self.shstrtab.items.len;
36323550 }
36333551}
36343552
......@@ -3661,7 +3579,7 @@ fn getMaxNumberOfPhdrs() u64 {
36613579/// We permit a maximum of 3**2 number of segments.
36623580fn calcNumberOfSegments(self: *Elf) usize {
36633581 var covers: [9]bool = [_]bool{false} ** 9;
3664 for (self.shdrs.items, 0..) |shdr, shndx| {
3582 for (self.sections.items(.shdr), 0..) |shdr, shndx| {
36653583 if (shdr.sh_type == elf.SHT_NULL) continue;
36663584 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
36673585 if (self.isZigSection(@intCast(shndx))) continue;
......@@ -3732,8 +3650,9 @@ pub fn allocateAllocSections(self: *Elf) !void {
37323650 }
37333651 };
37343652
3653 const slice = self.sections.slice();
37353654 var alignment = Align{};
3736 for (self.shdrs.items, 0..) |shdr, i| {
3655 for (slice.items(.shdr), 0..) |shdr, i| {
37373656 if (shdr.sh_type == elf.SHT_NULL) continue;
37383657 if (shdr.sh_flags & elf.SHF_TLS == 0) continue;
37393658 if (alignment.first_tls_index == null) alignment.first_tls_index = i;
......@@ -3758,7 +3677,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
37583677 cover.deinit();
37593678 };
37603679
3761 for (self.shdrs.items, 0..) |shdr, shndx| {
3680 for (slice.items(.shdr), 0..) |shdr, shndx| {
37623681 if (shdr.sh_type == elf.SHT_NULL) continue;
37633682 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
37643683 if (self.isZigSection(@intCast(shndx))) continue;
......@@ -3779,7 +3698,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
37793698
37803699 var @"align": u64 = self.page_size;
37813700 for (cover.items) |shndx| {
3782 const shdr = self.shdrs.items[shndx];
3701 const shdr = slice.items(.shdr)[shndx];
37833702 if (shdr.sh_type == elf.SHT_NOBITS and shdr.sh_flags & elf.SHF_TLS != 0) continue;
37843703 @"align" = @max(@"align", shdr.sh_addralign);
37853704 }
......@@ -3791,7 +3710,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
37913710 var i: usize = 0;
37923711 while (i < cover.items.len) : (i += 1) {
37933712 const shndx = cover.items[i];
3794 const shdr = &self.shdrs.items[shndx];
3713 const shdr = &slice.items(.shdr)[shndx];
37953714 if (shdr.sh_type == elf.SHT_NOBITS and shdr.sh_flags & elf.SHF_TLS != 0) {
37963715 // .tbss is a little special as it's used only by the loader meaning it doesn't
37973716 // need to be actually mmap'ed at runtime. We still need to correctly increment
......@@ -3807,11 +3726,11 @@ pub fn allocateAllocSections(self: *Elf) !void {
38073726 // ...
38083727 var tbss_addr = addr;
38093728 while (i < cover.items.len and
3810 self.shdrs.items[cover.items[i]].sh_type == elf.SHT_NOBITS and
3811 self.shdrs.items[cover.items[i]].sh_flags & elf.SHF_TLS != 0) : (i += 1)
3729 slice.items(.shdr)[cover.items[i]].sh_type == elf.SHT_NOBITS and
3730 slice.items(.shdr)[cover.items[i]].sh_flags & elf.SHF_TLS != 0) : (i += 1)
38123731 {
38133732 const tbss_shndx = cover.items[i];
3814 const tbss_shdr = &self.shdrs.items[tbss_shndx];
3733 const tbss_shdr = &slice.items(.shdr)[tbss_shndx];
38153734 tbss_addr = alignment.@"align"(tbss_shndx, tbss_shdr.sh_addralign, tbss_addr);
38163735 tbss_shdr.sh_addr = tbss_addr;
38173736 tbss_addr += tbss_shdr.sh_size;
......@@ -3830,7 +3749,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
38303749 addr += shdr.sh_size;
38313750 }
38323751
3833 const first = self.shdrs.items[cover.items[0]];
3752 const first = slice.items(.shdr)[cover.items[0]];
38343753 var off = try self.findFreeSpace(filesz, @"align");
38353754 const phndx = try self.addPhdr(.{
38363755 .type = elf.PT_LOAD,
......@@ -3843,7 +3762,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
38433762 });
38443763
38453764 for (cover.items) |shndx| {
3846 const shdr = &self.shdrs.items[shndx];
3765 const shdr = &slice.items(.shdr)[shndx];
38473766 if (shdr.sh_type == elf.SHT_NOBITS) {
38483767 shdr.sh_offset = 0;
38493768 continue;
......@@ -3851,7 +3770,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
38513770 off = alignment.@"align"(shndx, shdr.sh_addralign, off);
38523771 shdr.sh_offset = off;
38533772 off += shdr.sh_size;
3854 try self.phdr_to_shdr_table.putNoClobber(gpa, shndx, phndx);
3773 slice.items(.phndx)[shndx] = phndx;
38553774 }
38563775
38573776 addr = mem.alignForward(u64, addr, self.page_size);
......@@ -3860,7 +3779,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
38603779
38613780/// Allocates non-alloc sections (debug info, symtabs, etc.).
38623781pub fn allocateNonAllocSections(self: *Elf) !void {
3863 for (self.shdrs.items, 0..) |*shdr, shndx| {
3782 for (self.sections.items(.shdr), 0..) |*shdr, shndx| {
38643783 if (shdr.sh_type == elf.SHT_NULL) continue;
38653784 if (shdr.sh_flags & elf.SHF_ALLOC != 0) continue;
38663785 const needed_size = shdr.sh_size;
......@@ -3905,13 +3824,15 @@ pub fn allocateNonAllocSections(self: *Elf) !void {
39053824}
39063825
39073826fn allocateSpecialPhdrs(self: *Elf) void {
3827 const slice = self.sections.slice();
3828
39083829 for (&[_]struct { ?u16, ?u32 }{
39093830 .{ self.phdr_interp_index, self.interp_section_index },
39103831 .{ self.phdr_dynamic_index, self.dynamic_section_index },
39113832 .{ self.phdr_gnu_eh_frame_index, self.eh_frame_hdr_section_index },
39123833 }) |pair| {
39133834 if (pair[0]) |index| {
3914 const shdr = self.shdrs.items[pair[1].?];
3835 const shdr = slice.items(.shdr)[pair[1].?];
39153836 const phdr = &self.phdrs.items[index];
39163837 phdr.p_align = shdr.sh_addralign;
39173838 phdr.p_offset = shdr.sh_offset;
......@@ -3926,11 +3847,11 @@ fn allocateSpecialPhdrs(self: *Elf) void {
39263847 // We assume TLS sections are laid out contiguously and that there is
39273848 // a single TLS segment.
39283849 if (self.phdr_tls_index) |index| {
3929 const slice = self.shdrs.items;
3850 const shdrs = slice.items(.shdr);
39303851 const phdr = &self.phdrs.items[index];
39313852 var shndx: u32 = 0;
3932 while (shndx < slice.len) {
3933 const shdr = slice[shndx];
3853 while (shndx < shdrs.len) {
3854 const shdr = shdrs[shndx];
39343855 if (shdr.sh_flags & elf.SHF_TLS == 0) {
39353856 shndx += 1;
39363857 continue;
......@@ -3946,8 +3867,8 @@ fn allocateSpecialPhdrs(self: *Elf) void {
39463867 }
39473868 phdr.p_memsz = shdr.sh_addr + shdr.sh_size - phdr.p_vaddr;
39483869
3949 while (shndx < slice.len) : (shndx += 1) {
3950 const next = slice[shndx];
3870 while (shndx < shdrs.len) : (shndx += 1) {
3871 const next = shdrs[shndx];
39513872 if (next.sh_flags & elf.SHF_TLS == 0) break;
39523873 phdr.p_align = @max(phdr.p_align, next.sh_addralign);
39533874 if (next.sh_type != elf.SHT_NOBITS) {
......@@ -3971,13 +3892,10 @@ fn writeAtoms(self: *Elf) !void {
39713892 }
39723893
39733894 var has_reloc_errors = false;
3974
3975 // TODO iterate over `output_sections` directly
3976 for (self.shdrs.items, 0..) |shdr, shndx| {
3895 const slice = self.sections.slice();
3896 for (slice.items(.shdr), slice.items(.atom_list), 0..) |shdr, atom_list, shndx| {
39773897 if (shdr.sh_type == elf.SHT_NULL) continue;
39783898 if (shdr.sh_type == elf.SHT_NOBITS) continue;
3979
3980 const atom_list = self.output_sections.get(@intCast(shndx)) orelse continue;
39813899 if (atom_list.items.len == 0) continue;
39823900
39833901 log.debug("writing atoms in '{s}' section", .{self.getShString(shdr.sh_name)});
......@@ -4056,7 +3974,7 @@ fn writeAtoms(self: *Elf) !void {
40563974 for (self.thunks.items) |th| {
40573975 const thunk_size = th.size(self);
40583976 try buffer.ensureUnusedCapacity(thunk_size);
4059 const shdr = self.shdrs.items[th.output_section_index];
3977 const shdr = slice.items(.shdr)[th.output_section_index];
40603978 const offset = @as(u64, @intCast(th.value)) + shdr.sh_offset;
40613979 try th.write(self, buffer.writer());
40623980 assert(buffer.items.len == thunk_size);
......@@ -4086,12 +4004,7 @@ pub fn updateSymtabSize(self: *Elf) !void {
40864004 if (self.linker_defined_index) |index| files.appendAssumeCapacity(index);
40874005
40884006 // Section symbols
4089 for (self.output_sections.keys()) |_| {
4090 nlocals += 1;
4091 }
4092 if (self.eh_frame_section_index) |_| {
4093 nlocals += 1;
4094 }
4007 nlocals += @intCast(self.sections.slice().len);
40954008
40964009 if (self.requiresThunks()) for (self.thunks.items) |*th| {
40974010 th.output_symtab_ctx.ilocal = nlocals + 1;
......@@ -4142,7 +4055,8 @@ pub fn updateSymtabSize(self: *Elf) !void {
41424055 ctx.iglobal += nlocals;
41434056 }
41444057
4145 const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?];
4058 const slice = self.sections.slice();
4059 const symtab_shdr = &slice.items(.shdr)[self.symtab_section_index.?];
41464060 symtab_shdr.sh_info = nlocals + 1;
41474061 symtab_shdr.sh_link = self.strtab_section_index.?;
41484062
......@@ -4153,13 +4067,14 @@ pub fn updateSymtabSize(self: *Elf) !void {
41534067 const needed_size = (nlocals + nglobals + 1) * sym_size;
41544068 symtab_shdr.sh_size = needed_size;
41554069
4156 const strtab = &self.shdrs.items[self.strtab_section_index.?];
4070 const strtab = &slice.items(.shdr)[self.strtab_section_index.?];
41574071 strtab.sh_size = strsize + 1;
41584072}
41594073
41604074fn writeSyntheticSections(self: *Elf) !void {
4161 const target = self.base.comp.root_mod.resolved_target.result;
41624075 const gpa = self.base.comp.gpa;
4076 const target = self.getTarget();
4077 const slice = self.sections.slice();
41634078
41644079 if (self.interp_section_index) |shndx| {
41654080 var buffer: [256]u8 = undefined;
......@@ -4167,18 +4082,18 @@ fn writeSyntheticSections(self: *Elf) !void {
41674082 @memcpy(buffer[0..interp.len], interp);
41684083 buffer[interp.len] = 0;
41694084 const contents = buffer[0 .. interp.len + 1];
4170 const shdr = self.shdrs.items[shndx];
4085 const shdr = slice.items(.shdr)[shndx];
41714086 assert(shdr.sh_size == contents.len);
41724087 try self.base.file.?.pwriteAll(contents, shdr.sh_offset);
41734088 }
41744089
41754090 if (self.hash_section_index) |shndx| {
4176 const shdr = self.shdrs.items[shndx];
4091 const shdr = slice.items(.shdr)[shndx];
41774092 try self.base.file.?.pwriteAll(self.hash.buffer.items, shdr.sh_offset);
41784093 }
41794094
41804095 if (self.gnu_hash_section_index) |shndx| {
4181 const shdr = self.shdrs.items[shndx];
4096 const shdr = slice.items(.shdr)[shndx];
41824097 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.gnu_hash.size());
41834098 defer buffer.deinit();
41844099 try self.gnu_hash.write(self, buffer.writer());
......@@ -4186,12 +4101,12 @@ fn writeSyntheticSections(self: *Elf) !void {
41864101 }
41874102
41884103 if (self.versym_section_index) |shndx| {
4189 const shdr = self.shdrs.items[shndx];
4104 const shdr = slice.items(.shdr)[shndx];
41904105 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.versym.items), shdr.sh_offset);
41914106 }
41924107
41934108 if (self.verneed_section_index) |shndx| {
4194 const shdr = self.shdrs.items[shndx];
4109 const shdr = slice.items(.shdr)[shndx];
41954110 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.verneed.size());
41964111 defer buffer.deinit();
41974112 try self.verneed.write(buffer.writer());
......@@ -4199,7 +4114,7 @@ fn writeSyntheticSections(self: *Elf) !void {
41994114 }
42004115
42014116 if (self.dynamic_section_index) |shndx| {
4202 const shdr = self.shdrs.items[shndx];
4117 const shdr = slice.items(.shdr)[shndx];
42034118 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynamic.size(self));
42044119 defer buffer.deinit();
42054120 try self.dynamic.write(self, buffer.writer());
......@@ -4207,7 +4122,7 @@ fn writeSyntheticSections(self: *Elf) !void {
42074122 }
42084123
42094124 if (self.dynsymtab_section_index) |shndx| {
4210 const shdr = self.shdrs.items[shndx];
4125 const shdr = slice.items(.shdr)[shndx];
42114126 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynsym.size());
42124127 defer buffer.deinit();
42134128 try self.dynsym.write(self, buffer.writer());
......@@ -4215,12 +4130,12 @@ fn writeSyntheticSections(self: *Elf) !void {
42154130 }
42164131
42174132 if (self.dynstrtab_section_index) |shndx| {
4218 const shdr = self.shdrs.items[shndx];
4133 const shdr = slice.items(.shdr)[shndx];
42194134 try self.base.file.?.pwriteAll(self.dynstrtab.items, shdr.sh_offset);
42204135 }
42214136
42224137 if (self.eh_frame_section_index) |shndx| {
4223 const shdr = self.shdrs.items[shndx];
4138 const shdr = slice.items(.shdr)[shndx];
42244139 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
42254140 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
42264141 defer buffer.deinit();
......@@ -4229,7 +4144,7 @@ fn writeSyntheticSections(self: *Elf) !void {
42294144 }
42304145
42314146 if (self.eh_frame_hdr_section_index) |shndx| {
4232 const shdr = self.shdrs.items[shndx];
4147 const shdr = slice.items(.shdr)[shndx];
42334148 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
42344149 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
42354150 defer buffer.deinit();
......@@ -4238,7 +4153,7 @@ fn writeSyntheticSections(self: *Elf) !void {
42384153 }
42394154
42404155 if (self.got_section_index) |index| {
4241 const shdr = self.shdrs.items[index];
4156 const shdr = slice.items(.shdr)[index];
42424157 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got.size(self));
42434158 defer buffer.deinit();
42444159 try self.got.write(self, buffer.writer());
......@@ -4246,7 +4161,7 @@ fn writeSyntheticSections(self: *Elf) !void {
42464161 }
42474162
42484163 if (self.rela_dyn_section_index) |shndx| {
4249 const shdr = self.shdrs.items[shndx];
4164 const shdr = slice.items(.shdr)[shndx];
42504165 try self.got.addRela(self);
42514166 try self.copy_rel.addRela(self);
42524167 self.sortRelaDyn();
......@@ -4254,7 +4169,7 @@ fn writeSyntheticSections(self: *Elf) !void {
42544169 }
42554170
42564171 if (self.plt_section_index) |shndx| {
4257 const shdr = self.shdrs.items[shndx];
4172 const shdr = slice.items(.shdr)[shndx];
42584173 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt.size(self));
42594174 defer buffer.deinit();
42604175 try self.plt.write(self, buffer.writer());
......@@ -4262,7 +4177,7 @@ fn writeSyntheticSections(self: *Elf) !void {
42624177 }
42634178
42644179 if (self.got_plt_section_index) |shndx| {
4265 const shdr = self.shdrs.items[shndx];
4180 const shdr = slice.items(.shdr)[shndx];
42664181 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got_plt.size(self));
42674182 defer buffer.deinit();
42684183 try self.got_plt.write(self, buffer.writer());
......@@ -4270,7 +4185,7 @@ fn writeSyntheticSections(self: *Elf) !void {
42704185 }
42714186
42724187 if (self.plt_got_section_index) |shndx| {
4273 const shdr = self.shdrs.items[shndx];
4188 const shdr = slice.items(.shdr)[shndx];
42744189 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt_got.size(self));
42754190 defer buffer.deinit();
42764191 try self.plt_got.write(self, buffer.writer());
......@@ -4278,7 +4193,7 @@ fn writeSyntheticSections(self: *Elf) !void {
42784193 }
42794194
42804195 if (self.rela_plt_section_index) |shndx| {
4281 const shdr = self.shdrs.items[shndx];
4196 const shdr = slice.items(.shdr)[shndx];
42824197 try self.plt.addRela(self);
42834198 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_plt.items), shdr.sh_offset);
42844199 }
......@@ -4287,19 +4202,21 @@ fn writeSyntheticSections(self: *Elf) !void {
42874202 try self.writeShStrtab();
42884203}
42894204
4205// FIXME:JK again, why is this needed?
42904206pub fn writeShStrtab(self: *Elf) !void {
42914207 if (self.shstrtab_section_index) |index| {
4292 const shdr = self.shdrs.items[index];
4208 const shdr = self.sections.items(.shdr)[index];
42934209 log.debug("writing .shstrtab from 0x{x} to 0x{x}", .{ shdr.sh_offset, shdr.sh_offset + shdr.sh_size });
42944210 try self.base.file.?.pwriteAll(self.shstrtab.items, shdr.sh_offset);
42954211 }
42964212}
42974213
42984214pub fn writeSymtab(self: *Elf) !void {
4299 const target = self.base.comp.root_mod.resolved_target.result;
43004215 const gpa = self.base.comp.gpa;
4301 const symtab_shdr = self.shdrs.items[self.symtab_section_index.?];
4302 const strtab_shdr = self.shdrs.items[self.strtab_section_index.?];
4216 const target = self.getTarget();
4217 const slice = self.sections.slice();
4218 const symtab_shdr = slice.items(.shdr)[self.symtab_section_index.?];
4219 const strtab_shdr = slice.items(.shdr)[self.strtab_section_index.?];
43034220 const sym_size: u64 = switch (self.ptr_width) {
43044221 .p32 => @sizeOf(elf.Elf32_Sym),
43054222 .p64 => @sizeOf(elf.Elf64_Sym),
......@@ -4387,9 +4304,9 @@ pub fn writeSymtab(self: *Elf) !void {
43874304}
43884305
43894306fn writeSectionSymbols(self: *Elf) void {
4307 const slice = self.sections.slice();
43904308 var ilocal: u32 = 1;
4391 for (self.output_sections.keys()) |shndx| {
4392 const shdr = self.shdrs.items[shndx];
4309 for (slice.items(.shdr), 0..) |shdr, shndx| {
43934310 const out_sym = &self.symtab.items[ilocal];
43944311 out_sym.* = .{
43954312 .st_name = 0,
......@@ -4403,7 +4320,7 @@ fn writeSectionSymbols(self: *Elf) void {
44034320 }
44044321
44054322 if (self.eh_frame_section_index) |shndx| {
4406 const shdr = self.shdrs.items[shndx];
4323 const shdr = slice.items(.shdr)[shndx];
44074324 const out_sym = &self.symtab.items[ilocal];
44084325 out_sym.* = .{
44094326 .st_name = 0,
......@@ -4418,10 +4335,8 @@ fn writeSectionSymbols(self: *Elf) void {
44184335}
44194336
44204337pub fn sectionSymbolOutputSymtabIndex(self: Elf, shndx: u32) u32 {
4421 if (self.eh_frame_section_index) |index| {
4422 if (index == shndx) return @intCast(self.output_sections.keys().len + 1);
4423 }
4424 return @intCast(self.output_sections.getIndex(shndx).? + 1);
4338 _ = self;
4339 return shndx + 1;
44254340}
44264341
44274342/// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF.
......@@ -4435,8 +4350,7 @@ pub fn ptrWidthBytes(self: Elf) u8 {
44354350/// Does not necessarily match `ptrWidthBytes` for example can be 2 bytes
44364351/// in a 32-bit ELF file.
44374352pub fn archPtrWidthBytes(self: Elf) u8 {
4438 const target = self.base.comp.root_mod.resolved_target.result;
4439 return @intCast(@divExact(target.ptrBitWidth(), 8));
4353 return @intCast(@divExact(self.getTarget().ptrBitWidth(), 8));
44404354}
44414355
44424356fn phdrTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr {
......@@ -4816,25 +4730,26 @@ pub const AddSectionOpts = struct {
48164730
48174731pub fn addSection(self: *Elf, opts: AddSectionOpts) !u32 {
48184732 const gpa = self.base.comp.gpa;
4819 const index: u32 = @intCast(self.shdrs.items.len);
4820 const shdr = try self.shdrs.addOne(gpa);
4821 shdr.* = .{
4822 .sh_name = opts.name,
4823 .sh_type = opts.type,
4824 .sh_flags = opts.flags,
4825 .sh_addr = 0,
4826 .sh_offset = opts.offset,
4827 .sh_size = 0,
4828 .sh_link = opts.link,
4829 .sh_info = opts.info,
4830 .sh_addralign = opts.addralign,
4831 .sh_entsize = opts.entsize,
4832 };
4733 const index: u32 = @intCast(try self.sections.addOne(gpa));
4734 self.sections.set(index, .{
4735 .shdr = .{
4736 .sh_name = opts.name,
4737 .sh_type = opts.type,
4738 .sh_flags = opts.flags,
4739 .sh_addr = 0,
4740 .sh_offset = opts.offset,
4741 .sh_size = 0,
4742 .sh_link = opts.link,
4743 .sh_info = opts.info,
4744 .sh_addralign = opts.addralign,
4745 .sh_entsize = opts.entsize,
4746 },
4747 });
48334748 return index;
48344749}
48354750
48364751pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u32 {
4837 for (self.shdrs.items, 0..) |*shdr, i| {
4752 for (self.sections.items(.shdr), 0..) |*shdr, i| {
48384753 const this_name = self.getShString(shdr.sh_name);
48394754 if (mem.eql(u8, this_name, name)) return @intCast(i);
48404755 } else return null;
......@@ -5012,7 +4927,7 @@ pub fn gotAddress(self: *Elf) i64 {
50124927 break :blk self.got_plt_section_index.?;
50134928 break :blk if (self.got_section_index) |shndx| shndx else null;
50144929 };
5015 return if (shndx) |index| @intCast(self.shdrs.items[index].sh_addr) else 0;
4930 return if (shndx) |index| @intCast(self.sections.items(.shdr)[index].sh_addr) else 0;
50164931}
50174932
50184933pub fn tpAddress(self: *Elf) i64 {
......@@ -5366,16 +5281,16 @@ fn fmtDumpState(
53665281 }
53675282
53685283 try writer.writeAll("\nOutput shdrs\n");
5369 for (self.shdrs.items, 0..) |shdr, shndx| {
5370 try writer.print(" shdr({d}) : phdr({?d}) : {}\n", .{
5284 for (self.sections.items(.shdr), self.sections.items(.phndx), 0..) |shdr, phndx, shndx| {
5285 try writer.print(" shdr({d}) : phdr({d}) : {}\n", .{
53715286 shndx,
5372 self.phdr_to_shdr_table.get(@intCast(shndx)),
5287 phndx,
53735288 self.fmtShdr(shdr),
53745289 });
53755290 }
53765291 try writer.writeAll("\nOutput phdrs\n");
53775292 for (self.phdrs.items, 0..) |phdr, phndx| {
5378 try writer.print(" phdr{d} : {}\n", .{ phndx, self.fmtPhdr(phdr) });
5293 try writer.print(" phdr({d}) : {}\n", .{ phndx, self.fmtPhdr(phdr) });
53795294 }
53805295}
53815296
......@@ -5613,7 +5528,11 @@ pub const SymbolResolver = struct {
56135528 pub const Index = u32;
56145529};
56155530
5616const LastAtomAndFreeList = struct {
5531const Section = struct {
5532 shdr: elf.Elf64_Shdr,
5533 phndx: u32 = 0,
5534 atom_list: std.ArrayListUnmanaged(Ref) = .{},
5535
56175536 /// Index of the last allocated atom in this section.
56185537 last_atom_index: Atom.Index = 0,
56195538
......@@ -5634,13 +5553,6 @@ const LastAtomAndFreeList = struct {
56345553 /// by 1 byte. It will then have -1 overcapacity.
56355554 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},
56365555};
5637const LastAtomAndFreeListTable = std.AutoArrayHashMapUnmanaged(u32, LastAtomAndFreeList);
5638
5639const RelaSection = struct {
5640 shndx: u32,
5641 atom_list: std.ArrayListUnmanaged(Ref) = .{},
5642};
5643const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);
56445556
56455557fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {
56465558 return switch (cpu_arch) {
src/link/Elf/Atom.zig+8-8
......@@ -48,7 +48,7 @@ pub fn name(self: Atom, elf_file: *Elf) [:0]const u8 {
4848}
4949
5050pub fn address(self: Atom, elf_file: *Elf) i64 {
51 const shdr = elf_file.shdrs.items[self.output_section_index];
51 const shdr = elf_file.sections.items(.shdr)[self.output_section_index];
5252 return @as(i64, @intCast(shdr.sh_addr)) + self.value;
5353}
5454
......@@ -116,10 +116,10 @@ pub fn freeListEligible(self: Atom, elf_file: *Elf) bool {
116116
117117pub fn allocate(self: *Atom, elf_file: *Elf) !void {
118118 const zo = elf_file.zigObjectPtr().?;
119 const shdr = &elf_file.shdrs.items[self.output_section_index];
120 const meta = elf_file.last_atom_and_free_list_table.getPtr(self.output_section_index).?;
121 const free_list = &meta.free_list;
122 const last_atom_index = &meta.last_atom_index;
119 const slice = elf_file.sections.slice();
120 const shdr = &slice.items(.shdr)[self.output_section_index];
121 const free_list = &slice.items(.free_list)[self.output_section_index];
122 const last_atom_index = &slice.items(.last_atom_index)[self.output_section_index];
123123 const new_atom_ideal_capacity = Elf.padToIdeal(self.size);
124124
125125 // We use these to indicate our intention to update metadata, placing the new atom,
......@@ -254,9 +254,9 @@ pub fn free(self: *Atom, elf_file: *Elf) void {
254254 const comp = elf_file.base.comp;
255255 const gpa = comp.gpa;
256256 const shndx = self.output_section_index;
257 const meta = elf_file.last_atom_and_free_list_table.getPtr(shndx).?;
258 const free_list = &meta.free_list;
259 const last_atom_index = &meta.last_atom_index;
257 const slice = elf_file.sections.slice();
258 const free_list = &slice.items(.free_list)[shndx];
259 const last_atom_index = &slice.items(.last_atom_index)[shndx];
260260 var already_have_free_list_node = false;
261261 {
262262 var i: usize = 0;
src/link/Elf/LinkerDefined.zig+17-15
......@@ -129,9 +129,10 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
129129
130130pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
131131 const gpa = elf_file.base.comp.gpa;
132 const slice = elf_file.sections.slice();
132133
133134 var nsyms: usize = 0;
134 for (elf_file.shdrs.items) |shdr| {
135 for (slice.items(.shdr)) |shdr| {
135136 if (elf_file.getStartStopBasename(shdr)) |_| {
136137 nsyms += 2; // __start_, __stop_
137138 }
......@@ -143,7 +144,7 @@ pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
143144 try self.symbols_extra.ensureUnusedCapacity(gpa, nsyms * @sizeOf(Symbol.Extra));
144145 try self.symbols_resolver.ensureUnusedCapacity(gpa, nsyms);
145146
146 for (elf_file.shdrs.items) |shdr| {
147 for (slice.items(.shdr)) |shdr| {
147148 if (elf_file.getStartStopBasename(shdr)) |name| {
148149 const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name});
149150 defer gpa.free(start_name);
......@@ -193,6 +194,7 @@ pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
193194pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
194195 const comp = elf_file.base.comp;
195196 const link_mode = comp.config.link_mode;
197 const shdrs = elf_file.sections.items(.shdr);
196198
197199 const allocSymbol = struct {
198200 fn allocSymbol(ld: *LinkerDefined, index: Symbol.Index, value: u64, osec: u32, ef: *Elf) void {
......@@ -204,7 +206,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
204206
205207 // _DYNAMIC
206208 if (elf_file.dynamic_section_index) |shndx| {
207 const shdr = &elf_file.shdrs.items[shndx];
209 const shdr = shdrs[shndx];
208210 allocSymbol(self, self.dynamic_index.?, shdr.sh_addr, shndx, elf_file);
209211 }
210212
......@@ -213,21 +215,21 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
213215
214216 // __init_array_start, __init_array_end
215217 if (elf_file.sectionByName(".init_array")) |shndx| {
216 const shdr = &elf_file.shdrs.items[shndx];
218 const shdr = shdrs[shndx];
217219 allocSymbol(self, self.init_array_start_index.?, shdr.sh_addr, shndx, elf_file);
218220 allocSymbol(self, self.init_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);
219221 }
220222
221223 // __fini_array_start, __fini_array_end
222224 if (elf_file.sectionByName(".fini_array")) |shndx| {
223 const shdr = &elf_file.shdrs.items[shndx];
225 const shdr = shdrs[shndx];
224226 allocSymbol(self, self.fini_array_start_index.?, shdr.sh_addr, shndx, elf_file);
225227 allocSymbol(self, self.fini_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);
226228 }
227229
228230 // __preinit_array_start, __preinit_array_end
229231 if (elf_file.sectionByName(".preinit_array")) |shndx| {
230 const shdr = &elf_file.shdrs.items[shndx];
232 const shdr = shdrs[shndx];
231233 allocSymbol(self, self.preinit_array_start_index.?, shdr.sh_addr, shndx, elf_file);
232234 allocSymbol(self, self.preinit_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);
233235 }
......@@ -235,38 +237,38 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
235237 // _GLOBAL_OFFSET_TABLE_
236238 if (elf_file.getTarget().cpu.arch == .x86_64) {
237239 if (elf_file.got_plt_section_index) |shndx| {
238 const shdr = elf_file.shdrs.items[shndx];
240 const shdr = shdrs[shndx];
239241 allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file);
240242 }
241243 } else {
242244 if (elf_file.got_section_index) |shndx| {
243 const shdr = elf_file.shdrs.items[shndx];
245 const shdr = shdrs[shndx];
244246 allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file);
245247 }
246248 }
247249
248250 // _PROCEDURE_LINKAGE_TABLE_
249251 if (elf_file.plt_section_index) |shndx| {
250 const shdr = &elf_file.shdrs.items[shndx];
252 const shdr = shdrs[shndx];
251253 allocSymbol(self, self.plt_index.?, shdr.sh_addr, shndx, elf_file);
252254 }
253255
254256 // __dso_handle
255257 if (self.dso_handle_index) |index| {
256 const shdr = &elf_file.shdrs.items[1];
258 const shdr = shdrs[1];
257259 allocSymbol(self, index, shdr.sh_addr, 0, elf_file);
258260 }
259261
260262 // __GNU_EH_FRAME_HDR
261263 if (elf_file.eh_frame_hdr_section_index) |shndx| {
262 const shdr = &elf_file.shdrs.items[shndx];
264 const shdr = shdrs[shndx];
263265 allocSymbol(self, self.gnu_eh_frame_hdr_index.?, shdr.sh_addr, shndx, elf_file);
264266 }
265267
266268 // __rela_iplt_start, __rela_iplt_end
267269 if (elf_file.rela_dyn_section_index) |shndx| blk: {
268270 if (link_mode != .static or comp.config.pie) break :blk;
269 const shdr = &elf_file.shdrs.items[shndx];
271 const shdr = shdrs[shndx];
270272 const end_addr = shdr.sh_addr + shdr.sh_size;
271273 const start_addr = end_addr - elf_file.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela);
272274 allocSymbol(self, self.rela_iplt_start_index.?, start_addr, shndx, elf_file);
......@@ -277,7 +279,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
277279 {
278280 var value: u64 = 0;
279281 var osec: u32 = 0;
280 for (elf_file.shdrs.items, 0..) |shdr, shndx| {
282 for (shdrs, 0..) |shdr, shndx| {
281283 if (shdr.sh_flags & elf.SHF_ALLOC != 0) {
282284 value = shdr.sh_addr + shdr.sh_size;
283285 osec = @intCast(shndx);
......@@ -289,7 +291,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
289291 // __global_pointer$
290292 if (self.global_pointer_index) |index| {
291293 const value, const osec = if (elf_file.sectionByName(".sdata")) |shndx| .{
292 elf_file.shdrs.items[shndx].sh_addr + 0x800,
294 shdrs[shndx].sh_addr + 0x800,
293295 shndx,
294296 } else .{ 0, 0 };
295297 allocSymbol(self, index, value, osec, elf_file);
......@@ -305,7 +307,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
305307 const stop_ref = self.resolveSymbol(self.start_stop_indexes.items[index + 1], elf_file);
306308 const stop = elf_file.symbol(stop_ref).?;
307309 const shndx = elf_file.sectionByName(name["__start_".len..]).?;
308 const shdr = &elf_file.shdrs.items[shndx];
310 const shdr = shdrs[shndx];
309311 start.value = @intCast(shdr.sh_addr);
310312 start.output_section_index = shndx;
311313 stop.value = @intCast(shdr.sh_addr + shdr.sh_size);
src/link/Elf/Object.zig+7-12
......@@ -998,9 +998,8 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {
998998
999999 const comp = elf_file.base.comp;
10001000 const gpa = comp.gpa;
1001 const gop = try elf_file.output_sections.getOrPut(gpa, atom_ptr.output_section_index);
1002 if (!gop.found_existing) gop.value_ptr.* = .{};
1003 try gop.value_ptr.append(gpa, .{ .index = atom_index, .file = self.index });
1001 const atom_list = &elf_file.sections.items(.atom_list)[atom_ptr.output_section_index];
1002 try atom_list.append(gpa, .{ .index = atom_index, .file = self.index });
10041003 }
10051004}
10061005
......@@ -1011,14 +1010,15 @@ pub fn initRelaSections(self: *Object, elf_file: *Elf) !void {
10111010 const shndx = atom_ptr.relocsShndx() orelse continue;
10121011 const shdr = self.shdrs.items[shndx];
10131012 const out_shndx = try self.initOutputSection(elf_file, shdr);
1014 const out_shdr = &elf_file.shdrs.items[out_shndx];
1013 const out_shdr = &elf_file.sections.items(.shdr)[out_shndx];
1014 out_shdr.sh_type = elf.SHT_RELA;
10151015 out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela);
10161016 out_shdr.sh_entsize = @sizeOf(elf.Elf64_Rela);
10171017 out_shdr.sh_flags |= elf.SHF_INFO_LINK;
10181018 }
10191019}
10201020
1021pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {
1021pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) void {
10221022 for (self.atoms_indexes.items) |atom_index| {
10231023 const atom_ptr = self.atom(atom_index) orelse continue;
10241024 if (!atom_ptr.alive) continue;
......@@ -1027,15 +1027,10 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {
10271027 const shdr = self.shdrs.items[shndx];
10281028 break :blk self.initOutputSection(elf_file, shdr) catch unreachable;
10291029 };
1030 const shdr = &elf_file.shdrs.items[shndx];
1030 const slice = elf_file.sections.slice();
1031 const shdr = &slice.items(.shdr)[shndx];
10311032 shdr.sh_info = atom_ptr.output_section_index;
10321033 shdr.sh_link = elf_file.symtab_section_index.?;
1033
1034 const comp = elf_file.base.comp;
1035 const gpa = comp.gpa;
1036 const gop = try elf_file.output_rela_sections.getOrPut(gpa, atom_ptr.output_section_index);
1037 if (!gop.found_existing) gop.value_ptr.* = .{ .shndx = shndx };
1038 try gop.value_ptr.atom_list.append(gpa, .{ .index = atom_index, .file = self.index });
10391034 }
10401035}
10411036
src/link/Elf/Symbol.zig+6-6
......@@ -126,7 +126,7 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true, trampoline: bool
126126 const sym_name = symbol.name(elf_file);
127127 const sh_addr, const sh_size = blk: {
128128 const shndx = elf_file.eh_frame_section_index orelse break :blk .{ 0, 0 };
129 const shdr = elf_file.shdrs.items[shndx];
129 const shdr = elf_file.sections.items(.shdr)[shndx];
130130 break :blk .{ shdr.sh_addr, shdr.sh_size };
131131 };
132132 if (mem.startsWith(u8, sym_name, "__EH_FRAME_BEGIN__") or
......@@ -173,7 +173,7 @@ pub fn gotAddress(symbol: Symbol, elf_file: *Elf) i64 {
173173pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 {
174174 if (!(symbol.flags.has_plt and symbol.flags.has_got)) return 0;
175175 const extras = symbol.extra(elf_file);
176 const shdr = elf_file.shdrs.items[elf_file.plt_got_section_index.?];
176 const shdr = elf_file.sections.items(.shdr)[elf_file.plt_got_section_index.?];
177177 const cpu_arch = elf_file.getTarget().cpu.arch;
178178 return @intCast(shdr.sh_addr + extras.plt_got * PltGotSection.entrySize(cpu_arch));
179179}
......@@ -181,7 +181,7 @@ pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 {
181181pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 {
182182 if (!symbol.flags.has_plt) return 0;
183183 const extras = symbol.extra(elf_file);
184 const shdr = elf_file.shdrs.items[elf_file.plt_section_index.?];
184 const shdr = elf_file.sections.items(.shdr)[elf_file.plt_section_index.?];
185185 const cpu_arch = elf_file.getTarget().cpu.arch;
186186 return @intCast(shdr.sh_addr + extras.plt * PltSection.entrySize(cpu_arch) + PltSection.preambleSize(cpu_arch));
187187}
......@@ -189,13 +189,13 @@ pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 {
189189pub fn gotPltAddress(symbol: Symbol, elf_file: *Elf) i64 {
190190 if (!symbol.flags.has_plt) return 0;
191191 const extras = symbol.extra(elf_file);
192 const shdr = elf_file.shdrs.items[elf_file.got_plt_section_index.?];
192 const shdr = elf_file.sections.items(.shdr)[elf_file.got_plt_section_index.?];
193193 return @intCast(shdr.sh_addr + extras.plt * 8 + GotPltSection.preamble_size);
194194}
195195
196196pub fn copyRelAddress(symbol: Symbol, elf_file: *Elf) i64 {
197197 if (!symbol.flags.has_copy_rel) return 0;
198 const shdr = elf_file.shdrs.items[elf_file.copy_rel_section_index.?];
198 const shdr = elf_file.sections.items(.shdr)[elf_file.copy_rel_section_index.?];
199199 return @as(i64, @intCast(shdr.sh_addr)) + symbol.value;
200200}
201201
......@@ -300,7 +300,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
300300 break :blk 0;
301301 }
302302 if (st_shndx == elf.SHN_ABS or st_shndx == elf.SHN_COMMON) break :blk symbol.address(.{ .plt = false }, elf_file);
303 const shdr = elf_file.shdrs.items[st_shndx];
303 const shdr = elf_file.sections.items(.shdr)[st_shndx];
304304 if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined)
305305 break :blk symbol.address(.{ .plt = false }, elf_file) - elf_file.tlsAddress();
306306 break :blk symbol.address(.{ .plt = false, .trampoline = false }, elf_file);
src/link/Elf/ZigObject.zig+41-81
......@@ -170,25 +170,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
170170 .addralign = 1,
171171 .offset = std.math.maxInt(u64),
172172 });
173 const shdr = &elf_file.shdrs.items[elf_file.zig_text_section_index.?];
173 const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_text_section_index.?];
174 const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_text_section_index.?];
174175 try fillSection(elf_file, shdr, options.program_code_size_hint, elf_file.phdr_zig_load_re_index);
175176 if (elf_file.base.isRelocatable()) {
176 const rela_shndx = try elf_file.addRelaShdr(
177 _ = try elf_file.addRelaShdr(
177178 try elf_file.insertShString(".rela.text.zig"),
178179 elf_file.zig_text_section_index.?,
179180 );
180 try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{
181 .shndx = rela_shndx,
182 });
183181 } else {
184 try elf_file.phdr_to_shdr_table.putNoClobber(
185 gpa,
186 elf_file.zig_text_section_index.?,
187 elf_file.phdr_zig_load_re_index.?,
188 );
182 phndx.* = elf_file.phdr_zig_load_re_index.?;
189183 }
190 try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{});
191 try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{});
192184 }
193185
194186 if (elf_file.zig_data_rel_ro_section_index == null) {
......@@ -199,25 +191,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
199191 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
200192 .offset = std.math.maxInt(u64),
201193 });
202 const shdr = &elf_file.shdrs.items[elf_file.zig_data_rel_ro_section_index.?];
194 const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_data_rel_ro_section_index.?];
195 const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_data_rel_ro_section_index.?];
203196 try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_ro_index);
204197 if (elf_file.base.isRelocatable()) {
205 const rela_shndx = try elf_file.addRelaShdr(
198 _ = try elf_file.addRelaShdr(
206199 try elf_file.insertShString(".rela.data.rel.ro.zig"),
207200 elf_file.zig_data_rel_ro_section_index.?,
208201 );
209 try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{
210 .shndx = rela_shndx,
211 });
212202 } else {
213 try elf_file.phdr_to_shdr_table.putNoClobber(
214 gpa,
215 elf_file.zig_data_rel_ro_section_index.?,
216 elf_file.phdr_zig_load_ro_index.?,
217 );
203 phndx.* = elf_file.phdr_zig_load_ro_index.?;
218204 }
219 try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{});
220 try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{});
221205 }
222206
223207 if (elf_file.zig_data_section_index == null) {
......@@ -228,25 +212,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
228212 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
229213 .offset = std.math.maxInt(u64),
230214 });
231 const shdr = &elf_file.shdrs.items[elf_file.zig_data_section_index.?];
215 const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_data_section_index.?];
216 const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_data_section_index.?];
232217 try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_rw_index);
233218 if (elf_file.base.isRelocatable()) {
234 const rela_shndx = try elf_file.addRelaShdr(
219 _ = try elf_file.addRelaShdr(
235220 try elf_file.insertShString(".rela.data.zig"),
236221 elf_file.zig_data_section_index.?,
237222 );
238 try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{
239 .shndx = rela_shndx,
240 });
241223 } else {
242 try elf_file.phdr_to_shdr_table.putNoClobber(
243 gpa,
244 elf_file.zig_data_section_index.?,
245 elf_file.phdr_zig_load_rw_index.?,
246 );
224 phndx.* = elf_file.phdr_zig_load_rw_index.?;
247225 }
248 try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{});
249 try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{});
250226 }
251227
252228 if (elf_file.zig_bss_section_index == null) {
......@@ -257,17 +233,16 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
257233 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
258234 .offset = 0,
259235 });
260 const shdr = &elf_file.shdrs.items[elf_file.zig_bss_section_index.?];
261 if (elf_file.phdr_zig_load_zerofill_index) |phndx| {
262 const phdr = elf_file.phdrs.items[phndx];
236 const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_bss_section_index.?];
237 const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_bss_section_index.?];
238 if (elf_file.base.isRelocatable()) {
239 shdr.sh_size = 1024;
240 } else {
241 phndx.* = elf_file.phdr_zig_load_zerofill_index.?;
242 const phdr = elf_file.phdrs.items[phndx.*];
263243 shdr.sh_addr = phdr.p_vaddr;
264244 shdr.sh_size = phdr.p_memsz;
265 try elf_file.phdr_to_shdr_table.putNoClobber(gpa, elf_file.zig_bss_section_index.?, phndx);
266 } else {
267 shdr.sh_size = 1024;
268245 }
269 try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_bss_section_index.?, .{});
270 try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_bss_section_index.?, .{});
271246 }
272247
273248 switch (comp.config.debug_format) {
......@@ -305,7 +280,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
305280 });
306281 self.debug_str_section_dirty = true;
307282 self.debug_str_index = try addSectionSymbol(self, gpa, ".debug_str", .@"1", elf_file.debug_str_section_index.?);
308 try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_str_section_index.?, .{});
309283 }
310284
311285 if (elf_file.debug_info_section_index == null) {
......@@ -316,7 +290,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
316290 });
317291 self.debug_info_section_dirty = true;
318292 self.debug_info_index = try addSectionSymbol(self, gpa, ".debug_info", .@"1", elf_file.debug_info_section_index.?);
319 try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_info_section_index.?, .{});
320293 }
321294
322295 if (elf_file.debug_abbrev_section_index == null) {
......@@ -327,7 +300,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
327300 });
328301 self.debug_abbrev_section_dirty = true;
329302 self.debug_abbrev_index = try addSectionSymbol(self, gpa, ".debug_abbrev", .@"1", elf_file.debug_abbrev_section_index.?);
330 try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_abbrev_section_index.?, .{});
331303 }
332304
333305 if (elf_file.debug_aranges_section_index == null) {
......@@ -338,7 +310,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
338310 });
339311 self.debug_aranges_section_dirty = true;
340312 self.debug_aranges_index = try addSectionSymbol(self, gpa, ".debug_aranges", .@"16", elf_file.debug_aranges_section_index.?);
341 try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_aranges_section_index.?, .{});
342313 }
343314
344315 if (elf_file.debug_line_section_index == null) {
......@@ -349,7 +320,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
349320 });
350321 self.debug_line_section_dirty = true;
351322 self.debug_line_index = try addSectionSymbol(self, gpa, ".debug_line", .@"1", elf_file.debug_line_section_index.?);
352 try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_line_section_index.?, .{});
353323 }
354324
355325 if (elf_file.debug_line_str_section_index == null) {
......@@ -362,7 +332,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
362332 });
363333 self.debug_line_str_section_dirty = true;
364334 self.debug_line_str_index = try addSectionSymbol(self, gpa, ".debug_line_str", .@"1", elf_file.debug_line_str_section_index.?);
365 try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_line_str_section_index.?, .{});
366335 }
367336
368337 if (elf_file.debug_loclists_section_index == null) {
......@@ -373,7 +342,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
373342 });
374343 self.debug_loclists_section_dirty = true;
375344 self.debug_loclists_index = try addSectionSymbol(self, gpa, ".debug_loclists", .@"1", elf_file.debug_loclists_section_index.?);
376 try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_loclists_section_index.?, .{});
377345 }
378346
379347 if (elf_file.debug_rnglists_section_index == null) {
......@@ -384,7 +352,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
384352 });
385353 self.debug_rnglists_section_dirty = true;
386354 self.debug_rnglists_index = try addSectionSymbol(self, gpa, ".debug_rnglists", .@"1", elf_file.debug_rnglists_section_index.?);
387 try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_rnglists_section_index.?, .{});
388355 }
389356
390357 try dwarf.initMetadata();
......@@ -507,7 +474,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
507474 const atom_ptr = self.atom(sym.ref.index).?;
508475 if (!atom_ptr.alive) continue;
509476 const shndx = sym.outputShndx(elf_file).?;
510 const shdr = elf_file.shdrs.items[shndx];
477 const shdr = elf_file.sections.items(.shdr)[shndx];
511478 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
512479 esym.st_size = shdr.sh_size;
513480 atom_ptr.size = shdr.sh_size;
......@@ -667,13 +634,10 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
667634 }
668635
669636 if (elf_file.base.isRelocatable() and relocs.items.len > 0) {
670 const gop = try elf_file.output_rela_sections.getOrPut(gpa, shndx);
671 if (!gop.found_existing) {
672 const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)});
673 defer gpa.free(rela_sect_name);
674 const rela_sh_name = try elf_file.insertShString(rela_sect_name);
675 const rela_shndx = try elf_file.addRelaShdr(rela_sh_name, shndx);
676 gop.value_ptr.* = .{ .shndx = rela_shndx };
637 const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)});
638 defer gpa.free(rela_sect_name);
639 if (elf_file.sectionByName(rela_sect_name) == null) {
640 _ = try elf_file.addRelaShdr(try elf_file.insertShString(rela_sect_name), shndx);
677641 }
678642 }
679643 }
......@@ -769,7 +733,7 @@ fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Sym
769733pub fn inputShdr(self: *ZigObject, atom_index: Atom.Index, elf_file: *Elf) elf.Elf64_Shdr {
770734 const atom_ptr = self.atom(atom_index) orelse return Elf.null_shdr;
771735 const shndx = atom_ptr.output_section_index;
772 var shdr = elf_file.shdrs.items[shndx];
736 var shdr = elf_file.sections.items(.shdr)[shndx];
773737 shdr.sh_addr = 0;
774738 shdr.sh_offset = 0;
775739 shdr.sh_size = atom_ptr.size;
......@@ -947,8 +911,8 @@ pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void {
947911 .p32 => @sizeOf(elf.Elf32_Shdr),
948912 .p64 => @sizeOf(elf.Elf64_Shdr),
949913 };
950 var end_pos: u64 = elf_file.shdr_table_offset.? + elf_file.shdrs.items.len * shsize;
951 for (elf_file.shdrs.items) |shdr| {
914 var end_pos: u64 = elf_file.shdr_table_offset.? + elf_file.sections.items(.shdr).len * shsize;
915 for (elf_file.sections.items(.shdr)) |shdr| {
952916 if (shdr.sh_type == elf.SHT_NOBITS) continue;
953917 end_pos = @max(end_pos, shdr.sh_offset + shdr.sh_size);
954918 }
......@@ -1001,12 +965,11 @@ pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void {
1001965 // TODO this check will become obsolete when we rework our relocs mechanism at the ZigObject level
1002966 if (self.relocs.items[rela_shndx].items.len == 0) continue;
1003967 const out_shndx = atom_ptr.output_section_index;
1004 const out_shdr = elf_file.shdrs.items[out_shndx];
968 const out_shdr = elf_file.sections.items(.shdr)[out_shndx];
1005969 if (out_shdr.sh_type == elf.SHT_NOBITS) continue;
1006
970 const atom_list = &elf_file.sections.items(.atom_list)[out_shndx];
1007971 const gpa = elf_file.base.comp.gpa;
1008 const sec = elf_file.output_rela_sections.getPtr(out_shndx).?;
1009 try sec.atom_list.append(gpa, .{ .index = atom_index, .file = self.index });
972 try atom_list.append(gpa, .{ .index = atom_index, .file = self.index });
1010973 }
1011974}
1012975
......@@ -1076,7 +1039,7 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void {
10761039pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 {
10771040 const gpa = elf_file.base.comp.gpa;
10781041 const atom_ptr = self.atom(atom_index).?;
1079 const shdr = &elf_file.shdrs.items[atom_ptr.output_section_index];
1042 const shdr = &elf_file.sections.items(.shdr)[atom_ptr.output_section_index];
10801043
10811044 if (shdr.sh_flags & elf.SHF_TLS != 0) {
10821045 const tlv = self.tls_variables.get(atom_index).?;
......@@ -1403,7 +1366,7 @@ fn updateNavCode(
14031366 }
14041367 }
14051368
1406 const shdr = elf_file.shdrs.items[shdr_index];
1369 const shdr = elf_file.sections.items(.shdr)[shdr_index];
14071370 if (shdr.sh_type != elf.SHT_NOBITS) {
14081371 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
14091372 try elf_file.base.file.?.pwriteAll(code, file_offset);
......@@ -1458,16 +1421,13 @@ fn updateTlv(
14581421 gop.value_ptr.* = .{ .symbol_index = sym_index };
14591422
14601423 // We only store the data for the TLV if it's non-zerofill.
1461 if (elf_file.shdrs.items[shndx].sh_type != elf.SHT_NOBITS) {
1424 if (elf_file.sections.items(.shdr)[shndx].sh_type != elf.SHT_NOBITS) {
14621425 gop.value_ptr.code = try gpa.dupe(u8, code);
14631426 }
14641427 }
14651428
1466 {
1467 const gop = try elf_file.output_sections.getOrPut(gpa, atom_ptr.output_section_index);
1468 if (!gop.found_existing) gop.value_ptr.* = .{};
1469 try gop.value_ptr.append(gpa, .{ .index = atom_ptr.atom_index, .file = self.index });
1470 }
1429 const atom_list = &elf_file.sections.items(.atom_list)[atom_ptr.output_section_index];
1430 try atom_list.append(gpa, .{ .index = atom_ptr.atom_index, .file = self.index });
14711431}
14721432
14731433pub fn updateFunc(
......@@ -1519,7 +1479,7 @@ pub fn updateFunc(
15191479 const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code);
15201480 log.debug("setting shdr({x},{s}) for {}", .{
15211481 shndx,
1522 elf_file.getShString(elf_file.shdrs.items[shndx].sh_name),
1482 elf_file.getShString(elf_file.sections.items(.shdr)[shndx].sh_name),
15231483 ip.getNav(func.owner_nav).fqn.fmt(ip),
15241484 });
15251485 const old_rva, const old_alignment = blk: {
......@@ -1647,10 +1607,10 @@ pub fn updateNav(
16471607 const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code);
16481608 log.debug("setting shdr({x},{s}) for {}", .{
16491609 shndx,
1650 elf_file.getShString(elf_file.shdrs.items[shndx].sh_name),
1610 elf_file.getShString(elf_file.sections.items(.shdr)[shndx].sh_name),
16511611 nav.fqn.fmt(ip),
16521612 });
1653 if (elf_file.shdrs.items[shndx].sh_flags & elf.SHF_TLS != 0)
1613 if (elf_file.sections.items(.shdr)[shndx].sh_flags & elf.SHF_TLS != 0)
16541614 try self.updateTlv(elf_file, pt, nav_index, sym_index, shndx, code)
16551615 else
16561616 try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT);
......@@ -1749,7 +1709,7 @@ fn updateLazySymbol(
17491709 local_sym.value = 0;
17501710 local_esym.st_value = 0;
17511711
1752 const shdr = elf_file.shdrs.items[output_section_index];
1712 const shdr = elf_file.sections.items(.shdr)[output_section_index];
17531713 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
17541714 try elf_file.base.file.?.pwriteAll(code, file_offset);
17551715}
......@@ -1805,7 +1765,7 @@ fn lowerConst(
18051765 // TODO rename and re-audit this method
18061766 errdefer self.freeNavMetadata(elf_file, sym_index);
18071767
1808 const shdr = elf_file.shdrs.items[output_section_index];
1768 const shdr = elf_file.sections.items(.shdr)[output_section_index];
18091769 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
18101770 try elf_file.base.file.?.pwriteAll(code, file_offset);
18111771
......@@ -1969,7 +1929,7 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) u64 {
19691929
19701930fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void {
19711931 const atom_ptr = tr_sym.atom(elf_file).?;
1972 const shdr = elf_file.shdrs.items[atom_ptr.output_section_index];
1932 const shdr = elf_file.sections.items(.shdr)[atom_ptr.output_section_index];
19731933 const fileoff = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
19741934 const source_addr = tr_sym.address(.{}, elf_file);
19751935 const target_addr = target.address(.{ .trampoline = false }, elf_file);
src/link/Elf/eh_frame.zig+11-6
......@@ -13,7 +13,7 @@ pub const Fde = struct {
1313
1414 pub fn address(fde: Fde, elf_file: *Elf) u64 {
1515 const base: u64 = if (elf_file.eh_frame_section_index) |shndx|
16 elf_file.shdrs.items[shndx].sh_addr
16 elf_file.sections.items(.shdr)[shndx].sh_addr
1717 else
1818 0;
1919 return base + fde.out_offset;
......@@ -112,7 +112,7 @@ pub const Cie = struct {
112112
113113 pub fn address(cie: Cie, elf_file: *Elf) u64 {
114114 const base: u64 = if (elf_file.eh_frame_section_index) |shndx|
115 elf_file.shdrs.items[shndx].sh_addr
115 elf_file.sections.items(.shdr)[shndx].sh_addr
116116 else
117117 0;
118118 return base + cie.out_offset;
......@@ -326,7 +326,9 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file:
326326}
327327
328328pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
329 relocs_log.debug("{x}: .eh_frame", .{elf_file.shdrs.items[elf_file.eh_frame_section_index.?].sh_addr});
329 relocs_log.debug("{x}: .eh_frame", .{
330 elf_file.sections.items(.shdr)[elf_file.eh_frame_section_index.?].sh_addr,
331 });
330332
331333 var has_reloc_errors = false;
332334
......@@ -446,7 +448,9 @@ fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Re
446448}
447449
448450pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void {
449 relocs_log.debug("{x}: .eh_frame", .{elf_file.shdrs.items[elf_file.eh_frame_section_index.?].sh_addr});
451 relocs_log.debug("{x}: .eh_frame", .{
452 elf_file.sections.items(.shdr)[elf_file.eh_frame_section_index.?].sh_addr,
453 });
450454
451455 for (elf_file.objects.items) |index| {
452456 const object = elf_file.file(index).?.object;
......@@ -482,8 +486,9 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {
482486 try writer.writeByte(EH_PE.udata4);
483487 try writer.writeByte(EH_PE.datarel | EH_PE.sdata4);
484488
485 const eh_frame_shdr = elf_file.shdrs.items[elf_file.eh_frame_section_index.?];
486 const eh_frame_hdr_shdr = elf_file.shdrs.items[elf_file.eh_frame_hdr_section_index.?];
489 const shdrs = elf_file.sections.items(.shdr);
490 const eh_frame_shdr = shdrs[elf_file.eh_frame_section_index.?];
491 const eh_frame_hdr_shdr = shdrs[elf_file.eh_frame_hdr_section_index.?];
487492 const num_fdes = @as(u32, @intCast(@divExact(eh_frame_hdr_shdr.sh_size - eh_frame_hdr_header_size, 8)));
488493 try writer.writeInt(
489494 u32,
src/link/Elf/merge_section.zig+2-4
......@@ -29,7 +29,7 @@ pub const MergeSection = struct {
2929 }
3030
3131 pub fn address(msec: MergeSection, elf_file: *Elf) i64 {
32 const shdr = elf_file.shdrs.items[msec.output_section_index];
32 const shdr = elf_file.sections.items(.shdr)[msec.output_section_index];
3333 return @intCast(shdr.sh_addr + msec.value);
3434 }
3535
......@@ -108,13 +108,11 @@ pub const MergeSection = struct {
108108 }
109109
110110 pub fn initOutputSection(msec: *MergeSection, elf_file: *Elf) !void {
111 const shndx = elf_file.sectionByName(msec.name(elf_file)) orelse try elf_file.addSection(.{
111 msec.output_section_index = elf_file.sectionByName(msec.name(elf_file)) orelse try elf_file.addSection(.{
112112 .name = msec.name_offset,
113113 .type = msec.type,
114114 .flags = msec.flags,
115115 });
116 try elf_file.output_sections.put(elf_file.base.comp.gpa, shndx, .{});
117 msec.output_section_index = shndx;
118116 }
119117
120118 pub fn addMergeSubsection(msec: *MergeSection, allocator: Allocator) !MergeSubsection.Index {
src/link/Elf/relocatable.zig+39-37
......@@ -209,7 +209,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]const
209209 for (elf_file.objects.items) |index| {
210210 const object = elf_file.file(index).?.object;
211211 try object.addAtomsToOutputSections(elf_file);
212 try object.addAtomsToRelaSections(elf_file);
212 object.addAtomsToRelaSections(elf_file);
213213 }
214214 try elf_file.updateMergeSectionSizes();
215215 try updateSectionSizes(elf_file);
......@@ -347,36 +347,37 @@ fn initComdatGroups(elf_file: *Elf) !void {
347347}
348348
349349fn updateSectionSizes(elf_file: *Elf) !void {
350 for (elf_file.output_sections.keys(), elf_file.output_sections.values()) |shndx, atom_list| {
351 const shdr = &elf_file.shdrs.items[shndx];
352 for (atom_list.items) |ref| {
353 const atom_ptr = elf_file.atom(ref) orelse continue;
354 if (!atom_ptr.alive) continue;
355 const offset = atom_ptr.alignment.forward(shdr.sh_size);
356 const padding = offset - shdr.sh_size;
357 atom_ptr.value = @intCast(offset);
358 shdr.sh_size += padding + atom_ptr.size;
359 shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits() orelse 1);
360 }
361 }
350 const slice = elf_file.sections.slice();
351 for (slice.items(.shdr), 0..) |*shdr, shndx| {
352 if (shdr.sh_type != elf.SHT_RELA) {
353 const atom_list = slice.items(.atom_list)[shndx];
354 for (atom_list.items) |ref| {
355 const atom_ptr = elf_file.atom(ref) orelse continue;
356 if (!atom_ptr.alive) continue;
357 const offset = atom_ptr.alignment.forward(shdr.sh_size);
358 const padding = offset - shdr.sh_size;
359 atom_ptr.value = @intCast(offset);
360 shdr.sh_size += padding + atom_ptr.size;
361 shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits() orelse 1);
362 }
363 } else {
364 const atom_list = slice.items(.atom_list)[shdr.sh_info];
365 for (atom_list.items) |ref| {
366 const atom_ptr = elf_file.atom(ref) orelse continue;
367 if (!atom_ptr.alive) continue;
368 const relocs = atom_ptr.relocs(elf_file);
369 shdr.sh_size += shdr.sh_entsize * relocs.len;
370 }
362371
363 for (elf_file.output_rela_sections.values()) |sec| {
364 const shdr = &elf_file.shdrs.items[sec.shndx];
365 for (sec.atom_list.items) |ref| {
366 const atom_ptr = elf_file.atom(ref) orelse continue;
367 if (!atom_ptr.alive) continue;
368 const relocs = atom_ptr.relocs(elf_file);
369 shdr.sh_size += shdr.sh_entsize * relocs.len;
372 if (shdr.sh_size == 0) shdr.sh_offset = 0;
370373 }
371
372 if (shdr.sh_size == 0) shdr.sh_offset = 0;
373374 }
374375
375376 if (elf_file.eh_frame_section_index) |index| {
376 elf_file.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(elf_file);
377 slice.items(.shdr)[index].sh_size = try eh_frame.calcEhFrameSize(elf_file);
377378 }
378379 if (elf_file.eh_frame_rela_section_index) |index| {
379 const shdr = &elf_file.shdrs.items[index];
380 const shdr = &slice.items(.shdr)[index];
380381 shdr.sh_size = eh_frame.calcEhFrameRelocs(elf_file) * shdr.sh_entsize;
381382 }
382383
......@@ -387,7 +388,7 @@ fn updateSectionSizes(elf_file: *Elf) !void {
387388
388389fn updateComdatGroupsSizes(elf_file: *Elf) void {
389390 for (elf_file.comdat_group_sections.items) |cg| {
390 const shdr = &elf_file.shdrs.items[cg.shndx];
391 const shdr = &elf_file.sections.items(.shdr)[cg.shndx];
391392 shdr.sh_size = cg.size(elf_file);
392393 shdr.sh_link = elf_file.symtab_section_index.?;
393394
......@@ -399,7 +400,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void {
399400
400401/// Allocates alloc sections when merging relocatable objects files together.
401402fn allocateAllocSections(elf_file: *Elf) !void {
402 for (elf_file.shdrs.items) |*shdr| {
403 for (elf_file.sections.items(.shdr)) |*shdr| {
403404 if (shdr.sh_type == elf.SHT_NULL) continue;
404405 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
405406 if (shdr.sh_type == elf.SHT_NOBITS) {
......@@ -418,13 +419,13 @@ fn allocateAllocSections(elf_file: *Elf) !void {
418419
419420fn writeAtoms(elf_file: *Elf) !void {
420421 const gpa = elf_file.base.comp.gpa;
422 const slice = elf_file.sections.slice();
421423
422424 // TODO iterate over `output_sections` directly
423 for (elf_file.shdrs.items, 0..) |shdr, shndx| {
425 for (slice.items(.shdr), slice.items(.atom_list), 0..) |shdr, atom_list, shndx| {
424426 if (shdr.sh_type == elf.SHT_NULL) continue;
425427 if (shdr.sh_type == elf.SHT_NOBITS) continue;
426
427 const atom_list = elf_file.output_sections.get(@intCast(shndx)) orelse continue;
428 if (shdr.sh_type == elf.SHT_RELA) continue;
428429 if (atom_list.items.len == 0) continue;
429430
430431 log.debug("writing atoms in '{s}' section", .{elf_file.getShString(shdr.sh_name)});
......@@ -490,18 +491,19 @@ fn writeAtoms(elf_file: *Elf) !void {
490491
491492fn writeSyntheticSections(elf_file: *Elf) !void {
492493 const gpa = elf_file.base.comp.gpa;
494 const slice = elf_file.sections.slice();
493495
494 for (elf_file.output_rela_sections.values()) |sec| {
495 if (sec.atom_list.items.len == 0) continue;
496
497 const shdr = elf_file.shdrs.items[sec.shndx];
496 for (slice.items(.shdr)) |shdr| {
497 if (shdr.sh_type != elf.SHT_RELA) continue;
498 const atom_list = slice.items(.atom_list)[shdr.sh_info];
499 if (atom_list.items.len == 0) continue;
498500
499501 const num_relocs = math.cast(usize, @divExact(shdr.sh_size, shdr.sh_entsize)) orelse
500502 return error.Overflow;
501503 var relocs = try std.ArrayList(elf.Elf64_Rela).initCapacity(gpa, num_relocs);
502504 defer relocs.deinit();
503505
504 for (sec.atom_list.items) |ref| {
506 for (atom_list.items) |ref| {
505507 const atom_ptr = elf_file.atom(ref) orelse continue;
506508 if (!atom_ptr.alive) continue;
507509 try atom_ptr.writeRelocs(elf_file, &relocs);
......@@ -527,7 +529,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {
527529 }
528530
529531 if (elf_file.eh_frame_section_index) |shndx| {
530 const shdr = elf_file.shdrs.items[shndx];
532 const shdr = slice.items(.shdr)[shndx];
531533 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
532534 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
533535 defer buffer.deinit();
......@@ -540,7 +542,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {
540542 try elf_file.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
541543 }
542544 if (elf_file.eh_frame_rela_section_index) |shndx| {
543 const shdr = elf_file.shdrs.items[shndx];
545 const shdr = slice.items(.shdr)[shndx];
544546 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
545547 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
546548 defer buffer.deinit();
......@@ -561,7 +563,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {
561563fn writeComdatGroups(elf_file: *Elf) !void {
562564 const gpa = elf_file.base.comp.gpa;
563565 for (elf_file.comdat_group_sections.items) |cgs| {
564 const shdr = elf_file.shdrs.items[cgs.shndx];
566 const shdr = elf_file.sections.items(.shdr)[cgs.shndx];
565567 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
566568 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
567569 defer buffer.deinit();
src/link/Elf/synthetic_sections.zig+30-22
......@@ -95,6 +95,8 @@ pub const DynamicSection = struct {
9595 }
9696
9797 pub fn write(dt: DynamicSection, elf_file: *Elf, writer: anytype) !void {
98 const shdrs = elf_file.sections.items(.shdr);
99
98100 // NEEDED
99101 for (dt.needed.items) |off| {
100102 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NEEDED, .d_val = off });
......@@ -112,33 +114,33 @@ pub const DynamicSection = struct {
112114
113115 // INIT
114116 if (elf_file.sectionByName(".init")) |shndx| {
115 const addr = elf_file.shdrs.items[shndx].sh_addr;
117 const addr = shdrs[shndx].sh_addr;
116118 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT, .d_val = addr });
117119 }
118120
119121 // FINI
120122 if (elf_file.sectionByName(".fini")) |shndx| {
121 const addr = elf_file.shdrs.items[shndx].sh_addr;
123 const addr = shdrs[shndx].sh_addr;
122124 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI, .d_val = addr });
123125 }
124126
125127 // INIT_ARRAY
126128 if (elf_file.sectionByName(".init_array")) |shndx| {
127 const shdr = elf_file.shdrs.items[shndx];
129 const shdr = shdrs[shndx];
128130 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAY, .d_val = shdr.sh_addr });
129131 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAYSZ, .d_val = shdr.sh_size });
130132 }
131133
132134 // FINI_ARRAY
133135 if (elf_file.sectionByName(".fini_array")) |shndx| {
134 const shdr = elf_file.shdrs.items[shndx];
136 const shdr = shdrs[shndx];
135137 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAY, .d_val = shdr.sh_addr });
136138 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAYSZ, .d_val = shdr.sh_size });
137139 }
138140
139141 // RELA
140142 if (elf_file.rela_dyn_section_index) |shndx| {
141 const shdr = elf_file.shdrs.items[shndx];
143 const shdr = shdrs[shndx];
142144 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELA, .d_val = shdr.sh_addr });
143145 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELASZ, .d_val = shdr.sh_size });
144146 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELAENT, .d_val = shdr.sh_entsize });
......@@ -146,7 +148,7 @@ pub const DynamicSection = struct {
146148
147149 // JMPREL
148150 if (elf_file.rela_plt_section_index) |shndx| {
149 const shdr = elf_file.shdrs.items[shndx];
151 const shdr = shdrs[shndx];
150152 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_JMPREL, .d_val = shdr.sh_addr });
151153 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTRELSZ, .d_val = shdr.sh_size });
152154 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTREL, .d_val = elf.DT_RELA });
......@@ -154,18 +156,18 @@ pub const DynamicSection = struct {
154156
155157 // PLTGOT
156158 if (elf_file.got_plt_section_index) |shndx| {
157 const addr = elf_file.shdrs.items[shndx].sh_addr;
159 const addr = shdrs[shndx].sh_addr;
158160 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTGOT, .d_val = addr });
159161 }
160162
161163 {
162164 assert(elf_file.hash_section_index != null);
163 const addr = elf_file.shdrs.items[elf_file.hash_section_index.?].sh_addr;
165 const addr = shdrs[elf_file.hash_section_index.?].sh_addr;
164166 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_HASH, .d_val = addr });
165167 }
166168
167169 if (elf_file.gnu_hash_section_index) |shndx| {
168 const addr = elf_file.shdrs.items[shndx].sh_addr;
170 const addr = shdrs[shndx].sh_addr;
169171 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_GNU_HASH, .d_val = addr });
170172 }
171173
......@@ -177,7 +179,7 @@ pub const DynamicSection = struct {
177179 // SYMTAB + SYMENT
178180 {
179181 assert(elf_file.dynsymtab_section_index != null);
180 const shdr = elf_file.shdrs.items[elf_file.dynsymtab_section_index.?];
182 const shdr = shdrs[elf_file.dynsymtab_section_index.?];
181183 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMTAB, .d_val = shdr.sh_addr });
182184 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMENT, .d_val = shdr.sh_entsize });
183185 }
......@@ -185,20 +187,20 @@ pub const DynamicSection = struct {
185187 // STRTAB + STRSZ
186188 {
187189 assert(elf_file.dynstrtab_section_index != null);
188 const shdr = elf_file.shdrs.items[elf_file.dynstrtab_section_index.?];
190 const shdr = shdrs[elf_file.dynstrtab_section_index.?];
189191 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRTAB, .d_val = shdr.sh_addr });
190192 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRSZ, .d_val = shdr.sh_size });
191193 }
192194
193195 // VERSYM
194196 if (elf_file.versym_section_index) |shndx| {
195 const addr = elf_file.shdrs.items[shndx].sh_addr;
197 const addr = shdrs[shndx].sh_addr;
196198 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERSYM, .d_val = addr });
197199 }
198200
199201 // VERNEED + VERNEEDNUM
200202 if (elf_file.verneed_section_index) |shndx| {
201 const addr = elf_file.shdrs.items[shndx].sh_addr;
203 const addr = shdrs[shndx].sh_addr;
202204 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERNEED, .d_val = addr });
203205 try writer.writeStruct(elf.Elf64_Dyn{
204206 .d_tag = elf.DT_VERNEEDNUM,
......@@ -259,7 +261,7 @@ pub const GotSection = struct {
259261
260262 pub fn address(entry: Entry, elf_file: *Elf) i64 {
261263 const ptr_bytes = elf_file.archPtrWidthBytes();
262 const shdr = &elf_file.shdrs.items[elf_file.got_section_index.?];
264 const shdr = &elf_file.sections.items(.shdr)[elf_file.got_section_index.?];
263265 return @as(i64, @intCast(shdr.sh_addr)) + entry.cell_index * ptr_bytes;
264266 }
265267 };
......@@ -759,8 +761,9 @@ pub const PltSection = struct {
759761
760762 const x86_64 = struct {
761763 fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void {
762 const plt_addr = elf_file.shdrs.items[elf_file.plt_section_index.?].sh_addr;
763 const got_plt_addr = elf_file.shdrs.items[elf_file.got_plt_section_index.?].sh_addr;
764 const shdrs = elf_file.sections.items(.shdr);
765 const plt_addr = shdrs[elf_file.plt_section_index.?].sh_addr;
766 const got_plt_addr = shdrs[elf_file.got_plt_section_index.?].sh_addr;
764767 var preamble = [_]u8{
765768 0xf3, 0x0f, 0x1e, 0xfa, // endbr64
766769 0x41, 0x53, // push r11
......@@ -794,8 +797,9 @@ pub const PltSection = struct {
794797 const aarch64 = struct {
795798 fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void {
796799 {
797 const plt_addr: i64 = @intCast(elf_file.shdrs.items[elf_file.plt_section_index.?].sh_addr);
798 const got_plt_addr: i64 = @intCast(elf_file.shdrs.items[elf_file.got_plt_section_index.?].sh_addr);
800 const shdrs = elf_file.sections.items(.shdr);
801 const plt_addr: i64 = @intCast(shdrs[elf_file.plt_section_index.?].sh_addr);
802 const got_plt_addr: i64 = @intCast(shdrs[elf_file.got_plt_section_index.?].sh_addr);
799803 // TODO: relax if possible
800804 // .got.plt[2]
801805 const pages = try aarch64_util.calcNumberOfPages(plt_addr + 4, got_plt_addr + 16);
......@@ -869,7 +873,7 @@ pub const GotPltSection = struct {
869873 try writer.writeInt(u64, 0x0, .little);
870874 try writer.writeInt(u64, 0x0, .little);
871875 if (elf_file.plt_section_index) |shndx| {
872 const plt_addr = elf_file.shdrs.items[shndx].sh_addr;
876 const plt_addr = elf_file.sections.items(.shdr)[shndx].sh_addr;
873877 for (0..elf_file.plt.symbols.items.len) |_| {
874878 // [N]: .plt
875879 try writer.writeInt(u64, plt_addr, .little);
......@@ -1027,7 +1031,7 @@ pub const CopyRelSection = struct {
10271031 }
10281032
10291033 pub fn updateSectionSize(copy_rel: CopyRelSection, shndx: u32, elf_file: *Elf) !void {
1030 const shdr = &elf_file.shdrs.items[shndx];
1034 const shdr = &elf_file.sections.items(.shdr)[shndx];
10311035 for (copy_rel.symbols.items) |ref| {
10321036 const symbol = elf_file.symbol(ref).?;
10331037 const shared_object = symbol.file(elf_file).?.shared_object;
......@@ -1487,8 +1491,12 @@ pub const ComdatGroupSection = struct {
14871491 elf.SHT_RELA => {
14881492 const atom_index = object.atoms_indexes.items[shdr.sh_info];
14891493 const atom = object.atom(atom_index).?;
1490 const rela = elf_file.output_rela_sections.get(atom.output_section_index).?;
1491 try writer.writeInt(u32, rela.shndx, .little);
1494 const rela_shndx = for (elf_file.sections.items(.shdr), 0..) |rela_shdr, rela_shndx| {
1495 if (rela_shdr.sh_type == elf.SHT_RELA and
1496 atom.output_section_index == rela_shdr.sh_info)
1497 break rela_shndx;
1498 } else unreachable;
1499 try writer.writeInt(u32, @intCast(rela_shndx), .little);
14921500 },
14931501 else => {
14941502 const atom_index = object.atoms_indexes.items[shndx];
src/link/Elf/thunks.zig+3-4
......@@ -1,9 +1,8 @@
1pub fn createThunks(shndx: u32, elf_file: *Elf) !void {
1pub fn createThunks(shdr: *elf.Elf64_Shdr, shndx: u32, elf_file: *Elf) !void {
22 const gpa = elf_file.base.comp.gpa;
33 const cpu_arch = elf_file.getTarget().cpu.arch;
44 const max_distance = maxAllowedDistance(cpu_arch);
5 const shdr = &elf_file.shdrs.items[shndx];
6 const atoms = elf_file.output_sections.get(shndx).?.items;
5 const atoms = elf_file.sections.items(.atom_list)[shndx].items;
76 assert(atoms.len > 0);
87
98 for (atoms) |ref| {
......@@ -89,7 +88,7 @@ pub const Thunk = struct {
8988 }
9089
9190 pub fn address(thunk: Thunk, elf_file: *Elf) i64 {
92 const shdr = elf_file.shdrs.items[thunk.output_section_index];
91 const shdr = elf_file.sections.items(.shdr)[thunk.output_section_index];
9392 return @as(i64, @intCast(shdr.sh_addr)) + thunk.value;
9493 }
9594