mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
elf: streamline sections container
This commit is contained in:
parent
a6bf762a8b
commit
a9d3885ac7
@ -317,7 +317,7 @@ pub const Section = struct {
|
||||
fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void {
|
||||
if (dwarf.bin_file.cast(.elf)) |elf_file| {
|
||||
try elf_file.growNonAllocSection(sec.index, len, @intCast(sec.alignment.toByteUnits().?), true);
|
||||
const shdr = &elf_file.shdrs.items[sec.index];
|
||||
const shdr = &elf_file.sections.items(.shdr)[sec.index];
|
||||
sec.off = shdr.sh_offset;
|
||||
sec.len = shdr.sh_size;
|
||||
} else if (dwarf.bin_file.cast(.macho)) |macho_file| {
|
||||
@ -340,7 +340,7 @@ pub const Section = struct {
|
||||
sec.off += len;
|
||||
sec.len -= len;
|
||||
if (dwarf.bin_file.cast(.elf)) |elf_file| {
|
||||
const shdr = &elf_file.shdrs.items[sec.index];
|
||||
const shdr = &elf_file.sections.items(.shdr)[sec.index];
|
||||
shdr.sh_offset = sec.off;
|
||||
shdr.sh_size = sec.len;
|
||||
} else if (dwarf.bin_file.cast(.macho)) |macho_file| {
|
||||
@ -771,7 +771,7 @@ const Entry = struct {
|
||||
log.err("missing {} from {s}", .{
|
||||
@as(Entry.Index, @enumFromInt(entry - unit.entries.items.ptr)),
|
||||
std.mem.sliceTo(if (dwarf.bin_file.cast(.elf)) |elf_file|
|
||||
elf_file.shstrtab.items[elf_file.shdrs.items[sec.index].sh_name..]
|
||||
elf_file.shstrtab.items[elf_file.sections.items(.shdr)[sec.index].sh_name..]
|
||||
else if (dwarf.bin_file.cast(.macho)) |macho_file|
|
||||
if (macho_file.d_sym) |*d_sym|
|
||||
&d_sym.sections.items[sec.index].segname
|
||||
@ -1529,7 +1529,7 @@ pub fn reloadSectionMetadata(dwarf: *Dwarf) void {
|
||||
elf_file.debug_rnglists_section_index.?,
|
||||
elf_file.debug_str_section_index.?,
|
||||
}) |sec, section_index| {
|
||||
const shdr = &elf_file.shdrs.items[section_index];
|
||||
const shdr = &elf_file.sections.items(.shdr)[section_index];
|
||||
sec.index = section_index;
|
||||
sec.off = shdr.sh_offset;
|
||||
sec.len = shdr.sh_size;
|
||||
|
||||
424
src/link/Elf.zig
424
src/link/Elf.zig
File diff suppressed because it is too large
Load Diff
@ -48,7 +48,7 @@ pub fn name(self: Atom, elf_file: *Elf) [:0]const u8 {
|
||||
}
|
||||
|
||||
pub fn address(self: Atom, elf_file: *Elf) i64 {
|
||||
const shdr = elf_file.shdrs.items[self.output_section_index];
|
||||
const shdr = elf_file.sections.items(.shdr)[self.output_section_index];
|
||||
return @as(i64, @intCast(shdr.sh_addr)) + self.value;
|
||||
}
|
||||
|
||||
@ -116,10 +116,10 @@ pub fn freeListEligible(self: Atom, elf_file: *Elf) bool {
|
||||
|
||||
pub fn allocate(self: *Atom, elf_file: *Elf) !void {
|
||||
const zo = elf_file.zigObjectPtr().?;
|
||||
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 slice = elf_file.sections.slice();
|
||||
const shdr = &slice.items(.shdr)[self.output_section_index];
|
||||
const free_list = &slice.items(.free_list)[self.output_section_index];
|
||||
const last_atom_index = &slice.items(.last_atom_index)[self.output_section_index];
|
||||
const new_atom_ideal_capacity = Elf.padToIdeal(self.size);
|
||||
|
||||
// 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 {
|
||||
const comp = elf_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const shndx = self.output_section_index;
|
||||
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;
|
||||
const slice = elf_file.sections.slice();
|
||||
const free_list = &slice.items(.free_list)[shndx];
|
||||
const last_atom_index = &slice.items(.last_atom_index)[shndx];
|
||||
var already_have_free_list_node = false;
|
||||
{
|
||||
var i: usize = 0;
|
||||
|
||||
@ -129,9 +129,10 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
|
||||
|
||||
pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
const slice = elf_file.sections.slice();
|
||||
|
||||
var nsyms: usize = 0;
|
||||
for (elf_file.shdrs.items) |shdr| {
|
||||
for (slice.items(.shdr)) |shdr| {
|
||||
if (elf_file.getStartStopBasename(shdr)) |_| {
|
||||
nsyms += 2; // __start_, __stop_
|
||||
}
|
||||
@ -143,7 +144,7 @@ pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
|
||||
try self.symbols_extra.ensureUnusedCapacity(gpa, nsyms * @sizeOf(Symbol.Extra));
|
||||
try self.symbols_resolver.ensureUnusedCapacity(gpa, nsyms);
|
||||
|
||||
for (elf_file.shdrs.items) |shdr| {
|
||||
for (slice.items(.shdr)) |shdr| {
|
||||
if (elf_file.getStartStopBasename(shdr)) |name| {
|
||||
const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name});
|
||||
defer gpa.free(start_name);
|
||||
@ -193,6 +194,7 @@ pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
|
||||
pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
|
||||
const comp = elf_file.base.comp;
|
||||
const link_mode = comp.config.link_mode;
|
||||
const shdrs = elf_file.sections.items(.shdr);
|
||||
|
||||
const allocSymbol = struct {
|
||||
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 {
|
||||
|
||||
// _DYNAMIC
|
||||
if (elf_file.dynamic_section_index) |shndx| {
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
allocSymbol(self, self.dynamic_index.?, shdr.sh_addr, shndx, elf_file);
|
||||
}
|
||||
|
||||
@ -213,21 +215,21 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
|
||||
|
||||
// __init_array_start, __init_array_end
|
||||
if (elf_file.sectionByName(".init_array")) |shndx| {
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
allocSymbol(self, self.init_array_start_index.?, shdr.sh_addr, shndx, elf_file);
|
||||
allocSymbol(self, self.init_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);
|
||||
}
|
||||
|
||||
// __fini_array_start, __fini_array_end
|
||||
if (elf_file.sectionByName(".fini_array")) |shndx| {
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
allocSymbol(self, self.fini_array_start_index.?, shdr.sh_addr, shndx, elf_file);
|
||||
allocSymbol(self, self.fini_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);
|
||||
}
|
||||
|
||||
// __preinit_array_start, __preinit_array_end
|
||||
if (elf_file.sectionByName(".preinit_array")) |shndx| {
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
allocSymbol(self, self.preinit_array_start_index.?, shdr.sh_addr, shndx, elf_file);
|
||||
allocSymbol(self, self.preinit_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file);
|
||||
}
|
||||
@ -235,38 +237,38 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
|
||||
// _GLOBAL_OFFSET_TABLE_
|
||||
if (elf_file.getTarget().cpu.arch == .x86_64) {
|
||||
if (elf_file.got_plt_section_index) |shndx| {
|
||||
const shdr = elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file);
|
||||
}
|
||||
} else {
|
||||
if (elf_file.got_section_index) |shndx| {
|
||||
const shdr = elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file);
|
||||
}
|
||||
}
|
||||
|
||||
// _PROCEDURE_LINKAGE_TABLE_
|
||||
if (elf_file.plt_section_index) |shndx| {
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
allocSymbol(self, self.plt_index.?, shdr.sh_addr, shndx, elf_file);
|
||||
}
|
||||
|
||||
// __dso_handle
|
||||
if (self.dso_handle_index) |index| {
|
||||
const shdr = &elf_file.shdrs.items[1];
|
||||
const shdr = shdrs[1];
|
||||
allocSymbol(self, index, shdr.sh_addr, 0, elf_file);
|
||||
}
|
||||
|
||||
// __GNU_EH_FRAME_HDR
|
||||
if (elf_file.eh_frame_hdr_section_index) |shndx| {
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
allocSymbol(self, self.gnu_eh_frame_hdr_index.?, shdr.sh_addr, shndx, elf_file);
|
||||
}
|
||||
|
||||
// __rela_iplt_start, __rela_iplt_end
|
||||
if (elf_file.rela_dyn_section_index) |shndx| blk: {
|
||||
if (link_mode != .static or comp.config.pie) break :blk;
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
const end_addr = shdr.sh_addr + shdr.sh_size;
|
||||
const start_addr = end_addr - elf_file.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela);
|
||||
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 {
|
||||
{
|
||||
var value: u64 = 0;
|
||||
var osec: u32 = 0;
|
||||
for (elf_file.shdrs.items, 0..) |shdr, shndx| {
|
||||
for (shdrs, 0..) |shdr, shndx| {
|
||||
if (shdr.sh_flags & elf.SHF_ALLOC != 0) {
|
||||
value = shdr.sh_addr + shdr.sh_size;
|
||||
osec = @intCast(shndx);
|
||||
@ -289,7 +291,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
|
||||
// __global_pointer$
|
||||
if (self.global_pointer_index) |index| {
|
||||
const value, const osec = if (elf_file.sectionByName(".sdata")) |shndx| .{
|
||||
elf_file.shdrs.items[shndx].sh_addr + 0x800,
|
||||
shdrs[shndx].sh_addr + 0x800,
|
||||
shndx,
|
||||
} else .{ 0, 0 };
|
||||
allocSymbol(self, index, value, osec, elf_file);
|
||||
@ -305,7 +307,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
|
||||
const stop_ref = self.resolveSymbol(self.start_stop_indexes.items[index + 1], elf_file);
|
||||
const stop = elf_file.symbol(stop_ref).?;
|
||||
const shndx = elf_file.sectionByName(name["__start_".len..]).?;
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
start.value = @intCast(shdr.sh_addr);
|
||||
start.output_section_index = shndx;
|
||||
stop.value = @intCast(shdr.sh_addr + shdr.sh_size);
|
||||
|
||||
@ -998,9 +998,8 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {
|
||||
|
||||
const comp = elf_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const gop = try elf_file.output_sections.getOrPut(gpa, atom_ptr.output_section_index);
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{};
|
||||
try gop.value_ptr.append(gpa, .{ .index = atom_index, .file = self.index });
|
||||
const atom_list = &elf_file.sections.items(.atom_list)[atom_ptr.output_section_index];
|
||||
try atom_list.append(gpa, .{ .index = atom_index, .file = self.index });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1011,14 +1010,15 @@ pub fn initRelaSections(self: *Object, elf_file: *Elf) !void {
|
||||
const shndx = atom_ptr.relocsShndx() orelse continue;
|
||||
const shdr = self.shdrs.items[shndx];
|
||||
const out_shndx = try self.initOutputSection(elf_file, shdr);
|
||||
const out_shdr = &elf_file.shdrs.items[out_shndx];
|
||||
const out_shdr = &elf_file.sections.items(.shdr)[out_shndx];
|
||||
out_shdr.sh_type = elf.SHT_RELA;
|
||||
out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela);
|
||||
out_shdr.sh_entsize = @sizeOf(elf.Elf64_Rela);
|
||||
out_shdr.sh_flags |= elf.SHF_INFO_LINK;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {
|
||||
pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) void {
|
||||
for (self.atoms_indexes.items) |atom_index| {
|
||||
const atom_ptr = self.atom(atom_index) orelse continue;
|
||||
if (!atom_ptr.alive) continue;
|
||||
@ -1027,15 +1027,10 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void {
|
||||
const shdr = self.shdrs.items[shndx];
|
||||
break :blk self.initOutputSection(elf_file, shdr) catch unreachable;
|
||||
};
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
const slice = elf_file.sections.slice();
|
||||
const shdr = &slice.items(.shdr)[shndx];
|
||||
shdr.sh_info = atom_ptr.output_section_index;
|
||||
shdr.sh_link = elf_file.symtab_section_index.?;
|
||||
|
||||
const comp = elf_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const gop = try elf_file.output_rela_sections.getOrPut(gpa, atom_ptr.output_section_index);
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{ .shndx = shndx };
|
||||
try gop.value_ptr.atom_list.append(gpa, .{ .index = atom_index, .file = self.index });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -126,7 +126,7 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true, trampoline: bool
|
||||
const sym_name = symbol.name(elf_file);
|
||||
const sh_addr, const sh_size = blk: {
|
||||
const shndx = elf_file.eh_frame_section_index orelse break :blk .{ 0, 0 };
|
||||
const shdr = elf_file.shdrs.items[shndx];
|
||||
const shdr = elf_file.sections.items(.shdr)[shndx];
|
||||
break :blk .{ shdr.sh_addr, shdr.sh_size };
|
||||
};
|
||||
if (mem.startsWith(u8, sym_name, "__EH_FRAME_BEGIN__") or
|
||||
@ -173,7 +173,7 @@ pub fn gotAddress(symbol: Symbol, elf_file: *Elf) i64 {
|
||||
pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 {
|
||||
if (!(symbol.flags.has_plt and symbol.flags.has_got)) return 0;
|
||||
const extras = symbol.extra(elf_file);
|
||||
const shdr = elf_file.shdrs.items[elf_file.plt_got_section_index.?];
|
||||
const shdr = elf_file.sections.items(.shdr)[elf_file.plt_got_section_index.?];
|
||||
const cpu_arch = elf_file.getTarget().cpu.arch;
|
||||
return @intCast(shdr.sh_addr + extras.plt_got * PltGotSection.entrySize(cpu_arch));
|
||||
}
|
||||
@ -181,7 +181,7 @@ pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 {
|
||||
pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 {
|
||||
if (!symbol.flags.has_plt) return 0;
|
||||
const extras = symbol.extra(elf_file);
|
||||
const shdr = elf_file.shdrs.items[elf_file.plt_section_index.?];
|
||||
const shdr = elf_file.sections.items(.shdr)[elf_file.plt_section_index.?];
|
||||
const cpu_arch = elf_file.getTarget().cpu.arch;
|
||||
return @intCast(shdr.sh_addr + extras.plt * PltSection.entrySize(cpu_arch) + PltSection.preambleSize(cpu_arch));
|
||||
}
|
||||
@ -189,13 +189,13 @@ pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 {
|
||||
pub fn gotPltAddress(symbol: Symbol, elf_file: *Elf) i64 {
|
||||
if (!symbol.flags.has_plt) return 0;
|
||||
const extras = symbol.extra(elf_file);
|
||||
const shdr = elf_file.shdrs.items[elf_file.got_plt_section_index.?];
|
||||
const shdr = elf_file.sections.items(.shdr)[elf_file.got_plt_section_index.?];
|
||||
return @intCast(shdr.sh_addr + extras.plt * 8 + GotPltSection.preamble_size);
|
||||
}
|
||||
|
||||
pub fn copyRelAddress(symbol: Symbol, elf_file: *Elf) i64 {
|
||||
if (!symbol.flags.has_copy_rel) return 0;
|
||||
const shdr = elf_file.shdrs.items[elf_file.copy_rel_section_index.?];
|
||||
const shdr = elf_file.sections.items(.shdr)[elf_file.copy_rel_section_index.?];
|
||||
return @as(i64, @intCast(shdr.sh_addr)) + symbol.value;
|
||||
}
|
||||
|
||||
@ -300,7 +300,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
|
||||
break :blk 0;
|
||||
}
|
||||
if (st_shndx == elf.SHN_ABS or st_shndx == elf.SHN_COMMON) break :blk symbol.address(.{ .plt = false }, elf_file);
|
||||
const shdr = elf_file.shdrs.items[st_shndx];
|
||||
const shdr = elf_file.sections.items(.shdr)[st_shndx];
|
||||
if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined)
|
||||
break :blk symbol.address(.{ .plt = false }, elf_file) - elf_file.tlsAddress();
|
||||
break :blk symbol.address(.{ .plt = false, .trampoline = false }, elf_file);
|
||||
|
||||
@ -170,25 +170,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
.addralign = 1,
|
||||
.offset = std.math.maxInt(u64),
|
||||
});
|
||||
const shdr = &elf_file.shdrs.items[elf_file.zig_text_section_index.?];
|
||||
const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_text_section_index.?];
|
||||
const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_text_section_index.?];
|
||||
try fillSection(elf_file, shdr, options.program_code_size_hint, elf_file.phdr_zig_load_re_index);
|
||||
if (elf_file.base.isRelocatable()) {
|
||||
const rela_shndx = try elf_file.addRelaShdr(
|
||||
_ = try elf_file.addRelaShdr(
|
||||
try elf_file.insertShString(".rela.text.zig"),
|
||||
elf_file.zig_text_section_index.?,
|
||||
);
|
||||
try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{
|
||||
.shndx = rela_shndx,
|
||||
});
|
||||
} else {
|
||||
try elf_file.phdr_to_shdr_table.putNoClobber(
|
||||
gpa,
|
||||
elf_file.zig_text_section_index.?,
|
||||
elf_file.phdr_zig_load_re_index.?,
|
||||
);
|
||||
phndx.* = elf_file.phdr_zig_load_re_index.?;
|
||||
}
|
||||
try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{});
|
||||
try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{});
|
||||
}
|
||||
|
||||
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 {
|
||||
.flags = elf.SHF_ALLOC | elf.SHF_WRITE,
|
||||
.offset = std.math.maxInt(u64),
|
||||
});
|
||||
const shdr = &elf_file.shdrs.items[elf_file.zig_data_rel_ro_section_index.?];
|
||||
const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_data_rel_ro_section_index.?];
|
||||
const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_data_rel_ro_section_index.?];
|
||||
try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_ro_index);
|
||||
if (elf_file.base.isRelocatable()) {
|
||||
const rela_shndx = try elf_file.addRelaShdr(
|
||||
_ = try elf_file.addRelaShdr(
|
||||
try elf_file.insertShString(".rela.data.rel.ro.zig"),
|
||||
elf_file.zig_data_rel_ro_section_index.?,
|
||||
);
|
||||
try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{
|
||||
.shndx = rela_shndx,
|
||||
});
|
||||
} else {
|
||||
try elf_file.phdr_to_shdr_table.putNoClobber(
|
||||
gpa,
|
||||
elf_file.zig_data_rel_ro_section_index.?,
|
||||
elf_file.phdr_zig_load_ro_index.?,
|
||||
);
|
||||
phndx.* = elf_file.phdr_zig_load_ro_index.?;
|
||||
}
|
||||
try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{});
|
||||
try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{});
|
||||
}
|
||||
|
||||
if (elf_file.zig_data_section_index == null) {
|
||||
@ -228,25 +212,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
.flags = elf.SHF_ALLOC | elf.SHF_WRITE,
|
||||
.offset = std.math.maxInt(u64),
|
||||
});
|
||||
const shdr = &elf_file.shdrs.items[elf_file.zig_data_section_index.?];
|
||||
const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_data_section_index.?];
|
||||
const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_data_section_index.?];
|
||||
try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_rw_index);
|
||||
if (elf_file.base.isRelocatable()) {
|
||||
const rela_shndx = try elf_file.addRelaShdr(
|
||||
_ = try elf_file.addRelaShdr(
|
||||
try elf_file.insertShString(".rela.data.zig"),
|
||||
elf_file.zig_data_section_index.?,
|
||||
);
|
||||
try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{
|
||||
.shndx = rela_shndx,
|
||||
});
|
||||
} else {
|
||||
try elf_file.phdr_to_shdr_table.putNoClobber(
|
||||
gpa,
|
||||
elf_file.zig_data_section_index.?,
|
||||
elf_file.phdr_zig_load_rw_index.?,
|
||||
);
|
||||
phndx.* = elf_file.phdr_zig_load_rw_index.?;
|
||||
}
|
||||
try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{});
|
||||
try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{});
|
||||
}
|
||||
|
||||
if (elf_file.zig_bss_section_index == null) {
|
||||
@ -257,17 +233,16 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
.flags = elf.SHF_ALLOC | elf.SHF_WRITE,
|
||||
.offset = 0,
|
||||
});
|
||||
const shdr = &elf_file.shdrs.items[elf_file.zig_bss_section_index.?];
|
||||
if (elf_file.phdr_zig_load_zerofill_index) |phndx| {
|
||||
const phdr = elf_file.phdrs.items[phndx];
|
||||
const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_bss_section_index.?];
|
||||
const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_bss_section_index.?];
|
||||
if (elf_file.base.isRelocatable()) {
|
||||
shdr.sh_size = 1024;
|
||||
} else {
|
||||
phndx.* = elf_file.phdr_zig_load_zerofill_index.?;
|
||||
const phdr = elf_file.phdrs.items[phndx.*];
|
||||
shdr.sh_addr = phdr.p_vaddr;
|
||||
shdr.sh_size = phdr.p_memsz;
|
||||
try elf_file.phdr_to_shdr_table.putNoClobber(gpa, elf_file.zig_bss_section_index.?, phndx);
|
||||
} else {
|
||||
shdr.sh_size = 1024;
|
||||
}
|
||||
try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_bss_section_index.?, .{});
|
||||
try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_bss_section_index.?, .{});
|
||||
}
|
||||
|
||||
switch (comp.config.debug_format) {
|
||||
@ -305,7 +280,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
});
|
||||
self.debug_str_section_dirty = true;
|
||||
self.debug_str_index = try addSectionSymbol(self, gpa, ".debug_str", .@"1", elf_file.debug_str_section_index.?);
|
||||
try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_str_section_index.?, .{});
|
||||
}
|
||||
|
||||
if (elf_file.debug_info_section_index == null) {
|
||||
@ -316,7 +290,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
});
|
||||
self.debug_info_section_dirty = true;
|
||||
self.debug_info_index = try addSectionSymbol(self, gpa, ".debug_info", .@"1", elf_file.debug_info_section_index.?);
|
||||
try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_info_section_index.?, .{});
|
||||
}
|
||||
|
||||
if (elf_file.debug_abbrev_section_index == null) {
|
||||
@ -327,7 +300,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
});
|
||||
self.debug_abbrev_section_dirty = true;
|
||||
self.debug_abbrev_index = try addSectionSymbol(self, gpa, ".debug_abbrev", .@"1", elf_file.debug_abbrev_section_index.?);
|
||||
try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_abbrev_section_index.?, .{});
|
||||
}
|
||||
|
||||
if (elf_file.debug_aranges_section_index == null) {
|
||||
@ -338,7 +310,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
});
|
||||
self.debug_aranges_section_dirty = true;
|
||||
self.debug_aranges_index = try addSectionSymbol(self, gpa, ".debug_aranges", .@"16", elf_file.debug_aranges_section_index.?);
|
||||
try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_aranges_section_index.?, .{});
|
||||
}
|
||||
|
||||
if (elf_file.debug_line_section_index == null) {
|
||||
@ -349,7 +320,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
});
|
||||
self.debug_line_section_dirty = true;
|
||||
self.debug_line_index = try addSectionSymbol(self, gpa, ".debug_line", .@"1", elf_file.debug_line_section_index.?);
|
||||
try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_line_section_index.?, .{});
|
||||
}
|
||||
|
||||
if (elf_file.debug_line_str_section_index == null) {
|
||||
@ -362,7 +332,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
});
|
||||
self.debug_line_str_section_dirty = true;
|
||||
self.debug_line_str_index = try addSectionSymbol(self, gpa, ".debug_line_str", .@"1", elf_file.debug_line_str_section_index.?);
|
||||
try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_line_str_section_index.?, .{});
|
||||
}
|
||||
|
||||
if (elf_file.debug_loclists_section_index == null) {
|
||||
@ -373,7 +342,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
});
|
||||
self.debug_loclists_section_dirty = true;
|
||||
self.debug_loclists_index = try addSectionSymbol(self, gpa, ".debug_loclists", .@"1", elf_file.debug_loclists_section_index.?);
|
||||
try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_loclists_section_index.?, .{});
|
||||
}
|
||||
|
||||
if (elf_file.debug_rnglists_section_index == null) {
|
||||
@ -384,7 +352,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
});
|
||||
self.debug_rnglists_section_dirty = true;
|
||||
self.debug_rnglists_index = try addSectionSymbol(self, gpa, ".debug_rnglists", .@"1", elf_file.debug_rnglists_section_index.?);
|
||||
try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_rnglists_section_index.?, .{});
|
||||
}
|
||||
|
||||
try dwarf.initMetadata();
|
||||
@ -507,7 +474,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
|
||||
const atom_ptr = self.atom(sym.ref.index).?;
|
||||
if (!atom_ptr.alive) continue;
|
||||
const shndx = sym.outputShndx(elf_file).?;
|
||||
const shdr = elf_file.shdrs.items[shndx];
|
||||
const shdr = elf_file.sections.items(.shdr)[shndx];
|
||||
const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
|
||||
esym.st_size = shdr.sh_size;
|
||||
atom_ptr.size = shdr.sh_size;
|
||||
@ -667,13 +634,10 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
|
||||
}
|
||||
|
||||
if (elf_file.base.isRelocatable() and relocs.items.len > 0) {
|
||||
const gop = try elf_file.output_rela_sections.getOrPut(gpa, shndx);
|
||||
if (!gop.found_existing) {
|
||||
const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)});
|
||||
defer gpa.free(rela_sect_name);
|
||||
const rela_sh_name = try elf_file.insertShString(rela_sect_name);
|
||||
const rela_shndx = try elf_file.addRelaShdr(rela_sh_name, shndx);
|
||||
gop.value_ptr.* = .{ .shndx = rela_shndx };
|
||||
const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)});
|
||||
defer gpa.free(rela_sect_name);
|
||||
if (elf_file.sectionByName(rela_sect_name) == null) {
|
||||
_ = try elf_file.addRelaShdr(try elf_file.insertShString(rela_sect_name), shndx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -769,7 +733,7 @@ fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Sym
|
||||
pub fn inputShdr(self: *ZigObject, atom_index: Atom.Index, elf_file: *Elf) elf.Elf64_Shdr {
|
||||
const atom_ptr = self.atom(atom_index) orelse return Elf.null_shdr;
|
||||
const shndx = atom_ptr.output_section_index;
|
||||
var shdr = elf_file.shdrs.items[shndx];
|
||||
var shdr = elf_file.sections.items(.shdr)[shndx];
|
||||
shdr.sh_addr = 0;
|
||||
shdr.sh_offset = 0;
|
||||
shdr.sh_size = atom_ptr.size;
|
||||
@ -947,8 +911,8 @@ pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void {
|
||||
.p32 => @sizeOf(elf.Elf32_Shdr),
|
||||
.p64 => @sizeOf(elf.Elf64_Shdr),
|
||||
};
|
||||
var end_pos: u64 = elf_file.shdr_table_offset.? + elf_file.shdrs.items.len * shsize;
|
||||
for (elf_file.shdrs.items) |shdr| {
|
||||
var end_pos: u64 = elf_file.shdr_table_offset.? + elf_file.sections.items(.shdr).len * shsize;
|
||||
for (elf_file.sections.items(.shdr)) |shdr| {
|
||||
if (shdr.sh_type == elf.SHT_NOBITS) continue;
|
||||
end_pos = @max(end_pos, shdr.sh_offset + shdr.sh_size);
|
||||
}
|
||||
@ -1001,12 +965,11 @@ pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void {
|
||||
// TODO this check will become obsolete when we rework our relocs mechanism at the ZigObject level
|
||||
if (self.relocs.items[rela_shndx].items.len == 0) continue;
|
||||
const out_shndx = atom_ptr.output_section_index;
|
||||
const out_shdr = elf_file.shdrs.items[out_shndx];
|
||||
const out_shdr = elf_file.sections.items(.shdr)[out_shndx];
|
||||
if (out_shdr.sh_type == elf.SHT_NOBITS) continue;
|
||||
|
||||
const atom_list = &elf_file.sections.items(.atom_list)[out_shndx];
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
const sec = elf_file.output_rela_sections.getPtr(out_shndx).?;
|
||||
try sec.atom_list.append(gpa, .{ .index = atom_index, .file = self.index });
|
||||
try atom_list.append(gpa, .{ .index = atom_index, .file = self.index });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1076,7 +1039,7 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void {
|
||||
pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
const atom_ptr = self.atom(atom_index).?;
|
||||
const shdr = &elf_file.shdrs.items[atom_ptr.output_section_index];
|
||||
const shdr = &elf_file.sections.items(.shdr)[atom_ptr.output_section_index];
|
||||
|
||||
if (shdr.sh_flags & elf.SHF_TLS != 0) {
|
||||
const tlv = self.tls_variables.get(atom_index).?;
|
||||
@ -1403,7 +1366,7 @@ fn updateNavCode(
|
||||
}
|
||||
}
|
||||
|
||||
const shdr = elf_file.shdrs.items[shdr_index];
|
||||
const shdr = elf_file.sections.items(.shdr)[shdr_index];
|
||||
if (shdr.sh_type != elf.SHT_NOBITS) {
|
||||
const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
|
||||
try elf_file.base.file.?.pwriteAll(code, file_offset);
|
||||
@ -1458,16 +1421,13 @@ fn updateTlv(
|
||||
gop.value_ptr.* = .{ .symbol_index = sym_index };
|
||||
|
||||
// We only store the data for the TLV if it's non-zerofill.
|
||||
if (elf_file.shdrs.items[shndx].sh_type != elf.SHT_NOBITS) {
|
||||
if (elf_file.sections.items(.shdr)[shndx].sh_type != elf.SHT_NOBITS) {
|
||||
gop.value_ptr.code = try gpa.dupe(u8, code);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const gop = try elf_file.output_sections.getOrPut(gpa, atom_ptr.output_section_index);
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{};
|
||||
try gop.value_ptr.append(gpa, .{ .index = atom_ptr.atom_index, .file = self.index });
|
||||
}
|
||||
const atom_list = &elf_file.sections.items(.atom_list)[atom_ptr.output_section_index];
|
||||
try atom_list.append(gpa, .{ .index = atom_ptr.atom_index, .file = self.index });
|
||||
}
|
||||
|
||||
pub fn updateFunc(
|
||||
@ -1519,7 +1479,7 @@ pub fn updateFunc(
|
||||
const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code);
|
||||
log.debug("setting shdr({x},{s}) for {}", .{
|
||||
shndx,
|
||||
elf_file.getShString(elf_file.shdrs.items[shndx].sh_name),
|
||||
elf_file.getShString(elf_file.sections.items(.shdr)[shndx].sh_name),
|
||||
ip.getNav(func.owner_nav).fqn.fmt(ip),
|
||||
});
|
||||
const old_rva, const old_alignment = blk: {
|
||||
@ -1647,10 +1607,10 @@ pub fn updateNav(
|
||||
const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code);
|
||||
log.debug("setting shdr({x},{s}) for {}", .{
|
||||
shndx,
|
||||
elf_file.getShString(elf_file.shdrs.items[shndx].sh_name),
|
||||
elf_file.getShString(elf_file.sections.items(.shdr)[shndx].sh_name),
|
||||
nav.fqn.fmt(ip),
|
||||
});
|
||||
if (elf_file.shdrs.items[shndx].sh_flags & elf.SHF_TLS != 0)
|
||||
if (elf_file.sections.items(.shdr)[shndx].sh_flags & elf.SHF_TLS != 0)
|
||||
try self.updateTlv(elf_file, pt, nav_index, sym_index, shndx, code)
|
||||
else
|
||||
try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT);
|
||||
@ -1749,7 +1709,7 @@ fn updateLazySymbol(
|
||||
local_sym.value = 0;
|
||||
local_esym.st_value = 0;
|
||||
|
||||
const shdr = elf_file.shdrs.items[output_section_index];
|
||||
const shdr = elf_file.sections.items(.shdr)[output_section_index];
|
||||
const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
|
||||
try elf_file.base.file.?.pwriteAll(code, file_offset);
|
||||
}
|
||||
@ -1805,7 +1765,7 @@ fn lowerConst(
|
||||
// TODO rename and re-audit this method
|
||||
errdefer self.freeNavMetadata(elf_file, sym_index);
|
||||
|
||||
const shdr = elf_file.shdrs.items[output_section_index];
|
||||
const shdr = elf_file.sections.items(.shdr)[output_section_index];
|
||||
const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
|
||||
try elf_file.base.file.?.pwriteAll(code, file_offset);
|
||||
|
||||
@ -1969,7 +1929,7 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) u64 {
|
||||
|
||||
fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void {
|
||||
const atom_ptr = tr_sym.atom(elf_file).?;
|
||||
const shdr = elf_file.shdrs.items[atom_ptr.output_section_index];
|
||||
const shdr = elf_file.sections.items(.shdr)[atom_ptr.output_section_index];
|
||||
const fileoff = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
|
||||
const source_addr = tr_sym.address(.{}, elf_file);
|
||||
const target_addr = target.address(.{ .trampoline = false }, elf_file);
|
||||
|
||||
@ -13,7 +13,7 @@ pub const Fde = struct {
|
||||
|
||||
pub fn address(fde: Fde, elf_file: *Elf) u64 {
|
||||
const base: u64 = if (elf_file.eh_frame_section_index) |shndx|
|
||||
elf_file.shdrs.items[shndx].sh_addr
|
||||
elf_file.sections.items(.shdr)[shndx].sh_addr
|
||||
else
|
||||
0;
|
||||
return base + fde.out_offset;
|
||||
@ -112,7 +112,7 @@ pub const Cie = struct {
|
||||
|
||||
pub fn address(cie: Cie, elf_file: *Elf) u64 {
|
||||
const base: u64 = if (elf_file.eh_frame_section_index) |shndx|
|
||||
elf_file.shdrs.items[shndx].sh_addr
|
||||
elf_file.sections.items(.shdr)[shndx].sh_addr
|
||||
else
|
||||
0;
|
||||
return base + cie.out_offset;
|
||||
@ -326,7 +326,9 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file:
|
||||
}
|
||||
|
||||
pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
|
||||
relocs_log.debug("{x}: .eh_frame", .{elf_file.shdrs.items[elf_file.eh_frame_section_index.?].sh_addr});
|
||||
relocs_log.debug("{x}: .eh_frame", .{
|
||||
elf_file.sections.items(.shdr)[elf_file.eh_frame_section_index.?].sh_addr,
|
||||
});
|
||||
|
||||
var has_reloc_errors = false;
|
||||
|
||||
@ -446,7 +448,9 @@ fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Re
|
||||
}
|
||||
|
||||
pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void {
|
||||
relocs_log.debug("{x}: .eh_frame", .{elf_file.shdrs.items[elf_file.eh_frame_section_index.?].sh_addr});
|
||||
relocs_log.debug("{x}: .eh_frame", .{
|
||||
elf_file.sections.items(.shdr)[elf_file.eh_frame_section_index.?].sh_addr,
|
||||
});
|
||||
|
||||
for (elf_file.objects.items) |index| {
|
||||
const object = elf_file.file(index).?.object;
|
||||
@ -482,8 +486,9 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {
|
||||
try writer.writeByte(EH_PE.udata4);
|
||||
try writer.writeByte(EH_PE.datarel | EH_PE.sdata4);
|
||||
|
||||
const eh_frame_shdr = elf_file.shdrs.items[elf_file.eh_frame_section_index.?];
|
||||
const eh_frame_hdr_shdr = elf_file.shdrs.items[elf_file.eh_frame_hdr_section_index.?];
|
||||
const shdrs = elf_file.sections.items(.shdr);
|
||||
const eh_frame_shdr = shdrs[elf_file.eh_frame_section_index.?];
|
||||
const eh_frame_hdr_shdr = shdrs[elf_file.eh_frame_hdr_section_index.?];
|
||||
const num_fdes = @as(u32, @intCast(@divExact(eh_frame_hdr_shdr.sh_size - eh_frame_hdr_header_size, 8)));
|
||||
try writer.writeInt(
|
||||
u32,
|
||||
|
||||
@ -29,7 +29,7 @@ pub const MergeSection = struct {
|
||||
}
|
||||
|
||||
pub fn address(msec: MergeSection, elf_file: *Elf) i64 {
|
||||
const shdr = elf_file.shdrs.items[msec.output_section_index];
|
||||
const shdr = elf_file.sections.items(.shdr)[msec.output_section_index];
|
||||
return @intCast(shdr.sh_addr + msec.value);
|
||||
}
|
||||
|
||||
@ -108,13 +108,11 @@ pub const MergeSection = struct {
|
||||
}
|
||||
|
||||
pub fn initOutputSection(msec: *MergeSection, elf_file: *Elf) !void {
|
||||
const shndx = elf_file.sectionByName(msec.name(elf_file)) orelse try elf_file.addSection(.{
|
||||
msec.output_section_index = elf_file.sectionByName(msec.name(elf_file)) orelse try elf_file.addSection(.{
|
||||
.name = msec.name_offset,
|
||||
.type = msec.type,
|
||||
.flags = msec.flags,
|
||||
});
|
||||
try elf_file.output_sections.put(elf_file.base.comp.gpa, shndx, .{});
|
||||
msec.output_section_index = shndx;
|
||||
}
|
||||
|
||||
pub fn addMergeSubsection(msec: *MergeSection, allocator: Allocator) !MergeSubsection.Index {
|
||||
|
||||
@ -209,7 +209,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]const
|
||||
for (elf_file.objects.items) |index| {
|
||||
const object = elf_file.file(index).?.object;
|
||||
try object.addAtomsToOutputSections(elf_file);
|
||||
try object.addAtomsToRelaSections(elf_file);
|
||||
object.addAtomsToRelaSections(elf_file);
|
||||
}
|
||||
try elf_file.updateMergeSectionSizes();
|
||||
try updateSectionSizes(elf_file);
|
||||
@ -347,36 +347,37 @@ fn initComdatGroups(elf_file: *Elf) !void {
|
||||
}
|
||||
|
||||
fn updateSectionSizes(elf_file: *Elf) !void {
|
||||
for (elf_file.output_sections.keys(), elf_file.output_sections.values()) |shndx, atom_list| {
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
for (atom_list.items) |ref| {
|
||||
const atom_ptr = elf_file.atom(ref) orelse continue;
|
||||
if (!atom_ptr.alive) continue;
|
||||
const offset = atom_ptr.alignment.forward(shdr.sh_size);
|
||||
const padding = offset - shdr.sh_size;
|
||||
atom_ptr.value = @intCast(offset);
|
||||
shdr.sh_size += padding + atom_ptr.size;
|
||||
shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits() orelse 1);
|
||||
}
|
||||
}
|
||||
const slice = elf_file.sections.slice();
|
||||
for (slice.items(.shdr), 0..) |*shdr, shndx| {
|
||||
if (shdr.sh_type != elf.SHT_RELA) {
|
||||
const atom_list = slice.items(.atom_list)[shndx];
|
||||
for (atom_list.items) |ref| {
|
||||
const atom_ptr = elf_file.atom(ref) orelse continue;
|
||||
if (!atom_ptr.alive) continue;
|
||||
const offset = atom_ptr.alignment.forward(shdr.sh_size);
|
||||
const padding = offset - shdr.sh_size;
|
||||
atom_ptr.value = @intCast(offset);
|
||||
shdr.sh_size += padding + atom_ptr.size;
|
||||
shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits() orelse 1);
|
||||
}
|
||||
} else {
|
||||
const atom_list = slice.items(.atom_list)[shdr.sh_info];
|
||||
for (atom_list.items) |ref| {
|
||||
const atom_ptr = elf_file.atom(ref) orelse continue;
|
||||
if (!atom_ptr.alive) continue;
|
||||
const relocs = atom_ptr.relocs(elf_file);
|
||||
shdr.sh_size += shdr.sh_entsize * relocs.len;
|
||||
}
|
||||
|
||||
for (elf_file.output_rela_sections.values()) |sec| {
|
||||
const shdr = &elf_file.shdrs.items[sec.shndx];
|
||||
for (sec.atom_list.items) |ref| {
|
||||
const atom_ptr = elf_file.atom(ref) orelse continue;
|
||||
if (!atom_ptr.alive) continue;
|
||||
const relocs = atom_ptr.relocs(elf_file);
|
||||
shdr.sh_size += shdr.sh_entsize * relocs.len;
|
||||
if (shdr.sh_size == 0) shdr.sh_offset = 0;
|
||||
}
|
||||
|
||||
if (shdr.sh_size == 0) shdr.sh_offset = 0;
|
||||
}
|
||||
|
||||
if (elf_file.eh_frame_section_index) |index| {
|
||||
elf_file.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(elf_file);
|
||||
slice.items(.shdr)[index].sh_size = try eh_frame.calcEhFrameSize(elf_file);
|
||||
}
|
||||
if (elf_file.eh_frame_rela_section_index) |index| {
|
||||
const shdr = &elf_file.shdrs.items[index];
|
||||
const shdr = &slice.items(.shdr)[index];
|
||||
shdr.sh_size = eh_frame.calcEhFrameRelocs(elf_file) * shdr.sh_entsize;
|
||||
}
|
||||
|
||||
@ -387,7 +388,7 @@ fn updateSectionSizes(elf_file: *Elf) !void {
|
||||
|
||||
fn updateComdatGroupsSizes(elf_file: *Elf) void {
|
||||
for (elf_file.comdat_group_sections.items) |cg| {
|
||||
const shdr = &elf_file.shdrs.items[cg.shndx];
|
||||
const shdr = &elf_file.sections.items(.shdr)[cg.shndx];
|
||||
shdr.sh_size = cg.size(elf_file);
|
||||
shdr.sh_link = elf_file.symtab_section_index.?;
|
||||
|
||||
@ -399,7 +400,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void {
|
||||
|
||||
/// Allocates alloc sections when merging relocatable objects files together.
|
||||
fn allocateAllocSections(elf_file: *Elf) !void {
|
||||
for (elf_file.shdrs.items) |*shdr| {
|
||||
for (elf_file.sections.items(.shdr)) |*shdr| {
|
||||
if (shdr.sh_type == elf.SHT_NULL) continue;
|
||||
if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
|
||||
if (shdr.sh_type == elf.SHT_NOBITS) {
|
||||
@ -418,13 +419,13 @@ fn allocateAllocSections(elf_file: *Elf) !void {
|
||||
|
||||
fn writeAtoms(elf_file: *Elf) !void {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
const slice = elf_file.sections.slice();
|
||||
|
||||
// TODO iterate over `output_sections` directly
|
||||
for (elf_file.shdrs.items, 0..) |shdr, shndx| {
|
||||
for (slice.items(.shdr), slice.items(.atom_list), 0..) |shdr, atom_list, shndx| {
|
||||
if (shdr.sh_type == elf.SHT_NULL) continue;
|
||||
if (shdr.sh_type == elf.SHT_NOBITS) continue;
|
||||
|
||||
const atom_list = elf_file.output_sections.get(@intCast(shndx)) orelse continue;
|
||||
if (shdr.sh_type == elf.SHT_RELA) continue;
|
||||
if (atom_list.items.len == 0) continue;
|
||||
|
||||
log.debug("writing atoms in '{s}' section", .{elf_file.getShString(shdr.sh_name)});
|
||||
@ -490,18 +491,19 @@ fn writeAtoms(elf_file: *Elf) !void {
|
||||
|
||||
fn writeSyntheticSections(elf_file: *Elf) !void {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
const slice = elf_file.sections.slice();
|
||||
|
||||
for (elf_file.output_rela_sections.values()) |sec| {
|
||||
if (sec.atom_list.items.len == 0) continue;
|
||||
|
||||
const shdr = elf_file.shdrs.items[sec.shndx];
|
||||
for (slice.items(.shdr)) |shdr| {
|
||||
if (shdr.sh_type != elf.SHT_RELA) continue;
|
||||
const atom_list = slice.items(.atom_list)[shdr.sh_info];
|
||||
if (atom_list.items.len == 0) continue;
|
||||
|
||||
const num_relocs = math.cast(usize, @divExact(shdr.sh_size, shdr.sh_entsize)) orelse
|
||||
return error.Overflow;
|
||||
var relocs = try std.ArrayList(elf.Elf64_Rela).initCapacity(gpa, num_relocs);
|
||||
defer relocs.deinit();
|
||||
|
||||
for (sec.atom_list.items) |ref| {
|
||||
for (atom_list.items) |ref| {
|
||||
const atom_ptr = elf_file.atom(ref) orelse continue;
|
||||
if (!atom_ptr.alive) continue;
|
||||
try atom_ptr.writeRelocs(elf_file, &relocs);
|
||||
@ -527,7 +529,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {
|
||||
}
|
||||
|
||||
if (elf_file.eh_frame_section_index) |shndx| {
|
||||
const shdr = elf_file.shdrs.items[shndx];
|
||||
const shdr = slice.items(.shdr)[shndx];
|
||||
const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
|
||||
var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
|
||||
defer buffer.deinit();
|
||||
@ -540,7 +542,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {
|
||||
try elf_file.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
|
||||
}
|
||||
if (elf_file.eh_frame_rela_section_index) |shndx| {
|
||||
const shdr = elf_file.shdrs.items[shndx];
|
||||
const shdr = slice.items(.shdr)[shndx];
|
||||
const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
|
||||
var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
|
||||
defer buffer.deinit();
|
||||
@ -561,7 +563,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void {
|
||||
fn writeComdatGroups(elf_file: *Elf) !void {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
for (elf_file.comdat_group_sections.items) |cgs| {
|
||||
const shdr = elf_file.shdrs.items[cgs.shndx];
|
||||
const shdr = elf_file.sections.items(.shdr)[cgs.shndx];
|
||||
const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
|
||||
var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
|
||||
defer buffer.deinit();
|
||||
|
||||
@ -95,6 +95,8 @@ pub const DynamicSection = struct {
|
||||
}
|
||||
|
||||
pub fn write(dt: DynamicSection, elf_file: *Elf, writer: anytype) !void {
|
||||
const shdrs = elf_file.sections.items(.shdr);
|
||||
|
||||
// NEEDED
|
||||
for (dt.needed.items) |off| {
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NEEDED, .d_val = off });
|
||||
@ -112,33 +114,33 @@ pub const DynamicSection = struct {
|
||||
|
||||
// INIT
|
||||
if (elf_file.sectionByName(".init")) |shndx| {
|
||||
const addr = elf_file.shdrs.items[shndx].sh_addr;
|
||||
const addr = shdrs[shndx].sh_addr;
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT, .d_val = addr });
|
||||
}
|
||||
|
||||
// FINI
|
||||
if (elf_file.sectionByName(".fini")) |shndx| {
|
||||
const addr = elf_file.shdrs.items[shndx].sh_addr;
|
||||
const addr = shdrs[shndx].sh_addr;
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI, .d_val = addr });
|
||||
}
|
||||
|
||||
// INIT_ARRAY
|
||||
if (elf_file.sectionByName(".init_array")) |shndx| {
|
||||
const shdr = elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAY, .d_val = shdr.sh_addr });
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAYSZ, .d_val = shdr.sh_size });
|
||||
}
|
||||
|
||||
// FINI_ARRAY
|
||||
if (elf_file.sectionByName(".fini_array")) |shndx| {
|
||||
const shdr = elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAY, .d_val = shdr.sh_addr });
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAYSZ, .d_val = shdr.sh_size });
|
||||
}
|
||||
|
||||
// RELA
|
||||
if (elf_file.rela_dyn_section_index) |shndx| {
|
||||
const shdr = elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELA, .d_val = shdr.sh_addr });
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELASZ, .d_val = shdr.sh_size });
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELAENT, .d_val = shdr.sh_entsize });
|
||||
@ -146,7 +148,7 @@ pub const DynamicSection = struct {
|
||||
|
||||
// JMPREL
|
||||
if (elf_file.rela_plt_section_index) |shndx| {
|
||||
const shdr = elf_file.shdrs.items[shndx];
|
||||
const shdr = shdrs[shndx];
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_JMPREL, .d_val = shdr.sh_addr });
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTRELSZ, .d_val = shdr.sh_size });
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTREL, .d_val = elf.DT_RELA });
|
||||
@ -154,18 +156,18 @@ pub const DynamicSection = struct {
|
||||
|
||||
// PLTGOT
|
||||
if (elf_file.got_plt_section_index) |shndx| {
|
||||
const addr = elf_file.shdrs.items[shndx].sh_addr;
|
||||
const addr = shdrs[shndx].sh_addr;
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTGOT, .d_val = addr });
|
||||
}
|
||||
|
||||
{
|
||||
assert(elf_file.hash_section_index != null);
|
||||
const addr = elf_file.shdrs.items[elf_file.hash_section_index.?].sh_addr;
|
||||
const addr = shdrs[elf_file.hash_section_index.?].sh_addr;
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_HASH, .d_val = addr });
|
||||
}
|
||||
|
||||
if (elf_file.gnu_hash_section_index) |shndx| {
|
||||
const addr = elf_file.shdrs.items[shndx].sh_addr;
|
||||
const addr = shdrs[shndx].sh_addr;
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_GNU_HASH, .d_val = addr });
|
||||
}
|
||||
|
||||
@ -177,7 +179,7 @@ pub const DynamicSection = struct {
|
||||
// SYMTAB + SYMENT
|
||||
{
|
||||
assert(elf_file.dynsymtab_section_index != null);
|
||||
const shdr = elf_file.shdrs.items[elf_file.dynsymtab_section_index.?];
|
||||
const shdr = shdrs[elf_file.dynsymtab_section_index.?];
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMTAB, .d_val = shdr.sh_addr });
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMENT, .d_val = shdr.sh_entsize });
|
||||
}
|
||||
@ -185,20 +187,20 @@ pub const DynamicSection = struct {
|
||||
// STRTAB + STRSZ
|
||||
{
|
||||
assert(elf_file.dynstrtab_section_index != null);
|
||||
const shdr = elf_file.shdrs.items[elf_file.dynstrtab_section_index.?];
|
||||
const shdr = shdrs[elf_file.dynstrtab_section_index.?];
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRTAB, .d_val = shdr.sh_addr });
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRSZ, .d_val = shdr.sh_size });
|
||||
}
|
||||
|
||||
// VERSYM
|
||||
if (elf_file.versym_section_index) |shndx| {
|
||||
const addr = elf_file.shdrs.items[shndx].sh_addr;
|
||||
const addr = shdrs[shndx].sh_addr;
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERSYM, .d_val = addr });
|
||||
}
|
||||
|
||||
// VERNEED + VERNEEDNUM
|
||||
if (elf_file.verneed_section_index) |shndx| {
|
||||
const addr = elf_file.shdrs.items[shndx].sh_addr;
|
||||
const addr = shdrs[shndx].sh_addr;
|
||||
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERNEED, .d_val = addr });
|
||||
try writer.writeStruct(elf.Elf64_Dyn{
|
||||
.d_tag = elf.DT_VERNEEDNUM,
|
||||
@ -259,7 +261,7 @@ pub const GotSection = struct {
|
||||
|
||||
pub fn address(entry: Entry, elf_file: *Elf) i64 {
|
||||
const ptr_bytes = elf_file.archPtrWidthBytes();
|
||||
const shdr = &elf_file.shdrs.items[elf_file.got_section_index.?];
|
||||
const shdr = &elf_file.sections.items(.shdr)[elf_file.got_section_index.?];
|
||||
return @as(i64, @intCast(shdr.sh_addr)) + entry.cell_index * ptr_bytes;
|
||||
}
|
||||
};
|
||||
@ -759,8 +761,9 @@ pub const PltSection = struct {
|
||||
|
||||
const x86_64 = struct {
|
||||
fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void {
|
||||
const plt_addr = elf_file.shdrs.items[elf_file.plt_section_index.?].sh_addr;
|
||||
const got_plt_addr = elf_file.shdrs.items[elf_file.got_plt_section_index.?].sh_addr;
|
||||
const shdrs = elf_file.sections.items(.shdr);
|
||||
const plt_addr = shdrs[elf_file.plt_section_index.?].sh_addr;
|
||||
const got_plt_addr = shdrs[elf_file.got_plt_section_index.?].sh_addr;
|
||||
var preamble = [_]u8{
|
||||
0xf3, 0x0f, 0x1e, 0xfa, // endbr64
|
||||
0x41, 0x53, // push r11
|
||||
@ -794,8 +797,9 @@ pub const PltSection = struct {
|
||||
const aarch64 = struct {
|
||||
fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void {
|
||||
{
|
||||
const plt_addr: i64 = @intCast(elf_file.shdrs.items[elf_file.plt_section_index.?].sh_addr);
|
||||
const got_plt_addr: i64 = @intCast(elf_file.shdrs.items[elf_file.got_plt_section_index.?].sh_addr);
|
||||
const shdrs = elf_file.sections.items(.shdr);
|
||||
const plt_addr: i64 = @intCast(shdrs[elf_file.plt_section_index.?].sh_addr);
|
||||
const got_plt_addr: i64 = @intCast(shdrs[elf_file.got_plt_section_index.?].sh_addr);
|
||||
// TODO: relax if possible
|
||||
// .got.plt[2]
|
||||
const pages = try aarch64_util.calcNumberOfPages(plt_addr + 4, got_plt_addr + 16);
|
||||
@ -869,7 +873,7 @@ pub const GotPltSection = struct {
|
||||
try writer.writeInt(u64, 0x0, .little);
|
||||
try writer.writeInt(u64, 0x0, .little);
|
||||
if (elf_file.plt_section_index) |shndx| {
|
||||
const plt_addr = elf_file.shdrs.items[shndx].sh_addr;
|
||||
const plt_addr = elf_file.sections.items(.shdr)[shndx].sh_addr;
|
||||
for (0..elf_file.plt.symbols.items.len) |_| {
|
||||
// [N]: .plt
|
||||
try writer.writeInt(u64, plt_addr, .little);
|
||||
@ -1027,7 +1031,7 @@ pub const CopyRelSection = struct {
|
||||
}
|
||||
|
||||
pub fn updateSectionSize(copy_rel: CopyRelSection, shndx: u32, elf_file: *Elf) !void {
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
const shdr = &elf_file.sections.items(.shdr)[shndx];
|
||||
for (copy_rel.symbols.items) |ref| {
|
||||
const symbol = elf_file.symbol(ref).?;
|
||||
const shared_object = symbol.file(elf_file).?.shared_object;
|
||||
@ -1487,8 +1491,12 @@ pub const ComdatGroupSection = struct {
|
||||
elf.SHT_RELA => {
|
||||
const atom_index = object.atoms_indexes.items[shdr.sh_info];
|
||||
const atom = object.atom(atom_index).?;
|
||||
const rela = elf_file.output_rela_sections.get(atom.output_section_index).?;
|
||||
try writer.writeInt(u32, rela.shndx, .little);
|
||||
const rela_shndx = for (elf_file.sections.items(.shdr), 0..) |rela_shdr, rela_shndx| {
|
||||
if (rela_shdr.sh_type == elf.SHT_RELA and
|
||||
atom.output_section_index == rela_shdr.sh_info)
|
||||
break rela_shndx;
|
||||
} else unreachable;
|
||||
try writer.writeInt(u32, @intCast(rela_shndx), .little);
|
||||
},
|
||||
else => {
|
||||
const atom_index = object.atoms_indexes.items[shndx];
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
pub fn createThunks(shndx: u32, elf_file: *Elf) !void {
|
||||
pub fn createThunks(shdr: *elf.Elf64_Shdr, shndx: u32, elf_file: *Elf) !void {
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
const cpu_arch = elf_file.getTarget().cpu.arch;
|
||||
const max_distance = maxAllowedDistance(cpu_arch);
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
const atoms = elf_file.output_sections.get(shndx).?.items;
|
||||
const atoms = elf_file.sections.items(.atom_list)[shndx].items;
|
||||
assert(atoms.len > 0);
|
||||
|
||||
for (atoms) |ref| {
|
||||
@ -89,7 +88,7 @@ pub const Thunk = struct {
|
||||
}
|
||||
|
||||
pub fn address(thunk: Thunk, elf_file: *Elf) i64 {
|
||||
const shdr = elf_file.shdrs.items[thunk.output_section_index];
|
||||
const shdr = elf_file.sections.items(.shdr)[thunk.output_section_index];
|
||||
return @as(i64, @intCast(shdr.sh_addr)) + thunk.value;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user