aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/link/Dwarf.zig24
-rw-r--r--src/link/Elf.zig496
-rw-r--r--src/link/Elf/Atom.zig12
-rw-r--r--src/link/Elf/synthetic_sections.zig4
4 files changed, 250 insertions, 286 deletions
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig
index 252388cc8b..fab6d3107c 100644
--- a/src/link/Dwarf.zig
+++ b/src/link/Dwarf.zig
@@ -1108,7 +1108,7 @@ pub fn commitDeclState(
switch (self.bin_file.tag) {
.elf => {
const elf_file = self.bin_file.cast(File.Elf).?;
- const debug_line_sect = &elf_file.sections.items(.shdr)[elf_file.debug_line_section_index.?];
+ const debug_line_sect = &elf_file.shdrs.items[elf_file.debug_line_section_index.?];
const file_pos = debug_line_sect.sh_offset + src_fn.off;
try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);
},
@@ -1170,7 +1170,7 @@ pub fn commitDeclState(
const elf_file = self.bin_file.cast(File.Elf).?;
const shdr_index = elf_file.debug_line_section_index.?;
try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
- const debug_line_sect = elf_file.sections.items(.shdr)[shdr_index];
+ const debug_line_sect = elf_file.shdrs.items[shdr_index];
const file_pos = debug_line_sect.sh_offset + src_fn.off;
try pwriteDbgLineNops(
elf_file.base.file.?,
@@ -1337,7 +1337,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)
switch (self.bin_file.tag) {
.elf => {
const elf_file = self.bin_file.cast(File.Elf).?;
- const debug_info_sect = &elf_file.sections.items(.shdr)[elf_file.debug_info_section_index.?];
+ const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];
const file_pos = debug_info_sect.sh_offset + atom.off;
try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);
},
@@ -1415,7 +1415,7 @@ fn writeDeclDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []cons
const elf_file = self.bin_file.cast(File.Elf).?;
const shdr_index = elf_file.debug_info_section_index.?;
try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
- const debug_info_sect = elf_file.sections.items(.shdr)[shdr_index];
+ const debug_info_sect = &elf_file.shdrs.items[shdr_index];
const file_pos = debug_info_sect.sh_offset + atom.off;
try pwriteDbgInfoNops(
elf_file.base.file.?,
@@ -1496,7 +1496,7 @@ pub fn updateDeclLineNumber(self: *Dwarf, mod: *Module, decl_index: Module.Decl.
switch (self.bin_file.tag) {
.elf => {
const elf_file = self.bin_file.cast(File.Elf).?;
- const shdr = elf_file.sections.items(.shdr)[elf_file.debug_line_section_index.?];
+ const shdr = elf_file.shdrs.items[elf_file.debug_line_section_index.?];
const file_pos = shdr.sh_offset + atom.off + self.getRelocDbgLineOff();
try elf_file.base.file.?.pwriteAll(&data, file_pos);
},
@@ -1713,7 +1713,7 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void {
const elf_file = self.bin_file.cast(File.Elf).?;
const shdr_index = elf_file.debug_abbrev_section_index.?;
try elf_file.growNonAllocSection(shdr_index, needed_size, 1, false);
- const debug_abbrev_sect = elf_file.sections.items(.shdr)[shdr_index];
+ const debug_abbrev_sect = &elf_file.shdrs.items[shdr_index];
const file_pos = debug_abbrev_sect.sh_offset + abbrev_offset;
try elf_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);
},
@@ -1828,7 +1828,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u
switch (self.bin_file.tag) {
.elf => {
const elf_file = self.bin_file.cast(File.Elf).?;
- const debug_info_sect = elf_file.sections.items(.shdr)[elf_file.debug_info_section_index.?];
+ const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];
const file_pos = debug_info_sect.sh_offset;
try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);
},
@@ -2147,7 +2147,7 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
const elf_file = self.bin_file.cast(File.Elf).?;
const shdr_index = elf_file.debug_aranges_section_index.?;
try elf_file.growNonAllocSection(shdr_index, needed_size, 16, false);
- const debug_aranges_sect = elf_file.sections.items(.shdr)[shdr_index];
+ const debug_aranges_sect = &elf_file.shdrs.items[shdr_index];
const file_pos = debug_aranges_sect.sh_offset;
try elf_file.base.file.?.pwriteAll(di_buf.items, file_pos);
},
@@ -2312,9 +2312,9 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
.elf => {
const elf_file = self.bin_file.cast(File.Elf).?;
const shdr_index = elf_file.debug_line_section_index.?;
- const needed_size = elf_file.sections.items(.shdr)[shdr_index].sh_size + delta;
+ const needed_size = elf_file.shdrs.items[shdr_index].sh_size + delta;
try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
- const file_pos = elf_file.sections.items(.shdr)[shdr_index].sh_offset + first_fn.off;
+ const file_pos = elf_file.shdrs.items[shdr_index].sh_offset + first_fn.off;
const amt = try elf_file.base.file.?.preadAll(buffer, file_pos);
if (amt != buffer.len) return error.InputOutput;
@@ -2377,7 +2377,7 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
switch (self.bin_file.tag) {
.elf => {
const elf_file = self.bin_file.cast(File.Elf).?;
- const debug_line_sect = elf_file.sections.items(.shdr)[elf_file.debug_line_section_index.?];
+ const debug_line_sect = &elf_file.shdrs.items[elf_file.debug_line_section_index.?];
const file_pos = debug_line_sect.sh_offset;
try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);
},
@@ -2500,7 +2500,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
switch (self.bin_file.tag) {
.elf => {
const elf_file = self.bin_file.cast(File.Elf).?;
- const debug_info_sect = &elf_file.sections.items(.shdr)[elf_file.debug_info_section_index.?];
+ const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];
break :blk debug_info_sect.sh_offset;
},
.macho => {
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index c8cdd31105..2fade5c82f 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -12,7 +12,10 @@ linker_defined_index: ?File.Index = null,
/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.
/// Same order as in the file.
-sections: std.MultiArrayList(Section) = .{},
+shdrs: std.ArrayListUnmanaged(elf.Elf64_Shdr) = .{},
+/// Given index to a section, pulls index of containing phdr if any.
+phdr_to_shdr_table: std.AutoHashMapUnmanaged(u16, u16) = .{},
+/// File offset into the shdr table.
shdr_table_offset: ?u64 = null,
/// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write.
@@ -85,7 +88,6 @@ symbols: std.ArrayListUnmanaged(Symbol) = .{},
symbols_extra: std.ArrayListUnmanaged(u32) = .{},
resolver: std.AutoArrayHashMapUnmanaged(u32, Symbol.Index) = .{},
unresolved: std.AutoArrayHashMapUnmanaged(u32, void) = .{},
-
symbols_free_list: std.ArrayListUnmanaged(Symbol.Index) = .{},
phdr_table_dirty: bool = false,
@@ -109,6 +111,8 @@ decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},
/// List of atoms that are owned directly by the linker.
atoms: std.ArrayListUnmanaged(Atom) = .{},
+/// Table of last atom index in a section and matching atom free list if any.
+last_atom_and_free_list_table: std.AutoArrayHashMapUnmanaged(u16, LastAtomAndFreeList) = .{},
/// Table of unnamed constants associated with a parent `Decl`.
/// We store them here so that we can free the constants whenever the `Decl`
@@ -176,21 +180,18 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
try self.atoms.append(allocator, .{});
// Append null file at index 0
try self.files.append(allocator, .null);
- // There must always be a null section in index 0
- try self.sections.append(allocator, .{
- .shdr = .{
- .sh_name = 0,
- .sh_type = elf.SHT_NULL,
- .sh_flags = 0,
- .sh_addr = 0,
- .sh_offset = 0,
- .sh_size = 0,
- .sh_link = 0,
- .sh_info = 0,
- .sh_addralign = 0,
- .sh_entsize = 0,
- },
- .phdr_index = undefined,
+ // There must always be a null shdr in index 0
+ try self.shdrs.append(allocator, .{
+ .sh_name = 0,
+ .sh_type = elf.SHT_NULL,
+ .sh_flags = 0,
+ .sh_addr = 0,
+ .sh_offset = 0,
+ .sh_size = 0,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = 0,
+ .sh_entsize = 0,
});
try self.populateMissingMetadata();
@@ -256,11 +257,8 @@ pub fn deinit(self: *Elf) void {
};
self.files.deinit(gpa);
- for (self.sections.items(.free_list)) |*free_list| {
- free_list.deinit(gpa);
- }
- self.sections.deinit(gpa);
-
+ self.shdrs.deinit(gpa);
+ self.phdr_to_shdr_table.deinit(gpa);
self.phdrs.deinit(gpa);
self.shstrtab.deinit(gpa);
self.strtab.deinit(gpa);
@@ -281,6 +279,10 @@ pub fn deinit(self: *Elf) void {
}
self.atoms.deinit(gpa);
+ for (self.last_atom_and_free_list_table.values()) |*value| {
+ value.free_list.deinit(gpa);
+ }
+ self.last_atom_and_free_list_table.deinit(gpa);
self.lazy_syms.deinit(gpa);
{
@@ -332,7 +334,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 {
if (self.shdr_table_offset) |off| {
const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr);
- const tight_size = self.sections.slice().len * shdr_size;
+ const tight_size = self.shdrs.items.len * shdr_size;
const increased_size = padToIdeal(tight_size);
const test_end = off + increased_size;
if (end > off and start < test_end) {
@@ -340,7 +342,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 {
}
}
- for (self.sections.items(.shdr)) |section| {
+ for (self.shdrs.items) |section| {
const increased_size = padToIdeal(section.sh_size);
const test_end = section.sh_offset + increased_size;
if (end > section.sh_offset and start < test_end) {
@@ -364,7 +366,7 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 {
if (self.shdr_table_offset) |off| {
if (off > start and off < min_pos) min_pos = off;
}
- for (self.sections.items(.shdr)) |section| {
+ for (self.shdrs.items) |section| {
if (section.sh_offset <= start) continue;
if (section.sh_offset < min_pos) min_pos = section.sh_offset;
}
@@ -522,197 +524,174 @@ pub fn populateMissingMetadata(self: *Elf) !void {
}
if (self.shstrtab_section_index == null) {
- self.shstrtab_section_index = @as(u16, @intCast(self.sections.slice().len));
+ self.shstrtab_section_index = @as(u16, @intCast(self.shdrs.items.len));
assert(self.shstrtab.buffer.items.len == 0);
try self.shstrtab.buffer.append(gpa, 0); // need a 0 at position 0
const off = self.findFreeSpace(self.shstrtab.buffer.items.len, 1);
log.debug("found .shstrtab free space 0x{x} to 0x{x}", .{ off, off + self.shstrtab.buffer.items.len });
- try self.sections.append(gpa, .{
- .shdr = .{
- .sh_name = try self.shstrtab.insert(gpa, ".shstrtab"),
- .sh_type = elf.SHT_STRTAB,
- .sh_flags = 0,
- .sh_addr = 0,
- .sh_offset = off,
- .sh_size = self.shstrtab.buffer.items.len,
- .sh_link = 0,
- .sh_info = 0,
- .sh_addralign = 1,
- .sh_entsize = 0,
- },
- .phdr_index = undefined,
+ try self.shdrs.append(gpa, .{
+ .sh_name = try self.shstrtab.insert(gpa, ".shstrtab"),
+ .sh_type = elf.SHT_STRTAB,
+ .sh_flags = 0,
+ .sh_addr = 0,
+ .sh_offset = off,
+ .sh_size = self.shstrtab.buffer.items.len,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = 1,
+ .sh_entsize = 0,
});
self.shstrtab_dirty = true;
self.shdr_table_dirty = true;
}
if (self.strtab_section_index == null) {
- self.strtab_section_index = @as(u16, @intCast(self.sections.slice().len));
+ self.strtab_section_index = @as(u16, @intCast(self.shdrs.items.len));
assert(self.strtab.buffer.items.len == 0);
try self.strtab.buffer.append(gpa, 0); // need a 0 at position 0
const off = self.findFreeSpace(self.strtab.buffer.items.len, 1);
log.debug("found .strtab free space 0x{x} to 0x{x}", .{ off, off + self.strtab.buffer.items.len });
- try self.sections.append(gpa, .{
- .shdr = .{
- .sh_name = try self.shstrtab.insert(gpa, ".strtab"),
- .sh_type = elf.SHT_STRTAB,
- .sh_flags = 0,
- .sh_addr = 0,
- .sh_offset = off,
- .sh_size = self.strtab.buffer.items.len,
- .sh_link = 0,
- .sh_info = 0,
- .sh_addralign = 1,
- .sh_entsize = 0,
- },
- .phdr_index = undefined,
+ try self.shdrs.append(gpa, .{
+ .sh_name = try self.shstrtab.insert(gpa, ".strtab"),
+ .sh_type = elf.SHT_STRTAB,
+ .sh_flags = 0,
+ .sh_addr = 0,
+ .sh_offset = off,
+ .sh_size = self.strtab.buffer.items.len,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = 1,
+ .sh_entsize = 0,
});
self.strtab_dirty = true;
self.shdr_table_dirty = true;
}
if (self.text_section_index == null) {
- self.text_section_index = @as(u16, @intCast(self.sections.slice().len));
+ self.text_section_index = @as(u16, @intCast(self.shdrs.items.len));
const phdr = &self.phdrs.items[self.phdr_load_re_index.?];
-
- try self.sections.append(gpa, .{
- .shdr = .{
- .sh_name = try self.shstrtab.insert(gpa, ".text"),
- .sh_type = elf.SHT_PROGBITS,
- .sh_flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
- .sh_addr = phdr.p_vaddr,
- .sh_offset = phdr.p_offset,
- .sh_size = phdr.p_filesz,
- .sh_link = 0,
- .sh_info = 0,
- .sh_addralign = 1,
- .sh_entsize = 0,
- },
- .phdr_index = self.phdr_load_re_index.?,
+ try self.shdrs.append(gpa, .{
+ .sh_name = try self.shstrtab.insert(gpa, ".text"),
+ .sh_type = elf.SHT_PROGBITS,
+ .sh_flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
+ .sh_addr = phdr.p_vaddr,
+ .sh_offset = phdr.p_offset,
+ .sh_size = phdr.p_filesz,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = 1,
+ .sh_entsize = 0,
});
+ try self.phdr_to_shdr_table.putNoClobber(gpa, self.text_section_index.?, self.phdr_load_re_index.?);
+ try self.last_atom_and_free_list_table.putNoClobber(gpa, self.text_section_index.?, .{});
self.shdr_table_dirty = true;
}
if (self.got_section_index == null) {
- self.got_section_index = @as(u16, @intCast(self.sections.slice().len));
+ self.got_section_index = @as(u16, @intCast(self.shdrs.items.len));
const phdr = &self.phdrs.items[self.phdr_got_index.?];
-
- try self.sections.append(gpa, .{
- .shdr = .{
- .sh_name = try self.shstrtab.insert(gpa, ".got"),
- .sh_type = elf.SHT_PROGBITS,
- .sh_flags = elf.SHF_ALLOC,
- .sh_addr = phdr.p_vaddr,
- .sh_offset = phdr.p_offset,
- .sh_size = phdr.p_filesz,
- .sh_link = 0,
- .sh_info = 0,
- .sh_addralign = @as(u16, ptr_size),
- .sh_entsize = 0,
- },
- .phdr_index = self.phdr_got_index.?,
+ try self.shdrs.append(gpa, .{
+ .sh_name = try self.shstrtab.insert(gpa, ".got"),
+ .sh_type = elf.SHT_PROGBITS,
+ .sh_flags = elf.SHF_ALLOC,
+ .sh_addr = phdr.p_vaddr,
+ .sh_offset = phdr.p_offset,
+ .sh_size = phdr.p_filesz,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = @as(u16, ptr_size),
+ .sh_entsize = 0,
});
+ try self.phdr_to_shdr_table.putNoClobber(gpa, self.got_section_index.?, self.phdr_got_index.?);
self.shdr_table_dirty = true;
}
if (self.rodata_section_index == null) {
- self.rodata_section_index = @as(u16, @intCast(self.sections.slice().len));
+ self.rodata_section_index = @as(u16, @intCast(self.shdrs.items.len));
const phdr = &self.phdrs.items[self.phdr_load_ro_index.?];
-
- try self.sections.append(gpa, .{
- .shdr = .{
- .sh_name = try self.shstrtab.insert(gpa, ".rodata"),
- .sh_type = elf.SHT_PROGBITS,
- .sh_flags = elf.SHF_ALLOC,
- .sh_addr = phdr.p_vaddr,
- .sh_offset = phdr.p_offset,
- .sh_size = phdr.p_filesz,
- .sh_link = 0,
- .sh_info = 0,
- .sh_addralign = 1,
- .sh_entsize = 0,
- },
- .phdr_index = self.phdr_load_ro_index.?,
+ try self.shdrs.append(gpa, .{
+ .sh_name = try self.shstrtab.insert(gpa, ".rodata"),
+ .sh_type = elf.SHT_PROGBITS,
+ .sh_flags = elf.SHF_ALLOC,
+ .sh_addr = phdr.p_vaddr,
+ .sh_offset = phdr.p_offset,
+ .sh_size = phdr.p_filesz,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = 1,
+ .sh_entsize = 0,
});
+ try self.phdr_to_shdr_table.putNoClobber(gpa, self.rodata_section_index.?, self.phdr_load_ro_index.?);
+ try self.last_atom_and_free_list_table.putNoClobber(gpa, self.rodata_section_index.?, .{});
self.shdr_table_dirty = true;
}
if (self.data_section_index == null) {
- self.data_section_index = @as(u16, @intCast(self.sections.slice().len));
+ self.data_section_index = @as(u16, @intCast(self.shdrs.items.len));
const phdr = &self.phdrs.items[self.phdr_load_rw_index.?];
-
- try self.sections.append(gpa, .{
- .shdr = .{
- .sh_name = try self.shstrtab.insert(gpa, ".data"),
- .sh_type = elf.SHT_PROGBITS,
- .sh_flags = elf.SHF_WRITE | elf.SHF_ALLOC,
- .sh_addr = phdr.p_vaddr,
- .sh_offset = phdr.p_offset,
- .sh_size = phdr.p_filesz,
- .sh_link = 0,
- .sh_info = 0,
- .sh_addralign = @as(u16, ptr_size),
- .sh_entsize = 0,
- },
- .phdr_index = self.phdr_load_rw_index.?,
+ try self.shdrs.append(gpa, .{
+ .sh_name = try self.shstrtab.insert(gpa, ".data"),
+ .sh_type = elf.SHT_PROGBITS,
+ .sh_flags = elf.SHF_WRITE | elf.SHF_ALLOC,
+ .sh_addr = phdr.p_vaddr,
+ .sh_offset = phdr.p_offset,
+ .sh_size = phdr.p_filesz,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = @as(u16, ptr_size),
+ .sh_entsize = 0,
});
+ try self.phdr_to_shdr_table.putNoClobber(gpa, self.data_section_index.?, self.phdr_load_rw_index.?);
+ try self.last_atom_and_free_list_table.putNoClobber(gpa, self.data_section_index.?, .{});
self.shdr_table_dirty = true;
}
if (self.symtab_section_index == null) {
- self.symtab_section_index = @as(u16, @intCast(self.sections.slice().len));
+ self.symtab_section_index = @as(u16, @intCast(self.shdrs.items.len));
const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym);
const each_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym);
const file_size = self.base.options.symbol_count_hint * each_size;
const off = self.findFreeSpace(file_size, min_align);
log.debug("found symtab free space 0x{x} to 0x{x}", .{ off, off + file_size });
-
- try self.sections.append(gpa, .{
- .shdr = .{
- .sh_name = try self.shstrtab.insert(gpa, ".symtab"),
- .sh_type = elf.SHT_SYMTAB,
- .sh_flags = 0,
- .sh_addr = 0,
- .sh_offset = off,
- .sh_size = file_size,
- // The section header index of the associated string table.
- .sh_link = self.strtab_section_index.?,
- .sh_info = @as(u32, @intCast(self.symbols.items.len)),
- .sh_addralign = min_align,
- .sh_entsize = each_size,
- },
- .phdr_index = undefined,
+ try self.shdrs.append(gpa, .{
+ .sh_name = try self.shstrtab.insert(gpa, ".symtab"),
+ .sh_type = elf.SHT_SYMTAB,
+ .sh_flags = 0,
+ .sh_addr = 0,
+ .sh_offset = off,
+ .sh_size = file_size,
+ // The section header index of the associated string table.
+ .sh_link = self.strtab_section_index.?,
+ .sh_info = @as(u32, @intCast(self.symbols.items.len)),
+ .sh_addralign = min_align,
+ .sh_entsize = each_size,
});
self.shdr_table_dirty = true;
}
if (self.dwarf) |*dw| {
if (self.debug_str_section_index == null) {
- self.debug_str_section_index = @as(u16, @intCast(self.sections.slice().len));
+ self.debug_str_section_index = @as(u16, @intCast(self.shdrs.items.len));
assert(dw.strtab.buffer.items.len == 0);
try dw.strtab.buffer.append(gpa, 0);
- try self.sections.append(gpa, .{
- .shdr = .{
- .sh_name = try self.shstrtab.insert(gpa, ".debug_str"),
- .sh_type = elf.SHT_PROGBITS,
- .sh_flags = elf.SHF_MERGE | elf.SHF_STRINGS,
- .sh_addr = 0,
- .sh_offset = 0,
- .sh_size = 0,
- .sh_link = 0,
- .sh_info = 0,
- .sh_addralign = 1,
- .sh_entsize = 1,
- },
- .phdr_index = undefined,
+ try self.shdrs.append(gpa, .{
+ .sh_name = try self.shstrtab.insert(gpa, ".debug_str"),
+ .sh_type = elf.SHT_PROGBITS,
+ .sh_flags = elf.SHF_MERGE | elf.SHF_STRINGS,
+ .sh_addr = 0,
+ .sh_offset = 0,
+ .sh_size = 0,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = 1,
+ .sh_entsize = 1,
});
self.debug_strtab_dirty = true;
self.shdr_table_dirty = true;
}
if (self.debug_info_section_index == null) {
- self.debug_info_section_index = @as(u16, @intCast(self.sections.slice().len));
-
+ self.debug_info_section_index = @as(u16, @intCast(self.shdrs.items.len));
const file_size_hint = 200;
const p_align = 1;
const off = self.findFreeSpace(file_size_hint, p_align);
@@ -720,28 +699,24 @@ pub fn populateMissingMetadata(self: *Elf) !void {
off,
off + file_size_hint,
});
- try self.sections.append(gpa, .{
- .shdr = .{
- .sh_name = try self.shstrtab.insert(gpa, ".debug_info"),
- .sh_type = elf.SHT_PROGBITS,
- .sh_flags = 0,
- .sh_addr = 0,
- .sh_offset = off,
- .sh_size = file_size_hint,
- .sh_link = 0,
- .sh_info = 0,
- .sh_addralign = p_align,
- .sh_entsize = 0,
- },
- .phdr_index = undefined,
+ try self.shdrs.append(gpa, .{
+ .sh_name = try self.shstrtab.insert(gpa, ".debug_info"),
+ .sh_type = elf.SHT_PROGBITS,
+ .sh_flags = 0,
+ .sh_addr = 0,
+ .sh_offset = off,
+ .sh_size = file_size_hint,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = p_align,
+ .sh_entsize = 0,
});
self.shdr_table_dirty = true;
self.debug_info_header_dirty = true;
}
if (self.debug_abbrev_section_index == null) {
- self.debug_abbrev_section_index = @as(u16, @intCast(self.sections.slice().len));
-
+ self.debug_abbrev_section_index = @as(u16, @intCast(self.shdrs.items.len));
const file_size_hint = 128;
const p_align = 1;
const off = self.findFreeSpace(file_size_hint, p_align);
@@ -749,28 +724,24 @@ pub fn populateMissingMetadata(self: *Elf) !void {
off,
off + file_size_hint,
});
- try self.sections.append(gpa, .{
- .shdr = .{
- .sh_name = try self.shstrtab.insert(gpa, ".debug_abbrev"),
- .sh_type = elf.SHT_PROGBITS,
- .sh_flags = 0,
- .sh_addr = 0,
- .sh_offset = off,
- .sh_size = file_size_hint,
- .sh_link = 0,
- .sh_info = 0,
- .sh_addralign = p_align,
- .sh_entsize = 0,
- },
- .phdr_index = undefined,
+ try self.shdrs.append(gpa, .{
+ .sh_name = try self.shstrtab.insert(gpa, ".debug_abbrev"),
+ .sh_type = elf.SHT_PROGBITS,
+ .sh_flags = 0,
+ .sh_addr = 0,
+ .sh_offset = off,
+ .sh_size = file_size_hint,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = p_align,
+ .sh_entsize = 0,
});
self.shdr_table_dirty = true;
self.debug_abbrev_section_dirty = true;
}
if (self.debug_aranges_section_index == null) {
- self.debug_aranges_section_index = @as(u16, @intCast(self.sections.slice().len));
-
+ self.debug_aranges_section_index = @as(u16, @intCast(self.shdrs.items.len));
const file_size_hint = 160;
const p_align = 16;
const off = self.findFreeSpace(file_size_hint, p_align);
@@ -778,28 +749,24 @@ pub fn populateMissingMetadata(self: *Elf) !void {
off,
off + file_size_hint,
});
- try self.sections.append(gpa, .{
- .shdr = .{
- .sh_name = try self.shstrtab.insert(gpa, ".debug_aranges"),
- .sh_type = elf.SHT_PROGBITS,
- .sh_flags = 0,
- .sh_addr = 0,
- .sh_offset = off,
- .sh_size = file_size_hint,
- .sh_link = 0,
- .sh_info = 0,
- .sh_addralign = p_align,
- .sh_entsize = 0,
- },
- .phdr_index = undefined,
+ try self.shdrs.append(gpa, .{
+ .sh_name = try self.shstrtab.insert(gpa, ".debug_aranges"),
+ .sh_type = elf.SHT_PROGBITS,
+ .sh_flags = 0,
+ .sh_addr = 0,
+ .sh_offset = off,
+ .sh_size = file_size_hint,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = p_align,
+ .sh_entsize = 0,
});
self.shdr_table_dirty = true;
self.debug_aranges_section_dirty = true;
}
if (self.debug_line_section_index == null) {
- self.debug_line_section_index = @as(u16, @intCast(self.sections.slice().len));
-
+ self.debug_line_section_index = @as(u16, @intCast(self.shdrs.items.len));
const file_size_hint = 250;
const p_align = 1;
const off = self.findFreeSpace(file_size_hint, p_align);
@@ -807,20 +774,17 @@ pub fn populateMissingMetadata(self: *Elf) !void {
off,
off + file_size_hint,
});
- try self.sections.append(gpa, .{
- .shdr = .{
- .sh_name = try self.shstrtab.insert(gpa, ".debug_line"),
- .sh_type = elf.SHT_PROGBITS,
- .sh_flags = 0,
- .sh_addr = 0,
- .sh_offset = off,
- .sh_size = file_size_hint,
- .sh_link = 0,
- .sh_info = 0,
- .sh_addralign = p_align,
- .sh_entsize = 0,
- },
- .phdr_index = undefined,
+ try self.shdrs.append(gpa, .{
+ .sh_name = try self.shstrtab.insert(gpa, ".debug_line"),
+ .sh_type = elf.SHT_PROGBITS,
+ .sh_flags = 0,
+ .sh_addr = 0,
+ .sh_offset = off,
+ .sh_size = file_size_hint,
+ .sh_link = 0,
+ .sh_info = 0,
+ .sh_addralign = p_align,
+ .sh_entsize = 0,
});
self.shdr_table_dirty = true;
self.debug_line_header_dirty = true;
@@ -836,7 +800,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
.p64 => @alignOf(elf.Elf64_Shdr),
};
if (self.shdr_table_offset == null) {
- self.shdr_table_offset = self.findFreeSpace(self.sections.slice().len * shsize, shalign);
+ self.shdr_table_offset = self.findFreeSpace(self.shdrs.items.len * shsize, shalign);
self.shdr_table_dirty = true;
}
@@ -854,7 +818,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
// offset + it's filesize.
var max_file_offset: u64 = 0;
- for (self.sections.items(.shdr)) |shdr| {
+ for (self.shdrs.items) |shdr| {
if (shdr.sh_offset + shdr.sh_size > max_file_offset) {
max_file_offset = shdr.sh_offset + shdr.sh_size;
}
@@ -885,19 +849,17 @@ pub fn populateMissingMetadata(self: *Elf) !void {
pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {
// TODO Also detect virtual address collisions.
- const shdr = &self.sections.items(.shdr)[shdr_index];
- const phdr_index = self.sections.items(.phdr_index)[shdr_index];
+ const shdr = &self.shdrs.items[shdr_index];
+ const phdr_index = self.phdr_to_shdr_table.get(shdr_index).?;
const phdr = &self.phdrs.items[phdr_index];
- const last_atom_index = self.sections.items(.last_atom_index)[shdr_index];
if (needed_size > self.allocatedSize(shdr.sh_offset)) {
// Must move the entire section.
const new_offset = self.findFreeSpace(needed_size, self.page_size);
- const existing_size = if (self.atom(last_atom_index)) |last| blk: {
+ const existing_size = if (self.last_atom_and_free_list_table.get(shdr_index)) |meta| blk: {
+ const last = self.atom(meta.last_atom_index) orelse break :blk 0;
break :blk (last.value + last.size) - phdr.p_vaddr;
- } else if (shdr_index == self.got_section_index.?) blk: {
- break :blk shdr.sh_size;
- } else 0;
+ } else shdr.sh_size;
shdr.sh_size = 0;
log.debug("new '{?s}' file offset 0x{x} to 0x{x}", .{
@@ -927,7 +889,7 @@ pub fn growNonAllocSection(
min_alignment: u32,
requires_file_copy: bool,
) !void {
- const shdr = &self.sections.items(.shdr)[shdr_index];
+ const shdr = &self.shdrs.items[shdr_index];
if (needed_size > self.allocatedSize(shdr.sh_offset)) {
const existing_size = if (self.symtab_section_index.? == shdr_index) blk: {
@@ -940,7 +902,12 @@ pub fn growNonAllocSection(
shdr.sh_size = 0;
// Move all the symbols to a new file location.
const new_offset = self.findFreeSpace(needed_size, min_alignment);
- log.debug("moving '{?s}' from 0x{x} to 0x{x}", .{ self.shstrtab.get(shdr.sh_name), shdr.sh_offset, new_offset });
+
+ log.debug("moving '{?s}' from 0x{x} to 0x{x}", .{
+ self.shstrtab.get(shdr.sh_name),
+ shdr.sh_offset,
+ new_offset,
+ });
if (requires_file_copy) {
const amt = try self.base.file.?.copyRangeAll(
@@ -1071,7 +1038,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
const atom_index = entry.key_ptr.*;
const relocs = entry.value_ptr.*;
const atom_ptr = self.atom(atom_index).?;
- const source_shdr = self.sections.items(.shdr)[atom_ptr.output_section_index];
+ const source_shdr = &self.shdrs.items[atom_ptr.output_section_index];
log.debug("relocating '{s}'", .{atom_ptr.name(self)});
@@ -1209,9 +1176,9 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
{
const shdr_index = self.shstrtab_section_index.?;
- if (self.shstrtab_dirty or self.shstrtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) {
+ if (self.shstrtab_dirty or self.shstrtab.buffer.items.len != self.shdrs.items[shdr_index].sh_size) {
try self.growNonAllocSection(shdr_index, self.shstrtab.buffer.items.len, 1, false);
- const shstrtab_sect = self.sections.items(.shdr)[shdr_index];
+ const shstrtab_sect = &self.shdrs.items[shdr_index];
try self.base.file.?.pwriteAll(self.shstrtab.buffer.items, shstrtab_sect.sh_offset);
self.shstrtab_dirty = false;
}
@@ -1219,9 +1186,9 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
{
const shdr_index = self.strtab_section_index.?;
- if (self.strtab_dirty or self.strtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) {
+ if (self.strtab_dirty or self.strtab.buffer.items.len != self.shdrs.items[shdr_index].sh_size) {
try self.growNonAllocSection(shdr_index, self.strtab.buffer.items.len, 1, false);
- const strtab_sect = self.sections.items(.shdr)[shdr_index];
+ const strtab_sect = self.shdrs.items[shdr_index];
try self.base.file.?.pwriteAll(self.strtab.buffer.items, strtab_sect.sh_offset);
self.strtab_dirty = false;
}
@@ -1229,9 +1196,9 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
if (self.dwarf) |dwarf| {
const shdr_index = self.debug_str_section_index.?;
- if (self.debug_strtab_dirty or dwarf.strtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) {
+ if (self.debug_strtab_dirty or dwarf.strtab.buffer.items.len != self.shdrs.items[shdr_index].sh_size) {
try self.growNonAllocSection(shdr_index, dwarf.strtab.buffer.items.len, 1, false);
- const debug_strtab_sect = self.sections.items(.shdr)[shdr_index];
+ const debug_strtab_sect = self.shdrs.items[shdr_index];
try self.base.file.?.pwriteAll(dwarf.strtab.buffer.items, debug_strtab_sect.sh_offset);
self.debug_strtab_dirty = false;
}
@@ -1247,7 +1214,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
.p64 => @alignOf(elf.Elf64_Shdr),
};
const allocated_size = self.allocatedSize(self.shdr_table_offset.?);
- const needed_size = self.sections.slice().len * shsize;
+ const needed_size = self.shdrs.items.len * shsize;
if (needed_size > allocated_size) {
self.shdr_table_offset = null; // free the space
@@ -1256,12 +1223,11 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
switch (self.ptr_width) {
.p32 => {
- const slice = self.sections.slice();
- const buf = try gpa.alloc(elf.Elf32_Shdr, slice.len);
+ const buf = try gpa.alloc(elf.Elf32_Shdr, self.shdrs.items.len);
defer gpa.free(buf);
for (buf, 0..) |*shdr, i| {
- shdr.* = shdrTo32(slice.items(.shdr)[i]);
+ shdr.* = shdrTo32(self.shdrs.items[i]);
log.debug("writing section {?s}: {}", .{ self.shstrtab.get(shdr.sh_name), shdr.* });
if (foreign_endian) {
mem.byteSwapAllFields(elf.Elf32_Shdr, shdr);
@@ -1270,12 +1236,11 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?);
},
.p64 => {
- const slice = self.sections.slice();
- const buf = try gpa.alloc(elf.Elf64_Shdr, slice.len);
+ const buf = try gpa.alloc(elf.Elf64_Shdr, self.shdrs.items.len);
defer gpa.free(buf);
for (buf, 0..) |*shdr, i| {
- shdr.* = slice.items(.shdr)[i];
+ shdr.* = self.shdrs.items[i];
log.debug("writing section {?s}: {}", .{ self.shstrtab.get(shdr.sh_name), shdr.* });
if (foreign_endian) {
mem.byteSwapAllFields(elf.Elf64_Shdr, shdr);
@@ -2118,7 +2083,7 @@ fn writeElfHeader(self: *Elf) !void {
mem.writeInt(u16, hdr_buf[index..][0..2], e_shentsize, endian);
index += 2;
- const e_shnum = @as(u16, @intCast(self.sections.slice().len));
+ const e_shnum = @as(u16, @intCast(self.shdrs.items.len));
mem.writeInt(u16, hdr_buf[index..][0..2], e_shnum, endian);
index += 2;
@@ -2305,9 +2270,9 @@ fn updateDeclCode(
try self.got.writeEntry(self, got_index);
}
- const phdr_index = self.sections.items(.phdr_index)[shdr_index];
+ const phdr_index = self.phdr_to_shdr_table.get(shdr_index).?;
const section_offset = sym.value - self.phdrs.items[phdr_index].p_vaddr;
- const file_offset = self.sections.items(.shdr)[shdr_index].sh_offset + section_offset;
+ const file_offset = self.shdrs.items[shdr_index].sh_offset + section_offset;
if (self.base.child_pid) |pid| {
switch (builtin.os.tag) {
@@ -2510,7 +2475,7 @@ fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol.
};
const local_sym = self.symbol(symbol_index);
- const phdr_index = self.sections.items(.phdr_index)[local_sym.output_section_index];
+ const phdr_index = self.phdr_to_shdr_table.get(local_sym.output_section_index).?;
local_sym.name_offset = name_str_index;
const local_esym = local_sym.sourceSymbol(self);
local_esym.st_name = name_str_index;
@@ -2537,7 +2502,7 @@ fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol.
try self.got.writeEntry(self, got_index);
const section_offset = atom_ptr.value - self.phdrs.items[phdr_index].p_vaddr;
- const file_offset = self.sections.items(.shdr)[local_sym.output_section_index].sh_offset + section_offset;
+ const file_offset = self.shdrs.items[local_sym.output_section_index].sh_offset + section_offset;
try self.base.file.?.pwriteAll(code, file_offset);
}
@@ -2584,7 +2549,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
const required_alignment = typed_value.ty.abiAlignment(mod);
const shdr_index = self.rodata_section_index.?;
- const phdr_index = self.sections.items(.phdr_index)[shdr_index];
+ const phdr_index = self.phdr_to_shdr_table.get(shdr_index).?;
const local_sym = self.symbol(sym_index);
local_sym.name_offset = name_str_index;
const local_esym = local_sym.sourceSymbol(self);
@@ -2607,7 +2572,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
try unnamed_consts.append(gpa, atom_ptr.atom_index);
const section_offset = atom_ptr.value - self.phdrs.items[phdr_index].p_vaddr;
- const file_offset = self.sections.items(.shdr)[shdr_index].sh_offset + section_offset;
+ const file_offset = self.shdrs.items[shdr_index].sh_offset + section_offset;
try self.base.file.?.pwriteAll(code, file_offset);
return sym_index;
@@ -2775,7 +2740,7 @@ fn addLinkerDefinedSymbols(self: *Elf) !void {
fn allocateLinkerDefinedSymbols(self: *Elf) void {
// _DYNAMIC
if (self.dynamic_section_index) |shndx| {
- const shdr = self.sections.items(.shdr)[shndx];
+ const shdr = &self.shdrs.items[shndx];
const symbol_ptr = self.symbol(self.dynamic_index.?);
symbol_ptr.value = shdr.sh_addr;
symbol_ptr.output_section_index = shndx;
@@ -2792,7 +2757,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
if (self.sectionByName(".init_array")) |shndx| {
const start_sym = self.symbol(self.init_array_start_index.?);
const end_sym = self.symbol(self.init_array_end_index.?);
- const shdr = &self.sections.items(.shdr)[shndx];
+ const shdr = &self.shdrs.items[shndx];
start_sym.output_section_index = shndx;
start_sym.value = shdr.sh_addr;
end_sym.output_section_index = shndx;
@@ -2803,7 +2768,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
if (self.sectionByName(".fini_array")) |shndx| {
const start_sym = self.symbol(self.fini_array_start_index.?);
const end_sym = self.symbol(self.fini_array_end_index.?);
- const shdr = &self.sections.items(.shdr)[shndx];
+ const shdr = &self.shdrs.items[shndx];
start_sym.output_section_index = shndx;
start_sym.value = shdr.sh_addr;
end_sym.output_section_index = shndx;
@@ -2814,7 +2779,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
if (self.sectionByName(".preinit_array")) |shndx| {
const start_sym = self.symbol(self.preinit_array_start_index.?);
const end_sym = self.symbol(self.preinit_array_end_index.?);
- const shdr = &self.sections.items(.shdr)[shndx];
+ const shdr = &self.shdrs.items[shndx];
start_sym.output_section_index = shndx;
start_sym.value = shdr.sh_addr;
end_sym.output_section_index = shndx;
@@ -2823,7 +2788,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
// _GLOBAL_OFFSET_TABLE_
if (self.got_plt_section_index) |shndx| {
- const shdr = &self.sections.items(.shdr)[shndx];
+ const shdr = &self.shdrs.items[shndx];
const symbol_ptr = self.symbol(self.got_index.?);
symbol_ptr.value = shdr.sh_addr;
symbol_ptr.output_section_index = shndx;
@@ -2831,7 +2796,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
// _PROCEDURE_LINKAGE_TABLE_
if (self.plt_section_index) |shndx| {
- const shdr = &self.sections.items(.shdr)[shndx];
+ const shdr = &self.shdrs.items[shndx];
const symbol_ptr = self.symbol(self.plt_index.?);
symbol_ptr.value = shdr.sh_addr;
symbol_ptr.output_section_index = shndx;
@@ -2839,7 +2804,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
// __dso_handle
if (self.dso_handle_index) |index| {
- const shdr = &self.sections.items(.shdr)[1];
+ const shdr = &self.shdrs.items[1];
const symbol_ptr = self.symbol(index);
symbol_ptr.value = shdr.sh_addr;
symbol_ptr.output_section_index = 0;
@@ -2847,7 +2812,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
// __GNU_EH_FRAME_HDR
if (self.eh_frame_hdr_section_index) |shndx| {
- const shdr = &self.sections.items(.shdr)[shndx];
+ const shdr = &self.shdrs.items[shndx];
const symbol_ptr = self.symbol(self.gnu_eh_frame_hdr_index.?);
symbol_ptr.value = shdr.sh_addr;
symbol_ptr.output_section_index = shndx;
@@ -2856,7 +2821,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
// __rela_iplt_start, __rela_iplt_end
if (self.rela_dyn_section_index) |shndx| blk: {
if (self.base.options.link_mode != .Static or self.base.options.pie) break :blk;
- const shdr = &self.sections.items(.shdr)[shndx];
+ const shdr = &self.shdrs.items[shndx];
const end_addr = shdr.sh_addr + shdr.sh_size;
const start_addr = end_addr - self.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela);
const start_sym = self.symbol(self.rela_iplt_start_index.?);
@@ -2870,7 +2835,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
// _end
{
const end_symbol = self.symbol(self.end_index.?);
- for (self.sections.items(.shdr), 0..) |shdr, shndx| {
+ for (self.shdrs.items, 0..) |*shdr, shndx| {
if (shdr.sh_flags & elf.SHF_ALLOC != 0) {
end_symbol.value = shdr.sh_addr + shdr.sh_size;
end_symbol.output_section_index = @intCast(shndx);
@@ -2886,7 +2851,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
const name = start.name(self);
const stop = self.symbol(self.start_stop_indexes.items[index + 1]);
const shndx = self.sectionByName(name["__start_".len..]).?;
- const shdr = self.sections.items(.shdr)[shndx];
+ const shdr = &self.shdrs.items[shndx];
start.value = shdr.sh_addr;
start.output_section_index = shndx;
stop.value = shdr.sh_addr + shdr.sh_size;
@@ -2916,7 +2881,7 @@ fn updateSymtabSize(self: *Elf) !void {
sizes.nlocals += linker_defined.output_symtab_size.nlocals;
}
- const shdr = &self.sections.items(.shdr)[self.symtab_section_index.?];
+ const shdr = &self.shdrs.items[self.symtab_section_index.?];
shdr.sh_info = sizes.nlocals + 1;
self.markDirty(self.symtab_section_index.?, null);
@@ -2934,7 +2899,7 @@ fn updateSymtabSize(self: *Elf) !void {
fn writeSymtab(self: *Elf) !void {
const gpa = self.base.allocator;
- const shdr = &self.sections.items(.shdr)[self.symtab_section_index.?];
+ const shdr = &self.shdrs.items[self.symtab_section_index.?];
const sym_size: u64 = switch (self.ptr_width) {
.p32 => @sizeOf(elf.Elf32_Sym),
.p64 => @sizeOf(elf.Elf64_Sym),
@@ -3031,7 +2996,7 @@ fn writeShdr(self: *Elf, index: usize) !void {
switch (self.ptr_width) {
.p32 => {
var shdr: [1]elf.Elf32_Shdr = undefined;
- shdr[0] = shdrTo32(self.sections.items(.shdr)[index]);
+ shdr[0] = shdrTo32(self.shdrs.items[index]);
if (foreign_endian) {
mem.byteSwapAllFields(elf.Elf32_Shdr, &shdr[0]);
}
@@ -3039,7 +3004,7 @@ fn writeShdr(self: *Elf, index: usize) !void {
return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset);
},
.p64 => {
- var shdr = [1]elf.Elf64_Shdr{self.sections.items(.shdr)[index]};
+ var shdr = [1]elf.Elf64_Shdr{self.shdrs.items[index]};
if (foreign_endian) {
mem.byteSwapAllFields(elf.Elf64_Shdr, &shdr[0]);
}
@@ -3327,7 +3292,7 @@ pub fn defaultEntryAddress(self: Elf) u64 {
}
pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u16 {
- for (self.sections.items(.shdr), 0..) |shdr, i| {
+ for (self.shdrs.items, 0..) |*shdr, i| {
const this_name = self.shstrtab.getAssumeExists(shdr.sh_name);
if (mem.eql(u8, this_name, name)) return @as(u16, @intCast(i));
} else return null;
@@ -3481,10 +3446,7 @@ const default_entry_addr = 0x8000000;
pub const base_tag: link.File.Tag = .elf;
-const Section = struct {
- shdr: elf.Elf64_Shdr,
- phdr_index: u16,
-
+const LastAtomAndFreeList = struct {
/// Index of the last allocated atom in this section.
last_atom_index: Atom.Index = 0,
diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig
index 6c83350561..ead42917a1 100644
--- a/src/link/Elf/Atom.zig
+++ b/src/link/Elf/Atom.zig
@@ -79,9 +79,10 @@ pub fn freeRelocations(elf_file: *Elf, atom_index: Index) void {
}
pub fn allocate(self: *Atom, elf_file: *Elf) !void {
- const shdr = &elf_file.sections.items(.shdr)[self.output_section_index];
- const free_list = &elf_file.sections.items(.free_list)[self.output_section_index];
- const last_atom_index = &elf_file.sections.items(.last_atom_index)[self.output_section_index];
+ const shdr = &elf_file.shdrs.items[self.output_section_index];
+ const meta = elf_file.last_atom_and_free_list_table.getPtr(self.output_section_index).?;
+ const free_list = &meta.free_list;
+ const last_atom_index = &meta.last_atom_index;
const new_atom_ideal_capacity = Elf.padToIdeal(self.size);
const alignment = try std.math.powi(u64, 2, self.alignment);
@@ -208,7 +209,9 @@ pub fn free(self: *Atom, elf_file: *Elf) void {
const gpa = elf_file.base.allocator;
const shndx = self.output_section_index;
- const free_list = &elf_file.sections.items(.free_list)[shndx];
+ const meta = elf_file.last_atom_and_free_list_table.getPtr(shndx).?;
+ const free_list = &meta.free_list;
+ const last_atom_index = &meta.last_atom_index;
var already_have_free_list_node = false;
{
var i: usize = 0;
@@ -225,7 +228,6 @@ pub fn free(self: *Atom, elf_file: *Elf) void {
}
}
- const last_atom_index = &elf_file.sections.items(.last_atom_index)[shndx];
if (elf_file.atom(last_atom_index.*)) |last_atom| {
if (last_atom.atom_index == self.atom_index) {
if (elf_file.atom(self.prev_index)) |_| {
diff --git a/src/link/Elf/synthetic_sections.zig b/src/link/Elf/synthetic_sections.zig
index 00d3b41b61..f178f1370f 100644
--- a/src/link/Elf/synthetic_sections.zig
+++ b/src/link/Elf/synthetic_sections.zig
@@ -29,7 +29,7 @@ pub const GotSection = struct {
pub fn address(entry: Entry, elf_file: *Elf) u64 {
const ptr_bytes = @as(u64, elf_file.archPtrWidthBytes());
- const shdr = &elf_file.sections.items(.shdr)[elf_file.got_section_index.?];
+ const shdr = &elf_file.shdrs.items[elf_file.got_section_index.?];
return shdr.sh_addr + @as(u64, entry.cell_index) * ptr_bytes;
}
};
@@ -124,7 +124,7 @@ pub const GotSection = struct {
}
const endian = elf_file.base.options.target.cpu.arch.endian();
const entry = got.entries.items[index];
- const shdr = &elf_file.sections.items(.shdr)[elf_file.got_section_index.?];
+ const shdr = &elf_file.shdrs.items[elf_file.got_section_index.?];
const off = shdr.sh_offset + @as(u64, entry_size) * entry.cell_index;
const vaddr = shdr.sh_addr + @as(u64, entry_size) * entry.cell_index;
const value = elf_file.symbol(entry.symbol_index).value;