mirror of
https://github.com/ziglang/zig.git
synced 2026-01-18 13:25:15 +00:00
elf: emit (broken) debug sections
This commit is contained in:
parent
85d451f96c
commit
5fad683791
115
src/link/Elf.zig
115
src/link/Elf.zig
@ -1515,6 +1515,47 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
// Scan and create missing synthetic entries such as GOT indirection.
|
||||
try self.scanRelocs();
|
||||
|
||||
// TODO I need to re-think how to handle ZigModule's debug sections AND debug sections
|
||||
// extracted from input object files correctly.
|
||||
if (self.dwarf) |*dw| {
|
||||
if (self.debug_abbrev_section_dirty) {
|
||||
try dw.writeDbgAbbrev();
|
||||
self.debug_abbrev_section_dirty = false;
|
||||
}
|
||||
|
||||
if (self.debug_info_header_dirty) {
|
||||
// Currently only one compilation unit is supported, so the address range is simply
|
||||
// identical to the main program header virtual address and memory size.
|
||||
const text_phdr = &self.phdrs.items[self.phdr_zig_load_re_index.?];
|
||||
const low_pc = text_phdr.p_vaddr;
|
||||
const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz;
|
||||
try dw.writeDbgInfoHeader(self.base.options.module.?, low_pc, high_pc);
|
||||
self.debug_info_header_dirty = false;
|
||||
}
|
||||
|
||||
if (self.debug_aranges_section_dirty) {
|
||||
// Currently only one compilation unit is supported, so the address range is simply
|
||||
// identical to the main program header virtual address and memory size.
|
||||
const text_phdr = &self.phdrs.items[self.phdr_zig_load_re_index.?];
|
||||
try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz);
|
||||
self.debug_aranges_section_dirty = false;
|
||||
}
|
||||
|
||||
if (self.debug_line_header_dirty) {
|
||||
try dw.writeDbgLineHeader();
|
||||
self.debug_line_header_dirty = false;
|
||||
}
|
||||
|
||||
if (self.debug_str_section_index) |shndx| {
|
||||
if (self.debug_strtab_dirty or dw.strtab.buffer.items.len != self.shdrs.items[shndx].sh_size) {
|
||||
try self.growNonAllocSection(shndx, dw.strtab.buffer.items.len, 1, false);
|
||||
const shdr = self.shdrs.items[shndx];
|
||||
try self.base.file.?.pwriteAll(dw.strtab.buffer.items, shdr.sh_offset);
|
||||
self.debug_strtab_dirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate and emit non-incremental sections.
|
||||
try self.initSections();
|
||||
try self.initSpecialPhdrs();
|
||||
@ -1531,7 +1572,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
|
||||
self.allocatePhdrTable();
|
||||
try self.allocateAllocSections();
|
||||
self.allocateNonAllocSections();
|
||||
try self.allocateNonAllocSections();
|
||||
self.allocateSpecialPhdrs();
|
||||
self.allocateAtoms();
|
||||
self.allocateLinkerDefinedSymbols();
|
||||
@ -1574,45 +1615,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
};
|
||||
try self.base.file.?.pwriteAll(code, file_offset);
|
||||
}
|
||||
|
||||
if (self.dwarf) |*dw| {
|
||||
if (self.debug_abbrev_section_dirty) {
|
||||
try dw.writeDbgAbbrev();
|
||||
self.debug_abbrev_section_dirty = false;
|
||||
}
|
||||
|
||||
if (self.debug_info_header_dirty) {
|
||||
// Currently only one compilation unit is supported, so the address range is simply
|
||||
// identical to the main program header virtual address and memory size.
|
||||
const text_phdr = &self.phdrs.items[self.phdr_zig_load_re_index.?];
|
||||
const low_pc = text_phdr.p_vaddr;
|
||||
const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz;
|
||||
try dw.writeDbgInfoHeader(self.base.options.module.?, low_pc, high_pc);
|
||||
self.debug_info_header_dirty = false;
|
||||
}
|
||||
|
||||
if (self.debug_aranges_section_dirty) {
|
||||
// Currently only one compilation unit is supported, so the address range is simply
|
||||
// identical to the main program header virtual address and memory size.
|
||||
const text_phdr = &self.phdrs.items[self.phdr_zig_load_re_index.?];
|
||||
try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz);
|
||||
self.debug_aranges_section_dirty = false;
|
||||
}
|
||||
|
||||
if (self.debug_line_header_dirty) {
|
||||
try dw.writeDbgLineHeader();
|
||||
self.debug_line_header_dirty = false;
|
||||
}
|
||||
|
||||
if (self.debug_str_section_index) |shndx| {
|
||||
if (self.debug_strtab_dirty or dw.strtab.buffer.items.len != self.shdrs.items[shndx].sh_size) {
|
||||
try self.growNonAllocSection(shndx, dw.strtab.buffer.items.len, 1, false);
|
||||
const shdr = self.shdrs.items[shndx];
|
||||
try self.base.file.?.pwriteAll(dw.strtab.buffer.items, shdr.sh_offset);
|
||||
self.debug_strtab_dirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try self.writePhdrTable();
|
||||
@ -4601,14 +4603,26 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void {
|
||||
}
|
||||
|
||||
/// Allocates non-alloc sections (debug info, symtabs, etc.).
|
||||
fn allocateNonAllocSections(self: *Elf) void {
|
||||
for (self.shdrs.items) |*shdr| {
|
||||
fn allocateNonAllocSections(self: *Elf) !void {
|
||||
for (self.shdrs.items, 0..) |*shdr, shndx| {
|
||||
if (shdr.sh_type == elf.SHT_NULL) continue;
|
||||
if (shdr.sh_flags & elf.SHF_ALLOC != 0) continue;
|
||||
const needed_size = shdr.sh_size;
|
||||
if (needed_size > self.allocatedSize(shdr.sh_offset)) {
|
||||
shdr.sh_size = 0;
|
||||
shdr.sh_offset = self.findFreeSpace(needed_size, shdr.sh_addralign);
|
||||
const new_offset = self.findFreeSpace(needed_size, shdr.sh_addralign);
|
||||
|
||||
if (self.isDebugSection(@intCast(shndx))) {
|
||||
const amt = try self.base.file.?.copyRangeAll(
|
||||
shdr.sh_offset,
|
||||
self.base.file.?,
|
||||
new_offset,
|
||||
needed_size, // TODO this will copy too much but ah well
|
||||
);
|
||||
if (amt != needed_size) return error.InputOutput;
|
||||
}
|
||||
|
||||
shdr.sh_offset = new_offset;
|
||||
}
|
||||
shdr.sh_size = needed_size;
|
||||
}
|
||||
@ -5354,6 +5368,21 @@ pub fn isZigSection(self: Elf, shndx: u16) bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn isDebugSection(self: Elf, shndx: u16) bool {
|
||||
inline for (&[_]?u16{
|
||||
self.debug_info_section_index,
|
||||
self.debug_abbrev_section_index,
|
||||
self.debug_str_section_index,
|
||||
self.debug_aranges_section_index,
|
||||
self.debug_line_section_index,
|
||||
}) |maybe_index| {
|
||||
if (maybe_index) |index| {
|
||||
if (index == shndx) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
fn addPhdr(self: *Elf, opts: struct {
|
||||
type: u32 = 0,
|
||||
flags: u32 = 0,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user