authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-29 07:30:36+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-09-04 13:34:25+02:00
log0b92404ddf71c72664d2d4dd252e211a9678492d
tree72f12db832f936b041f873b93227646b2ae41b95
parent37a1f0e7f2586b1fd3c88c3483f0c9f731f41a30

elf: allocate .data in ZigObject similarly to .eh_frame


2 files changed, 72 insertions(+), 61 deletions(-)

src/link/Elf.zig+32-20
......@@ -59,8 +59,6 @@ phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{},
5959phdr_zig_load_re_index: ?u16 = null,
6060/// The index into the program headers of a PT_LOAD program header with Read flag
6161phdr_zig_load_ro_index: ?u16 = null,
62/// The index into the program headers of a PT_LOAD program header with Write flag
63phdr_zig_load_rw_index: ?u16 = null,
6462
6563/// Special program headers
6664/// PT_PHDR
......@@ -126,7 +124,6 @@ comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{},
126124/// .rela.* sections are only used when emitting a relocatable object file.
127125zig_text_section_index: ?u32 = null,
128126zig_data_rel_ro_section_index: ?u32 = null,
129zig_data_section_index: ?u32 = null,
130127
131128debug_info_section_index: ?u32 = null,
132129debug_abbrev_section_index: ?u32 = null,
......@@ -3491,7 +3488,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
34913488 &self.verneed_section_index,
34923489 &self.zig_text_section_index,
34933490 &self.zig_data_rel_ro_section_index,
3494 &self.zig_data_section_index,
34953491 &self.debug_info_section_index,
34963492 &self.debug_abbrev_section_index,
34973493 &self.debug_str_section_index,
......@@ -3589,12 +3585,16 @@ fn updateSectionSizes(self: *Elf) !void {
35893585 for (slice.items(.shdr), slice.items(.atom_list), 0..) |*shdr, atom_list, shndx| {
35903586 if (atom_list.items.len == 0) continue;
35913587 if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue;
3592 if (self.zigObjectPtr()) |zo| {
3593 if (zo.bss_index) |sym_index| {
3594 const atom_ptr = zo.symbol(sym_index).atom(self).?;
3595 if (shndx == atom_ptr.output_section_index) {
3596 shdr.sh_size = atom_ptr.size;
3597 }
3588 if (self.zigObjectPtr()) |zo| blk: {
3589 const sym_index = for ([_]?Symbol.Index{
3590 zo.data_index,
3591 zo.bss_index,
3592 }) |maybe_idx| {
3593 if (maybe_idx) |idx| break idx;
3594 } else break :blk;
3595 const atom_ptr = zo.symbol(sym_index).atom(self).?;
3596 if (shndx == atom_ptr.output_section_index) {
3597 shdr.sh_size = atom_ptr.size;
35983598 }
35993599 }
36003600 for (atom_list.items) |ref| {
......@@ -3929,10 +3929,16 @@ pub fn allocateAllocSections(self: *Elf) !void {
39293929 }
39303930 new_offset = alignment.@"align"(shndx, shdr.sh_addralign, new_offset);
39313931
3932 if (shndx == self.eh_frame_section_index) eh_frame: {
3933 const zo = self.zigObjectPtr() orelse break :eh_frame;
3934 const sym = zo.symbol(zo.eh_frame_index orelse break :eh_frame);
3935 const existing_size = sym.atom(self).?.size;
3932 if (self.zigObjectPtr()) |zo| blk: {
3933 const existing_size = for ([_]?Symbol.Index{
3934 zo.data_index,
3935 zo.eh_frame_index,
3936 }) |maybe_sym_index| {
3937 const sect_sym_index = maybe_sym_index orelse continue;
3938 const sect_atom_ptr = zo.symbol(sect_sym_index).atom(self).?;
3939 if (sect_atom_ptr.output_section_index != shndx) continue;
3940 break sect_atom_ptr.size;
3941 } else break :blk;
39363942 log.debug("moving {s} from 0x{x} to 0x{x}", .{
39373943 self.getShString(shdr.sh_name),
39383944 shdr.sh_offset,
......@@ -4096,10 +4102,17 @@ fn writeAtoms(self: *Elf) !void {
40964102 if (atom_ptr.output_section_index == shndx) break :base_offset atom_ptr.size;
40974103 }
40984104 break :base_offset 0;
4099 } else if (@as(u32, @intCast(shndx)) == self.eh_frame_section_index) base_offset: {
4100 const zo = self.zigObjectPtr() orelse break :base_offset 0;
4101 const sym = zo.symbol(zo.eh_frame_index orelse break :base_offset 0);
4102 break :base_offset sym.atom(self).?.size;
4105 } else if (self.zigObjectPtr()) |zo| base_offset: {
4106 const sym_index = for ([_]?Symbol.Index{
4107 zo.data_index,
4108 zo.eh_frame_index,
4109 }) |maybe_idx| {
4110 if (maybe_idx) |idx| break idx;
4111 } else break :base_offset 0;
4112 const sym = zo.symbol(sym_index);
4113 const atom_ptr = sym.atom(self).?;
4114 if (atom_ptr.output_section_index == @as(u32, @intCast(shndx))) break :base_offset atom_ptr.size;
4115 break :base_offset 0;
41034116 } else 0;
41044117 const sh_offset = shdr.sh_offset + base_offset;
41054118 const sh_size = math.cast(usize, shdr.sh_size - base_offset) orelse return error.Overflow;
......@@ -4806,7 +4819,6 @@ pub fn isZigSection(self: Elf, shndx: u32) bool {
48064819 inline for (&[_]?u32{
48074820 self.zig_text_section_index,
48084821 self.zig_data_rel_ro_section_index,
4809 self.zig_data_section_index,
48104822 }) |index| {
48114823 if (index == shndx) return true;
48124824 }
......@@ -5507,7 +5519,7 @@ fn requiresThunks(self: Elf) bool {
55075519/// so that we reserve enough space for the program header table up-front.
55085520/// Bump these numbers when adding or deleting a Zig specific pre-allocated segment, or adding
55095521/// more special-purpose program headers.
5510pub const number_of_zig_segments = 4;
5522pub const number_of_zig_segments = 2;
55115523const max_number_of_object_segments = 9;
55125524const max_number_of_special_phdrs = 5;
55135525
src/link/Elf/ZigObject.zig+40-41
......@@ -61,6 +61,7 @@ debug_loclists_index: ?Symbol.Index = null,
6161debug_rnglists_index: ?Symbol.Index = null,
6262eh_frame_index: ?Symbol.Index = null,
6363bss_index: ?Symbol.Index = null,
64data_index: ?Symbol.Index = null,
6465
6566pub const global_symbol_bit: u32 = 0x80000000;
6667pub const symbol_mask: u32 = 0x7fffffff;
......@@ -104,7 +105,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
104105 }
105106 }.fillSection;
106107
107 comptime assert(Elf.number_of_zig_segments == 4);
108 comptime assert(Elf.number_of_zig_segments == 2);
108109
109110 if (!elf_file.base.isRelocatable()) {
110111 if (elf_file.phdr_zig_load_re_index == null) {
......@@ -135,21 +136,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
135136 .flags = elf.PF_R | elf.PF_W,
136137 });
137138 }
138
139 if (elf_file.phdr_zig_load_rw_index == null) {
140 const alignment = elf_file.page_size;
141 const filesz: u64 = 1024;
142 const off = try elf_file.findFreeSpace(filesz, alignment);
143 elf_file.phdr_zig_load_rw_index = try elf_file.addPhdr(.{
144 .type = elf.PT_LOAD,
145 .offset = off,
146 .filesz = filesz,
147 .addr = if (ptr_size >= 4) 0x10000000 else 0xc000,
148 .memsz = filesz,
149 .@"align" = alignment,
150 .flags = elf.PF_R | elf.PF_W,
151 });
152 }
153139 }
154140
155141 if (elf_file.zig_text_section_index == null) {
......@@ -194,27 +180,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
194180 }
195181 }
196182
197 if (elf_file.zig_data_section_index == null) {
198 elf_file.zig_data_section_index = try elf_file.addSection(.{
199 .name = try elf_file.insertShString(".data.zig"),
200 .type = elf.SHT_PROGBITS,
201 .addralign = ptr_size,
202 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
203 .offset = std.math.maxInt(u64),
204 });
205 const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_data_section_index.?];
206 const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_data_section_index.?];
207 try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_rw_index);
208 if (elf_file.base.isRelocatable()) {
209 _ = try elf_file.addRelaShdr(
210 try elf_file.insertShString(".rela.data.zig"),
211 elf_file.zig_data_section_index.?,
212 );
213 } else {
214 phndx.* = elf_file.phdr_zig_load_rw_index.?;
215 }
216 }
217
218183 switch (comp.config.debug_format) {
219184 .strip => {},
220185 .dwarf => |v| {
......@@ -1246,6 +1211,8 @@ fn getNavShdrIndex(
12461211 sym_index: Symbol.Index,
12471212 code: []const u8,
12481213) error{OutOfMemory}!u32 {
1214 const gpa = elf_file.base.comp.gpa;
1215 const ptr_size = elf_file.ptrWidthBytes();
12491216 const ip = &zcu.intern_pool;
12501217 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
12511218 const nav_val = zcu.navValue(nav_index);
......@@ -1276,7 +1243,19 @@ fn getNavShdrIndex(
12761243 if (is_const) return elf_file.zig_data_rel_ro_section_index.?;
12771244 if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu))
12781245 return switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
1279 .Debug, .ReleaseSafe => elf_file.zig_data_section_index.?,
1246 .Debug, .ReleaseSafe => {
1247 if (self.data_index) |symbol_index|
1248 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
1249 const osec = try elf_file.addSection(.{
1250 .name = try elf_file.insertShString(".data"),
1251 .type = elf.SHT_PROGBITS,
1252 .addralign = ptr_size,
1253 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
1254 .offset = std.math.maxInt(u64),
1255 });
1256 self.data_index = try self.addSectionSymbol(gpa, ".data", .@"1", osec);
1257 return osec;
1258 },
12801259 .ReleaseFast, .ReleaseSmall => {
12811260 if (self.bss_index) |symbol_index|
12821261 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
......@@ -1286,7 +1265,7 @@ fn getNavShdrIndex(
12861265 .name = try elf_file.insertShString(".bss"),
12871266 .addralign = 1,
12881267 });
1289 self.bss_index = try self.addSectionSymbol(elf_file.base.comp.gpa, ".bss", .@"1", osec);
1268 self.bss_index = try self.addSectionSymbol(gpa, ".bss", .@"1", osec);
12901269 return osec;
12911270 },
12921271 };
......@@ -1302,10 +1281,20 @@ fn getNavShdrIndex(
13021281 .name = try elf_file.insertShString(".bss"),
13031282 .addralign = 1,
13041283 });
1305 self.bss_index = try self.addSectionSymbol(elf_file.base.comp.gpa, ".bss", .@"1", osec);
1284 self.bss_index = try self.addSectionSymbol(gpa, ".bss", .@"1", osec);
13061285 return osec;
13071286 }
1308 return elf_file.zig_data_section_index.?;
1287 if (self.data_index) |symbol_index|
1288 return self.symbol(symbol_index).atom(elf_file).?.output_section_index;
1289 const osec = try elf_file.addSection(.{
1290 .name = try elf_file.insertShString(".data"),
1291 .type = elf.SHT_PROGBITS,
1292 .addralign = ptr_size,
1293 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
1294 .offset = std.math.maxInt(u64),
1295 });
1296 self.data_index = try self.addSectionSymbol(gpa, ".data", .@"1", osec);
1297 return osec;
13091298}
13101299
13111300fn updateNavCode(
......@@ -2014,6 +2003,16 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void {
20142003 }
20152004 shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits().?);
20162005
2006 const sect_atom_ptr = for ([_]?Symbol.Index{self.data_index}) |maybe_sym_index| {
2007 const sect_sym_index = maybe_sym_index orelse continue;
2008 const sect_atom_ptr = self.symbol(sect_sym_index).atom(elf_file).?;
2009 if (sect_atom_ptr.output_section_index == atom_ptr.output_section_index) break sect_atom_ptr;
2010 } else null;
2011 if (sect_atom_ptr) |sap| {
2012 sap.size = shdr.sh_size;
2013 sap.alignment = Atom.Alignment.fromNonzeroByteUnits(shdr.sh_addralign);
2014 }
2015
20172016 // This function can also reallocate an atom.
20182017 // In this case we need to "unplug" it from its previous location before
20192018 // plugging it in to its new location.