diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-30 11:34:21 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-09-04 13:34:25 +0200 |
| commit | da60159d85f2b23e35b62f0626163d798413916f (patch) | |
| tree | a539ff934e8bb2a472eb3b04797ac4dfa611363a /src | |
| parent | acb91f4b30e6cbb14bb81406ca6ca71241dc3a98 (diff) | |
| download | zig-da60159d85f2b23e35b62f0626163d798413916f.tar.gz zig-da60159d85f2b23e35b62f0626163d798413916f.zip | |
elf+dwarf: refer sections via section symbols
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/Dwarf.zig | 85 | ||||
| -rw-r--r-- | src/link/Elf.zig | 61 | ||||
| -rw-r--r-- | src/link/Elf/ZigObject.zig | 60 |
3 files changed, 100 insertions, 106 deletions
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index c3197f7651..332c79e0fc 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -375,12 +375,17 @@ pub const Section = struct { fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void { if (len <= sec.len) return; if (dwarf.bin_file.cast(.elf)) |elf_file| { + const zo = elf_file.zigObjectPtr().?; + const atom = zo.symbol(sec.index).atom(elf_file).?; + const shndx = atom.output_section_index; if (sec == &dwarf.debug_frame.section) - try elf_file.growAllocSection(sec.index, len) + try elf_file.growAllocSection(shndx, len) else - try elf_file.growNonAllocSection(sec.index, len, @intCast(sec.alignment.toByteUnits().?), true); - const shdr = &elf_file.sections.items(.shdr)[sec.index]; - sec.off = shdr.sh_offset; + try elf_file.growNonAllocSection(shndx, len, @intCast(sec.alignment.toByteUnits().?), true); + const shdr = elf_file.sections.items(.shdr)[shndx]; + atom.size = shdr.sh_size; + atom.alignment = InternPool.Alignment.fromNonzeroByteUnits(shdr.sh_addralign); + sec.off = shdr.sh_offset + @as(u64, @intCast(atom.value)); sec.len = shdr.sh_size; } else if (dwarf.bin_file.cast(.macho)) |macho_file| { const header = if (macho_file.d_sym) |*d_sym| header: { @@ -402,7 +407,11 @@ pub const Section = struct { sec.off += len; sec.len -= len; if (dwarf.bin_file.cast(.elf)) |elf_file| { - const shdr = &elf_file.sections.items(.shdr)[sec.index]; + const zo = elf_file.zigObjectPtr().?; + const atom = zo.symbol(sec.index).atom(elf_file).?; + const shndx = atom.output_section_index; + const shdr = &elf_file.sections.items(.shdr)[shndx]; + atom.size = sec.len; shdr.sh_offset = sec.off; shdr.sh_size = sec.len; } else if (dwarf.bin_file.cast(.macho)) |macho_file| { @@ -891,9 +900,11 @@ const Entry = struct { if (std.debug.runtime_safety) { log.err("missing {} from {s}", .{ @as(Entry.Index, @enumFromInt(entry - unit.entries.items.ptr)), - std.mem.sliceTo(if (dwarf.bin_file.cast(.elf)) |elf_file| - elf_file.shstrtab.items[elf_file.sections.items(.shdr)[sec.index].sh_name..] - else if (dwarf.bin_file.cast(.macho)) |macho_file| + std.mem.sliceTo(if (dwarf.bin_file.cast(.elf)) |elf_file| sh_name: { + const zo = elf_file.zigObjectPtr().?; + const shndx = zo.symbol(sec.index).atom(elf_file).?.output_section_index; + break :sh_name elf_file.shstrtab.items[elf_file.sections.items(.shdr)[shndx].sh_name..]; + } else if (dwarf.bin_file.cast(.macho)) |macho_file| if (macho_file.d_sym) |*d_sym| &d_sym.sections.items[sec.index].segname else @@ -961,7 +972,8 @@ const Entry = struct { .none, .debug_frame => {}, .eh_frame => return if (dwarf.bin_file.cast(.elf)) |elf_file| { const zo = elf_file.zigObjectPtr().?; - const entry_addr: i64 = @intCast(entry_off - sec.off + elf_file.shdrs.items[sec.index].sh_addr); + const shndx = zo.symbol(sec.index).atom(elf_file).?.output_section_index; + const entry_addr: i64 = @intCast(entry_off - sec.off + elf_file.shdrs.items[shndx].sh_addr); for (entry.external_relocs.items) |reloc| { const symbol = zo.symbol(reloc.target_sym); try dwarf.resolveReloc( @@ -1877,34 +1889,7 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf { } pub fn reloadSectionMetadata(dwarf: *Dwarf) void { - if (dwarf.bin_file.cast(.elf)) |elf_file| { - for ([_]*Section{ - &dwarf.debug_abbrev.section, - &dwarf.debug_aranges.section, - &dwarf.debug_frame.section, - &dwarf.debug_info.section, - &dwarf.debug_line.section, - &dwarf.debug_line_str.section, - &dwarf.debug_loclists.section, - &dwarf.debug_rnglists.section, - &dwarf.debug_str.section, - }, [_]u32{ - elf_file.debug_abbrev_section_index.?, - elf_file.debug_aranges_section_index.?, - elf_file.eh_frame_section_index.?, - elf_file.debug_info_section_index.?, - elf_file.debug_line_section_index.?, - elf_file.debug_line_str_section_index.?, - elf_file.debug_loclists_section_index.?, - elf_file.debug_rnglists_section_index.?, - elf_file.debug_str_section_index.?, - }) |sec, section_index| { - const shdr = &elf_file.sections.items(.shdr)[section_index]; - sec.index = section_index; - sec.off = shdr.sh_offset; - sec.len = shdr.sh_size; - } - } else if (dwarf.bin_file.cast(.macho)) |macho_file| { + if (dwarf.bin_file.cast(.macho)) |macho_file| { if (macho_file.d_sym) |*d_sym| { for ([_]*Section{ &dwarf.debug_abbrev.section, @@ -1960,6 +1945,32 @@ pub fn reloadSectionMetadata(dwarf: *Dwarf) void { } pub fn initMetadata(dwarf: *Dwarf) UpdateError!void { + if (dwarf.bin_file.cast(.elf)) |elf_file| { + const zo = elf_file.zigObjectPtr().?; + for ([_]*Section{ + &dwarf.debug_abbrev.section, + &dwarf.debug_aranges.section, + &dwarf.debug_frame.section, + &dwarf.debug_info.section, + &dwarf.debug_line.section, + &dwarf.debug_line_str.section, + &dwarf.debug_loclists.section, + &dwarf.debug_rnglists.section, + &dwarf.debug_str.section, + }, [_]u32{ + zo.debug_abbrev_index.?, + zo.debug_aranges_index.?, + zo.eh_frame_index.?, + zo.debug_info_index.?, + zo.debug_line_index.?, + zo.debug_line_str_index.?, + zo.debug_loclists_index.?, + zo.debug_rnglists_index.?, + zo.debug_str_index.?, + }) |sec, sym_index| { + sec.index = sym_index; + } + } dwarf.reloadSectionMetadata(); dwarf.debug_abbrev.section.pad_to_ideal = false; diff --git a/src/link/Elf.zig b/src/link/Elf.zig index d44892836c..2940759009 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -114,15 +114,6 @@ rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{}, /// Applies only to a relocatable. comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{}, -debug_info_section_index: ?u32 = null, -debug_abbrev_section_index: ?u32 = null, -debug_str_section_index: ?u32 = null, -debug_aranges_section_index: ?u32 = null, -debug_line_section_index: ?u32 = null, -debug_line_str_section_index: ?u32 = null, -debug_loclists_section_index: ?u32 = null, -debug_rnglists_section_index: ?u32 = null, - copy_rel_section_index: ?u32 = null, dynamic_section_index: ?u32 = null, dynstrtab_section_index: ?u32 = null, @@ -636,24 +627,31 @@ pub fn growNonAllocSection( } pub fn markDirty(self: *Elf, shdr_index: u32) void { - const zig_object = self.zigObjectPtr().?; - if (zig_object.dwarf) |_| { - if (self.debug_info_section_index.? == shdr_index) { - zig_object.debug_info_section_dirty = true; - } else if (self.debug_abbrev_section_index.? == shdr_index) { - zig_object.debug_abbrev_section_dirty = true; - } else if (self.debug_str_section_index.? == shdr_index) { - zig_object.debug_str_section_dirty = true; - } else if (self.debug_aranges_section_index.? == shdr_index) { - zig_object.debug_aranges_section_dirty = true; - } else if (self.debug_line_section_index.? == shdr_index) { - zig_object.debug_line_section_dirty = true; - } else if (self.debug_line_str_section_index.? == shdr_index) { - zig_object.debug_line_str_section_dirty = true; - } else if (self.debug_loclists_section_index.? == shdr_index) { - zig_object.debug_loclists_section_dirty = true; - } else if (self.debug_rnglists_section_index.? == shdr_index) { - zig_object.debug_rnglists_section_dirty = true; + if (self.zigObjectPtr()) |zo| { + for ([_]?Symbol.Index{ + zo.debug_info_index, + zo.debug_abbrev_index, + zo.debug_aranges_index, + zo.debug_str_index, + zo.debug_line_index, + zo.debug_line_str_index, + zo.debug_loclists_index, + zo.debug_rnglists_index, + }, [_]*bool{ + &zo.debug_info_section_dirty, + &zo.debug_abbrev_section_dirty, + &zo.debug_aranges_section_dirty, + &zo.debug_str_section_dirty, + &zo.debug_line_section_dirty, + &zo.debug_line_str_section_dirty, + &zo.debug_loclists_section_dirty, + &zo.debug_rnglists_section_dirty, + }) |maybe_sym_index, dirty| { + const sym_index = maybe_sym_index orelse continue; + if (zo.symbol(sym_index).atom(self).?.output_section_index == shdr_index) { + dirty.* = true; + break; + } } } } @@ -3473,14 +3471,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void { &self.copy_rel_section_index, &self.versym_section_index, &self.verneed_section_index, - &self.debug_info_section_index, - &self.debug_abbrev_section_index, - &self.debug_str_section_index, - &self.debug_aranges_section_index, - &self.debug_line_section_index, - &self.debug_line_str_section_index, - &self.debug_loclists_section_index, - &self.debug_rnglists_section_index, }) |maybe_index| { if (maybe_index.*) |*index| { index.* = backlinks[index.*]; @@ -3505,7 +3495,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void { const atom_ptr = zo.atom(atom_index) orelse continue; atom_ptr.output_section_index = backlinks[atom_ptr.output_section_index]; } - if (zo.dwarf) |*dwarf| dwarf.reloadSectionMetadata(); } for (self.comdat_group_sections.items) |*cg| { diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 27fb121b04..8de8551463 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -99,8 +99,8 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { .dwarf => |v| { var dwarf = Dwarf.init(&elf_file.base, v); - if (elf_file.debug_str_section_index == null) { - elf_file.debug_str_section_index = try elf_file.addSection(.{ + if (self.debug_str_index == null) { + const osec = try elf_file.addSection(.{ .name = try elf_file.insertShString(".debug_str"), .flags = elf.SHF_MERGE | elf.SHF_STRINGS, .entsize = 1, @@ -108,51 +108,51 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { .addralign = 1, }); self.debug_str_section_dirty = true; - self.debug_str_index = try self.addSectionSymbol(gpa, ".debug_str", .@"1", elf_file.debug_str_section_index.?); + self.debug_str_index = try self.addSectionSymbol(gpa, ".debug_str", .@"1", osec); } - if (elf_file.debug_info_section_index == null) { - elf_file.debug_info_section_index = try elf_file.addSection(.{ + if (self.debug_info_index == null) { + const osec = try elf_file.addSection(.{ .name = try elf_file.insertShString(".debug_info"), .type = elf.SHT_PROGBITS, .addralign = 1, }); self.debug_info_section_dirty = true; - self.debug_info_index = try self.addSectionSymbol(gpa, ".debug_info", .@"1", elf_file.debug_info_section_index.?); + self.debug_info_index = try self.addSectionSymbol(gpa, ".debug_info", .@"1", osec); } - if (elf_file.debug_abbrev_section_index == null) { - elf_file.debug_abbrev_section_index = try elf_file.addSection(.{ + if (self.debug_abbrev_index == null) { + const osec = try elf_file.addSection(.{ .name = try elf_file.insertShString(".debug_abbrev"), .type = elf.SHT_PROGBITS, .addralign = 1, }); self.debug_abbrev_section_dirty = true; - self.debug_abbrev_index = try self.addSectionSymbol(gpa, ".debug_abbrev", .@"1", elf_file.debug_abbrev_section_index.?); + self.debug_abbrev_index = try self.addSectionSymbol(gpa, ".debug_abbrev", .@"1", osec); } - if (elf_file.debug_aranges_section_index == null) { - elf_file.debug_aranges_section_index = try elf_file.addSection(.{ + if (self.debug_aranges_index == null) { + const osec = try elf_file.addSection(.{ .name = try elf_file.insertShString(".debug_aranges"), .type = elf.SHT_PROGBITS, .addralign = 16, }); self.debug_aranges_section_dirty = true; - self.debug_aranges_index = try self.addSectionSymbol(gpa, ".debug_aranges", .@"16", elf_file.debug_aranges_section_index.?); + self.debug_aranges_index = try self.addSectionSymbol(gpa, ".debug_aranges", .@"16", osec); } - if (elf_file.debug_line_section_index == null) { - elf_file.debug_line_section_index = try elf_file.addSection(.{ + if (self.debug_line_index == null) { + const osec = try elf_file.addSection(.{ .name = try elf_file.insertShString(".debug_line"), .type = elf.SHT_PROGBITS, .addralign = 1, }); self.debug_line_section_dirty = true; - self.debug_line_index = try self.addSectionSymbol(gpa, ".debug_line", .@"1", elf_file.debug_line_section_index.?); + self.debug_line_index = try self.addSectionSymbol(gpa, ".debug_line", .@"1", osec); } - if (elf_file.debug_line_str_section_index == null) { - elf_file.debug_line_str_section_index = try elf_file.addSection(.{ + if (self.debug_line_str_index == null) { + const osec = try elf_file.addSection(.{ .name = try elf_file.insertShString(".debug_line_str"), .flags = elf.SHF_MERGE | elf.SHF_STRINGS, .entsize = 1, @@ -160,31 +160,31 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { .addralign = 1, }); self.debug_line_str_section_dirty = true; - self.debug_line_str_index = try self.addSectionSymbol(gpa, ".debug_line_str", .@"1", elf_file.debug_line_str_section_index.?); + self.debug_line_str_index = try self.addSectionSymbol(gpa, ".debug_line_str", .@"1", osec); } - if (elf_file.debug_loclists_section_index == null) { - elf_file.debug_loclists_section_index = try elf_file.addSection(.{ + if (self.debug_loclists_index == null) { + const osec = try elf_file.addSection(.{ .name = try elf_file.insertShString(".debug_loclists"), .type = elf.SHT_PROGBITS, .addralign = 1, }); self.debug_loclists_section_dirty = true; - self.debug_loclists_index = try self.addSectionSymbol(gpa, ".debug_loclists", .@"1", elf_file.debug_loclists_section_index.?); + self.debug_loclists_index = try self.addSectionSymbol(gpa, ".debug_loclists", .@"1", osec); } - if (elf_file.debug_rnglists_section_index == null) { - elf_file.debug_rnglists_section_index = try elf_file.addSection(.{ + if (self.debug_rnglists_index == null) { + const osec = try elf_file.addSection(.{ .name = try elf_file.insertShString(".debug_rnglists"), .type = elf.SHT_PROGBITS, .addralign = 1, }); self.debug_rnglists_section_dirty = true; - self.debug_rnglists_index = try self.addSectionSymbol(gpa, ".debug_rnglists", .@"1", elf_file.debug_rnglists_section_index.?); + self.debug_rnglists_index = try self.addSectionSymbol(gpa, ".debug_rnglists", .@"1", osec); } - if (elf_file.eh_frame_section_index == null) { - elf_file.eh_frame_section_index = try elf_file.addSection(.{ + if (self.eh_frame_index == null) { + const osec = try elf_file.addSection(.{ .name = try elf_file.insertShString(".eh_frame"), .type = if (elf_file.getTarget().cpu.arch == .x86_64) elf.SHT_X86_64_UNWIND @@ -194,7 +194,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { .addralign = ptr_size, }); self.eh_frame_section_dirty = true; - self.eh_frame_index = try self.addSectionSymbol(gpa, ".eh_frame", Atom.Alignment.fromNonzeroByteUnits(ptr_size), elf_file.eh_frame_section_index.?); + self.eh_frame_index = try self.addSectionSymbol(gpa, ".eh_frame", Atom.Alignment.fromNonzeroByteUnits(ptr_size), osec); } try dwarf.initMetadata(); @@ -328,12 +328,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi const sym = self.symbol(sym_index); const atom_ptr = self.atom(sym.ref.index).?; if (!atom_ptr.alive) continue; - const shndx = sym.outputShndx(elf_file).?; - const shdr = elf_file.sections.items(.shdr)[shndx]; - const esym = &self.symtab.items(.elf_sym)[sym.esym_index]; - esym.st_size = shdr.sh_size; - atom_ptr.size = shdr.sh_size; - atom_ptr.alignment = Atom.Alignment.fromNonzeroByteUnits(shdr.sh_addralign); log.debug("parsing relocs in {s}", .{sym.name(elf_file)}); |
