authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-29 21:14:46+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-09-04 13:34:25+02:00
log2d0f4fc9c0401a3c0fcf68dfc67c7948351c7f73
treed5e09216afdf9a6c15fbfbf36cca51dc45bdf42b
parent848535535d88641a97c6f364cc78171743d7ae81

elf: allocate .text in ZigObject similarly to .eh_frame


2 files changed, 48 insertions(+), 84 deletions(-)

src/link/Elf.zig+1-22
......@@ -54,10 +54,6 @@ shdr_table_offset: ?u64 = null,
5454/// Same order as in the file.
5555phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{},
5656
57/// Tracked loadable segments during incremental linking.
58/// The index into the program headers of a PT_LOAD program header with Read and Execute flags
59phdr_zig_load_re_index: ?u16 = null,
60
6157/// Special program headers
6258/// PT_PHDR
6359phdr_table_index: ?u16 = null,
......@@ -118,10 +114,6 @@ rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{},
118114/// Applies only to a relocatable.
119115comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{},
120116
121/// Tracked section headers with incremental updates to Zig object.
122/// .rela.* sections are only used when emitting a relocatable object file.
123zig_text_section_index: ?u32 = null,
124
125117debug_info_section_index: ?u32 = null,
126118debug_abbrev_section_index: ?u32 = null,
127119debug_str_section_index: ?u32 = null,
......@@ -3356,7 +3348,6 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {
33563348 }
33573349
33583350 for (&[_]*?u16{
3359 &self.phdr_zig_load_re_index,
33603351 &self.phdr_table_index,
33613352 &self.phdr_table_load_index,
33623353 &self.phdr_interp_index,
......@@ -3482,7 +3473,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
34823473 &self.copy_rel_section_index,
34833474 &self.versym_section_index,
34843475 &self.verneed_section_index,
3485 &self.zig_text_section_index,
34863476 &self.debug_info_section_index,
34873477 &self.debug_abbrev_section_index,
34883478 &self.debug_str_section_index,
......@@ -3734,10 +3724,9 @@ fn getMaxNumberOfPhdrs() u64 {
37343724/// We permit a maximum of 3**2 number of segments.
37353725fn calcNumberOfSegments(self: *Elf) usize {
37363726 var covers: [9]bool = [_]bool{false} ** 9;
3737 for (self.sections.items(.shdr), 0..) |shdr, shndx| {
3727 for (self.sections.items(.shdr)) |shdr| {
37383728 if (shdr.sh_type == elf.SHT_NULL) continue;
37393729 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
3740 if (self.isZigSection(@intCast(shndx))) continue;
37413730 const flags = shdrToPhdrFlags(shdr.sh_flags);
37423731 covers[flags - 1] = true;
37433732 }
......@@ -3835,7 +3824,6 @@ pub fn allocateAllocSections(self: *Elf) !void {
38353824 for (slice.items(.shdr), 0..) |shdr, shndx| {
38363825 if (shdr.sh_type == elf.SHT_NULL) continue;
38373826 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
3838 if (self.isZigSection(@intCast(shndx))) continue;
38393827 const flags = shdrToPhdrFlags(shdr.sh_flags);
38403828 try covers[flags - 1].append(@intCast(shndx));
38413829 }
......@@ -4813,15 +4801,6 @@ pub fn isEffectivelyDynLib(self: Elf) bool {
48134801 };
48144802}
48154803
4816pub fn isZigSection(self: Elf, shndx: u32) bool {
4817 inline for (&[_]?u32{
4818 self.zig_text_section_index,
4819 }) |index| {
4820 if (index == shndx) return true;
4821 }
4822 return false;
4823}
4824
48254804pub fn isDebugSection(self: Elf, shndx: u32) bool {
48264805 inline for (&[_]?u32{
48274806 self.debug_info_section_index,
src/link/Elf/ZigObject.zig+47-62
......@@ -51,6 +51,12 @@ debug_loclists_section_dirty: bool = false,
5151debug_rnglists_section_dirty: bool = false,
5252eh_frame_section_dirty: bool = false,
5353
54text_index: ?Symbol.Index = null,
55data_relro_index: ?Symbol.Index = null,
56rodata_index: ?Symbol.Index = null,
57data_index: ?Symbol.Index = null,
58bss_index: ?Symbol.Index = null,
59eh_frame_index: ?Symbol.Index = null,
5460debug_info_index: ?Symbol.Index = null,
5561debug_abbrev_index: ?Symbol.Index = null,
5662debug_aranges_index: ?Symbol.Index = null,
......@@ -59,11 +65,6 @@ debug_line_index: ?Symbol.Index = null,
5965debug_line_str_index: ?Symbol.Index = null,
6066debug_loclists_index: ?Symbol.Index = null,
6167debug_rnglists_index: ?Symbol.Index = null,
62eh_frame_index: ?Symbol.Index = null,
63bss_index: ?Symbol.Index = null,
64data_index: ?Symbol.Index = null,
65data_relro_index: ?Symbol.Index = null,
66rodata_index: ?Symbol.Index = null,
6768
6869pub const global_symbol_bit: u32 = 0x80000000;
6970pub const symbol_mask: u32 = 0x7fffffff;
......@@ -75,6 +76,7 @@ const InitOptions = struct {
7576};
7677
7778pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
79 _ = options;
7880 const comp = elf_file.base.comp;
7981 const gpa = comp.gpa;
8082 const ptr_size = elf_file.ptrWidthBytes();
......@@ -92,60 +94,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
9294 esym.st_shndx = elf.SHN_ABS;
9395 }
9496
95 const fillSection = struct {
96 fn fillSection(ef: *Elf, shdr: *elf.Elf64_Shdr, size: u64, phndx: ?u16) !void {
97 if (ef.base.isRelocatable()) {
98 const off = try ef.findFreeSpace(size, shdr.sh_addralign);
99 shdr.sh_offset = off;
100 shdr.sh_size = size;
101 } else {
102 const phdr = ef.phdrs.items[phndx.?];
103 shdr.sh_addr = phdr.p_vaddr;
104 shdr.sh_offset = phdr.p_offset;
105 shdr.sh_size = phdr.p_memsz;
106 }
107 }
108 }.fillSection;
109
110 comptime assert(Elf.number_of_zig_segments == 2);
111
112 if (!elf_file.base.isRelocatable()) {
113 if (elf_file.phdr_zig_load_re_index == null) {
114 const filesz = options.program_code_size_hint;
115 const off = try elf_file.findFreeSpace(filesz, elf_file.page_size);
116 elf_file.phdr_zig_load_re_index = try elf_file.addPhdr(.{
117 .type = elf.PT_LOAD,
118 .offset = off,
119 .filesz = filesz,
120 .addr = if (ptr_size >= 4) 0x4000000 else 0x4000,
121 .memsz = filesz,
122 .@"align" = elf_file.page_size,
123 .flags = elf.PF_X | elf.PF_R | elf.PF_W,
124 });
125 }
126 }
127
128 if (elf_file.zig_text_section_index == null) {
129 elf_file.zig_text_section_index = try elf_file.addSection(.{
130 .name = try elf_file.insertShString(".text.zig"),
131 .type = elf.SHT_PROGBITS,
132 .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
133 .addralign = 1,
134 .offset = std.math.maxInt(u64),
135 });
136 const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_text_section_index.?];
137 const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_text_section_index.?];
138 try fillSection(elf_file, shdr, options.program_code_size_hint, elf_file.phdr_zig_load_re_index);
139 if (elf_file.base.isRelocatable()) {
140 _ = try elf_file.addRelaShdr(
141 try elf_file.insertShString(".rela.text.zig"),
142 elf_file.zig_text_section_index.?,
143 );
144 } else {
145 phndx.* = elf_file.phdr_zig_load_re_index.?;
146 }
147 }
148
14997 switch (comp.config.debug_format) {
15098 .strip => {},
15199 .dwarf => |v| {
......@@ -1196,7 +1144,19 @@ fn getNavShdrIndex(
11961144 const ip = &zcu.intern_pool;
11971145 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
11981146 const nav_val = zcu.navValue(nav_index);
1199 if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) return elf_file.zig_text_section_index.?;
1147 if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) {
1148 if (self.text_index) |symbol_index|
1149 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
1150 const osec = try elf_file.addSection(.{
1151 .type = elf.SHT_PROGBITS,
1152 .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
1153 .name = try elf_file.insertShString(".text"),
1154 .addralign = 1,
1155 .offset = std.math.maxInt(u64),
1156 });
1157 self.text_index = try self.addSectionSymbol(gpa, ".text", .@"1", osec);
1158 return osec;
1159 }
12001160 const is_const, const is_threadlocal, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
12011161 .variable => |variable| .{ false, variable.is_threadlocal, variable.init },
12021162 .@"extern" => |@"extern"| .{ @"extern".is_const, @"extern".is_threadlocal, .none },
......@@ -1538,6 +1498,19 @@ pub fn updateFunc(
15381498 self.symbol(sym_index).name(elf_file),
15391499 });
15401500 defer gpa.free(name);
1501 const osec = if (self.text_index) |sect_sym_index|
1502 self.symbol(sect_sym_index).atom(elf_file).?.output_section_index
1503 else osec: {
1504 const osec = try elf_file.addSection(.{
1505 .name = try elf_file.insertShString(".text"),
1506 .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
1507 .type = elf.SHT_PROGBITS,
1508 .addralign = 1,
1509 .offset = std.math.maxInt(u64),
1510 });
1511 self.text_index = try self.addSectionSymbol(gpa, ".text", .@"1", osec);
1512 break :osec osec;
1513 };
15411514 const name_off = try self.addString(gpa, name);
15421515 const tr_size = trampolineSize(elf_file.getTarget().cpu.arch);
15431516 const tr_sym_index = try self.newSymbolWithAtom(gpa, name_off);
......@@ -1549,7 +1522,7 @@ pub fn updateFunc(
15491522 tr_atom_ptr.value = old_rva;
15501523 tr_atom_ptr.alive = true;
15511524 tr_atom_ptr.alignment = old_alignment;
1552 tr_atom_ptr.output_section_index = elf_file.zig_text_section_index.?;
1525 tr_atom_ptr.output_section_index = osec;
15531526 tr_atom_ptr.size = tr_size;
15541527 const target_sym = self.symbol(sym_index);
15551528 target_sym.addExtra(.{ .trampoline = tr_sym_index }, elf_file);
......@@ -1703,7 +1676,19 @@ fn updateLazySymbol(
17031676 };
17041677
17051678 const output_section_index = switch (sym.kind) {
1706 .code => elf_file.zig_text_section_index.?,
1679 .code => if (self.text_index) |sym_index|
1680 self.symbol(sym_index).atom(elf_file).?.output_section_index
1681 else osec: {
1682 const osec = try elf_file.addSection(.{
1683 .name = try elf_file.insertShString(".text"),
1684 .type = elf.SHT_PROGBITS,
1685 .addralign = 1,
1686 .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR,
1687 .offset = std.math.maxInt(u64),
1688 });
1689 self.text_index = try self.addSectionSymbol(gpa, ".text", .@"1", osec);
1690 break :osec osec;
1691 },
17071692 .const_data => if (self.rodata_index) |sym_index|
17081693 self.symbol(sym_index).atom(elf_file).?.output_section_index
17091694 else osec: {