elf: allocate .bss in ZigObject similarly to .eh_frame

This commit is contained in:
Jakub Konka
2024-08-28 06:57:55 +02:00
parent 8f1ce3c85b
commit 37a1f0e7f2
2 changed files with 61 additions and 69 deletions

View File

@@ -61,8 +61,6 @@ phdr_zig_load_re_index: ?u16 = null,
phdr_zig_load_ro_index: ?u16 = null,
/// The index into the program headers of a PT_LOAD program header with Write flag
phdr_zig_load_rw_index: ?u16 = null,
/// The index into the program headers of a PT_LOAD program header with zerofill data.
phdr_zig_load_zerofill_index: ?u16 = null,
/// Special program headers
/// PT_PHDR
@@ -129,7 +127,6 @@ comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{},
zig_text_section_index: ?u32 = null,
zig_data_rel_ro_section_index: ?u32 = null,
zig_data_section_index: ?u32 = null,
zig_bss_section_index: ?u32 = null,
debug_info_section_index: ?u32 = null,
debug_abbrev_section_index: ?u32 = null,
@@ -3367,7 +3364,6 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {
for (&[_]*?u16{
&self.phdr_zig_load_re_index,
&self.phdr_zig_load_ro_index,
&self.phdr_zig_load_zerofill_index,
&self.phdr_table_index,
&self.phdr_table_load_index,
&self.phdr_interp_index,
@@ -3496,7 +3492,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
&self.zig_text_section_index,
&self.zig_data_rel_ro_section_index,
&self.zig_data_section_index,
&self.zig_bss_section_index,
&self.debug_info_section_index,
&self.debug_abbrev_section_index,
&self.debug_str_section_index,
@@ -3591,9 +3586,17 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
fn updateSectionSizes(self: *Elf) !void {
const slice = self.sections.slice();
for (slice.items(.shdr), slice.items(.atom_list)) |*shdr, atom_list| {
for (slice.items(.shdr), slice.items(.atom_list), 0..) |*shdr, atom_list, shndx| {
if (atom_list.items.len == 0) continue;
if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue;
if (self.zigObjectPtr()) |zo| {
if (zo.bss_index) |sym_index| {
const atom_ptr = zo.symbol(sym_index).atom(self).?;
if (shndx == atom_ptr.output_section_index) {
shdr.sh_size = atom_ptr.size;
}
}
}
for (atom_list.items) |ref| {
const atom_ptr = self.atom(ref) orelse continue;
if (!atom_ptr.alive) continue;
@@ -4804,7 +4807,6 @@ pub fn isZigSection(self: Elf, shndx: u32) bool {
self.zig_text_section_index,
self.zig_data_rel_ro_section_index,
self.zig_data_section_index,
self.zig_bss_section_index,
}) |index| {
if (index == shndx) return true;
}

View File

@@ -60,6 +60,7 @@ debug_line_str_index: ?Symbol.Index = null,
debug_loclists_index: ?Symbol.Index = null,
debug_rnglists_index: ?Symbol.Index = null,
eh_frame_index: ?Symbol.Index = null,
bss_index: ?Symbol.Index = null,
pub const global_symbol_bit: u32 = 0x80000000;
pub const symbol_mask: u32 = 0x7fffffff;
@@ -149,17 +150,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
.flags = elf.PF_R | elf.PF_W,
});
}
if (elf_file.phdr_zig_load_zerofill_index == null) {
const alignment = elf_file.page_size;
elf_file.phdr_zig_load_zerofill_index = try elf_file.addPhdr(.{
.type = elf.PT_LOAD,
.addr = if (ptr_size >= 4) 0x14000000 else 0xf000,
.memsz = 1024,
.@"align" = alignment,
.flags = elf.PF_R | elf.PF_W,
});
}
}
if (elf_file.zig_text_section_index == null) {
@@ -225,51 +215,11 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
}
}
if (elf_file.zig_bss_section_index == null) {
elf_file.zig_bss_section_index = try elf_file.addSection(.{
.name = try elf_file.insertShString(".bss.zig"),
.type = elf.SHT_NOBITS,
.addralign = ptr_size,
.flags = elf.SHF_ALLOC | elf.SHF_WRITE,
.offset = 0,
});
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;
}
}
switch (comp.config.debug_format) {
.strip => {},
.dwarf => |v| {
var dwarf = Dwarf.init(&elf_file.base, v);
const addSectionSymbol = struct {
fn addSectionSymbol(
zig_object: *ZigObject,
alloc: Allocator,
name: [:0]const u8,
alignment: Atom.Alignment,
shndx: u32,
) !Symbol.Index {
const name_off = try zig_object.addString(alloc, name);
const index = try zig_object.newSymbolWithAtom(alloc, name_off);
const sym = zig_object.symbol(index);
const esym = &zig_object.symtab.items(.elf_sym)[sym.esym_index];
esym.st_info |= elf.STT_SECTION;
const atom_ptr = zig_object.atom(sym.ref.index).?;
atom_ptr.alignment = alignment;
atom_ptr.output_section_index = shndx;
return index;
}
}.addSectionSymbol;
if (elf_file.debug_str_section_index == null) {
elf_file.debug_str_section_index = try elf_file.addSection(.{
.name = try elf_file.insertShString(".debug_str"),
@@ -279,7 +229,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
.addralign = 1,
});
self.debug_str_section_dirty = true;
self.debug_str_index = try addSectionSymbol(self, gpa, ".debug_str", .@"1", elf_file.debug_str_section_index.?);
self.debug_str_index = try self.addSectionSymbol(gpa, ".debug_str", .@"1", elf_file.debug_str_section_index.?);
}
if (elf_file.debug_info_section_index == null) {
@@ -289,7 +239,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
.addralign = 1,
});
self.debug_info_section_dirty = true;
self.debug_info_index = try addSectionSymbol(self, gpa, ".debug_info", .@"1", elf_file.debug_info_section_index.?);
self.debug_info_index = try self.addSectionSymbol(gpa, ".debug_info", .@"1", elf_file.debug_info_section_index.?);
}
if (elf_file.debug_abbrev_section_index == null) {
@@ -299,7 +249,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
.addralign = 1,
});
self.debug_abbrev_section_dirty = true;
self.debug_abbrev_index = try addSectionSymbol(self, gpa, ".debug_abbrev", .@"1", elf_file.debug_abbrev_section_index.?);
self.debug_abbrev_index = try self.addSectionSymbol(gpa, ".debug_abbrev", .@"1", elf_file.debug_abbrev_section_index.?);
}
if (elf_file.debug_aranges_section_index == null) {
@@ -309,7 +259,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
.addralign = 16,
});
self.debug_aranges_section_dirty = true;
self.debug_aranges_index = try addSectionSymbol(self, gpa, ".debug_aranges", .@"16", elf_file.debug_aranges_section_index.?);
self.debug_aranges_index = try self.addSectionSymbol(gpa, ".debug_aranges", .@"16", elf_file.debug_aranges_section_index.?);
}
if (elf_file.debug_line_section_index == null) {
@@ -319,7 +269,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
.addralign = 1,
});
self.debug_line_section_dirty = true;
self.debug_line_index = try addSectionSymbol(self, gpa, ".debug_line", .@"1", elf_file.debug_line_section_index.?);
self.debug_line_index = try self.addSectionSymbol(gpa, ".debug_line", .@"1", elf_file.debug_line_section_index.?);
}
if (elf_file.debug_line_str_section_index == null) {
@@ -331,7 +281,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
.addralign = 1,
});
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.?);
self.debug_line_str_index = try self.addSectionSymbol(gpa, ".debug_line_str", .@"1", elf_file.debug_line_str_section_index.?);
}
if (elf_file.debug_loclists_section_index == null) {
@@ -341,7 +291,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
.addralign = 1,
});
self.debug_loclists_section_dirty = true;
self.debug_loclists_index = try addSectionSymbol(self, gpa, ".debug_loclists", .@"1", elf_file.debug_loclists_section_index.?);
self.debug_loclists_index = try self.addSectionSymbol(gpa, ".debug_loclists", .@"1", elf_file.debug_loclists_section_index.?);
}
if (elf_file.debug_rnglists_section_index == null) {
@@ -351,7 +301,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
.addralign = 1,
});
self.debug_rnglists_section_dirty = true;
self.debug_rnglists_index = try addSectionSymbol(self, gpa, ".debug_rnglists", .@"1", elf_file.debug_rnglists_section_index.?);
self.debug_rnglists_index = try self.addSectionSymbol(gpa, ".debug_rnglists", .@"1", elf_file.debug_rnglists_section_index.?);
}
if (elf_file.eh_frame_section_index == null) {
@@ -365,7 +315,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
.addralign = ptr_size,
});
self.eh_frame_section_dirty = true;
self.eh_frame_index = try addSectionSymbol(self, gpa, ".eh_frame", Atom.Alignment.fromNonzeroByteUnits(ptr_size), elf_file.eh_frame_section_index.?);
self.eh_frame_index = try self.addSectionSymbol(gpa, ".eh_frame", Atom.Alignment.fromNonzeroByteUnits(ptr_size), elf_file.eh_frame_section_index.?);
}
try dwarf.initMetadata();
@@ -1270,6 +1220,24 @@ pub fn getOrCreateMetadataForNav(
return gop.value_ptr.symbol_index;
}
fn addSectionSymbol(
self: *ZigObject,
allocator: Allocator,
name: [:0]const u8,
alignment: Atom.Alignment,
shndx: u32,
) !Symbol.Index {
const name_off = try self.addString(allocator, name);
const index = try self.newSymbolWithAtom(allocator, name_off);
const sym = self.symbol(index);
const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
esym.st_info |= elf.STT_SECTION;
const atom_ptr = self.atom(sym.ref.index).?;
atom_ptr.alignment = alignment;
atom_ptr.output_section_index = shndx;
return index;
}
fn getNavShdrIndex(
self: *ZigObject,
elf_file: *Elf,
@@ -1309,12 +1277,34 @@ fn getNavShdrIndex(
if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu))
return switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
.Debug, .ReleaseSafe => elf_file.zig_data_section_index.?,
.ReleaseFast, .ReleaseSmall => elf_file.zig_bss_section_index.?,
.ReleaseFast, .ReleaseSmall => {
if (self.bss_index) |symbol_index|
return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
const osec = try elf_file.addSection(.{
.type = elf.SHT_NOBITS,
.flags = elf.SHF_ALLOC | elf.SHF_WRITE,
.name = try elf_file.insertShString(".bss"),
.addralign = 1,
});
self.bss_index = try self.addSectionSymbol(elf_file.base.comp.gpa, ".bss", .@"1", osec);
return osec;
},
};
const is_bss = !has_relocs and for (code) |byte| {
if (byte != 0) break false;
} else true;
if (is_bss) return elf_file.zig_bss_section_index.?;
if (is_bss) {
if (self.bss_index) |symbol_index|
return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
const osec = try elf_file.addSection(.{
.type = elf.SHT_NOBITS,
.flags = elf.SHF_ALLOC | elf.SHF_WRITE,
.name = try elf_file.insertShString(".bss"),
.addralign = 1,
});
self.bss_index = try self.addSectionSymbol(elf_file.base.comp.gpa, ".bss", .@"1", osec);
return osec;
}
return elf_file.zig_data_section_index.?;
}