diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-29 21:14:46 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-09-04 13:34:25 +0200 |
| commit | 2d0f4fc9c0401a3c0fcf68dfc67c7948351c7f73 (patch) | |
| tree | d5e09216afdf9a6c15fbfbf36cca51dc45bdf42b /src | |
| parent | 848535535d88641a97c6f364cc78171743d7ae81 (diff) | |
| download | zig-2d0f4fc9c0401a3c0fcf68dfc67c7948351c7f73.tar.gz zig-2d0f4fc9c0401a3c0fcf68dfc67c7948351c7f73.zip | |
elf: allocate .text in ZigObject similarly to .eh_frame
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/Elf.zig | 23 | ||||
| -rw-r--r-- | src/link/Elf/ZigObject.zig | 109 |
2 files changed, 48 insertions, 84 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 018cdda888..813d0c3afc 100644 --- a/src/link/Elf.zig +++ b/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, diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 2ebe82e866..39df4b78cc 100644 --- a/src/link/Elf/ZigObject.zig +++ b/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: { |
