diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-29 07:30:36 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-09-04 13:34:25 +0200 |
| commit | 0b92404ddf71c72664d2d4dd252e211a9678492d (patch) | |
| tree | 72f12db832f936b041f873b93227646b2ae41b95 /src | |
| parent | 37a1f0e7f2586b1fd3c88c3483f0c9f731f41a30 (diff) | |
| download | zig-0b92404ddf71c72664d2d4dd252e211a9678492d.tar.gz zig-0b92404ddf71c72664d2d4dd252e211a9678492d.zip | |
elf: allocate .data in ZigObject similarly to .eh_frame
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/Elf.zig | 52 | ||||
| -rw-r--r-- | src/link/Elf/ZigObject.zig | 81 |
2 files changed, 72 insertions, 61 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 5757e40ab8..ae6933fdf7 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -59,8 +59,6 @@ phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{}, phdr_zig_load_re_index: ?u16 = null, /// The index into the program headers of a PT_LOAD program header with Read flag phdr_zig_load_ro_index: ?u16 = null, -/// The index into the program headers of a PT_LOAD program header with Write flag -phdr_zig_load_rw_index: ?u16 = null, /// Special program headers /// PT_PHDR @@ -126,7 +124,6 @@ comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{}, /// .rela.* sections are only used when emitting a relocatable object file. zig_text_section_index: ?u32 = null, zig_data_rel_ro_section_index: ?u32 = null, -zig_data_section_index: ?u32 = null, debug_info_section_index: ?u32 = null, debug_abbrev_section_index: ?u32 = null, @@ -3491,7 +3488,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void { &self.verneed_section_index, &self.zig_text_section_index, &self.zig_data_rel_ro_section_index, - &self.zig_data_section_index, &self.debug_info_section_index, &self.debug_abbrev_section_index, &self.debug_str_section_index, @@ -3589,12 +3585,16 @@ fn updateSectionSizes(self: *Elf) !void { for (slice.items(.shdr), slice.items(.atom_list), 0..) |*shdr, atom_list, shndx| { if (atom_list.items.len == 0) continue; if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue; - if (self.zigObjectPtr()) |zo| { - if (zo.bss_index) |sym_index| { - const atom_ptr = zo.symbol(sym_index).atom(self).?; - if (shndx == atom_ptr.output_section_index) { - shdr.sh_size = atom_ptr.size; - } + if (self.zigObjectPtr()) |zo| blk: { + const sym_index = for ([_]?Symbol.Index{ + zo.data_index, + zo.bss_index, + }) |maybe_idx| { + if (maybe_idx) |idx| break idx; + } else break :blk; + const atom_ptr = zo.symbol(sym_index).atom(self).?; + if (shndx == atom_ptr.output_section_index) { + shdr.sh_size = atom_ptr.size; } } for (atom_list.items) |ref| { @@ -3929,10 +3929,16 @@ pub fn allocateAllocSections(self: *Elf) !void { } new_offset = alignment.@"align"(shndx, shdr.sh_addralign, new_offset); - if (shndx == self.eh_frame_section_index) eh_frame: { - const zo = self.zigObjectPtr() orelse break :eh_frame; - const sym = zo.symbol(zo.eh_frame_index orelse break :eh_frame); - const existing_size = sym.atom(self).?.size; + if (self.zigObjectPtr()) |zo| blk: { + const existing_size = for ([_]?Symbol.Index{ + zo.data_index, + zo.eh_frame_index, + }) |maybe_sym_index| { + const sect_sym_index = maybe_sym_index orelse continue; + const sect_atom_ptr = zo.symbol(sect_sym_index).atom(self).?; + if (sect_atom_ptr.output_section_index != shndx) continue; + break sect_atom_ptr.size; + } else break :blk; log.debug("moving {s} from 0x{x} to 0x{x}", .{ self.getShString(shdr.sh_name), shdr.sh_offset, @@ -4096,10 +4102,17 @@ fn writeAtoms(self: *Elf) !void { if (atom_ptr.output_section_index == shndx) break :base_offset atom_ptr.size; } break :base_offset 0; - } else if (@as(u32, @intCast(shndx)) == self.eh_frame_section_index) base_offset: { - const zo = self.zigObjectPtr() orelse break :base_offset 0; - const sym = zo.symbol(zo.eh_frame_index orelse break :base_offset 0); - break :base_offset sym.atom(self).?.size; + } else if (self.zigObjectPtr()) |zo| base_offset: { + const sym_index = for ([_]?Symbol.Index{ + zo.data_index, + zo.eh_frame_index, + }) |maybe_idx| { + if (maybe_idx) |idx| break idx; + } else break :base_offset 0; + const sym = zo.symbol(sym_index); + const atom_ptr = sym.atom(self).?; + if (atom_ptr.output_section_index == @as(u32, @intCast(shndx))) break :base_offset atom_ptr.size; + break :base_offset 0; } else 0; const sh_offset = shdr.sh_offset + base_offset; 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 { inline for (&[_]?u32{ self.zig_text_section_index, self.zig_data_rel_ro_section_index, - self.zig_data_section_index, }) |index| { if (index == shndx) return true; } @@ -5507,7 +5519,7 @@ fn requiresThunks(self: Elf) bool { /// so that we reserve enough space for the program header table up-front. /// Bump these numbers when adding or deleting a Zig specific pre-allocated segment, or adding /// more special-purpose program headers. -pub const number_of_zig_segments = 4; +pub const number_of_zig_segments = 2; const max_number_of_object_segments = 9; const max_number_of_special_phdrs = 5; diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 594dd5f640..8cd2341873 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -61,6 +61,7 @@ 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, pub const global_symbol_bit: u32 = 0x80000000; pub const symbol_mask: u32 = 0x7fffffff; @@ -104,7 +105,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { } }.fillSection; - comptime assert(Elf.number_of_zig_segments == 4); + comptime assert(Elf.number_of_zig_segments == 2); if (!elf_file.base.isRelocatable()) { if (elf_file.phdr_zig_load_re_index == null) { @@ -135,21 +136,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { .flags = elf.PF_R | elf.PF_W, }); } - - if (elf_file.phdr_zig_load_rw_index == null) { - const alignment = elf_file.page_size; - const filesz: u64 = 1024; - const off = try elf_file.findFreeSpace(filesz, alignment); - elf_file.phdr_zig_load_rw_index = try elf_file.addPhdr(.{ - .type = elf.PT_LOAD, - .offset = off, - .filesz = filesz, - .addr = if (ptr_size >= 4) 0x10000000 else 0xc000, - .memsz = filesz, - .@"align" = alignment, - .flags = elf.PF_R | elf.PF_W, - }); - } } if (elf_file.zig_text_section_index == null) { @@ -194,27 +180,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { } } - if (elf_file.zig_data_section_index == null) { - elf_file.zig_data_section_index = try elf_file.addSection(.{ - .name = try elf_file.insertShString(".data.zig"), - .type = elf.SHT_PROGBITS, - .addralign = ptr_size, - .flags = elf.SHF_ALLOC | elf.SHF_WRITE, - .offset = std.math.maxInt(u64), - }); - const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_data_section_index.?]; - const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_data_section_index.?]; - try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_rw_index); - if (elf_file.base.isRelocatable()) { - _ = try elf_file.addRelaShdr( - try elf_file.insertShString(".rela.data.zig"), - elf_file.zig_data_section_index.?, - ); - } else { - phndx.* = elf_file.phdr_zig_load_rw_index.?; - } - } - switch (comp.config.debug_format) { .strip => {}, .dwarf => |v| { @@ -1246,6 +1211,8 @@ fn getNavShdrIndex( sym_index: Symbol.Index, code: []const u8, ) error{OutOfMemory}!u32 { + const gpa = elf_file.base.comp.gpa; + const ptr_size = elf_file.ptrWidthBytes(); 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); @@ -1276,7 +1243,19 @@ fn getNavShdrIndex( if (is_const) return elf_file.zig_data_rel_ro_section_index.?; if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu)) return switch (zcu.navFileScope(nav_index).mod.optimize_mode) { - .Debug, .ReleaseSafe => elf_file.zig_data_section_index.?, + .Debug, .ReleaseSafe => { + if (self.data_index) |symbol_index| + return self.symbol(symbol_index).atom(elf_file).?.output_section_index; + const osec = try elf_file.addSection(.{ + .name = try elf_file.insertShString(".data"), + .type = elf.SHT_PROGBITS, + .addralign = ptr_size, + .flags = elf.SHF_ALLOC | elf.SHF_WRITE, + .offset = std.math.maxInt(u64), + }); + self.data_index = try self.addSectionSymbol(gpa, ".data", .@"1", osec); + return osec; + }, .ReleaseFast, .ReleaseSmall => { if (self.bss_index) |symbol_index| return self.symbol(symbol_index).atom(elf_file).?.output_section_index; @@ -1286,7 +1265,7 @@ fn getNavShdrIndex( .name = try elf_file.insertShString(".bss"), .addralign = 1, }); - self.bss_index = try self.addSectionSymbol(elf_file.base.comp.gpa, ".bss", .@"1", osec); + self.bss_index = try self.addSectionSymbol(gpa, ".bss", .@"1", osec); return osec; }, }; @@ -1302,10 +1281,20 @@ fn getNavShdrIndex( .name = try elf_file.insertShString(".bss"), .addralign = 1, }); - self.bss_index = try self.addSectionSymbol(elf_file.base.comp.gpa, ".bss", .@"1", osec); + self.bss_index = try self.addSectionSymbol(gpa, ".bss", .@"1", osec); return osec; } - return elf_file.zig_data_section_index.?; + if (self.data_index) |symbol_index| + return self.symbol(symbol_index).atom(elf_file).?.output_section_index; + const osec = try elf_file.addSection(.{ + .name = try elf_file.insertShString(".data"), + .type = elf.SHT_PROGBITS, + .addralign = ptr_size, + .flags = elf.SHF_ALLOC | elf.SHF_WRITE, + .offset = std.math.maxInt(u64), + }); + self.data_index = try self.addSectionSymbol(gpa, ".data", .@"1", osec); + return osec; } fn updateNavCode( @@ -2014,6 +2003,16 @@ fn allocateAtom(self: *ZigObject, atom_ptr: *Atom, elf_file: *Elf) !void { } shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits().?); + const sect_atom_ptr = for ([_]?Symbol.Index{self.data_index}) |maybe_sym_index| { + const sect_sym_index = maybe_sym_index orelse continue; + const sect_atom_ptr = self.symbol(sect_sym_index).atom(elf_file).?; + if (sect_atom_ptr.output_section_index == atom_ptr.output_section_index) break sect_atom_ptr; + } else null; + if (sect_atom_ptr) |sap| { + sap.size = shdr.sh_size; + sap.alignment = Atom.Alignment.fromNonzeroByteUnits(shdr.sh_addralign); + } + // This function can also reallocate an atom. // In this case we need to "unplug" it from its previous location before // plugging it in to its new location. |
