elf: allocate .text in ZigObject similarly to .eh_frame
This commit is contained in:
@@ -54,10 +54,6 @@ shdr_table_offset: ?u64 = null,
|
||||
/// Same order as in the file.
|
||||
phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{},
|
||||
|
||||
/// Tracked loadable segments during incremental linking.
|
||||
/// The index into the program headers of a PT_LOAD program header with Read and Execute flags
|
||||
phdr_zig_load_re_index: ?u16 = null,
|
||||
|
||||
/// Special program headers
|
||||
/// PT_PHDR
|
||||
phdr_table_index: ?u16 = null,
|
||||
@@ -118,10 +114,6 @@ rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{},
|
||||
/// Applies only to a relocatable.
|
||||
comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{},
|
||||
|
||||
/// Tracked section headers with incremental updates to Zig object.
|
||||
/// .rela.* sections are only used when emitting a relocatable object file.
|
||||
zig_text_section_index: ?u32 = null,
|
||||
|
||||
debug_info_section_index: ?u32 = null,
|
||||
debug_abbrev_section_index: ?u32 = null,
|
||||
debug_str_section_index: ?u32 = null,
|
||||
@@ -3356,7 +3348,6 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {
|
||||
}
|
||||
|
||||
for (&[_]*?u16{
|
||||
&self.phdr_zig_load_re_index,
|
||||
&self.phdr_table_index,
|
||||
&self.phdr_table_load_index,
|
||||
&self.phdr_interp_index,
|
||||
@@ -3482,7 +3473,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
|
||||
&self.copy_rel_section_index,
|
||||
&self.versym_section_index,
|
||||
&self.verneed_section_index,
|
||||
&self.zig_text_section_index,
|
||||
&self.debug_info_section_index,
|
||||
&self.debug_abbrev_section_index,
|
||||
&self.debug_str_section_index,
|
||||
@@ -3734,10 +3724,9 @@ fn getMaxNumberOfPhdrs() u64 {
|
||||
/// We permit a maximum of 3**2 number of segments.
|
||||
fn calcNumberOfSegments(self: *Elf) usize {
|
||||
var covers: [9]bool = [_]bool{false} ** 9;
|
||||
for (self.sections.items(.shdr), 0..) |shdr, shndx| {
|
||||
for (self.sections.items(.shdr)) |shdr| {
|
||||
if (shdr.sh_type == elf.SHT_NULL) continue;
|
||||
if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
|
||||
if (self.isZigSection(@intCast(shndx))) continue;
|
||||
const flags = shdrToPhdrFlags(shdr.sh_flags);
|
||||
covers[flags - 1] = true;
|
||||
}
|
||||
@@ -3835,7 +3824,6 @@ pub fn allocateAllocSections(self: *Elf) !void {
|
||||
for (slice.items(.shdr), 0..) |shdr, shndx| {
|
||||
if (shdr.sh_type == elf.SHT_NULL) continue;
|
||||
if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
|
||||
if (self.isZigSection(@intCast(shndx))) continue;
|
||||
const flags = shdrToPhdrFlags(shdr.sh_flags);
|
||||
try covers[flags - 1].append(@intCast(shndx));
|
||||
}
|
||||
@@ -4813,15 +4801,6 @@ pub fn isEffectivelyDynLib(self: Elf) bool {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isZigSection(self: Elf, shndx: u32) bool {
|
||||
inline for (&[_]?u32{
|
||||
self.zig_text_section_index,
|
||||
}) |index| {
|
||||
if (index == shndx) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn isDebugSection(self: Elf, shndx: u32) bool {
|
||||
inline for (&[_]?u32{
|
||||
self.debug_info_section_index,
|
||||
|
||||
@@ -51,6 +51,12 @@ debug_loclists_section_dirty: bool = false,
|
||||
debug_rnglists_section_dirty: bool = false,
|
||||
eh_frame_section_dirty: bool = false,
|
||||
|
||||
text_index: ?Symbol.Index = null,
|
||||
data_relro_index: ?Symbol.Index = null,
|
||||
rodata_index: ?Symbol.Index = null,
|
||||
data_index: ?Symbol.Index = null,
|
||||
bss_index: ?Symbol.Index = null,
|
||||
eh_frame_index: ?Symbol.Index = null,
|
||||
debug_info_index: ?Symbol.Index = null,
|
||||
debug_abbrev_index: ?Symbol.Index = null,
|
||||
debug_aranges_index: ?Symbol.Index = null,
|
||||
@@ -59,11 +65,6 @@ debug_line_index: ?Symbol.Index = null,
|
||||
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,
|
||||
data_index: ?Symbol.Index = null,
|
||||
data_relro_index: ?Symbol.Index = null,
|
||||
rodata_index: ?Symbol.Index = null,
|
||||
|
||||
pub const global_symbol_bit: u32 = 0x80000000;
|
||||
pub const symbol_mask: u32 = 0x7fffffff;
|
||||
@@ -75,6 +76,7 @@ const InitOptions = struct {
|
||||
};
|
||||
|
||||
pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
_ = options;
|
||||
const comp = elf_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const ptr_size = elf_file.ptrWidthBytes();
|
||||
@@ -92,60 +94,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
|
||||
esym.st_shndx = elf.SHN_ABS;
|
||||
}
|
||||
|
||||
const fillSection = struct {
|
||||
fn fillSection(ef: *Elf, shdr: *elf.Elf64_Shdr, size: u64, phndx: ?u16) !void {
|
||||
if (ef.base.isRelocatable()) {
|
||||
const off = try ef.findFreeSpace(size, shdr.sh_addralign);
|
||||
shdr.sh_offset = off;
|
||||
shdr.sh_size = size;
|
||||
} else {
|
||||
const phdr = ef.phdrs.items[phndx.?];
|
||||
shdr.sh_addr = phdr.p_vaddr;
|
||||
shdr.sh_offset = phdr.p_offset;
|
||||
shdr.sh_size = phdr.p_memsz;
|
||||
}
|
||||
}
|
||||
}.fillSection;
|
||||
|
||||
comptime assert(Elf.number_of_zig_segments == 2);
|
||||
|
||||
if (!elf_file.base.isRelocatable()) {
|
||||
if (elf_file.phdr_zig_load_re_index == null) {
|
||||
const filesz = options.program_code_size_hint;
|
||||
const off = try elf_file.findFreeSpace(filesz, elf_file.page_size);
|
||||
elf_file.phdr_zig_load_re_index = try elf_file.addPhdr(.{
|
||||
.type = elf.PT_LOAD,
|
||||
.offset = off,
|
||||
.filesz = filesz,
|
||||
.addr = if (ptr_size >= 4) 0x4000000 else 0x4000,
|
||||
.memsz = filesz,
|
||||
.@"align" = elf_file.page_size,
|
||||
.flags = elf.PF_X | elf.PF_R | elf.PF_W,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (elf_file.zig_text_section_index == null) {
|
||||
elf_file.zig_text_section_index = try elf_file.addSection(.{
|
||||
.name = try elf_file.insertShString(".text.zig"),
|
||||
.type = elf.SHT_PROGBITS,
|
||||
.flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
|
||||
.addralign = 1,
|
||||
.offset = std.math.maxInt(u64),
|
||||
});
|
||||
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()) {
|
||||
_ = try elf_file.addRelaShdr(
|
||||
try elf_file.insertShString(".rela.text.zig"),
|
||||
elf_file.zig_text_section_index.?,
|
||||
);
|
||||
} else {
|
||||
phndx.* = elf_file.phdr_zig_load_re_index.?;
|
||||
}
|
||||
}
|
||||
|
||||
switch (comp.config.debug_format) {
|
||||
.strip => {},
|
||||
.dwarf => |v| {
|
||||
@@ -1196,7 +1144,19 @@ fn getNavShdrIndex(
|
||||
const ip = &zcu.intern_pool;
|
||||
const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
|
||||
const nav_val = zcu.navValue(nav_index);
|
||||
if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) return elf_file.zig_text_section_index.?;
|
||||
if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) {
|
||||
if (self.text_index) |symbol_index|
|
||||
return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
|
||||
const osec = try elf_file.addSection(.{
|
||||
.type = elf.SHT_PROGBITS,
|
||||
.flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
|
||||
.name = try elf_file.insertShString(".text"),
|
||||
.addralign = 1,
|
||||
.offset = std.math.maxInt(u64),
|
||||
});
|
||||
self.text_index = try self.addSectionSymbol(gpa, ".text", .@"1", osec);
|
||||
return osec;
|
||||
}
|
||||
const is_const, const is_threadlocal, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
|
||||
.variable => |variable| .{ false, variable.is_threadlocal, variable.init },
|
||||
.@"extern" => |@"extern"| .{ @"extern".is_const, @"extern".is_threadlocal, .none },
|
||||
@@ -1538,6 +1498,19 @@ pub fn updateFunc(
|
||||
self.symbol(sym_index).name(elf_file),
|
||||
});
|
||||
defer gpa.free(name);
|
||||
const osec = if (self.text_index) |sect_sym_index|
|
||||
self.symbol(sect_sym_index).atom(elf_file).?.output_section_index
|
||||
else osec: {
|
||||
const osec = try elf_file.addSection(.{
|
||||
.name = try elf_file.insertShString(".text"),
|
||||
.flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
|
||||
.type = elf.SHT_PROGBITS,
|
||||
.addralign = 1,
|
||||
.offset = std.math.maxInt(u64),
|
||||
});
|
||||
self.text_index = try self.addSectionSymbol(gpa, ".text", .@"1", osec);
|
||||
break :osec osec;
|
||||
};
|
||||
const name_off = try self.addString(gpa, name);
|
||||
const tr_size = trampolineSize(elf_file.getTarget().cpu.arch);
|
||||
const tr_sym_index = try self.newSymbolWithAtom(gpa, name_off);
|
||||
@@ -1549,7 +1522,7 @@ pub fn updateFunc(
|
||||
tr_atom_ptr.value = old_rva;
|
||||
tr_atom_ptr.alive = true;
|
||||
tr_atom_ptr.alignment = old_alignment;
|
||||
tr_atom_ptr.output_section_index = elf_file.zig_text_section_index.?;
|
||||
tr_atom_ptr.output_section_index = osec;
|
||||
tr_atom_ptr.size = tr_size;
|
||||
const target_sym = self.symbol(sym_index);
|
||||
target_sym.addExtra(.{ .trampoline = tr_sym_index }, elf_file);
|
||||
@@ -1703,7 +1676,19 @@ fn updateLazySymbol(
|
||||
};
|
||||
|
||||
const output_section_index = switch (sym.kind) {
|
||||
.code => elf_file.zig_text_section_index.?,
|
||||
.code => if (self.text_index) |sym_index|
|
||||
self.symbol(sym_index).atom(elf_file).?.output_section_index
|
||||
else osec: {
|
||||
const osec = try elf_file.addSection(.{
|
||||
.name = try elf_file.insertShString(".text"),
|
||||
.type = elf.SHT_PROGBITS,
|
||||
.addralign = 1,
|
||||
.flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
|
||||
.offset = std.math.maxInt(u64),
|
||||
});
|
||||
self.text_index = try self.addSectionSymbol(gpa, ".text", .@"1", osec);
|
||||
break :osec osec;
|
||||
},
|
||||
.const_data => if (self.rodata_index) |sym_index|
|
||||
self.symbol(sym_index).atom(elf_file).?.output_section_index
|
||||
else osec: {
|
||||
|
||||
Reference in New Issue
Block a user