mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 07:03:11 +00:00
elf: emit valid section headers table when building an object file
This commit is contained in:
parent
74f12d0691
commit
0ee2ab413f
@ -768,15 +768,15 @@ pub fn initMetadata(self: *Elf) !void {
|
||||
|
||||
pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {
|
||||
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 maybe_phdr = if (self.phdr_to_shdr_table.get(shdr_index)) |phndx| &self.phdrs.items[phndx] else null;
|
||||
const is_zerofill = shdr.sh_type == elf.SHT_NOBITS;
|
||||
|
||||
if (needed_size > self.allocatedSize(shdr.sh_offset) and !is_zerofill) {
|
||||
const existing_size = shdr.sh_size;
|
||||
shdr.sh_size = 0;
|
||||
// Must move the entire section.
|
||||
const new_offset = self.findFreeSpace(needed_size, self.page_size);
|
||||
const alignment = if (maybe_phdr) |phdr| phdr.p_align else shdr.sh_addralign;
|
||||
const new_offset = self.findFreeSpace(needed_size, alignment);
|
||||
|
||||
log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{
|
||||
self.getShString(shdr.sh_name),
|
||||
@ -789,25 +789,27 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void {
|
||||
if (amt != existing_size) return error.InputOutput;
|
||||
|
||||
shdr.sh_offset = new_offset;
|
||||
phdr.p_offset = new_offset;
|
||||
if (maybe_phdr) |phdr| phdr.p_offset = new_offset;
|
||||
}
|
||||
|
||||
shdr.sh_size = needed_size;
|
||||
if (!is_zerofill) {
|
||||
phdr.p_filesz = needed_size;
|
||||
if (maybe_phdr) |phdr| phdr.p_filesz = needed_size;
|
||||
}
|
||||
|
||||
const mem_capacity = self.allocatedVirtualSize(phdr.p_vaddr);
|
||||
if (needed_size > mem_capacity) {
|
||||
var err = try self.addErrorWithNotes(2);
|
||||
try err.addMsg(self, "fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{
|
||||
phdr_index,
|
||||
});
|
||||
try err.addNote(self, "TODO: emit relocations to memory locations in self-hosted backends", .{});
|
||||
try err.addNote(self, "as a workaround, try increasing pre-allocated virtual memory of each segment", .{});
|
||||
}
|
||||
if (maybe_phdr) |phdr| {
|
||||
const mem_capacity = self.allocatedVirtualSize(phdr.p_vaddr);
|
||||
if (needed_size > mem_capacity) {
|
||||
var err = try self.addErrorWithNotes(2);
|
||||
try err.addMsg(self, "fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{
|
||||
self.phdr_to_shdr_table.get(shdr_index).?,
|
||||
});
|
||||
try err.addNote(self, "TODO: emit relocations to memory locations in self-hosted backends", .{});
|
||||
try err.addNote(self, "as a workaround, try increasing pre-allocated virtual memory of each segment", .{});
|
||||
}
|
||||
|
||||
phdr.p_memsz = needed_size;
|
||||
phdr.p_memsz = needed_size;
|
||||
}
|
||||
|
||||
self.markDirty(shdr_index);
|
||||
}
|
||||
@ -1499,7 +1501,17 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
pub fn flushObject(self: *Elf, comp: *Compilation) link.File.FlushError!void {
|
||||
_ = comp;
|
||||
try self.initSections();
|
||||
try self.sortShdrs();
|
||||
try self.updateSectionSizes();
|
||||
|
||||
try self.allocateNonAllocSections();
|
||||
|
||||
if (build_options.enable_logging) {
|
||||
state_log.debug("{}", .{self.dumpState()});
|
||||
}
|
||||
|
||||
try self.writeShdrTable();
|
||||
try self.writeSyntheticSections();
|
||||
try self.writeHeader();
|
||||
}
|
||||
|
||||
|
||||
@ -180,16 +180,16 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void {
|
||||
}
|
||||
|
||||
if (self.debug_info_header_dirty) {
|
||||
const text_phdr = &elf_file.phdrs.items[elf_file.phdr_zig_load_re_index.?];
|
||||
const low_pc = text_phdr.p_vaddr;
|
||||
const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz;
|
||||
const text_shdr = elf_file.shdrs.items[elf_file.zig_text_section_index.?];
|
||||
const low_pc = text_shdr.sh_addr;
|
||||
const high_pc = text_shdr.sh_addr + text_shdr.sh_size;
|
||||
try dw.writeDbgInfoHeader(elf_file.base.options.module.?, low_pc, high_pc);
|
||||
self.debug_info_header_dirty = false;
|
||||
}
|
||||
|
||||
if (self.debug_aranges_section_dirty) {
|
||||
const text_phdr = &elf_file.phdrs.items[elf_file.phdr_zig_load_re_index.?];
|
||||
try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz);
|
||||
const text_shdr = elf_file.shdrs.items[elf_file.zig_text_section_index.?];
|
||||
try dw.writeDbgAranges(text_shdr.sh_addr, text_shdr.sh_size);
|
||||
self.debug_aranges_section_dirty = false;
|
||||
}
|
||||
|
||||
@ -731,9 +731,7 @@ fn updateDeclCode(
|
||||
|
||||
const shdr = elf_file.shdrs.items[shdr_index];
|
||||
if (shdr.sh_type != elf.SHT_NOBITS) {
|
||||
const phdr_index = elf_file.phdr_to_shdr_table.get(shdr_index).?;
|
||||
const section_offset = sym.value - elf_file.phdrs.items[phdr_index].p_vaddr;
|
||||
const file_offset = shdr.sh_offset + section_offset;
|
||||
const file_offset = shdr.sh_offset + sym.value - shdr.sh_addr;
|
||||
try elf_file.base.file.?.pwriteAll(code, file_offset);
|
||||
}
|
||||
}
|
||||
@ -940,7 +938,6 @@ fn updateLazySymbol(
|
||||
.const_data => elf_file.zig_data_rel_ro_section_index.?,
|
||||
};
|
||||
const local_sym = elf_file.symbol(symbol_index);
|
||||
const phdr_index = elf_file.phdr_to_shdr_table.get(output_section_index).?;
|
||||
local_sym.name_offset = name_str_index;
|
||||
local_sym.output_section_index = output_section_index;
|
||||
const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index];
|
||||
@ -963,8 +960,8 @@ fn updateLazySymbol(
|
||||
const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file);
|
||||
try elf_file.zig_got.writeOne(elf_file, gop.index);
|
||||
|
||||
const section_offset = atom_ptr.value - elf_file.phdrs.items[phdr_index].p_vaddr;
|
||||
const file_offset = elf_file.shdrs.items[output_section_index].sh_offset + section_offset;
|
||||
const shdr = elf_file.shdrs.items[output_section_index];
|
||||
const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr;
|
||||
try elf_file.base.file.?.pwriteAll(code, file_offset);
|
||||
}
|
||||
|
||||
@ -1038,7 +1035,6 @@ fn lowerConst(
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
|
||||
const phdr_index = elf_file.phdr_to_shdr_table.get(output_section_index).?;
|
||||
const local_sym = elf_file.symbol(sym_index);
|
||||
const name_str_index = try self.insertString(gpa, name);
|
||||
local_sym.name_offset = name_str_index;
|
||||
@ -1061,8 +1057,8 @@ fn lowerConst(
|
||||
local_sym.value = atom_ptr.value;
|
||||
local_esym.st_value = atom_ptr.value;
|
||||
|
||||
const section_offset = atom_ptr.value - elf_file.phdrs.items[phdr_index].p_vaddr;
|
||||
const file_offset = elf_file.shdrs.items[output_section_index].sh_offset + section_offset;
|
||||
const shdr = elf_file.shdrs.items[output_section_index];
|
||||
const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr;
|
||||
try elf_file.base.file.?.pwriteAll(code, file_offset);
|
||||
|
||||
return .{ .ok = sym_index };
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user