Commit 2d0f4fc9c0
Changed files (2)
src
link
src/link/Elf/ZigObject.zig
@@ -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: {
src/link/Elf.zig
@@ -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,