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 {...@@ -317,7 +317,7 @@ pub const Section = struct {
317 fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void {317 fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void {
318 if (dwarf.bin_file.cast(.elf)) |elf_file| {318 if (dwarf.bin_file.cast(.elf)) |elf_file| {
319 try elf_file.growNonAllocSection(sec.index, len, @intCast(sec.alignment.toByteUnits().?), true);319 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];
321 sec.off = shdr.sh_offset;321 sec.off = shdr.sh_offset;
322 sec.len = shdr.sh_size;322 sec.len = shdr.sh_size;
323 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {323 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {
...@@ -340,7 +340,7 @@ pub const Section = struct {...@@ -340,7 +340,7 @@ pub const Section = struct {
340 sec.off += len;340 sec.off += len;
341 sec.len -= len;341 sec.len -= len;
342 if (dwarf.bin_file.cast(.elf)) |elf_file| {342 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];
344 shdr.sh_offset = sec.off;344 shdr.sh_offset = sec.off;
345 shdr.sh_size = sec.len;345 shdr.sh_size = sec.len;
346 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {346 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {
...@@ -771,7 +771,7 @@ const Entry = struct {...@@ -771,7 +771,7 @@ const Entry = struct {
771 log.err("missing {} from {s}", .{771 log.err("missing {} from {s}", .{
772 @as(Entry.Index, @enumFromInt(entry - unit.entries.items.ptr)),772 @as(Entry.Index, @enumFromInt(entry - unit.entries.items.ptr)),
773 std.mem.sliceTo(if (dwarf.bin_file.cast(.elf)) |elf_file|773 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..]
775 else if (dwarf.bin_file.cast(.macho)) |macho_file|775 else if (dwarf.bin_file.cast(.macho)) |macho_file|
776 if (macho_file.d_sym) |*d_sym|776 if (macho_file.d_sym) |*d_sym|
777 &d_sym.sections.items[sec.index].segname777 &d_sym.sections.items[sec.index].segname
...@@ -1529,7 +1529,7 @@ pub fn reloadSectionMetadata(dwarf: *Dwarf) void {...@@ -1529,7 +1529,7 @@ pub fn reloadSectionMetadata(dwarf: *Dwarf) void {
1529 elf_file.debug_rnglists_section_index.?,1529 elf_file.debug_rnglists_section_index.?,
1530 elf_file.debug_str_section_index.?,1530 elf_file.debug_str_section_index.?,
1531 }) |sec, section_index| {1531 }) |sec, section_index| {
1532 const shdr = &elf_file.shdrs.items[section_index];1532 const shdr = &elf_file.sections.items(.shdr)[section_index];
1533 sec.index = section_index;1533 sec.index = section_index;
1534 sec.off = shdr.sh_offset;1534 sec.off = shdr.sh_offset;
1535 sec.len = shdr.sh_size;1535 sec.len = shdr.sh_size;
src/link/Elf.zig+168-256
...@@ -45,17 +45,10 @@ linker_defined_index: ?File.Index = null,...@@ -45,17 +45,10 @@ linker_defined_index: ?File.Index = null,
45objects: std.ArrayListUnmanaged(File.Index) = .{},45objects: std.ArrayListUnmanaged(File.Index) = .{},
46shared_objects: std.ArrayListUnmanaged(File.Index) = .{},46shared_objects: std.ArrayListUnmanaged(File.Index) = .{},
4747
48/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.48/// List of all output sections and their associated metadata.
49/// Same order as in the file.49sections: std.MultiArrayList(Section) = .{},
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) = .{},
53/// File offset into the shdr table.50/// File offset into the shdr table.
54shdr_table_offset: ?u64 = null,51shdr_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
60/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.53/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.
61/// Same order as in the file.54/// Same order as in the file.
...@@ -181,9 +174,6 @@ thunks: std.ArrayListUnmanaged(Thunk) = .{},...@@ -181,9 +174,6 @@ thunks: std.ArrayListUnmanaged(Thunk) = .{},
181/// List of output merge sections with deduped contents.174/// List of output merge sections with deduped contents.
182merge_sections: std.ArrayListUnmanaged(MergeSection) = .{},175merge_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
187first_eflags: ?elf.Elf64_Word = null,177first_eflags: ?elf.Elf64_Word = null,
188178
189/// When allocating, the ideal_capacity is calculated by179/// When allocating, the ideal_capacity is calculated by
...@@ -429,17 +419,12 @@ pub fn deinit(self: *Elf) void {...@@ -429,17 +419,12 @@ pub fn deinit(self: *Elf) void {
429 self.objects.deinit(gpa);419 self.objects.deinit(gpa);
430 self.shared_objects.deinit(gpa);420 self.shared_objects.deinit(gpa);
431421
432 self.shdrs.deinit(gpa);422 for (self.sections.items(.atom_list), self.sections.items(.free_list)) |*atoms, *free_list| {
433 self.phdr_to_shdr_table.deinit(gpa);423 atoms.deinit(gpa);
434 self.phdrs.deinit(gpa);424 free_list.deinit(gpa);
435 for (self.output_sections.values()) |*list| {
436 list.deinit(gpa);
437 }425 }
438 self.output_sections.deinit(gpa);426 self.sections.deinit(gpa);
439 for (self.output_rela_sections.values()) |*sec| {427 self.phdrs.deinit(gpa);
440 sec.atom_list.deinit(gpa);
441 }
442 self.output_rela_sections.deinit(gpa);
443 self.shstrtab.deinit(gpa);428 self.shstrtab.deinit(gpa);
444 self.symtab.deinit(gpa);429 self.symtab.deinit(gpa);
445 self.strtab.deinit(gpa);430 self.strtab.deinit(gpa);
...@@ -453,10 +438,6 @@ pub fn deinit(self: *Elf) void {...@@ -453,10 +438,6 @@ pub fn deinit(self: *Elf) void {
453 sect.deinit(gpa);438 sect.deinit(gpa);
454 }439 }
455 self.merge_sections.deinit(gpa);440 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
461 self.got.deinit(gpa);442 self.got.deinit(gpa);
462 self.plt.deinit(gpa);443 self.plt.deinit(gpa);
...@@ -505,7 +486,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 {...@@ -505,7 +486,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 {
505486
506 if (self.shdr_table_offset) |off| {487 if (self.shdr_table_offset) |off| {
507 const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr);488 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;
509 const increased_size = padToIdeal(tight_size);490 const increased_size = padToIdeal(tight_size);
510 const test_end = off +| increased_size;491 const test_end = off +| increased_size;
511 if (start < test_end) {492 if (start < test_end) {
...@@ -514,7 +495,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 {...@@ -514,7 +495,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 {
514 }495 }
515 }496 }
516497
517 for (self.shdrs.items) |shdr| {498 for (self.sections.items(.shdr)) |shdr| {
518 if (shdr.sh_type == elf.SHT_NOBITS) continue;499 if (shdr.sh_type == elf.SHT_NOBITS) continue;
519 const increased_size = padToIdeal(shdr.sh_size);500 const increased_size = padToIdeal(shdr.sh_size);
520 const test_end = shdr.sh_offset +| increased_size;501 const test_end = shdr.sh_offset +| increased_size;
...@@ -544,7 +525,7 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 {...@@ -544,7 +525,7 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 {
544 if (self.shdr_table_offset) |off| {525 if (self.shdr_table_offset) |off| {
545 if (off > start and off < min_pos) min_pos = off;526 if (off > start and off < min_pos) min_pos = off;
546 }527 }
547 for (self.shdrs.items) |section| {528 for (self.sections.items(.shdr)) |section| {
548 if (section.sh_offset <= start) continue;529 if (section.sh_offset <= start) continue;
549 if (section.sh_offset < min_pos) min_pos = section.sh_offset;530 if (section.sh_offset < min_pos) min_pos = section.sh_offset;
550 }531 }
...@@ -574,8 +555,12 @@ pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) !u64 {...@@ -574,8 +555,12 @@ pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) !u64 {
574}555}
575556
576pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void {557pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void {
577 const shdr = &self.shdrs.items[shdr_index];558 const slice = self.sections.slice();
578 const maybe_phdr = if (self.phdr_to_shdr_table.get(shdr_index)) |phndx| &self.phdrs.items[phndx] else null;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
579 log.debug("allocated size {x} of {s}, needed size {x}", .{564 log.debug("allocated size {x} of {s}, needed size {x}", .{
580 self.allocatedSize(shdr.sh_offset),565 self.allocatedSize(shdr.sh_offset),
581 self.getShString(shdr.sh_name),566 self.getShString(shdr.sh_name),
...@@ -590,7 +575,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void {...@@ -590,7 +575,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void {
590 const existing_size = shdr.sh_size;575 const existing_size = shdr.sh_size;
591 shdr.sh_size = 0;576 shdr.sh_size = 0;
592 // Must move the entire section.577 // 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;
594 const new_offset = try self.findFreeSpace(needed_size, alignment);579 const new_offset = try self.findFreeSpace(needed_size, alignment);
595580
596 log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{581 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 {...@@ -604,19 +589,17 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void {
604 if (amt != existing_size) return error.InputOutput;589 if (amt != existing_size) return error.InputOutput;
605590
606 shdr.sh_offset = new_offset;591 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;
608 }593 }
609 if (maybe_phdr) |phdr| phdr.p_filesz = needed_size;594 if (phdr.p_type != elf.PT_NULL) phdr.p_filesz = needed_size;
610 }595 }
611 shdr.sh_size = needed_size;596 shdr.sh_size = needed_size;
612597
613 if (maybe_phdr) |phdr| {598 if (phdr.p_type != elf.PT_NULL) {
614 const mem_capacity = self.allocatedVirtualSize(phdr.p_vaddr);599 const mem_capacity = self.allocatedVirtualSize(phdr.p_vaddr);
615 if (needed_size > mem_capacity) {600 if (needed_size > mem_capacity) {
616 var err = try self.base.addErrorWithNotes(2);601 var err = try self.base.addErrorWithNotes(2);
617 try err.addMsg("fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{602 try err.addMsg("fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{phndx});
618 self.phdr_to_shdr_table.get(shdr_index).?,
619 });
620 try err.addNote("TODO: emit relocations to memory locations in self-hosted backends", .{});603 try err.addNote("TODO: emit relocations to memory locations in self-hosted backends", .{});
621 try err.addNote("as a workaround, try increasing pre-allocated virtual memory of each segment", .{});604 try err.addNote("as a workaround, try increasing pre-allocated virtual memory of each segment", .{});
622 }605 }
...@@ -634,7 +617,8 @@ pub fn growNonAllocSection(...@@ -634,7 +617,8 @@ pub fn growNonAllocSection(
634 min_alignment: u32,617 min_alignment: u32,
635 requires_file_copy: bool,618 requires_file_copy: bool,
636) !void {619) !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
639 const allocated_size = self.allocatedSize(shdr.sh_offset);623 const allocated_size = self.allocatedSize(shdr.sh_offset);
640 if (shdr.sh_offset + allocated_size == std.math.maxInt(u64)) {624 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...@@ -1018,7 +1002,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
1018 const atom_ptr = zo.atom(atom_index) orelse continue;1002 const atom_ptr = zo.atom(atom_index) orelse continue;
1019 if (!atom_ptr.alive) continue;1003 if (!atom_ptr.alive) continue;
1020 const out_shndx = atom_ptr.output_section_index;1004 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];
1022 if (shdr.sh_type == elf.SHT_NOBITS) continue;1006 if (shdr.sh_type == elf.SHT_NOBITS) continue;
1023 const code = try zo.codeAlloc(self, atom_index);1007 const code = try zo.codeAlloc(self, atom_index);
1024 defer gpa.free(code);1008 defer gpa.free(code);
...@@ -2382,7 +2366,7 @@ pub fn writeShdrTable(self: *Elf) !void {...@@ -2382,7 +2366,7 @@ pub fn writeShdrTable(self: *Elf) !void {
2382 };2366 };
23832367
2384 const shoff = self.shdr_table_offset orelse 0;2368 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
2387 if (needed_size > self.allocatedSize(shoff)) {2371 if (needed_size > self.allocatedSize(shoff)) {
2388 self.shdr_table_offset = null;2372 self.shdr_table_offset = null;
...@@ -2396,12 +2380,12 @@ pub fn writeShdrTable(self: *Elf) !void {...@@ -2396,12 +2380,12 @@ pub fn writeShdrTable(self: *Elf) !void {
23962380
2397 switch (self.ptr_width) {2381 switch (self.ptr_width) {
2398 .p32 => {2382 .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);
2400 defer gpa.free(buf);2384 defer gpa.free(buf);
24012385
2402 for (buf, 0..) |*shdr, i| {2386 for (buf, 0..) |*shdr, i| {
2403 assert(self.shdrs.items[i].sh_offset != math.maxInt(u64));2387 assert(self.sections.items(.shdr)[i].sh_offset != math.maxInt(u64));
2404 shdr.* = shdrTo32(self.shdrs.items[i]);2388 shdr.* = shdrTo32(self.sections.items(.shdr)[i]);
2405 if (foreign_endian) {2389 if (foreign_endian) {
2406 mem.byteSwapAllFields(elf.Elf32_Shdr, shdr);2390 mem.byteSwapAllFields(elf.Elf32_Shdr, shdr);
2407 }2391 }
...@@ -2409,12 +2393,12 @@ pub fn writeShdrTable(self: *Elf) !void {...@@ -2409,12 +2393,12 @@ pub fn writeShdrTable(self: *Elf) !void {
2409 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?);2393 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?);
2410 },2394 },
2411 .p64 => {2395 .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);
2413 defer gpa.free(buf);2397 defer gpa.free(buf);
24142398
2415 for (buf, 0..) |*shdr, i| {2399 for (buf, 0..) |*shdr, i| {
2416 assert(self.shdrs.items[i].sh_offset != math.maxInt(u64));2400 assert(self.sections.items(.shdr)[i].sh_offset != math.maxInt(u64));
2417 shdr.* = self.shdrs.items[i];2401 shdr.* = self.sections.items(.shdr)[i];
2418 if (foreign_endian) {2402 if (foreign_endian) {
2419 mem.byteSwapAllFields(elf.Elf64_Shdr, shdr);2403 mem.byteSwapAllFields(elf.Elf64_Shdr, shdr);
2420 }2404 }
...@@ -2582,7 +2566,7 @@ pub fn writeElfHeader(self: *Elf) !void {...@@ -2582,7 +2566,7 @@ pub fn writeElfHeader(self: *Elf) !void {
2582 mem.writeInt(u16, hdr_buf[index..][0..2], e_shentsize, endian);2566 mem.writeInt(u16, hdr_buf[index..][0..2], e_shentsize, endian);
2583 index += 2;2567 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));
2586 mem.writeInt(u16, hdr_buf[index..][0..2], e_shnum, endian);2570 mem.writeInt(u16, hdr_buf[index..][0..2], e_shnum, endian);
2587 index += 2;2571 index += 2;
25882572
...@@ -2741,7 +2725,7 @@ pub fn updateMergeSectionSizes(self: *Elf) !void {...@@ -2741,7 +2725,7 @@ pub fn updateMergeSectionSizes(self: *Elf) !void {
2741 msec.updateSize();2725 msec.updateSize();
2742 }2726 }
2743 for (self.merge_sections.items) |*msec| {2727 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];
2745 const offset = msec.alignment.forward(shdr.sh_size);2729 const offset = msec.alignment.forward(shdr.sh_size);
2746 const padding = offset - shdr.sh_size;2730 const padding = offset - shdr.sh_size;
2747 msec.value = @intCast(offset);2731 msec.value = @intCast(offset);
...@@ -2757,7 +2741,7 @@ pub fn writeMergeSections(self: *Elf) !void {...@@ -2757,7 +2741,7 @@ pub fn writeMergeSections(self: *Elf) !void {
2757 defer buffer.deinit();2741 defer buffer.deinit();
27582742
2759 for (self.merge_sections.items) |*msec| {2743 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];
2761 const fileoff = math.cast(usize, msec.value + shdr.sh_offset) orelse return error.Overflow;2745 const fileoff = math.cast(usize, msec.value + shdr.sh_offset) orelse return error.Overflow;
2762 const size = math.cast(usize, msec.size) orelse return error.Overflow;2746 const size = math.cast(usize, msec.size) orelse return error.Overflow;
2763 try buffer.ensureTotalCapacity(size);2747 try buffer.ensureTotalCapacity(size);
...@@ -3045,7 +3029,7 @@ fn initSpecialPhdrs(self: *Elf) !void {...@@ -3045,7 +3029,7 @@ fn initSpecialPhdrs(self: *Elf) !void {
3045 .@"align" = 1,3029 .@"align" = 1,
3046 });3030 });
30473031
3048 const has_tls = for (self.shdrs.items) |shdr| {3032 const has_tls = for (self.sections.items(.shdr)) |shdr| {
3049 if (shdr.sh_flags & elf.SHF_TLS != 0) break true;3033 if (shdr.sh_flags & elf.SHF_TLS != 0) break true;
3050 } else false;3034 } else false;
3051 if (has_tls) {3035 if (has_tls) {
...@@ -3074,6 +3058,7 @@ fn initSpecialPhdrs(self: *Elf) !void {...@@ -3074,6 +3058,7 @@ fn initSpecialPhdrs(self: *Elf) !void {
3074/// we are about to sort.3058/// we are about to sort.
3075fn sortInitFini(self: *Elf) !void {3059fn sortInitFini(self: *Elf) !void {
3076 const gpa = self.base.comp.gpa;3060 const gpa = self.base.comp.gpa;
3061 const slice = self.sections.slice();
30773062
3078 const Entry = struct {3063 const Entry = struct {
3079 priority: i32,3064 priority: i32,
...@@ -3087,7 +3072,7 @@ fn sortInitFini(self: *Elf) !void {...@@ -3087,7 +3072,7 @@ fn sortInitFini(self: *Elf) !void {
3087 }3072 }
3088 };3073 };
30893074
3090 for (self.shdrs.items, 0..) |shdr, shndx| {3075 for (slice.items(.shdr), slice.items(.atom_list)) |shdr, *atom_list| {
3091 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;3076 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
30923077
3093 var is_init_fini = false;3078 var is_init_fini = false;
...@@ -3104,8 +3089,6 @@ fn sortInitFini(self: *Elf) !void {...@@ -3104,8 +3089,6 @@ fn sortInitFini(self: *Elf) !void {
3104 }3089 }
31053090
3106 if (!is_init_fini and !is_ctor_dtor) continue;3091 if (!is_init_fini and !is_ctor_dtor) continue;
3107
3108 const atom_list = self.output_sections.getPtr(@intCast(shndx)).?;
3109 if (atom_list.items.len == 0) continue;3092 if (atom_list.items.len == 0) continue;
31103093
3111 var entries = std.ArrayList(Entry).init(gpa);3094 var entries = std.ArrayList(Entry).init(gpa);
...@@ -3173,7 +3156,7 @@ fn setVersionSymtab(self: *Elf) !void {...@@ -3173,7 +3156,7 @@ fn setVersionSymtab(self: *Elf) !void {
31733156
3174 if (self.verneed_section_index) |shndx| {3157 if (self.verneed_section_index) |shndx| {
3175 try self.verneed.generate(self);3158 try self.verneed.generate(self);
3176 const shdr = &self.shdrs.items[shndx];3159 const shdr = &self.sections.items(.shdr)[shndx];
3177 shdr.sh_info = @as(u32, @intCast(self.verneed.verneed.items.len));3160 shdr.sh_info = @as(u32, @intCast(self.verneed.verneed.items.len));
3178 }3161 }
3179}3162}
...@@ -3252,17 +3235,10 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {...@@ -3252,17 +3235,10 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {
3252 index.* = backlinks[index.*];3235 index.* = backlinks[index.*];
3253 }3236 }
3254 }3237 }
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 }
3262}3238}
32633239
3264fn shdrRank(self: *Elf, shndx: u32) u8 {3240fn shdrRank(self: *Elf, shndx: u32) u8 {
3265 const shdr = self.shdrs.items[shndx];3241 const shdr = self.sections.items(.shdr)[shndx];
3266 const name = self.getShString(shdr.sh_name);3242 const name = self.getShString(shdr.sh_name);
3267 const flags = shdr.sh_flags;3243 const flags = shdr.sh_flags;
32683244
...@@ -3319,9 +3295,9 @@ pub fn sortShdrs(self: *Elf) !void {...@@ -3319,9 +3295,9 @@ pub fn sortShdrs(self: *Elf) !void {
3319 };3295 };
33203296
3321 const gpa = self.base.comp.gpa;3297 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);
3323 defer entries.deinit();3299 defer entries.deinit();
3324 for (0..self.shdrs.items.len) |shndx| {3300 for (0..self.sections.items(.shdr).len) |shndx| {
3325 entries.appendAssumeCapacity(.{ .shndx = @intCast(shndx) });3301 entries.appendAssumeCapacity(.{ .shndx = @intCast(shndx) });
3326 }3302 }
33273303
...@@ -3333,20 +3309,18 @@ pub fn sortShdrs(self: *Elf) !void {...@@ -3333,20 +3309,18 @@ pub fn sortShdrs(self: *Elf) !void {
3333 backlinks[entry.shndx] = @intCast(i);3309 backlinks[entry.shndx] = @intCast(i);
3334 }3310 }
33353311
3336 const slice = try self.shdrs.toOwnedSlice(gpa);3312 var slice = self.sections.toOwnedSlice();
3337 defer gpa.free(slice);3313 defer slice.deinit(gpa);
33383314
3339 try self.shdrs.ensureTotalCapacityPrecise(gpa, slice.len);3315 try self.sections.ensureTotalCapacity(gpa, slice.len);
3340 for (entries.items) |sorted| {3316 for (entries.items) |sorted| {
3341 self.shdrs.appendAssumeCapacity(slice[sorted.shndx]);3317 self.sections.appendAssumeCapacity(slice.get(sorted.shndx));
3342 }3318 }
33433319
3344 try self.resetShdrIndexes(backlinks);3320 self.resetShdrIndexes(backlinks);
3345}3321}
33463322
3347fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {3323fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
3348 const gpa = self.base.comp.gpa;
3349
3350 for (&[_]*?u32{3324 for (&[_]*?u32{
3351 &self.eh_frame_section_index,3325 &self.eh_frame_section_index,
3352 &self.eh_frame_rela_section_index,3326 &self.eh_frame_rela_section_index,
...@@ -3388,116 +3362,65 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {...@@ -3388,116 +3362,65 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {
3388 }3362 }
33893363
3390 if (self.symtab_section_index) |index| {3364 if (self.symtab_section_index) |index| {
3391 const shdr = &self.shdrs.items[index];3365 const shdr = &self.sections.items(.shdr)[index];
3392 shdr.sh_link = self.strtab_section_index.?;3366 shdr.sh_link = self.strtab_section_index.?;
3393 }3367 }
33943368
3395 if (self.dynamic_section_index) |index| {3369 if (self.dynamic_section_index) |index| {
3396 const shdr = &self.shdrs.items[index];3370 const shdr = &self.sections.items(.shdr)[index];
3397 shdr.sh_link = self.dynstrtab_section_index.?;3371 shdr.sh_link = self.dynstrtab_section_index.?;
3398 }3372 }
33993373
3400 if (self.dynsymtab_section_index) |index| {3374 if (self.dynsymtab_section_index) |index| {
3401 const shdr = &self.shdrs.items[index];3375 const shdr = &self.sections.items(.shdr)[index];
3402 shdr.sh_link = self.dynstrtab_section_index.?;3376 shdr.sh_link = self.dynstrtab_section_index.?;
3403 }3377 }
34043378
3405 if (self.hash_section_index) |index| {3379 if (self.hash_section_index) |index| {
3406 const shdr = &self.shdrs.items[index];3380 const shdr = &self.sections.items(.shdr)[index];
3407 shdr.sh_link = self.dynsymtab_section_index.?;3381 shdr.sh_link = self.dynsymtab_section_index.?;
3408 }3382 }
34093383
3410 if (self.gnu_hash_section_index) |index| {3384 if (self.gnu_hash_section_index) |index| {
3411 const shdr = &self.shdrs.items[index];3385 const shdr = &self.sections.items(.shdr)[index];
3412 shdr.sh_link = self.dynsymtab_section_index.?;3386 shdr.sh_link = self.dynsymtab_section_index.?;
3413 }3387 }
34143388
3415 if (self.versym_section_index) |index| {3389 if (self.versym_section_index) |index| {
3416 const shdr = &self.shdrs.items[index];3390 const shdr = &self.sections.items(.shdr)[index];
3417 shdr.sh_link = self.dynsymtab_section_index.?;3391 shdr.sh_link = self.dynsymtab_section_index.?;
3418 }3392 }
34193393
3420 if (self.verneed_section_index) |index| {3394 if (self.verneed_section_index) |index| {
3421 const shdr = &self.shdrs.items[index];3395 const shdr = &self.sections.items(.shdr)[index];
3422 shdr.sh_link = self.dynstrtab_section_index.?;3396 shdr.sh_link = self.dynstrtab_section_index.?;
3423 }3397 }
34243398
3425 if (self.rela_dyn_section_index) |index| {3399 if (self.rela_dyn_section_index) |index| {
3426 const shdr = &self.shdrs.items[index];3400 const shdr = &self.sections.items(.shdr)[index];
3427 shdr.sh_link = self.dynsymtab_section_index orelse 0;3401 shdr.sh_link = self.dynsymtab_section_index orelse 0;
3428 }3402 }
34293403
3430 if (self.rela_plt_section_index) |index| {3404 if (self.rela_plt_section_index) |index| {
3431 const shdr = &self.shdrs.items[index];3405 const shdr = &self.sections.items(.shdr)[index];
3432 shdr.sh_link = self.dynsymtab_section_index.?;3406 shdr.sh_link = self.dynsymtab_section_index.?;
3433 shdr.sh_info = self.plt_section_index.?;3407 shdr.sh_info = self.plt_section_index.?;
3434 }3408 }
34353409
3436 if (self.eh_frame_rela_section_index) |index| {3410 if (self.eh_frame_rela_section_index) |index| {
3437 const shdr = &self.shdrs.items[index];3411 const shdr = &self.sections.items(.shdr)[index];
3438 shdr.sh_link = self.symtab_section_index.?;3412 shdr.sh_link = self.symtab_section_index.?;
3439 shdr.sh_info = self.eh_frame_section_index.?;3413 shdr.sh_info = self.eh_frame_section_index.?;
3440 }3414 }
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
3456 for (self.merge_sections.items) |*msec| {3416 for (self.merge_sections.items) |*msec| {
3457 msec.output_section_index = backlinks[msec.output_section_index];3417 msec.output_section_index = backlinks[msec.output_section_index];
3458 }3418 }
34593419
3460 {3420 for (self.sections.items(.shdr)) |*shdr| {
3461 var output_rela_sections = try self.output_rela_sections.clone(gpa);3421 if (shdr.sh_type != elf.SHT_RELA) continue;
3462 defer output_rela_sections.deinit(gpa);3422 shdr.sh_link = backlinks[shdr.sh_link];
34633423 shdr.sh_info = backlinks[shdr.sh_info];
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 }
3501 }3424 }
35023425
3503 if (self.zigObjectPtr()) |zo| {3426 if (self.zigObjectPtr()) |zo| {
...@@ -3508,12 +3431,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {...@@ -3508,12 +3431,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {
3508 if (zo.dwarf) |*dwarf| dwarf.reloadSectionMetadata();3431 if (zo.dwarf) |*dwarf| dwarf.reloadSectionMetadata();
3509 }3432 }
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
3517 for (self.comdat_group_sections.items) |*cg| {3434 for (self.comdat_group_sections.items) |*cg| {
3518 cg.shndx = backlinks[cg.shndx];3435 cg.shndx = backlinks[cg.shndx];
3519 }3436 }
...@@ -3521,8 +3438,8 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {...@@ -3521,8 +3438,8 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {
35213438
3522fn updateSectionSizes(self: *Elf) !void {3439fn updateSectionSizes(self: *Elf) !void {
3523 const target = self.base.comp.root_mod.resolved_target.result;3440 const target = self.base.comp.root_mod.resolved_target.result;
3524 for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| {3441 const slice = self.sections.slice();
3525 const shdr = &self.shdrs.items[shndx];3442 for (slice.items(.shdr), slice.items(.atom_list)) |*shdr, atom_list| {
3526 if (atom_list.items.len == 0) continue;3443 if (atom_list.items.len == 0) continue;
3527 if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue;3444 if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue;
3528 for (atom_list.items) |ref| {3445 for (atom_list.items) |ref| {
...@@ -3537,38 +3454,38 @@ fn updateSectionSizes(self: *Elf) !void {...@@ -3537,38 +3454,38 @@ fn updateSectionSizes(self: *Elf) !void {
3537 }3454 }
35383455
3539 if (self.requiresThunks()) {3456 if (self.requiresThunks()) {
3540 for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| {3457 for (slice.items(.shdr), slice.items(.atom_list), 0..) |*shdr, atom_list, shndx| {
3541 const shdr = self.shdrs.items[shndx];
3542 if (shdr.sh_flags & elf.SHF_EXECINSTR == 0) continue;3458 if (shdr.sh_flags & elf.SHF_EXECINSTR == 0) continue;
3543 if (atom_list.items.len == 0) continue;3459 if (atom_list.items.len == 0) continue;
35443460
3545 // Create jump/branch range extenders if needed.3461 // Create jump/branch range extenders if needed.
3546 try thunks.createThunks(shndx, self);3462 try thunks.createThunks(shdr, @intCast(shndx), self);
3547 }3463 }
3548 }3464 }
35493465
3466 const shdrs = slice.items(.shdr);
3550 if (self.eh_frame_section_index) |index| {3467 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);
3552 }3469 }
35533470
3554 if (self.eh_frame_hdr_section_index) |index| {3471 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);
3556 }3473 }
35573474
3558 if (self.got_section_index) |index| {3475 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);
3560 }3477 }
35613478
3562 if (self.plt_section_index) |index| {3479 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);
3564 }3481 }
35653482
3566 if (self.got_plt_section_index) |index| {3483 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);
3568 }3485 }
35693486
3570 if (self.plt_got_section_index) |index| {3487 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);
3572 }3489 }
35733490
3574 if (self.rela_dyn_section_index) |shndx| {3491 if (self.rela_dyn_section_index) |shndx| {
...@@ -3579,11 +3496,11 @@ fn updateSectionSizes(self: *Elf) !void {...@@ -3579,11 +3496,11 @@ fn updateSectionSizes(self: *Elf) !void {
3579 for (self.objects.items) |index| {3496 for (self.objects.items) |index| {
3580 num += self.file(index).?.object.num_dynrelocs;3497 num += self.file(index).?.object.num_dynrelocs;
3581 }3498 }
3582 self.shdrs.items[shndx].sh_size = num * @sizeOf(elf.Elf64_Rela);3499 shdrs[shndx].sh_size = num * @sizeOf(elf.Elf64_Rela);
3583 }3500 }
35843501
3585 if (self.rela_plt_section_index) |index| {3502 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);
3587 }3504 }
35883505
3589 if (self.copy_rel_section_index) |index| {3506 if (self.copy_rel_section_index) |index| {
...@@ -3591,44 +3508,45 @@ fn updateSectionSizes(self: *Elf) !void {...@@ -3591,44 +3508,45 @@ fn updateSectionSizes(self: *Elf) !void {
3591 }3508 }
35923509
3593 if (self.interp_section_index) |index| {3510 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;
3595 }3512 }
35963513
3597 if (self.hash_section_index) |index| {3514 if (self.hash_section_index) |index| {
3598 self.shdrs.items[index].sh_size = self.hash.size();3515 shdrs[index].sh_size = self.hash.size();
3599 }3516 }
36003517
3601 if (self.gnu_hash_section_index) |index| {3518 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();
3603 }3520 }
36043521
3605 if (self.dynamic_section_index) |index| {3522 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);
3607 }3524 }
36083525
3609 if (self.dynsymtab_section_index) |index| {3526 if (self.dynsymtab_section_index) |index| {
3610 self.shdrs.items[index].sh_size = self.dynsym.size();3527 shdrs[index].sh_size = self.dynsym.size();
3611 }3528 }
36123529
3613 if (self.dynstrtab_section_index) |index| {3530 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;
3615 }3532 }
36163533
3617 if (self.versym_section_index) |index| {3534 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);
3619 }3536 }
36203537
3621 if (self.verneed_section_index) |index| {3538 if (self.verneed_section_index) |index| {
3622 self.shdrs.items[index].sh_size = self.verneed.size();3539 shdrs[index].sh_size = self.verneed.size();
3623 }3540 }
36243541
3625 try self.updateSymtabSize();3542 try self.updateSymtabSize();
3626 self.updateShStrtabSize();3543 self.updateShStrtabSize();
3627}3544}
36283545
3546// FIXME:JK this is very much obsolete, remove!
3629pub fn updateShStrtabSize(self: *Elf) void {3547pub fn updateShStrtabSize(self: *Elf) void {
3630 if (self.shstrtab_section_index) |index| {3548 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;
3632 }3550 }
3633}3551}
36343552
...@@ -3661,7 +3579,7 @@ fn getMaxNumberOfPhdrs() u64 {...@@ -3661,7 +3579,7 @@ fn getMaxNumberOfPhdrs() u64 {
3661/// We permit a maximum of 3**2 number of segments.3579/// We permit a maximum of 3**2 number of segments.
3662fn calcNumberOfSegments(self: *Elf) usize {3580fn calcNumberOfSegments(self: *Elf) usize {
3663 var covers: [9]bool = [_]bool{false} ** 9;3581 var covers: [9]bool = [_]bool{false} ** 9;
3664 for (self.shdrs.items, 0..) |shdr, shndx| {3582 for (self.sections.items(.shdr), 0..) |shdr, shndx| {
3665 if (shdr.sh_type == elf.SHT_NULL) continue;3583 if (shdr.sh_type == elf.SHT_NULL) continue;
3666 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;3584 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
3667 if (self.isZigSection(@intCast(shndx))) continue;3585 if (self.isZigSection(@intCast(shndx))) continue;
...@@ -3732,8 +3650,9 @@ pub fn allocateAllocSections(self: *Elf) !void {...@@ -3732,8 +3650,9 @@ pub fn allocateAllocSections(self: *Elf) !void {
3732 }3650 }
3733 };3651 };
37343652
3653 const slice = self.sections.slice();
3735 var alignment = Align{};3654 var alignment = Align{};
3736 for (self.shdrs.items, 0..) |shdr, i| {3655 for (slice.items(.shdr), 0..) |shdr, i| {
3737 if (shdr.sh_type == elf.SHT_NULL) continue;3656 if (shdr.sh_type == elf.SHT_NULL) continue;
3738 if (shdr.sh_flags & elf.SHF_TLS == 0) continue;3657 if (shdr.sh_flags & elf.SHF_TLS == 0) continue;
3739 if (alignment.first_tls_index == null) alignment.first_tls_index = i;3658 if (alignment.first_tls_index == null) alignment.first_tls_index = i;
...@@ -3758,7 +3677,7 @@ pub fn allocateAllocSections(self: *Elf) !void {...@@ -3758,7 +3677,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
3758 cover.deinit();3677 cover.deinit();
3759 };3678 };
37603679
3761 for (self.shdrs.items, 0..) |shdr, shndx| {3680 for (slice.items(.shdr), 0..) |shdr, shndx| {
3762 if (shdr.sh_type == elf.SHT_NULL) continue;3681 if (shdr.sh_type == elf.SHT_NULL) continue;
3763 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;3682 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
3764 if (self.isZigSection(@intCast(shndx))) continue;3683 if (self.isZigSection(@intCast(shndx))) continue;
...@@ -3779,7 +3698,7 @@ pub fn allocateAllocSections(self: *Elf) !void {...@@ -3779,7 +3698,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
37793698
3780 var @"align": u64 = self.page_size;3699 var @"align": u64 = self.page_size;
3781 for (cover.items) |shndx| {3700 for (cover.items) |shndx| {
3782 const shdr = self.shdrs.items[shndx];3701 const shdr = slice.items(.shdr)[shndx];
3783 if (shdr.sh_type == elf.SHT_NOBITS and shdr.sh_flags & elf.SHF_TLS != 0) continue;3702 if (shdr.sh_type == elf.SHT_NOBITS and shdr.sh_flags & elf.SHF_TLS != 0) continue;
3784 @"align" = @max(@"align", shdr.sh_addralign);3703 @"align" = @max(@"align", shdr.sh_addralign);
3785 }3704 }
...@@ -3791,7 +3710,7 @@ pub fn allocateAllocSections(self: *Elf) !void {...@@ -3791,7 +3710,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
3791 var i: usize = 0;3710 var i: usize = 0;
3792 while (i < cover.items.len) : (i += 1) {3711 while (i < cover.items.len) : (i += 1) {
3793 const shndx = cover.items[i];3712 const shndx = cover.items[i];
3794 const shdr = &self.shdrs.items[shndx];3713 const shdr = &slice.items(.shdr)[shndx];
3795 if (shdr.sh_type == elf.SHT_NOBITS and shdr.sh_flags & elf.SHF_TLS != 0) {3714 if (shdr.sh_type == elf.SHT_NOBITS and shdr.sh_flags & elf.SHF_TLS != 0) {
3796 // .tbss is a little special as it's used only by the loader meaning it doesn't3715 // .tbss is a little special as it's used only by the loader meaning it doesn't
3797 // need to be actually mmap'ed at runtime. We still need to correctly increment3716 // need to be actually mmap'ed at runtime. We still need to correctly increment
...@@ -3807,11 +3726,11 @@ pub fn allocateAllocSections(self: *Elf) !void {...@@ -3807,11 +3726,11 @@ pub fn allocateAllocSections(self: *Elf) !void {
3807 // ...3726 // ...
3808 var tbss_addr = addr;3727 var tbss_addr = addr;
3809 while (i < cover.items.len and3728 while (i < cover.items.len and
3810 self.shdrs.items[cover.items[i]].sh_type == elf.SHT_NOBITS and3729 slice.items(.shdr)[cover.items[i]].sh_type == elf.SHT_NOBITS and
3811 self.shdrs.items[cover.items[i]].sh_flags & elf.SHF_TLS != 0) : (i += 1)3730 slice.items(.shdr)[cover.items[i]].sh_flags & elf.SHF_TLS != 0) : (i += 1)
3812 {3731 {
3813 const tbss_shndx = cover.items[i];3732 const tbss_shndx = cover.items[i];
3814 const tbss_shdr = &self.shdrs.items[tbss_shndx];3733 const tbss_shdr = &slice.items(.shdr)[tbss_shndx];
3815 tbss_addr = alignment.@"align"(tbss_shndx, tbss_shdr.sh_addralign, tbss_addr);3734 tbss_addr = alignment.@"align"(tbss_shndx, tbss_shdr.sh_addralign, tbss_addr);
3816 tbss_shdr.sh_addr = tbss_addr;3735 tbss_shdr.sh_addr = tbss_addr;
3817 tbss_addr += tbss_shdr.sh_size;3736 tbss_addr += tbss_shdr.sh_size;
...@@ -3830,7 +3749,7 @@ pub fn allocateAllocSections(self: *Elf) !void {...@@ -3830,7 +3749,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
3830 addr += shdr.sh_size;3749 addr += shdr.sh_size;
3831 }3750 }
38323751
3833 const first = self.shdrs.items[cover.items[0]];3752 const first = slice.items(.shdr)[cover.items[0]];
3834 var off = try self.findFreeSpace(filesz, @"align");3753 var off = try self.findFreeSpace(filesz, @"align");
3835 const phndx = try self.addPhdr(.{3754 const phndx = try self.addPhdr(.{
3836 .type = elf.PT_LOAD,3755 .type = elf.PT_LOAD,
...@@ -3843,7 +3762,7 @@ pub fn allocateAllocSections(self: *Elf) !void {...@@ -3843,7 +3762,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
3843 });3762 });
38443763
3845 for (cover.items) |shndx| {3764 for (cover.items) |shndx| {
3846 const shdr = &self.shdrs.items[shndx];3765 const shdr = &slice.items(.shdr)[shndx];
3847 if (shdr.sh_type == elf.SHT_NOBITS) {3766 if (shdr.sh_type == elf.SHT_NOBITS) {
3848 shdr.sh_offset = 0;3767 shdr.sh_offset = 0;
3849 continue;3768 continue;
...@@ -3851,7 +3770,7 @@ pub fn allocateAllocSections(self: *Elf) !void {...@@ -3851,7 +3770,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
3851 off = alignment.@"align"(shndx, shdr.sh_addralign, off);3770 off = alignment.@"align"(shndx, shdr.sh_addralign, off);
3852 shdr.sh_offset = off;3771 shdr.sh_offset = off;
3853 off += shdr.sh_size;3772 off += shdr.sh_size;
3854 try self.phdr_to_shdr_table.putNoClobber(gpa, shndx, phndx);3773 slice.items(.phndx)[shndx] = phndx;
3855 }3774 }
38563775
3857 addr = mem.alignForward(u64, addr, self.page_size);3776 addr = mem.alignForward(u64, addr, self.page_size);
...@@ -3860,7 +3779,7 @@ pub fn allocateAllocSections(self: *Elf) !void {...@@ -3860,7 +3779,7 @@ pub fn allocateAllocSections(self: *Elf) !void {
38603779
3861/// Allocates non-alloc sections (debug info, symtabs, etc.).3780/// Allocates non-alloc sections (debug info, symtabs, etc.).
3862pub fn allocateNonAllocSections(self: *Elf) !void {3781pub fn allocateNonAllocSections(self: *Elf) !void {
3863 for (self.shdrs.items, 0..) |*shdr, shndx| {3782 for (self.sections.items(.shdr), 0..) |*shdr, shndx| {
3864 if (shdr.sh_type == elf.SHT_NULL) continue;3783 if (shdr.sh_type == elf.SHT_NULL) continue;
3865 if (shdr.sh_flags & elf.SHF_ALLOC != 0) continue;3784 if (shdr.sh_flags & elf.SHF_ALLOC != 0) continue;
3866 const needed_size = shdr.sh_size;3785 const needed_size = shdr.sh_size;
...@@ -3905,13 +3824,15 @@ pub fn allocateNonAllocSections(self: *Elf) !void {...@@ -3905,13 +3824,15 @@ pub fn allocateNonAllocSections(self: *Elf) !void {
3905}3824}
39063825
3907fn allocateSpecialPhdrs(self: *Elf) void {3826fn allocateSpecialPhdrs(self: *Elf) void {
3827 const slice = self.sections.slice();
3828
3908 for (&[_]struct { ?u16, ?u32 }{3829 for (&[_]struct { ?u16, ?u32 }{
3909 .{ self.phdr_interp_index, self.interp_section_index },3830 .{ self.phdr_interp_index, self.interp_section_index },
3910 .{ self.phdr_dynamic_index, self.dynamic_section_index },3831 .{ self.phdr_dynamic_index, self.dynamic_section_index },
3911 .{ self.phdr_gnu_eh_frame_index, self.eh_frame_hdr_section_index },3832 .{ self.phdr_gnu_eh_frame_index, self.eh_frame_hdr_section_index },
3912 }) |pair| {3833 }) |pair| {
3913 if (pair[0]) |index| {3834 if (pair[0]) |index| {
3914 const shdr = self.shdrs.items[pair[1].?];3835 const shdr = slice.items(.shdr)[pair[1].?];
3915 const phdr = &self.phdrs.items[index];3836 const phdr = &self.phdrs.items[index];
3916 phdr.p_align = shdr.sh_addralign;3837 phdr.p_align = shdr.sh_addralign;
3917 phdr.p_offset = shdr.sh_offset;3838 phdr.p_offset = shdr.sh_offset;
...@@ -3926,11 +3847,11 @@ fn allocateSpecialPhdrs(self: *Elf) void {...@@ -3926,11 +3847,11 @@ fn allocateSpecialPhdrs(self: *Elf) void {
3926 // We assume TLS sections are laid out contiguously and that there is3847 // We assume TLS sections are laid out contiguously and that there is
3927 // a single TLS segment.3848 // a single TLS segment.
3928 if (self.phdr_tls_index) |index| {3849 if (self.phdr_tls_index) |index| {
3929 const slice = self.shdrs.items;3850 const shdrs = slice.items(.shdr);
3930 const phdr = &self.phdrs.items[index];3851 const phdr = &self.phdrs.items[index];
3931 var shndx: u32 = 0;3852 var shndx: u32 = 0;
3932 while (shndx < slice.len) {3853 while (shndx < shdrs.len) {
3933 const shdr = slice[shndx];3854 const shdr = shdrs[shndx];
3934 if (shdr.sh_flags & elf.SHF_TLS == 0) {3855 if (shdr.sh_flags & elf.SHF_TLS == 0) {
3935 shndx += 1;3856 shndx += 1;
3936 continue;3857 continue;
...@@ -3946,8 +3867,8 @@ fn allocateSpecialPhdrs(self: *Elf) void {...@@ -3946,8 +3867,8 @@ fn allocateSpecialPhdrs(self: *Elf) void {
3946 }3867 }
3947 phdr.p_memsz = shdr.sh_addr + shdr.sh_size - phdr.p_vaddr;3868 phdr.p_memsz = shdr.sh_addr + shdr.sh_size - phdr.p_vaddr;
39483869
3949 while (shndx < slice.len) : (shndx += 1) {3870 while (shndx < shdrs.len) : (shndx += 1) {
3950 const next = slice[shndx];3871 const next = shdrs[shndx];
3951 if (next.sh_flags & elf.SHF_TLS == 0) break;3872 if (next.sh_flags & elf.SHF_TLS == 0) break;
3952 phdr.p_align = @max(phdr.p_align, next.sh_addralign);3873 phdr.p_align = @max(phdr.p_align, next.sh_addralign);
3953 if (next.sh_type != elf.SHT_NOBITS) {3874 if (next.sh_type != elf.SHT_NOBITS) {
...@@ -3971,13 +3892,10 @@ fn writeAtoms(self: *Elf) !void {...@@ -3971,13 +3892,10 @@ fn writeAtoms(self: *Elf) !void {
3971 }3892 }
39723893
3973 var has_reloc_errors = false;3894 var has_reloc_errors = false;
39743895 const slice = self.sections.slice();
3975 // TODO iterate over `output_sections` directly3896 for (slice.items(.shdr), slice.items(.atom_list), 0..) |shdr, atom_list, shndx| {
3976 for (self.shdrs.items, 0..) |shdr, shndx| {
3977 if (shdr.sh_type == elf.SHT_NULL) continue;3897 if (shdr.sh_type == elf.SHT_NULL) continue;
3978 if (shdr.sh_type == elf.SHT_NOBITS) continue;3898 if (shdr.sh_type == elf.SHT_NOBITS) continue;
3979
3980 const atom_list = self.output_sections.get(@intCast(shndx)) orelse continue;
3981 if (atom_list.items.len == 0) continue;3899 if (atom_list.items.len == 0) continue;
39823900
3983 log.debug("writing atoms in '{s}' section", .{self.getShString(shdr.sh_name)});3901 log.debug("writing atoms in '{s}' section", .{self.getShString(shdr.sh_name)});
...@@ -4056,7 +3974,7 @@ fn writeAtoms(self: *Elf) !void {...@@ -4056,7 +3974,7 @@ fn writeAtoms(self: *Elf) !void {
4056 for (self.thunks.items) |th| {3974 for (self.thunks.items) |th| {
4057 const thunk_size = th.size(self);3975 const thunk_size = th.size(self);
4058 try buffer.ensureUnusedCapacity(thunk_size);3976 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];
4060 const offset = @as(u64, @intCast(th.value)) + shdr.sh_offset;3978 const offset = @as(u64, @intCast(th.value)) + shdr.sh_offset;
4061 try th.write(self, buffer.writer());3979 try th.write(self, buffer.writer());
4062 assert(buffer.items.len == thunk_size);3980 assert(buffer.items.len == thunk_size);
...@@ -4086,12 +4004,7 @@ pub fn updateSymtabSize(self: *Elf) !void {...@@ -4086,12 +4004,7 @@ pub fn updateSymtabSize(self: *Elf) !void {
4086 if (self.linker_defined_index) |index| files.appendAssumeCapacity(index);4004 if (self.linker_defined_index) |index| files.appendAssumeCapacity(index);
40874005
4088 // Section symbols4006 // Section symbols
4089 for (self.output_sections.keys()) |_| {4007 nlocals += @intCast(self.sections.slice().len);
4090 nlocals += 1;
4091 }
4092 if (self.eh_frame_section_index) |_| {
4093 nlocals += 1;
4094 }
40954008
4096 if (self.requiresThunks()) for (self.thunks.items) |*th| {4009 if (self.requiresThunks()) for (self.thunks.items) |*th| {
4097 th.output_symtab_ctx.ilocal = nlocals + 1;4010 th.output_symtab_ctx.ilocal = nlocals + 1;
...@@ -4142,7 +4055,8 @@ pub fn updateSymtabSize(self: *Elf) !void {...@@ -4142,7 +4055,8 @@ pub fn updateSymtabSize(self: *Elf) !void {
4142 ctx.iglobal += nlocals;4055 ctx.iglobal += nlocals;
4143 }4056 }
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.?];
4146 symtab_shdr.sh_info = nlocals + 1;4060 symtab_shdr.sh_info = nlocals + 1;
4147 symtab_shdr.sh_link = self.strtab_section_index.?;4061 symtab_shdr.sh_link = self.strtab_section_index.?;
41484062
...@@ -4153,13 +4067,14 @@ pub fn updateSymtabSize(self: *Elf) !void {...@@ -4153,13 +4067,14 @@ pub fn updateSymtabSize(self: *Elf) !void {
4153 const needed_size = (nlocals + nglobals + 1) * sym_size;4067 const needed_size = (nlocals + nglobals + 1) * sym_size;
4154 symtab_shdr.sh_size = needed_size;4068 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.?];
4157 strtab.sh_size = strsize + 1;4071 strtab.sh_size = strsize + 1;
4158}4072}
41594073
4160fn writeSyntheticSections(self: *Elf) !void {4074fn writeSyntheticSections(self: *Elf) !void {
4161 const target = self.base.comp.root_mod.resolved_target.result;
4162 const gpa = self.base.comp.gpa;4075 const gpa = self.base.comp.gpa;
4076 const target = self.getTarget();
4077 const slice = self.sections.slice();
41634078
4164 if (self.interp_section_index) |shndx| {4079 if (self.interp_section_index) |shndx| {
4165 var buffer: [256]u8 = undefined;4080 var buffer: [256]u8 = undefined;
...@@ -4167,18 +4082,18 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4167,18 +4082,18 @@ fn writeSyntheticSections(self: *Elf) !void {
4167 @memcpy(buffer[0..interp.len], interp);4082 @memcpy(buffer[0..interp.len], interp);
4168 buffer[interp.len] = 0;4083 buffer[interp.len] = 0;
4169 const contents = buffer[0 .. interp.len + 1];4084 const contents = buffer[0 .. interp.len + 1];
4170 const shdr = self.shdrs.items[shndx];4085 const shdr = slice.items(.shdr)[shndx];
4171 assert(shdr.sh_size == contents.len);4086 assert(shdr.sh_size == contents.len);
4172 try self.base.file.?.pwriteAll(contents, shdr.sh_offset);4087 try self.base.file.?.pwriteAll(contents, shdr.sh_offset);
4173 }4088 }
41744089
4175 if (self.hash_section_index) |shndx| {4090 if (self.hash_section_index) |shndx| {
4176 const shdr = self.shdrs.items[shndx];4091 const shdr = slice.items(.shdr)[shndx];
4177 try self.base.file.?.pwriteAll(self.hash.buffer.items, shdr.sh_offset);4092 try self.base.file.?.pwriteAll(self.hash.buffer.items, shdr.sh_offset);
4178 }4093 }
41794094
4180 if (self.gnu_hash_section_index) |shndx| {4095 if (self.gnu_hash_section_index) |shndx| {
4181 const shdr = self.shdrs.items[shndx];4096 const shdr = slice.items(.shdr)[shndx];
4182 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.gnu_hash.size());4097 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.gnu_hash.size());
4183 defer buffer.deinit();4098 defer buffer.deinit();
4184 try self.gnu_hash.write(self, buffer.writer());4099 try self.gnu_hash.write(self, buffer.writer());
...@@ -4186,12 +4101,12 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4186,12 +4101,12 @@ fn writeSyntheticSections(self: *Elf) !void {
4186 }4101 }
41874102
4188 if (self.versym_section_index) |shndx| {4103 if (self.versym_section_index) |shndx| {
4189 const shdr = self.shdrs.items[shndx];4104 const shdr = slice.items(.shdr)[shndx];
4190 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.versym.items), shdr.sh_offset);4105 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.versym.items), shdr.sh_offset);
4191 }4106 }
41924107
4193 if (self.verneed_section_index) |shndx| {4108 if (self.verneed_section_index) |shndx| {
4194 const shdr = self.shdrs.items[shndx];4109 const shdr = slice.items(.shdr)[shndx];
4195 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.verneed.size());4110 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.verneed.size());
4196 defer buffer.deinit();4111 defer buffer.deinit();
4197 try self.verneed.write(buffer.writer());4112 try self.verneed.write(buffer.writer());
...@@ -4199,7 +4114,7 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4199,7 +4114,7 @@ fn writeSyntheticSections(self: *Elf) !void {
4199 }4114 }
42004115
4201 if (self.dynamic_section_index) |shndx| {4116 if (self.dynamic_section_index) |shndx| {
4202 const shdr = self.shdrs.items[shndx];4117 const shdr = slice.items(.shdr)[shndx];
4203 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynamic.size(self));4118 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynamic.size(self));
4204 defer buffer.deinit();4119 defer buffer.deinit();
4205 try self.dynamic.write(self, buffer.writer());4120 try self.dynamic.write(self, buffer.writer());
...@@ -4207,7 +4122,7 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4207,7 +4122,7 @@ fn writeSyntheticSections(self: *Elf) !void {
4207 }4122 }
42084123
4209 if (self.dynsymtab_section_index) |shndx| {4124 if (self.dynsymtab_section_index) |shndx| {
4210 const shdr = self.shdrs.items[shndx];4125 const shdr = slice.items(.shdr)[shndx];
4211 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynsym.size());4126 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynsym.size());
4212 defer buffer.deinit();4127 defer buffer.deinit();
4213 try self.dynsym.write(self, buffer.writer());4128 try self.dynsym.write(self, buffer.writer());
...@@ -4215,12 +4130,12 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4215,12 +4130,12 @@ fn writeSyntheticSections(self: *Elf) !void {
4215 }4130 }
42164131
4217 if (self.dynstrtab_section_index) |shndx| {4132 if (self.dynstrtab_section_index) |shndx| {
4218 const shdr = self.shdrs.items[shndx];4133 const shdr = slice.items(.shdr)[shndx];
4219 try self.base.file.?.pwriteAll(self.dynstrtab.items, shdr.sh_offset);4134 try self.base.file.?.pwriteAll(self.dynstrtab.items, shdr.sh_offset);
4220 }4135 }
42214136
4222 if (self.eh_frame_section_index) |shndx| {4137 if (self.eh_frame_section_index) |shndx| {
4223 const shdr = self.shdrs.items[shndx];4138 const shdr = slice.items(.shdr)[shndx];
4224 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;4139 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
4225 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);4140 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
4226 defer buffer.deinit();4141 defer buffer.deinit();
...@@ -4229,7 +4144,7 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4229,7 +4144,7 @@ fn writeSyntheticSections(self: *Elf) !void {
4229 }4144 }
42304145
4231 if (self.eh_frame_hdr_section_index) |shndx| {4146 if (self.eh_frame_hdr_section_index) |shndx| {
4232 const shdr = self.shdrs.items[shndx];4147 const shdr = slice.items(.shdr)[shndx];
4233 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;4148 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
4234 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);4149 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
4235 defer buffer.deinit();4150 defer buffer.deinit();
...@@ -4238,7 +4153,7 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4238,7 +4153,7 @@ fn writeSyntheticSections(self: *Elf) !void {
4238 }4153 }
42394154
4240 if (self.got_section_index) |index| {4155 if (self.got_section_index) |index| {
4241 const shdr = self.shdrs.items[index];4156 const shdr = slice.items(.shdr)[index];
4242 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got.size(self));4157 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got.size(self));
4243 defer buffer.deinit();4158 defer buffer.deinit();
4244 try self.got.write(self, buffer.writer());4159 try self.got.write(self, buffer.writer());
...@@ -4246,7 +4161,7 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4246,7 +4161,7 @@ fn writeSyntheticSections(self: *Elf) !void {
4246 }4161 }
42474162
4248 if (self.rela_dyn_section_index) |shndx| {4163 if (self.rela_dyn_section_index) |shndx| {
4249 const shdr = self.shdrs.items[shndx];4164 const shdr = slice.items(.shdr)[shndx];
4250 try self.got.addRela(self);4165 try self.got.addRela(self);
4251 try self.copy_rel.addRela(self);4166 try self.copy_rel.addRela(self);
4252 self.sortRelaDyn();4167 self.sortRelaDyn();
...@@ -4254,7 +4169,7 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4254,7 +4169,7 @@ fn writeSyntheticSections(self: *Elf) !void {
4254 }4169 }
42554170
4256 if (self.plt_section_index) |shndx| {4171 if (self.plt_section_index) |shndx| {
4257 const shdr = self.shdrs.items[shndx];4172 const shdr = slice.items(.shdr)[shndx];
4258 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt.size(self));4173 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt.size(self));
4259 defer buffer.deinit();4174 defer buffer.deinit();
4260 try self.plt.write(self, buffer.writer());4175 try self.plt.write(self, buffer.writer());
...@@ -4262,7 +4177,7 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4262,7 +4177,7 @@ fn writeSyntheticSections(self: *Elf) !void {
4262 }4177 }
42634178
4264 if (self.got_plt_section_index) |shndx| {4179 if (self.got_plt_section_index) |shndx| {
4265 const shdr = self.shdrs.items[shndx];4180 const shdr = slice.items(.shdr)[shndx];
4266 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got_plt.size(self));4181 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got_plt.size(self));
4267 defer buffer.deinit();4182 defer buffer.deinit();
4268 try self.got_plt.write(self, buffer.writer());4183 try self.got_plt.write(self, buffer.writer());
...@@ -4270,7 +4185,7 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4270,7 +4185,7 @@ fn writeSyntheticSections(self: *Elf) !void {
4270 }4185 }
42714186
4272 if (self.plt_got_section_index) |shndx| {4187 if (self.plt_got_section_index) |shndx| {
4273 const shdr = self.shdrs.items[shndx];4188 const shdr = slice.items(.shdr)[shndx];
4274 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt_got.size(self));4189 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt_got.size(self));
4275 defer buffer.deinit();4190 defer buffer.deinit();
4276 try self.plt_got.write(self, buffer.writer());4191 try self.plt_got.write(self, buffer.writer());
...@@ -4278,7 +4193,7 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4278,7 +4193,7 @@ fn writeSyntheticSections(self: *Elf) !void {
4278 }4193 }
42794194
4280 if (self.rela_plt_section_index) |shndx| {4195 if (self.rela_plt_section_index) |shndx| {
4281 const shdr = self.shdrs.items[shndx];4196 const shdr = slice.items(.shdr)[shndx];
4282 try self.plt.addRela(self);4197 try self.plt.addRela(self);
4283 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_plt.items), shdr.sh_offset);4198 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_plt.items), shdr.sh_offset);
4284 }4199 }
...@@ -4287,19 +4202,21 @@ fn writeSyntheticSections(self: *Elf) !void {...@@ -4287,19 +4202,21 @@ fn writeSyntheticSections(self: *Elf) !void {
4287 try self.writeShStrtab();4202 try self.writeShStrtab();
4288}4203}
42894204
4205// FIXME:JK again, why is this needed?
4290pub fn writeShStrtab(self: *Elf) !void {4206pub fn writeShStrtab(self: *Elf) !void {
4291 if (self.shstrtab_section_index) |index| {4207 if (self.shstrtab_section_index) |index| {
4292 const shdr = self.shdrs.items[index];4208 const shdr = self.sections.items(.shdr)[index];
4293 log.debug("writing .shstrtab from 0x{x} to 0x{x}", .{ shdr.sh_offset, shdr.sh_offset + shdr.sh_size });4209 log.debug("writing .shstrtab from 0x{x} to 0x{x}", .{ shdr.sh_offset, shdr.sh_offset + shdr.sh_size });
4294 try self.base.file.?.pwriteAll(self.shstrtab.items, shdr.sh_offset);4210 try self.base.file.?.pwriteAll(self.shstrtab.items, shdr.sh_offset);
4295 }4211 }
4296}4212}
42974213
4298pub fn writeSymtab(self: *Elf) !void {4214pub fn writeSymtab(self: *Elf) !void {
4299 const target = self.base.comp.root_mod.resolved_target.result;
4300 const gpa = self.base.comp.gpa;4215 const gpa = self.base.comp.gpa;
4301 const symtab_shdr = self.shdrs.items[self.symtab_section_index.?];4216 const target = self.getTarget();
4302 const strtab_shdr = self.shdrs.items[self.strtab_section_index.?];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.?];
4303 const sym_size: u64 = switch (self.ptr_width) {4220 const sym_size: u64 = switch (self.ptr_width) {
4304 .p32 => @sizeOf(elf.Elf32_Sym),4221 .p32 => @sizeOf(elf.Elf32_Sym),
4305 .p64 => @sizeOf(elf.Elf64_Sym),4222 .p64 => @sizeOf(elf.Elf64_Sym),
...@@ -4387,9 +4304,9 @@ pub fn writeSymtab(self: *Elf) !void {...@@ -4387,9 +4304,9 @@ pub fn writeSymtab(self: *Elf) !void {
4387}4304}
43884305
4389fn writeSectionSymbols(self: *Elf) void {4306fn writeSectionSymbols(self: *Elf) void {
4307 const slice = self.sections.slice();
4390 var ilocal: u32 = 1;4308 var ilocal: u32 = 1;
4391 for (self.output_sections.keys()) |shndx| {4309 for (slice.items(.shdr), 0..) |shdr, shndx| {
4392 const shdr = self.shdrs.items[shndx];
4393 const out_sym = &self.symtab.items[ilocal];4310 const out_sym = &self.symtab.items[ilocal];
4394 out_sym.* = .{4311 out_sym.* = .{
4395 .st_name = 0,4312 .st_name = 0,
...@@ -4403,7 +4320,7 @@ fn writeSectionSymbols(self: *Elf) void {...@@ -4403,7 +4320,7 @@ fn writeSectionSymbols(self: *Elf) void {
4403 }4320 }
44044321
4405 if (self.eh_frame_section_index) |shndx| {4322 if (self.eh_frame_section_index) |shndx| {
4406 const shdr = self.shdrs.items[shndx];4323 const shdr = slice.items(.shdr)[shndx];
4407 const out_sym = &self.symtab.items[ilocal];4324 const out_sym = &self.symtab.items[ilocal];
4408 out_sym.* = .{4325 out_sym.* = .{
4409 .st_name = 0,4326 .st_name = 0,
...@@ -4418,10 +4335,8 @@ fn writeSectionSymbols(self: *Elf) void {...@@ -4418,10 +4335,8 @@ fn writeSectionSymbols(self: *Elf) void {
4418}4335}
44194336
4420pub fn sectionSymbolOutputSymtabIndex(self: Elf, shndx: u32) u32 {4337pub fn sectionSymbolOutputSymtabIndex(self: Elf, shndx: u32) u32 {
4421 if (self.eh_frame_section_index) |index| {4338 _ = self;
4422 if (index == shndx) return @intCast(self.output_sections.keys().len + 1);4339 return shndx + 1;
4423 }
4424 return @intCast(self.output_sections.getIndex(shndx).? + 1);
4425}4340}
44264341
4427/// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF.4342/// 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 {...@@ -4435,8 +4350,7 @@ pub fn ptrWidthBytes(self: Elf) u8 {
4435/// Does not necessarily match `ptrWidthBytes` for example can be 2 bytes4350/// Does not necessarily match `ptrWidthBytes` for example can be 2 bytes
4436/// in a 32-bit ELF file.4351/// in a 32-bit ELF file.
4437pub fn archPtrWidthBytes(self: Elf) u8 {4352pub fn archPtrWidthBytes(self: Elf) u8 {
4438 const target = self.base.comp.root_mod.resolved_target.result;4353 return @intCast(@divExact(self.getTarget().ptrBitWidth(), 8));
4439 return @intCast(@divExact(target.ptrBitWidth(), 8));
4440}4354}
44414355
4442fn phdrTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr {4356fn phdrTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr {
...@@ -4816,25 +4730,26 @@ pub const AddSectionOpts = struct {...@@ -4816,25 +4730,26 @@ pub const AddSectionOpts = struct {
48164730
4817pub fn addSection(self: *Elf, opts: AddSectionOpts) !u32 {4731pub fn addSection(self: *Elf, opts: AddSectionOpts) !u32 {
4818 const gpa = self.base.comp.gpa;4732 const gpa = self.base.comp.gpa;
4819 const index: u32 = @intCast(self.shdrs.items.len);4733 const index: u32 = @intCast(try self.sections.addOne(gpa));
4820 const shdr = try self.shdrs.addOne(gpa);4734 self.sections.set(index, .{
4821 shdr.* = .{4735 .shdr = .{
4822 .sh_name = opts.name,4736 .sh_name = opts.name,
4823 .sh_type = opts.type,4737 .sh_type = opts.type,
4824 .sh_flags = opts.flags,4738 .sh_flags = opts.flags,
4825 .sh_addr = 0,4739 .sh_addr = 0,
4826 .sh_offset = opts.offset,4740 .sh_offset = opts.offset,
4827 .sh_size = 0,4741 .sh_size = 0,
4828 .sh_link = opts.link,4742 .sh_link = opts.link,
4829 .sh_info = opts.info,4743 .sh_info = opts.info,
4830 .sh_addralign = opts.addralign,4744 .sh_addralign = opts.addralign,
4831 .sh_entsize = opts.entsize,4745 .sh_entsize = opts.entsize,
4832 };4746 },
4747 });
4833 return index;4748 return index;
4834}4749}
48354750
4836pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u32 {4751pub 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| {
4838 const this_name = self.getShString(shdr.sh_name);4753 const this_name = self.getShString(shdr.sh_name);
4839 if (mem.eql(u8, this_name, name)) return @intCast(i);4754 if (mem.eql(u8, this_name, name)) return @intCast(i);
4840 } else return null;4755 } else return null;
...@@ -5012,7 +4927,7 @@ pub fn gotAddress(self: *Elf) i64 {...@@ -5012,7 +4927,7 @@ pub fn gotAddress(self: *Elf) i64 {
5012 break :blk self.got_plt_section_index.?;4927 break :blk self.got_plt_section_index.?;
5013 break :blk if (self.got_section_index) |shndx| shndx else null;4928 break :blk if (self.got_section_index) |shndx| shndx else null;
5014 };4929 };
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;
5016}4931}
50174932
5018pub fn tpAddress(self: *Elf) i64 {4933pub fn tpAddress(self: *Elf) i64 {
...@@ -5366,16 +5281,16 @@ fn fmtDumpState(...@@ -5366,16 +5281,16 @@ fn fmtDumpState(
5366 }5281 }
53675282
5368 try writer.writeAll("\nOutput shdrs\n");5283 try writer.writeAll("\nOutput shdrs\n");
5369 for (self.shdrs.items, 0..) |shdr, shndx| {5284 for (self.sections.items(.shdr), self.sections.items(.phndx), 0..) |shdr, phndx, shndx| {
5370 try writer.print(" shdr({d}) : phdr({?d}) : {}\n", .{5285 try writer.print(" shdr({d}) : phdr({d}) : {}\n", .{
5371 shndx,5286 shndx,
5372 self.phdr_to_shdr_table.get(@intCast(shndx)),5287 phndx,
5373 self.fmtShdr(shdr),5288 self.fmtShdr(shdr),
5374 });5289 });
5375 }5290 }
5376 try writer.writeAll("\nOutput phdrs\n");5291 try writer.writeAll("\nOutput phdrs\n");
5377 for (self.phdrs.items, 0..) |phdr, phndx| {5292 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) });
5379 }5294 }
5380}5295}
53815296
...@@ -5613,7 +5528,11 @@ pub const SymbolResolver = struct {...@@ -5613,7 +5528,11 @@ pub const SymbolResolver = struct {
5613 pub const Index = u32;5528 pub const Index = u32;
5614};5529};
56155530
5616const LastAtomAndFreeList = struct {5531const Section = struct {
5532 shdr: elf.Elf64_Shdr,
5533 phndx: u32 = 0,
5534 atom_list: std.ArrayListUnmanaged(Ref) = .{},
5535
5617 /// Index of the last allocated atom in this section.5536 /// Index of the last allocated atom in this section.
5618 last_atom_index: Atom.Index = 0,5537 last_atom_index: Atom.Index = 0,
56195538
...@@ -5634,13 +5553,6 @@ const LastAtomAndFreeList = struct {...@@ -5634,13 +5553,6 @@ const LastAtomAndFreeList = struct {
5634 /// by 1 byte. It will then have -1 overcapacity.5553 /// by 1 byte. It will then have -1 overcapacity.
5635 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},5554 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},
5636};5555};
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
5645fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {5557fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {
5646 return switch (cpu_arch) {5558 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 {...@@ -48,7 +48,7 @@ pub fn name(self: Atom, elf_file: *Elf) [:0]const u8 {
48}48}
4949
50pub fn address(self: Atom, elf_file: *Elf) i64 {50pub 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];
52 return @as(i64, @intCast(shdr.sh_addr)) + self.value;52 return @as(i64, @intCast(shdr.sh_addr)) + self.value;
53}53}
5454
...@@ -116,10 +116,10 @@ pub fn freeListEligible(self: Atom, elf_file: *Elf) bool {...@@ -116,10 +116,10 @@ pub fn freeListEligible(self: Atom, elf_file: *Elf) bool {
116116
117pub fn allocate(self: *Atom, elf_file: *Elf) !void {117pub fn allocate(self: *Atom, elf_file: *Elf) !void {
118 const zo = elf_file.zigObjectPtr().?;118 const zo = elf_file.zigObjectPtr().?;
119 const shdr = &elf_file.shdrs.items[self.output_section_index];119 const slice = elf_file.sections.slice();
120 const meta = elf_file.last_atom_and_free_list_table.getPtr(self.output_section_index).?;120 const shdr = &slice.items(.shdr)[self.output_section_index];
121 const free_list = &meta.free_list;121 const free_list = &slice.items(.free_list)[self.output_section_index];
122 const last_atom_index = &meta.last_atom_index;122 const last_atom_index = &slice.items(.last_atom_index)[self.output_section_index];
123 const new_atom_ideal_capacity = Elf.padToIdeal(self.size);123 const new_atom_ideal_capacity = Elf.padToIdeal(self.size);
124124
125 // We use these to indicate our intention to update metadata, placing the new atom,125 // 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 {...@@ -254,9 +254,9 @@ pub fn free(self: *Atom, elf_file: *Elf) void {
254 const comp = elf_file.base.comp;254 const comp = elf_file.base.comp;
255 const gpa = comp.gpa;255 const gpa = comp.gpa;
256 const shndx = self.output_section_index;256 const shndx = self.output_section_index;
257 const meta = elf_file.last_atom_and_free_list_table.getPtr(shndx).?;257 const slice = elf_file.sections.slice();
258 const free_list = &meta.free_list;258 const free_list = &slice.items(.free_list)[shndx];
259 const last_atom_index = &meta.last_atom_index;259 const last_atom_index = &slice.items(.last_atom_index)[shndx];
260 var already_have_free_list_node = false;260 var already_have_free_list_node = false;
261 {261 {
262 var i: usize = 0;262 var i: usize = 0;
src/link/Elf/LinkerDefined.zig+17-15
...@@ -129,9 +129,10 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {...@@ -129,9 +129,10 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
129129
130pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void {130pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
131 const gpa = elf_file.base.comp.gpa;131 const gpa = elf_file.base.comp.gpa;
132 const slice = elf_file.sections.slice();
132133
133 var nsyms: usize = 0;134 var nsyms: usize = 0;
134 for (elf_file.shdrs.items) |shdr| {135 for (slice.items(.shdr)) |shdr| {
135 if (elf_file.getStartStopBasename(shdr)) |_| {136 if (elf_file.getStartStopBasename(shdr)) |_| {
136 nsyms += 2; // __start_, __stop_137 nsyms += 2; // __start_, __stop_
137 }138 }
...@@ -143,7 +144,7 @@ pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void {...@@ -143,7 +144,7 @@ pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
143 try self.symbols_extra.ensureUnusedCapacity(gpa, nsyms * @sizeOf(Symbol.Extra));144 try self.symbols_extra.ensureUnusedCapacity(gpa, nsyms * @sizeOf(Symbol.Extra));
144 try self.symbols_resolver.ensureUnusedCapacity(gpa, nsyms);145 try self.symbols_resolver.ensureUnusedCapacity(gpa, nsyms);
145146
146 for (elf_file.shdrs.items) |shdr| {147 for (slice.items(.shdr)) |shdr| {
147 if (elf_file.getStartStopBasename(shdr)) |name| {148 if (elf_file.getStartStopBasename(shdr)) |name| {
148 const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name});149 const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name});
149 defer gpa.free(start_name);150 defer gpa.free(start_name);
...@@ -193,6 +194,7 @@ pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) !void {...@@ -193,6 +194,7 @@ pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
193pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {194pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
194 const comp = elf_file.base.comp;195 const comp = elf_file.base.comp;
195 const link_mode = comp.config.link_mode;196 const link_mode = comp.config.link_mode;
197 const shdrs = elf_file.sections.items(.shdr);
196198
197 const allocSymbol = struct {199 const allocSymbol = struct {
198 fn allocSymbol(ld: *LinkerDefined, index: Symbol.Index, value: u64, osec: u32, ef: *Elf) void {200 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 {...@@ -204,7 +206,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
204206
205 // _DYNAMIC207 // _DYNAMIC
206 if (elf_file.dynamic_section_index) |shndx| {208 if (elf_file.dynamic_section_index) |shndx| {
207 const shdr = &elf_file.shdrs.items[shndx];209 const shdr = shdrs[shndx];
208 allocSymbol(self, self.dynamic_index.?, shdr.sh_addr, shndx, elf_file);210 allocSymbol(self, self.dynamic_index.?, shdr.sh_addr, shndx, elf_file);
209 }211 }
210212
...@@ -213,21 +215,21 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {...@@ -213,21 +215,21 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
213215
214 // __init_array_start, __init_array_end216 // __init_array_start, __init_array_end
215 if (elf_file.sectionByName(".init_array")) |shndx| {217 if (elf_file.sectionByName(".init_array")) |shndx| {
216 const shdr = &elf_file.shdrs.items[shndx];218 const shdr = shdrs[shndx];
217 allocSymbol(self, self.init_array_start_index.?, shdr.sh_addr, shndx, elf_file);219 allocSymbol(self, self.init_array_start_index.?, shdr.sh_addr, shndx, elf_file);
218 allocSymbol(self, self.init_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);220 allocSymbol(self, self.init_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);
219 }221 }
220222
221 // __fini_array_start, __fini_array_end223 // __fini_array_start, __fini_array_end
222 if (elf_file.sectionByName(".fini_array")) |shndx| {224 if (elf_file.sectionByName(".fini_array")) |shndx| {
223 const shdr = &elf_file.shdrs.items[shndx];225 const shdr = shdrs[shndx];
224 allocSymbol(self, self.fini_array_start_index.?, shdr.sh_addr, shndx, elf_file);226 allocSymbol(self, self.fini_array_start_index.?, shdr.sh_addr, shndx, elf_file);
225 allocSymbol(self, self.fini_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);227 allocSymbol(self, self.fini_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);
226 }228 }
227229
228 // __preinit_array_start, __preinit_array_end230 // __preinit_array_start, __preinit_array_end
229 if (elf_file.sectionByName(".preinit_array")) |shndx| {231 if (elf_file.sectionByName(".preinit_array")) |shndx| {
230 const shdr = &elf_file.shdrs.items[shndx];232 const shdr = shdrs[shndx];
231 allocSymbol(self, self.preinit_array_start_index.?, shdr.sh_addr, shndx, elf_file);233 allocSymbol(self, self.preinit_array_start_index.?, shdr.sh_addr, shndx, elf_file);
232 allocSymbol(self, self.preinit_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);234 allocSymbol(self, self.preinit_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);
233 }235 }
...@@ -235,38 +237,38 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {...@@ -235,38 +237,38 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
235 // _GLOBAL_OFFSET_TABLE_237 // _GLOBAL_OFFSET_TABLE_
236 if (elf_file.getTarget().cpu.arch == .x86_64) {238 if (elf_file.getTarget().cpu.arch == .x86_64) {
237 if (elf_file.got_plt_section_index) |shndx| {239 if (elf_file.got_plt_section_index) |shndx| {
238 const shdr = elf_file.shdrs.items[shndx];240 const shdr = shdrs[shndx];
239 allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file);241 allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file);
240 }242 }
241 } else {243 } else {
242 if (elf_file.got_section_index) |shndx| {244 if (elf_file.got_section_index) |shndx| {
243 const shdr = elf_file.shdrs.items[shndx];245 const shdr = shdrs[shndx];
244 allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file);246 allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file);
245 }247 }
246 }248 }
247249
248 // _PROCEDURE_LINKAGE_TABLE_250 // _PROCEDURE_LINKAGE_TABLE_
249 if (elf_file.plt_section_index) |shndx| {251 if (elf_file.plt_section_index) |shndx| {
250 const shdr = &elf_file.shdrs.items[shndx];252 const shdr = shdrs[shndx];
251 allocSymbol(self, self.plt_index.?, shdr.sh_addr, shndx, elf_file);253 allocSymbol(self, self.plt_index.?, shdr.sh_addr, shndx, elf_file);
252 }254 }
253255
254 // __dso_handle256 // __dso_handle
255 if (self.dso_handle_index) |index| {257 if (self.dso_handle_index) |index| {
256 const shdr = &elf_file.shdrs.items[1];258 const shdr = shdrs[1];
257 allocSymbol(self, index, shdr.sh_addr, 0, elf_file);259 allocSymbol(self, index, shdr.sh_addr, 0, elf_file);
258 }260 }
259261
260 // __GNU_EH_FRAME_HDR262 // __GNU_EH_FRAME_HDR
261 if (elf_file.eh_frame_hdr_section_index) |shndx| {263 if (elf_file.eh_frame_hdr_section_index) |shndx| {
262 const shdr = &elf_file.shdrs.items[shndx];264 const shdr = shdrs[shndx];
263 allocSymbol(self, self.gnu_eh_frame_hdr_index.?, shdr.sh_addr, shndx, elf_file);265 allocSymbol(self, self.gnu_eh_frame_hdr_index.?, shdr.sh_addr, shndx, elf_file);
264 }266 }
265267
266 // __rela_iplt_start, __rela_iplt_end268 // __rela_iplt_start, __rela_iplt_end
267 if (elf_file.rela_dyn_section_index) |shndx| blk: {269 if (elf_file.rela_dyn_section_index) |shndx| blk: {
268 if (link_mode != .static or comp.config.pie) break :blk;270 if (link_mode != .static or comp.config.pie) break :blk;
269 const shdr = &elf_file.shdrs.items[shndx];271 const shdr = shdrs[shndx];
270 const end_addr = shdr.sh_addr + shdr.sh_size;272 const end_addr = shdr.sh_addr + shdr.sh_size;
271 const start_addr = end_addr - elf_file.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela);273 const start_addr = end_addr - elf_file.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela);
272 allocSymbol(self, self.rela_iplt_start_index.?, start_addr, shndx, elf_file);274 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 {...@@ -277,7 +279,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
277 {279 {
278 var value: u64 = 0;280 var value: u64 = 0;
279 var osec: u32 = 0;281 var osec: u32 = 0;
280 for (elf_file.shdrs.items, 0..) |shdr, shndx| {282 for (shdrs, 0..) |shdr, shndx| {
281 if (shdr.sh_flags & elf.SHF_ALLOC != 0) {283 if (shdr.sh_flags & elf.SHF_ALLOC != 0) {
282 value = shdr.sh_addr + shdr.sh_size;284 value = shdr.sh_addr + shdr.sh_size;
283 osec = @intCast(shndx);285 osec = @intCast(shndx);
...@@ -289,7 +291,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {...@@ -289,7 +291,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
289 // __global_pointer$291 // __global_pointer$
290 if (self.global_pointer_index) |index| {292 if (self.global_pointer_index) |index| {
291 const value, const osec = if (elf_file.sectionByName(".sdata")) |shndx| .{293 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,
293 shndx,295 shndx,
294 } else .{ 0, 0 };296 } else .{ 0, 0 };
295 allocSymbol(self, index, value, osec, elf_file);297 allocSymbol(self, index, value, osec, elf_file);
...@@ -305,7 +307,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {...@@ -305,7 +307,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
305 const stop_ref = self.resolveSymbol(self.start_stop_indexes.items[index + 1], elf_file);307 const stop_ref = self.resolveSymbol(self.start_stop_indexes.items[index + 1], elf_file);
306 const stop = elf_file.symbol(stop_ref).?;308 const stop = elf_file.symbol(stop_ref).?;
307 const shndx = elf_file.sectionByName(name["__start_".len..]).?;309 const shndx = elf_file.sectionByName(name["__start_".len..]).?;
308 const shdr = &elf_file.shdrs.items[shndx];310 const shdr = shdrs[shndx];
309 start.value = @intCast(shdr.sh_addr);311 start.value = @intCast(shdr.sh_addr);
310 start.output_section_index = shndx;312 start.output_section_index = shndx;
311 stop.value = @intCast(shdr.sh_addr + shdr.sh_size);313 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 {...@@ -998,9 +998,8 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {
998998
999 const comp = elf_file.base.comp;999 const comp = elf_file.base.comp;
1000 const gpa = comp.gpa;1000 const gpa = comp.gpa;
1001 const gop = try elf_file.output_sections.getOrPut(gpa, atom_ptr.output_section_index);1001 const atom_list = &elf_file.sections.items(.atom_list)[atom_ptr.output_section_index];
1002 if (!gop.found_existing) gop.value_ptr.* = .{};1002 try atom_list.append(gpa, .{ .index = atom_index, .file = self.index });
1003 try gop.value_ptr.append(gpa, .{ .index = atom_index, .file = self.index });
1004 }1003 }
1005}1004}
10061005
...@@ -1011,14 +1010,15 @@ pub fn initRelaSections(self: *Object, elf_file: *Elf) !void {...@@ -1011,14 +1010,15 @@ pub fn initRelaSections(self: *Object, elf_file: *Elf) !void {
1011 const shndx = atom_ptr.relocsShndx() orelse continue;1010 const shndx = atom_ptr.relocsShndx() orelse continue;
1012 const shdr = self.shdrs.items[shndx];1011 const shdr = self.shdrs.items[shndx];
1013 const out_shndx = try self.initOutputSection(elf_file, shdr);1012 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;
1015 out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela);1015 out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela);
1016 out_shdr.sh_entsize = @sizeOf(elf.Elf64_Rela);1016 out_shdr.sh_entsize = @sizeOf(elf.Elf64_Rela);
1017 out_shdr.sh_flags |= elf.SHF_INFO_LINK;1017 out_shdr.sh_flags |= elf.SHF_INFO_LINK;
1018 }1018 }
1019}1019}
10201020
1021pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {1021pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) void {
1022 for (self.atoms_indexes.items) |atom_index| {1022 for (self.atoms_indexes.items) |atom_index| {
1023 const atom_ptr = self.atom(atom_index) orelse continue;1023 const atom_ptr = self.atom(atom_index) orelse continue;
1024 if (!atom_ptr.alive) continue;1024 if (!atom_ptr.alive) continue;
...@@ -1027,15 +1027,10 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {...@@ -1027,15 +1027,10 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {
1027 const shdr = self.shdrs.items[shndx];1027 const shdr = self.shdrs.items[shndx];
1028 break :blk self.initOutputSection(elf_file, shdr) catch unreachable;1028 break :blk self.initOutputSection(elf_file, shdr) catch unreachable;
1029 };1029 };
1030 const shdr = &elf_file.shdrs.items[shndx];1030 const slice = elf_file.sections.slice();
1031 const shdr = &slice.items(.shdr)[shndx];
1031 shdr.sh_info = atom_ptr.output_section_index;1032 shdr.sh_info = atom_ptr.output_section_index;
1032 shdr.sh_link = elf_file.symtab_section_index.?;1033 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 });
1039 }1034 }
1040}1035}
10411036
src/link/Elf/Symbol.zig+6-6
...@@ -126,7 +126,7 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true, trampoline: bool...@@ -126,7 +126,7 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true, trampoline: bool
126 const sym_name = symbol.name(elf_file);126 const sym_name = symbol.name(elf_file);
127 const sh_addr, const sh_size = blk: {127 const sh_addr, const sh_size = blk: {
128 const shndx = elf_file.eh_frame_section_index orelse break :blk .{ 0, 0 };128 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];
130 break :blk .{ shdr.sh_addr, shdr.sh_size };130 break :blk .{ shdr.sh_addr, shdr.sh_size };
131 };131 };
132 if (mem.startsWith(u8, sym_name, "__EH_FRAME_BEGIN__") or132 if (mem.startsWith(u8, sym_name, "__EH_FRAME_BEGIN__") or
...@@ -173,7 +173,7 @@ pub fn gotAddress(symbol: Symbol, elf_file: *Elf) i64 {...@@ -173,7 +173,7 @@ pub fn gotAddress(symbol: Symbol, elf_file: *Elf) i64 {
173pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 {173pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 {
174 if (!(symbol.flags.has_plt and symbol.flags.has_got)) return 0;174 if (!(symbol.flags.has_plt and symbol.flags.has_got)) return 0;
175 const extras = symbol.extra(elf_file);175 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.?];
177 const cpu_arch = elf_file.getTarget().cpu.arch;177 const cpu_arch = elf_file.getTarget().cpu.arch;
178 return @intCast(shdr.sh_addr + extras.plt_got * PltGotSection.entrySize(cpu_arch));178 return @intCast(shdr.sh_addr + extras.plt_got * PltGotSection.entrySize(cpu_arch));
179}179}
...@@ -181,7 +181,7 @@ pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 {...@@ -181,7 +181,7 @@ pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 {
181pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 {181pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 {
182 if (!symbol.flags.has_plt) return 0;182 if (!symbol.flags.has_plt) return 0;
183 const extras = symbol.extra(elf_file);183 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.?];
185 const cpu_arch = elf_file.getTarget().cpu.arch;185 const cpu_arch = elf_file.getTarget().cpu.arch;
186 return @intCast(shdr.sh_addr + extras.plt * PltSection.entrySize(cpu_arch) + PltSection.preambleSize(cpu_arch));186 return @intCast(shdr.sh_addr + extras.plt * PltSection.entrySize(cpu_arch) + PltSection.preambleSize(cpu_arch));
187}187}
...@@ -189,13 +189,13 @@ pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 {...@@ -189,13 +189,13 @@ pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 {
189pub fn gotPltAddress(symbol: Symbol, elf_file: *Elf) i64 {189pub fn gotPltAddress(symbol: Symbol, elf_file: *Elf) i64 {
190 if (!symbol.flags.has_plt) return 0;190 if (!symbol.flags.has_plt) return 0;
191 const extras = symbol.extra(elf_file);191 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.?];
193 return @intCast(shdr.sh_addr + extras.plt * 8 + GotPltSection.preamble_size);193 return @intCast(shdr.sh_addr + extras.plt * 8 + GotPltSection.preamble_size);
194}194}
195195
196pub fn copyRelAddress(symbol: Symbol, elf_file: *Elf) i64 {196pub fn copyRelAddress(symbol: Symbol, elf_file: *Elf) i64 {
197 if (!symbol.flags.has_copy_rel) return 0;197 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.?];
199 return @as(i64, @intCast(shdr.sh_addr)) + symbol.value;199 return @as(i64, @intCast(shdr.sh_addr)) + symbol.value;
200}200}
201201
...@@ -300,7 +300,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {...@@ -300,7 +300,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
300 break :blk 0;300 break :blk 0;
301 }301 }
302 if (st_shndx == elf.SHN_ABS or st_shndx == elf.SHN_COMMON) break :blk symbol.address(.{ .plt = false }, elf_file);302 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];
304 if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined)304 if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined)
305 break :blk symbol.address(.{ .plt = false }, elf_file) - elf_file.tlsAddress();305 break :blk symbol.address(.{ .plt = false }, elf_file) - elf_file.tlsAddress();
306 break :blk symbol.address(.{ .plt = false, .trampoline = false }, elf_file);306 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 {...@@ -170,25 +170,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
170 .addralign = 1,170 .addralign = 1,
171 .offset = std.math.maxInt(u64),171 .offset = std.math.maxInt(u64),
172 });172 });
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.?];
174 try fillSection(elf_file, shdr, options.program_code_size_hint, elf_file.phdr_zig_load_re_index);175 try fillSection(elf_file, shdr, options.program_code_size_hint, elf_file.phdr_zig_load_re_index);
175 if (elf_file.base.isRelocatable()) {176 if (elf_file.base.isRelocatable()) {
176 const rela_shndx = try elf_file.addRelaShdr(177 _ = try elf_file.addRelaShdr(
177 try elf_file.insertShString(".rela.text.zig"),178 try elf_file.insertShString(".rela.text.zig"),
178 elf_file.zig_text_section_index.?,179 elf_file.zig_text_section_index.?,
179 );180 );
180 try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{
181 .shndx = rela_shndx,
182 });
183 } else {181 } else {
184 try elf_file.phdr_to_shdr_table.putNoClobber(182 phndx.* = elf_file.phdr_zig_load_re_index.?;
185 gpa,
186 elf_file.zig_text_section_index.?,
187 elf_file.phdr_zig_load_re_index.?,
188 );
189 }183 }
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.?, .{});
192 }184 }
193185
194 if (elf_file.zig_data_rel_ro_section_index == null) {186 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 {...@@ -199,25 +191,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
199 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,191 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
200 .offset = std.math.maxInt(u64),192 .offset = std.math.maxInt(u64),
201 });193 });
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.?];
203 try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_ro_index);196 try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_ro_index);
204 if (elf_file.base.isRelocatable()) {197 if (elf_file.base.isRelocatable()) {
205 const rela_shndx = try elf_file.addRelaShdr(198 _ = try elf_file.addRelaShdr(
206 try elf_file.insertShString(".rela.data.rel.ro.zig"),199 try elf_file.insertShString(".rela.data.rel.ro.zig"),
207 elf_file.zig_data_rel_ro_section_index.?,200 elf_file.zig_data_rel_ro_section_index.?,
208 );201 );
209 try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{
210 .shndx = rela_shndx,
211 });
212 } else {202 } else {
213 try elf_file.phdr_to_shdr_table.putNoClobber(203 phndx.* = elf_file.phdr_zig_load_ro_index.?;
214 gpa,
215 elf_file.zig_data_rel_ro_section_index.?,
216 elf_file.phdr_zig_load_ro_index.?,
217 );
218 }204 }
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.?, .{});
221 }205 }
222206
223 if (elf_file.zig_data_section_index == null) {207 if (elf_file.zig_data_section_index == null) {
...@@ -228,25 +212,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -228,25 +212,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
228 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,212 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
229 .offset = std.math.maxInt(u64),213 .offset = std.math.maxInt(u64),
230 });214 });
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.?];
232 try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_rw_index);217 try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_rw_index);
233 if (elf_file.base.isRelocatable()) {218 if (elf_file.base.isRelocatable()) {
234 const rela_shndx = try elf_file.addRelaShdr(219 _ = try elf_file.addRelaShdr(
235 try elf_file.insertShString(".rela.data.zig"),220 try elf_file.insertShString(".rela.data.zig"),
236 elf_file.zig_data_section_index.?,221 elf_file.zig_data_section_index.?,
237 );222 );
238 try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{
239 .shndx = rela_shndx,
240 });
241 } else {223 } else {
242 try elf_file.phdr_to_shdr_table.putNoClobber(224 phndx.* = elf_file.phdr_zig_load_rw_index.?;
243 gpa,
244 elf_file.zig_data_section_index.?,
245 elf_file.phdr_zig_load_rw_index.?,
246 );
247 }225 }
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.?, .{});
250 }226 }
251227
252 if (elf_file.zig_bss_section_index == null) {228 if (elf_file.zig_bss_section_index == null) {
...@@ -257,17 +233,16 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -257,17 +233,16 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
257 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,233 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
258 .offset = 0,234 .offset = 0,
259 });235 });
260 const shdr = &elf_file.shdrs.items[elf_file.zig_bss_section_index.?];236 const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_bss_section_index.?];
261 if (elf_file.phdr_zig_load_zerofill_index) |phndx| {237 const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_bss_section_index.?];
262 const phdr = elf_file.phdrs.items[phndx];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.*];
263 shdr.sh_addr = phdr.p_vaddr;243 shdr.sh_addr = phdr.p_vaddr;
264 shdr.sh_size = phdr.p_memsz;244 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;
268 }245 }
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.?, .{});
271 }246 }
272247
273 switch (comp.config.debug_format) {248 switch (comp.config.debug_format) {
...@@ -305,7 +280,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -305,7 +280,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
305 });280 });
306 self.debug_str_section_dirty = true;281 self.debug_str_section_dirty = true;
307 self.debug_str_index = try addSectionSymbol(self, gpa, ".debug_str", .@"1", elf_file.debug_str_section_index.?);282 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.?, .{});
309 }283 }
310284
311 if (elf_file.debug_info_section_index == null) {285 if (elf_file.debug_info_section_index == null) {
...@@ -316,7 +290,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -316,7 +290,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
316 });290 });
317 self.debug_info_section_dirty = true;291 self.debug_info_section_dirty = true;
318 self.debug_info_index = try addSectionSymbol(self, gpa, ".debug_info", .@"1", elf_file.debug_info_section_index.?);292 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.?, .{});
320 }293 }
321294
322 if (elf_file.debug_abbrev_section_index == null) {295 if (elf_file.debug_abbrev_section_index == null) {
...@@ -327,7 +300,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -327,7 +300,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
327 });300 });
328 self.debug_abbrev_section_dirty = true;301 self.debug_abbrev_section_dirty = true;
329 self.debug_abbrev_index = try addSectionSymbol(self, gpa, ".debug_abbrev", .@"1", elf_file.debug_abbrev_section_index.?);302 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.?, .{});
331 }303 }
332304
333 if (elf_file.debug_aranges_section_index == null) {305 if (elf_file.debug_aranges_section_index == null) {
...@@ -338,7 +310,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -338,7 +310,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
338 });310 });
339 self.debug_aranges_section_dirty = true;311 self.debug_aranges_section_dirty = true;
340 self.debug_aranges_index = try addSectionSymbol(self, gpa, ".debug_aranges", .@"16", elf_file.debug_aranges_section_index.?);312 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.?, .{});
342 }313 }
343314
344 if (elf_file.debug_line_section_index == null) {315 if (elf_file.debug_line_section_index == null) {
...@@ -349,7 +320,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -349,7 +320,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
349 });320 });
350 self.debug_line_section_dirty = true;321 self.debug_line_section_dirty = true;
351 self.debug_line_index = try addSectionSymbol(self, gpa, ".debug_line", .@"1", elf_file.debug_line_section_index.?);322 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.?, .{});
353 }323 }
354324
355 if (elf_file.debug_line_str_section_index == null) {325 if (elf_file.debug_line_str_section_index == null) {
...@@ -362,7 +332,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -362,7 +332,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
362 });332 });
363 self.debug_line_str_section_dirty = true;333 self.debug_line_str_section_dirty = true;
364 self.debug_line_str_index = try addSectionSymbol(self, gpa, ".debug_line_str", .@"1", elf_file.debug_line_str_section_index.?);334 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.?, .{});
366 }335 }
367336
368 if (elf_file.debug_loclists_section_index == null) {337 if (elf_file.debug_loclists_section_index == null) {
...@@ -373,7 +342,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -373,7 +342,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
373 });342 });
374 self.debug_loclists_section_dirty = true;343 self.debug_loclists_section_dirty = true;
375 self.debug_loclists_index = try addSectionSymbol(self, gpa, ".debug_loclists", .@"1", elf_file.debug_loclists_section_index.?);344 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.?, .{});
377 }345 }
378346
379 if (elf_file.debug_rnglists_section_index == null) {347 if (elf_file.debug_rnglists_section_index == null) {
...@@ -384,7 +352,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {...@@ -384,7 +352,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
384 });352 });
385 self.debug_rnglists_section_dirty = true;353 self.debug_rnglists_section_dirty = true;
386 self.debug_rnglists_index = try addSectionSymbol(self, gpa, ".debug_rnglists", .@"1", elf_file.debug_rnglists_section_index.?);354 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.?, .{});
388 }355 }
389356
390 try dwarf.initMetadata();357 try dwarf.initMetadata();
...@@ -507,7 +474,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi...@@ -507,7 +474,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
507 const atom_ptr = self.atom(sym.ref.index).?;474 const atom_ptr = self.atom(sym.ref.index).?;
508 if (!atom_ptr.alive) continue;475 if (!atom_ptr.alive) continue;
509 const shndx = sym.outputShndx(elf_file).?;476 const shndx = sym.outputShndx(elf_file).?;
510 const shdr = elf_file.shdrs.items[shndx];477 const shdr = elf_file.sections.items(.shdr)[shndx];
511 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];478 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
512 esym.st_size = shdr.sh_size;479 esym.st_size = shdr.sh_size;
513 atom_ptr.size = shdr.sh_size;480 atom_ptr.size = shdr.sh_size;
...@@ -667,13 +634,10 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi...@@ -667,13 +634,10 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
667 }634 }
668635
669 if (elf_file.base.isRelocatable() and relocs.items.len > 0) {636 if (elf_file.base.isRelocatable() and relocs.items.len > 0) {
670 const gop = try elf_file.output_rela_sections.getOrPut(gpa, shndx);637 const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)});
671 if (!gop.found_existing) {638 defer gpa.free(rela_sect_name);
672 const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)});639 if (elf_file.sectionByName(rela_sect_name) == null) {
673 defer gpa.free(rela_sect_name);640 _ = try elf_file.addRelaShdr(try elf_file.insertShString(rela_sect_name), shndx);
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 };
677 }641 }
678 }642 }
679 }643 }
...@@ -769,7 +733,7 @@ fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Sym...@@ -769,7 +733,7 @@ fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Sym
769pub fn inputShdr(self: *ZigObject, atom_index: Atom.Index, elf_file: *Elf) elf.Elf64_Shdr {733pub fn inputShdr(self: *ZigObject, atom_index: Atom.Index, elf_file: *Elf) elf.Elf64_Shdr {
770 const atom_ptr = self.atom(atom_index) orelse return Elf.null_shdr;734 const atom_ptr = self.atom(atom_index) orelse return Elf.null_shdr;
771 const shndx = atom_ptr.output_section_index;735 const shndx = atom_ptr.output_section_index;
772 var shdr = elf_file.shdrs.items[shndx];736 var shdr = elf_file.sections.items(.shdr)[shndx];
773 shdr.sh_addr = 0;737 shdr.sh_addr = 0;
774 shdr.sh_offset = 0;738 shdr.sh_offset = 0;
775 shdr.sh_size = atom_ptr.size;739 shdr.sh_size = atom_ptr.size;
...@@ -947,8 +911,8 @@ pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void {...@@ -947,8 +911,8 @@ pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void {
947 .p32 => @sizeOf(elf.Elf32_Shdr),911 .p32 => @sizeOf(elf.Elf32_Shdr),
948 .p64 => @sizeOf(elf.Elf64_Shdr),912 .p64 => @sizeOf(elf.Elf64_Shdr),
949 };913 };
950 var end_pos: u64 = elf_file.shdr_table_offset.? + elf_file.shdrs.items.len * shsize;914 var end_pos: u64 = elf_file.shdr_table_offset.? + elf_file.sections.items(.shdr).len * shsize;
951 for (elf_file.shdrs.items) |shdr| {915 for (elf_file.sections.items(.shdr)) |shdr| {
952 if (shdr.sh_type == elf.SHT_NOBITS) continue;916 if (shdr.sh_type == elf.SHT_NOBITS) continue;
953 end_pos = @max(end_pos, shdr.sh_offset + shdr.sh_size);917 end_pos = @max(end_pos, shdr.sh_offset + shdr.sh_size);
954 }918 }
...@@ -1001,12 +965,11 @@ pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void {...@@ -1001,12 +965,11 @@ pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void {
1001 // TODO this check will become obsolete when we rework our relocs mechanism at the ZigObject level965 // TODO this check will become obsolete when we rework our relocs mechanism at the ZigObject level
1002 if (self.relocs.items[rela_shndx].items.len == 0) continue;966 if (self.relocs.items[rela_shndx].items.len == 0) continue;
1003 const out_shndx = atom_ptr.output_section_index;967 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];
1005 if (out_shdr.sh_type == elf.SHT_NOBITS) continue;969 if (out_shdr.sh_type == elf.SHT_NOBITS) continue;
1006970 const atom_list = &elf_file.sections.items(.atom_list)[out_shndx];
1007 const gpa = elf_file.base.comp.gpa;971 const gpa = elf_file.base.comp.gpa;
1008 const sec = elf_file.output_rela_sections.getPtr(out_shndx).?;972 try atom_list.append(gpa, .{ .index = atom_index, .file = self.index });
1009 try sec.atom_list.append(gpa, .{ .index = atom_index, .file = self.index });
1010 }973 }
1011}974}
1012975
...@@ -1076,7 +1039,7 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void {...@@ -1076,7 +1039,7 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void {
1076pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 {1039pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 {
1077 const gpa = elf_file.base.comp.gpa;1040 const gpa = elf_file.base.comp.gpa;
1078 const atom_ptr = self.atom(atom_index).?;1041 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
1081 if (shdr.sh_flags & elf.SHF_TLS != 0) {1044 if (shdr.sh_flags & elf.SHF_TLS != 0) {
1082 const tlv = self.tls_variables.get(atom_index).?;1045 const tlv = self.tls_variables.get(atom_index).?;
...@@ -1403,7 +1366,7 @@ fn updateNavCode(...@@ -1403,7 +1366,7 @@ fn updateNavCode(
1403 }1366 }
1404 }1367 }
14051368
1406 const shdr = elf_file.shdrs.items[shdr_index];1369 const shdr = elf_file.sections.items(.shdr)[shdr_index];
1407 if (shdr.sh_type != elf.SHT_NOBITS) {1370 if (shdr.sh_type != elf.SHT_NOBITS) {
1408 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));1371 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
1409 try elf_file.base.file.?.pwriteAll(code, file_offset);1372 try elf_file.base.file.?.pwriteAll(code, file_offset);
...@@ -1458,16 +1421,13 @@ fn updateTlv(...@@ -1458,16 +1421,13 @@ fn updateTlv(
1458 gop.value_ptr.* = .{ .symbol_index = sym_index };1421 gop.value_ptr.* = .{ .symbol_index = sym_index };
14591422
1460 // We only store the data for the TLV if it's non-zerofill.1423 // 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) {
1462 gop.value_ptr.code = try gpa.dupe(u8, code);1425 gop.value_ptr.code = try gpa.dupe(u8, code);
1463 }1426 }
1464 }1427 }
14651428
1466 {1429 const atom_list = &elf_file.sections.items(.atom_list)[atom_ptr.output_section_index];
1467 const gop = try elf_file.output_sections.getOrPut(gpa, atom_ptr.output_section_index);1430 try atom_list.append(gpa, .{ .index = atom_ptr.atom_index, .file = self.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 }
1471}1431}
14721432
1473pub fn updateFunc(1433pub fn updateFunc(
...@@ -1519,7 +1479,7 @@ pub fn updateFunc(...@@ -1519,7 +1479,7 @@ pub fn updateFunc(
1519 const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code);1479 const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code);
1520 log.debug("setting shdr({x},{s}) for {}", .{1480 log.debug("setting shdr({x},{s}) for {}", .{
1521 shndx,1481 shndx,
1522 elf_file.getShString(elf_file.shdrs.items[shndx].sh_name),1482 elf_file.getShString(elf_file.sections.items(.shdr)[shndx].sh_name),
1523 ip.getNav(func.owner_nav).fqn.fmt(ip),1483 ip.getNav(func.owner_nav).fqn.fmt(ip),
1524 });1484 });
1525 const old_rva, const old_alignment = blk: {1485 const old_rva, const old_alignment = blk: {
...@@ -1647,10 +1607,10 @@ pub fn updateNav(...@@ -1647,10 +1607,10 @@ pub fn updateNav(
1647 const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code);1607 const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code);
1648 log.debug("setting shdr({x},{s}) for {}", .{1608 log.debug("setting shdr({x},{s}) for {}", .{
1649 shndx,1609 shndx,
1650 elf_file.getShString(elf_file.shdrs.items[shndx].sh_name),1610 elf_file.getShString(elf_file.sections.items(.shdr)[shndx].sh_name),
1651 nav.fqn.fmt(ip),1611 nav.fqn.fmt(ip),
1652 });1612 });
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)
1654 try self.updateTlv(elf_file, pt, nav_index, sym_index, shndx, code)1614 try self.updateTlv(elf_file, pt, nav_index, sym_index, shndx, code)
1655 else1615 else
1656 try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT);1616 try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT);
...@@ -1749,7 +1709,7 @@ fn updateLazySymbol(...@@ -1749,7 +1709,7 @@ fn updateLazySymbol(
1749 local_sym.value = 0;1709 local_sym.value = 0;
1750 local_esym.st_value = 0;1710 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];
1753 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));1713 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
1754 try elf_file.base.file.?.pwriteAll(code, file_offset);1714 try elf_file.base.file.?.pwriteAll(code, file_offset);
1755}1715}
...@@ -1805,7 +1765,7 @@ fn lowerConst(...@@ -1805,7 +1765,7 @@ fn lowerConst(
1805 // TODO rename and re-audit this method1765 // TODO rename and re-audit this method
1806 errdefer self.freeNavMetadata(elf_file, sym_index);1766 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];
1809 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));1769 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
1810 try elf_file.base.file.?.pwriteAll(code, file_offset);1770 try elf_file.base.file.?.pwriteAll(code, file_offset);
18111771
...@@ -1969,7 +1929,7 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) u64 {...@@ -1969,7 +1929,7 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) u64 {
19691929
1970fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void {1930fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void {
1971 const atom_ptr = tr_sym.atom(elf_file).?;1931 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];
1973 const fileoff = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));1933 const fileoff = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
1974 const source_addr = tr_sym.address(.{}, elf_file);1934 const source_addr = tr_sym.address(.{}, elf_file);
1975 const target_addr = target.address(.{ .trampoline = false }, elf_file);1935 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 {...@@ -13,7 +13,7 @@ pub const Fde = struct {
1313
14 pub fn address(fde: Fde, elf_file: *Elf) u64 {14 pub fn address(fde: Fde, elf_file: *Elf) u64 {
15 const base: u64 = if (elf_file.eh_frame_section_index) |shndx|15 const base: u64 = if (elf_file.eh_frame_section_index) |shndx|
16 elf_file.shdrs.items[shndx].sh_addr16 elf_file.sections.items(.shdr)[shndx].sh_addr
17 else17 else
18 0;18 0;
19 return base + fde.out_offset;19 return base + fde.out_offset;
...@@ -112,7 +112,7 @@ pub const Cie = struct {...@@ -112,7 +112,7 @@ pub const Cie = struct {
112112
113 pub fn address(cie: Cie, elf_file: *Elf) u64 {113 pub fn address(cie: Cie, elf_file: *Elf) u64 {
114 const base: u64 = if (elf_file.eh_frame_section_index) |shndx|114 const base: u64 = if (elf_file.eh_frame_section_index) |shndx|
115 elf_file.shdrs.items[shndx].sh_addr115 elf_file.sections.items(.shdr)[shndx].sh_addr
116 else116 else
117 0;117 0;
118 return base + cie.out_offset;118 return base + cie.out_offset;
...@@ -326,7 +326,9 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file:...@@ -326,7 +326,9 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file:
326}326}
327327
328pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {328pub 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
331 var has_reloc_errors = false;333 var has_reloc_errors = false;
332334
...@@ -446,7 +448,9 @@ fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Re...@@ -446,7 +448,9 @@ fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Re
446}448}
447449
448pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void {450pub 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
451 for (elf_file.objects.items) |index| {455 for (elf_file.objects.items) |index| {
452 const object = elf_file.file(index).?.object;456 const object = elf_file.file(index).?.object;
...@@ -482,8 +486,9 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {...@@ -482,8 +486,9 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {
482 try writer.writeByte(EH_PE.udata4);486 try writer.writeByte(EH_PE.udata4);
483 try writer.writeByte(EH_PE.datarel | EH_PE.sdata4);487 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.?];489 const shdrs = elf_file.sections.items(.shdr);
486 const eh_frame_hdr_shdr = elf_file.shdrs.items[elf_file.eh_frame_hdr_section_index.?];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.?];
487 const num_fdes = @as(u32, @intCast(@divExact(eh_frame_hdr_shdr.sh_size - eh_frame_hdr_header_size, 8)));492 const num_fdes = @as(u32, @intCast(@divExact(eh_frame_hdr_shdr.sh_size - eh_frame_hdr_header_size, 8)));
488 try writer.writeInt(493 try writer.writeInt(
489 u32,494 u32,
src/link/Elf/merge_section.zig+2-4
...@@ -29,7 +29,7 @@ pub const MergeSection = struct {...@@ -29,7 +29,7 @@ pub const MergeSection = struct {
29 }29 }
3030
31 pub fn address(msec: MergeSection, elf_file: *Elf) i64 {31 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];
33 return @intCast(shdr.sh_addr + msec.value);33 return @intCast(shdr.sh_addr + msec.value);
34 }34 }
3535
...@@ -108,13 +108,11 @@ pub const MergeSection = struct {...@@ -108,13 +108,11 @@ pub const MergeSection = struct {
108 }108 }
109109
110 pub fn initOutputSection(msec: *MergeSection, elf_file: *Elf) !void {110 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(.{
112 .name = msec.name_offset,112 .name = msec.name_offset,
113 .type = msec.type,113 .type = msec.type,
114 .flags = msec.flags,114 .flags = msec.flags,
115 });115 });
116 try elf_file.output_sections.put(elf_file.base.comp.gpa, shndx, .{});
117 msec.output_section_index = shndx;
118 }116 }
119117
120 pub fn addMergeSubsection(msec: *MergeSection, allocator: Allocator) !MergeSubsection.Index {118 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...@@ -209,7 +209,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]const
209 for (elf_file.objects.items) |index| {209 for (elf_file.objects.items) |index| {
210 const object = elf_file.file(index).?.object;210 const object = elf_file.file(index).?.object;
211 try object.addAtomsToOutputSections(elf_file);211 try object.addAtomsToOutputSections(elf_file);
212 try object.addAtomsToRelaSections(elf_file);212 object.addAtomsToRelaSections(elf_file);
213 }213 }
214 try elf_file.updateMergeSectionSizes();214 try elf_file.updateMergeSectionSizes();
215 try updateSectionSizes(elf_file);215 try updateSectionSizes(elf_file);
...@@ -347,36 +347,37 @@ fn initComdatGroups(elf_file: *Elf) !void {...@@ -347,36 +347,37 @@ fn initComdatGroups(elf_file: *Elf) !void {
347}347}
348348
349fn updateSectionSizes(elf_file: *Elf) !void {349fn updateSectionSizes(elf_file: *Elf) !void {
350 for (elf_file.output_sections.keys(), elf_file.output_sections.values()) |shndx, atom_list| {350 const slice = elf_file.sections.slice();
351 const shdr = &elf_file.shdrs.items[shndx];351 for (slice.items(.shdr), 0..) |*shdr, shndx| {
352 for (atom_list.items) |ref| {352 if (shdr.sh_type != elf.SHT_RELA) {
353 const atom_ptr = elf_file.atom(ref) orelse continue;353 const atom_list = slice.items(.atom_list)[shndx];
354 if (!atom_ptr.alive) continue;354 for (atom_list.items) |ref| {
355 const offset = atom_ptr.alignment.forward(shdr.sh_size);355 const atom_ptr = elf_file.atom(ref) orelse continue;
356 const padding = offset - shdr.sh_size;356 if (!atom_ptr.alive) continue;
357 atom_ptr.value = @intCast(offset);357 const offset = atom_ptr.alignment.forward(shdr.sh_size);
358 shdr.sh_size += padding + atom_ptr.size;358 const padding = offset - shdr.sh_size;
359 shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits() orelse 1);359 atom_ptr.value = @intCast(offset);
360 }360 shdr.sh_size += padding + atom_ptr.size;
361 }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| {372 if (shdr.sh_size == 0) shdr.sh_offset = 0;
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;
370 }373 }
371
372 if (shdr.sh_size == 0) shdr.sh_offset = 0;
373 }374 }
374375
375 if (elf_file.eh_frame_section_index) |index| {376 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);
377 }378 }
378 if (elf_file.eh_frame_rela_section_index) |index| {379 if (elf_file.eh_frame_rela_section_index) |index| {
379 const shdr = &elf_file.shdrs.items[index];380 const shdr = &slice.items(.shdr)[index];
380 shdr.sh_size = eh_frame.calcEhFrameRelocs(elf_file) * shdr.sh_entsize;381 shdr.sh_size = eh_frame.calcEhFrameRelocs(elf_file) * shdr.sh_entsize;
381 }382 }
382383
...@@ -387,7 +388,7 @@ fn updateSectionSizes(elf_file: *Elf) !void {...@@ -387,7 +388,7 @@ fn updateSectionSizes(elf_file: *Elf) !void {
387388
388fn updateComdatGroupsSizes(elf_file: *Elf) void {389fn updateComdatGroupsSizes(elf_file: *Elf) void {
389 for (elf_file.comdat_group_sections.items) |cg| {390 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];
391 shdr.sh_size = cg.size(elf_file);392 shdr.sh_size = cg.size(elf_file);
392 shdr.sh_link = elf_file.symtab_section_index.?;393 shdr.sh_link = elf_file.symtab_section_index.?;
393394
...@@ -399,7 +400,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void {...@@ -399,7 +400,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void {
399400
400/// Allocates alloc sections when merging relocatable objects files together.401/// Allocates alloc sections when merging relocatable objects files together.
401fn allocateAllocSections(elf_file: *Elf) !void {402fn allocateAllocSections(elf_file: *Elf) !void {
402 for (elf_file.shdrs.items) |*shdr| {403 for (elf_file.sections.items(.shdr)) |*shdr| {
403 if (shdr.sh_type == elf.SHT_NULL) continue;404 if (shdr.sh_type == elf.SHT_NULL) continue;
404 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;405 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
405 if (shdr.sh_type == elf.SHT_NOBITS) {406 if (shdr.sh_type == elf.SHT_NOBITS) {
...@@ -418,13 +419,13 @@ fn allocateAllocSections(elf_file: *Elf) !void {...@@ -418,13 +419,13 @@ fn allocateAllocSections(elf_file: *Elf) !void {
418419
419fn writeAtoms(elf_file: *Elf) !void {420fn writeAtoms(elf_file: *Elf) !void {
420 const gpa = elf_file.base.comp.gpa;421 const gpa = elf_file.base.comp.gpa;
422 const slice = elf_file.sections.slice();
421423
422 // TODO iterate over `output_sections` directly424 // 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| {
424 if (shdr.sh_type == elf.SHT_NULL) continue;426 if (shdr.sh_type == elf.SHT_NULL) continue;
425 if (shdr.sh_type == elf.SHT_NOBITS) continue;427 if (shdr.sh_type == elf.SHT_NOBITS) continue;
426428 if (shdr.sh_type == elf.SHT_RELA) continue;
427 const atom_list = elf_file.output_sections.get(@intCast(shndx)) orelse continue;
428 if (atom_list.items.len == 0) continue;429 if (atom_list.items.len == 0) continue;
429430
430 log.debug("writing atoms in '{s}' section", .{elf_file.getShString(shdr.sh_name)});431 log.debug("writing atoms in '{s}' section", .{elf_file.getShString(shdr.sh_name)});
...@@ -490,18 +491,19 @@ fn writeAtoms(elf_file: *Elf) !void {...@@ -490,18 +491,19 @@ fn writeAtoms(elf_file: *Elf) !void {
490491
491fn writeSyntheticSections(elf_file: *Elf) !void {492fn writeSyntheticSections(elf_file: *Elf) !void {
492 const gpa = elf_file.base.comp.gpa;493 const gpa = elf_file.base.comp.gpa;
494 const slice = elf_file.sections.slice();
493495
494 for (elf_file.output_rela_sections.values()) |sec| {496 for (slice.items(.shdr)) |shdr| {
495 if (sec.atom_list.items.len == 0) continue;497 if (shdr.sh_type != elf.SHT_RELA) continue;
496498 const atom_list = slice.items(.atom_list)[shdr.sh_info];
497 const shdr = elf_file.shdrs.items[sec.shndx];499 if (atom_list.items.len == 0) continue;
498500
499 const num_relocs = math.cast(usize, @divExact(shdr.sh_size, shdr.sh_entsize)) orelse501 const num_relocs = math.cast(usize, @divExact(shdr.sh_size, shdr.sh_entsize)) orelse
500 return error.Overflow;502 return error.Overflow;
501 var relocs = try std.ArrayList(elf.Elf64_Rela).initCapacity(gpa, num_relocs);503 var relocs = try std.ArrayList(elf.Elf64_Rela).initCapacity(gpa, num_relocs);
502 defer relocs.deinit();504 defer relocs.deinit();
503505
504 for (sec.atom_list.items) |ref| {506 for (atom_list.items) |ref| {
505 const atom_ptr = elf_file.atom(ref) orelse continue;507 const atom_ptr = elf_file.atom(ref) orelse continue;
506 if (!atom_ptr.alive) continue;508 if (!atom_ptr.alive) continue;
507 try atom_ptr.writeRelocs(elf_file, &relocs);509 try atom_ptr.writeRelocs(elf_file, &relocs);
...@@ -527,7 +529,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {...@@ -527,7 +529,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {
527 }529 }
528530
529 if (elf_file.eh_frame_section_index) |shndx| {531 if (elf_file.eh_frame_section_index) |shndx| {
530 const shdr = elf_file.shdrs.items[shndx];532 const shdr = slice.items(.shdr)[shndx];
531 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;533 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
532 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);534 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
533 defer buffer.deinit();535 defer buffer.deinit();
...@@ -540,7 +542,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {...@@ -540,7 +542,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {
540 try elf_file.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);542 try elf_file.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
541 }543 }
542 if (elf_file.eh_frame_rela_section_index) |shndx| {544 if (elf_file.eh_frame_rela_section_index) |shndx| {
543 const shdr = elf_file.shdrs.items[shndx];545 const shdr = slice.items(.shdr)[shndx];
544 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;546 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
545 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);547 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
546 defer buffer.deinit();548 defer buffer.deinit();
...@@ -561,7 +563,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {...@@ -561,7 +563,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {
561fn writeComdatGroups(elf_file: *Elf) !void {563fn writeComdatGroups(elf_file: *Elf) !void {
562 const gpa = elf_file.base.comp.gpa;564 const gpa = elf_file.base.comp.gpa;
563 for (elf_file.comdat_group_sections.items) |cgs| {565 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];
565 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;567 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
566 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);568 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
567 defer buffer.deinit();569 defer buffer.deinit();
src/link/Elf/synthetic_sections.zig+30-22
...@@ -95,6 +95,8 @@ pub const DynamicSection = struct {...@@ -95,6 +95,8 @@ pub const DynamicSection = struct {
95 }95 }
9696
97 pub fn write(dt: DynamicSection, elf_file: *Elf, writer: anytype) !void {97 pub fn write(dt: DynamicSection, elf_file: *Elf, writer: anytype) !void {
98 const shdrs = elf_file.sections.items(.shdr);
99
98 // NEEDED100 // NEEDED
99 for (dt.needed.items) |off| {101 for (dt.needed.items) |off| {
100 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NEEDED, .d_val = off });102 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NEEDED, .d_val = off });
...@@ -112,33 +114,33 @@ pub const DynamicSection = struct {...@@ -112,33 +114,33 @@ pub const DynamicSection = struct {
112114
113 // INIT115 // INIT
114 if (elf_file.sectionByName(".init")) |shndx| {116 if (elf_file.sectionByName(".init")) |shndx| {
115 const addr = elf_file.shdrs.items[shndx].sh_addr;117 const addr = shdrs[shndx].sh_addr;
116 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT, .d_val = addr });118 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT, .d_val = addr });
117 }119 }
118120
119 // FINI121 // FINI
120 if (elf_file.sectionByName(".fini")) |shndx| {122 if (elf_file.sectionByName(".fini")) |shndx| {
121 const addr = elf_file.shdrs.items[shndx].sh_addr;123 const addr = shdrs[shndx].sh_addr;
122 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI, .d_val = addr });124 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI, .d_val = addr });
123 }125 }
124126
125 // INIT_ARRAY127 // INIT_ARRAY
126 if (elf_file.sectionByName(".init_array")) |shndx| {128 if (elf_file.sectionByName(".init_array")) |shndx| {
127 const shdr = elf_file.shdrs.items[shndx];129 const shdr = shdrs[shndx];
128 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAY, .d_val = shdr.sh_addr });130 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAY, .d_val = shdr.sh_addr });
129 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAYSZ, .d_val = shdr.sh_size });131 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAYSZ, .d_val = shdr.sh_size });
130 }132 }
131133
132 // FINI_ARRAY134 // FINI_ARRAY
133 if (elf_file.sectionByName(".fini_array")) |shndx| {135 if (elf_file.sectionByName(".fini_array")) |shndx| {
134 const shdr = elf_file.shdrs.items[shndx];136 const shdr = shdrs[shndx];
135 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAY, .d_val = shdr.sh_addr });137 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAY, .d_val = shdr.sh_addr });
136 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAYSZ, .d_val = shdr.sh_size });138 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAYSZ, .d_val = shdr.sh_size });
137 }139 }
138140
139 // RELA141 // RELA
140 if (elf_file.rela_dyn_section_index) |shndx| {142 if (elf_file.rela_dyn_section_index) |shndx| {
141 const shdr = elf_file.shdrs.items[shndx];143 const shdr = shdrs[shndx];
142 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELA, .d_val = shdr.sh_addr });144 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELA, .d_val = shdr.sh_addr });
143 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELASZ, .d_val = shdr.sh_size });145 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELASZ, .d_val = shdr.sh_size });
144 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELAENT, .d_val = shdr.sh_entsize });146 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELAENT, .d_val = shdr.sh_entsize });
...@@ -146,7 +148,7 @@ pub const DynamicSection = struct {...@@ -146,7 +148,7 @@ pub const DynamicSection = struct {
146148
147 // JMPREL149 // JMPREL
148 if (elf_file.rela_plt_section_index) |shndx| {150 if (elf_file.rela_plt_section_index) |shndx| {
149 const shdr = elf_file.shdrs.items[shndx];151 const shdr = shdrs[shndx];
150 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_JMPREL, .d_val = shdr.sh_addr });152 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_JMPREL, .d_val = shdr.sh_addr });
151 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTRELSZ, .d_val = shdr.sh_size });153 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTRELSZ, .d_val = shdr.sh_size });
152 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTREL, .d_val = elf.DT_RELA });154 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTREL, .d_val = elf.DT_RELA });
...@@ -154,18 +156,18 @@ pub const DynamicSection = struct {...@@ -154,18 +156,18 @@ pub const DynamicSection = struct {
154156
155 // PLTGOT157 // PLTGOT
156 if (elf_file.got_plt_section_index) |shndx| {158 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;
158 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTGOT, .d_val = addr });160 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTGOT, .d_val = addr });
159 }161 }
160162
161 {163 {
162 assert(elf_file.hash_section_index != null);164 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;
164 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_HASH, .d_val = addr });166 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_HASH, .d_val = addr });
165 }167 }
166168
167 if (elf_file.gnu_hash_section_index) |shndx| {169 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;
169 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_GNU_HASH, .d_val = addr });171 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_GNU_HASH, .d_val = addr });
170 }172 }
171173
...@@ -177,7 +179,7 @@ pub const DynamicSection = struct {...@@ -177,7 +179,7 @@ pub const DynamicSection = struct {
177 // SYMTAB + SYMENT179 // SYMTAB + SYMENT
178 {180 {
179 assert(elf_file.dynsymtab_section_index != null);181 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.?];
181 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMTAB, .d_val = shdr.sh_addr });183 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMTAB, .d_val = shdr.sh_addr });
182 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMENT, .d_val = shdr.sh_entsize });184 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMENT, .d_val = shdr.sh_entsize });
183 }185 }
...@@ -185,20 +187,20 @@ pub const DynamicSection = struct {...@@ -185,20 +187,20 @@ pub const DynamicSection = struct {
185 // STRTAB + STRSZ187 // STRTAB + STRSZ
186 {188 {
187 assert(elf_file.dynstrtab_section_index != null);189 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.?];
189 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRTAB, .d_val = shdr.sh_addr });191 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRTAB, .d_val = shdr.sh_addr });
190 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRSZ, .d_val = shdr.sh_size });192 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRSZ, .d_val = shdr.sh_size });
191 }193 }
192194
193 // VERSYM195 // VERSYM
194 if (elf_file.versym_section_index) |shndx| {196 if (elf_file.versym_section_index) |shndx| {
195 const addr = elf_file.shdrs.items[shndx].sh_addr;197 const addr = shdrs[shndx].sh_addr;
196 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERSYM, .d_val = addr });198 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERSYM, .d_val = addr });
197 }199 }
198200
199 // VERNEED + VERNEEDNUM201 // VERNEED + VERNEEDNUM
200 if (elf_file.verneed_section_index) |shndx| {202 if (elf_file.verneed_section_index) |shndx| {
201 const addr = elf_file.shdrs.items[shndx].sh_addr;203 const addr = shdrs[shndx].sh_addr;
202 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERNEED, .d_val = addr });204 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERNEED, .d_val = addr });
203 try writer.writeStruct(elf.Elf64_Dyn{205 try writer.writeStruct(elf.Elf64_Dyn{
204 .d_tag = elf.DT_VERNEEDNUM,206 .d_tag = elf.DT_VERNEEDNUM,
...@@ -259,7 +261,7 @@ pub const GotSection = struct {...@@ -259,7 +261,7 @@ pub const GotSection = struct {
259261
260 pub fn address(entry: Entry, elf_file: *Elf) i64 {262 pub fn address(entry: Entry, elf_file: *Elf) i64 {
261 const ptr_bytes = elf_file.archPtrWidthBytes();263 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.?];
263 return @as(i64, @intCast(shdr.sh_addr)) + entry.cell_index * ptr_bytes;265 return @as(i64, @intCast(shdr.sh_addr)) + entry.cell_index * ptr_bytes;
264 }266 }
265 };267 };
...@@ -759,8 +761,9 @@ pub const PltSection = struct {...@@ -759,8 +761,9 @@ pub const PltSection = struct {
759761
760 const x86_64 = struct {762 const x86_64 = struct {
761 fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void {763 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;764 const shdrs = elf_file.sections.items(.shdr);
763 const got_plt_addr = elf_file.shdrs.items[elf_file.got_plt_section_index.?].sh_addr;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;
764 var preamble = [_]u8{767 var preamble = [_]u8{
765 0xf3, 0x0f, 0x1e, 0xfa, // endbr64768 0xf3, 0x0f, 0x1e, 0xfa, // endbr64
766 0x41, 0x53, // push r11769 0x41, 0x53, // push r11
...@@ -794,8 +797,9 @@ pub const PltSection = struct {...@@ -794,8 +797,9 @@ pub const PltSection = struct {
794 const aarch64 = struct {797 const aarch64 = struct {
795 fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void {798 fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void {
796 {799 {
797 const plt_addr: i64 = @intCast(elf_file.shdrs.items[elf_file.plt_section_index.?].sh_addr);800 const shdrs = elf_file.sections.items(.shdr);
798 const got_plt_addr: i64 = @intCast(elf_file.shdrs.items[elf_file.got_plt_section_index.?].sh_addr);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);
799 // TODO: relax if possible803 // TODO: relax if possible
800 // .got.plt[2]804 // .got.plt[2]
801 const pages = try aarch64_util.calcNumberOfPages(plt_addr + 4, got_plt_addr + 16);805 const pages = try aarch64_util.calcNumberOfPages(plt_addr + 4, got_plt_addr + 16);
...@@ -869,7 +873,7 @@ pub const GotPltSection = struct {...@@ -869,7 +873,7 @@ pub const GotPltSection = struct {
869 try writer.writeInt(u64, 0x0, .little);873 try writer.writeInt(u64, 0x0, .little);
870 try writer.writeInt(u64, 0x0, .little);874 try writer.writeInt(u64, 0x0, .little);
871 if (elf_file.plt_section_index) |shndx| {875 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;
873 for (0..elf_file.plt.symbols.items.len) |_| {877 for (0..elf_file.plt.symbols.items.len) |_| {
874 // [N]: .plt878 // [N]: .plt
875 try writer.writeInt(u64, plt_addr, .little);879 try writer.writeInt(u64, plt_addr, .little);
...@@ -1027,7 +1031,7 @@ pub const CopyRelSection = struct {...@@ -1027,7 +1031,7 @@ pub const CopyRelSection = struct {
1027 }1031 }
10281032
1029 pub fn updateSectionSize(copy_rel: CopyRelSection, shndx: u32, elf_file: *Elf) !void {1033 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];
1031 for (copy_rel.symbols.items) |ref| {1035 for (copy_rel.symbols.items) |ref| {
1032 const symbol = elf_file.symbol(ref).?;1036 const symbol = elf_file.symbol(ref).?;
1033 const shared_object = symbol.file(elf_file).?.shared_object;1037 const shared_object = symbol.file(elf_file).?.shared_object;
...@@ -1487,8 +1491,12 @@ pub const ComdatGroupSection = struct {...@@ -1487,8 +1491,12 @@ pub const ComdatGroupSection = struct {
1487 elf.SHT_RELA => {1491 elf.SHT_RELA => {
1488 const atom_index = object.atoms_indexes.items[shdr.sh_info];1492 const atom_index = object.atoms_indexes.items[shdr.sh_info];
1489 const atom = object.atom(atom_index).?;1493 const atom = object.atom(atom_index).?;
1490 const rela = elf_file.output_rela_sections.get(atom.output_section_index).?;1494 const rela_shndx = for (elf_file.sections.items(.shdr), 0..) |rela_shdr, rela_shndx| {
1491 try writer.writeInt(u32, rela.shndx, .little);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);
1492 },1500 },
1493 else => {1501 else => {
1494 const atom_index = object.atoms_indexes.items[shndx];1502 const atom_index = object.atoms_indexes.items[shndx];
src/link/Elf/thunks.zig+3-4
...@@ -1,9 +1,8 @@...@@ -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 {
2 const gpa = elf_file.base.comp.gpa;2 const gpa = elf_file.base.comp.gpa;
3 const cpu_arch = elf_file.getTarget().cpu.arch;3 const cpu_arch = elf_file.getTarget().cpu.arch;
4 const max_distance = maxAllowedDistance(cpu_arch);4 const max_distance = maxAllowedDistance(cpu_arch);
5 const shdr = &elf_file.shdrs.items[shndx];5 const atoms = elf_file.sections.items(.atom_list)[shndx].items;
6 const atoms = elf_file.output_sections.get(shndx).?.items;
7 assert(atoms.len > 0);6 assert(atoms.len > 0);
87
9 for (atoms) |ref| {8 for (atoms) |ref| {
...@@ -89,7 +88,7 @@ pub const Thunk = struct {...@@ -89,7 +88,7 @@ pub const Thunk = struct {
89 }88 }
9089
91 pub fn address(thunk: Thunk, elf_file: *Elf) i64 {90 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];
93 return @as(i64, @intCast(shdr.sh_addr)) + thunk.value;92 return @as(i64, @intCast(shdr.sh_addr)) + thunk.value;
94 }93 }
9594