authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-03 16:40:39+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-16 19:33:04+02:00
log9ccd94d56037e05e87755887e334aa6a1a096ec5
tree9abe67a02442a5b6bad0a653104a98088e95ccd4
parent53340544c6666d9d35463f509fbe0416f607c91c

elf: refactor object.shdrContents to never error out


5 files changed, 167 insertions(+), 72 deletions(-)

src/link/Elf.zig+49-5
......@@ -1235,7 +1235,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
12351235 // input Object files.
12361236 // Any qualifing unresolved symbol will be upgraded to an absolute, weak
12371237 // symbol for potential resolution at load-time.
1238 try self.resolveSymbols();
1238 self.resolveSymbols();
1239 self.markEhFrameAtomsDead();
12391240 self.markImportsExports();
12401241 self.claimUnresolved();
12411242
......@@ -1610,7 +1611,7 @@ fn parseArchive(
16101611/// 4. Reset state of all resolved globals since we will redo this bit on the pruned set.
16111612/// 5. Remove references to dead objects/shared objects
16121613/// 6. Re-run symbol resolution on pruned objects and shared objects sets.
1613fn resolveSymbols(self: *Elf) error{Overflow}!void {
1614fn resolveSymbols(self: *Elf) void {
16141615 // Resolve symbols in the ZigModule. For now, we assume that it's always live.
16151616 if (self.zig_module_index) |index| self.file(index).?.resolveSymbols(self);
16161617 // Resolve symbols on the set of all objects and shared objects (even if some are unneeded).
......@@ -1652,11 +1653,11 @@ fn resolveSymbols(self: *Elf) error{Overflow}!void {
16521653 const cg = self.comdatGroup(cg_index);
16531654 const cg_owner = self.comdatGroupOwner(cg.owner);
16541655 if (cg_owner.file != index) {
1655 for (try object.comdatGroupMembers(cg.shndx)) |shndx| {
1656 for (object.comdatGroupMembers(cg.shndx)) |shndx| {
16561657 const atom_index = object.atoms.items[shndx];
16571658 if (self.atom(atom_index)) |atom_ptr| {
16581659 atom_ptr.flags.alive = false;
1659 // atom_ptr.markFdesDead(self);
1660 atom_ptr.markFdesDead(self);
16601661 }
16611662 }
16621663 }
......@@ -1680,6 +1681,14 @@ fn markLive(self: *Elf) void {
16801681 }
16811682}
16821683
1684fn markEhFrameAtomsDead(self: *Elf) void {
1685 for (self.objects.items) |index| {
1686 const file_ptr = self.file(index).?;
1687 if (!file_ptr.isAlive()) continue;
1688 file_ptr.object.markEhFrameAtomsDead(self);
1689 }
1690}
1691
16831692fn markImportsExports(self: *Elf) void {
16841693 const mark = struct {
16851694 fn mark(elf_file: *Elf, file_index: File.Index) void {
......@@ -3389,17 +3398,39 @@ fn initSections(self: *Elf) !void {
33893398 .p32 => true,
33903399 .p64 => false,
33913400 };
3401 const ptr_size = self.ptrWidthBytes();
33923402
33933403 for (self.objects.items) |index| {
33943404 try self.file(index).?.object.initOutputSections(self);
33953405 }
33963406
3407 const needs_eh_frame = for (self.objects.items) |index| {
3408 if (self.file(index).?.object.cies.items.len > 0) break true;
3409 } else false;
3410 if (needs_eh_frame) {
3411 self.eh_frame_section_index = try self.addSection(.{
3412 .name = ".eh_frame",
3413 .type = elf.SHT_PROGBITS,
3414 .flags = elf.SHF_ALLOC,
3415 .addralign = ptr_size,
3416 });
3417
3418 if (self.base.options.eh_frame_hdr) {
3419 self.eh_frame_hdr_section_index = try self.addSection(.{
3420 .name = ".eh_frame_hdr",
3421 .type = elf.SHT_PROGBITS,
3422 .flags = elf.SHF_ALLOC,
3423 .addralign = ptr_size,
3424 });
3425 }
3426 }
3427
33973428 if (self.got.entries.items.len > 0 and self.got_section_index == null) {
33983429 self.got_section_index = try self.addSection(.{
33993430 .name = ".got",
34003431 .type = elf.SHT_PROGBITS,
34013432 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
3402 .addralign = self.ptrWidthBytes(),
3433 .addralign = ptr_size,
34033434 });
34043435 }
34053436
......@@ -3533,6 +3564,18 @@ fn updateSectionSizes(self: *Elf) !void {
35333564 self.file(index).?.object.updateSectionSizes(self);
35343565 }
35353566
3567 if (self.eh_frame_section_index) |index| {
3568 const shdr = &self.shdrs.items[index];
3569 shdr.sh_size = try eh_frame.calcEhFrameSize(self);
3570 shdr.sh_addralign = @alignOf(u64);
3571 }
3572
3573 if (self.eh_frame_hdr_section_index) |index| {
3574 const shdr = &self.shdrs.items[index];
3575 shdr.sh_size = eh_frame.calcEhFrameHdrSize(self);
3576 shdr.sh_addralign = @alignOf(u32);
3577 }
3578
35363579 if (self.got_section_index) |index| {
35373580 self.shdrs.items[index].sh_size = self.got.size(self);
35383581 }
......@@ -4937,6 +4980,7 @@ const math = std.math;
49374980const mem = std.mem;
49384981
49394982const codegen = @import("../codegen.zig");
4983const eh_frame = @import("Elf/eh_frame.zig");
49404984const glibc = @import("../glibc.zig");
49414985const link = @import("../link.zig");
49424986const lldMain = @import("../main.zig").lldMain;
src/link/Elf/Atom.zig+21-6
......@@ -49,7 +49,7 @@ pub fn file(self: Atom, elf_file: *Elf) ?File {
4949 return elf_file.file(self.file_index);
5050}
5151
52pub fn inputShdr(self: Atom, elf_file: *Elf) elf.Elf64_Shdr {
52pub fn inputShdr(self: Atom, elf_file: *Elf) Object.ElfShdr {
5353 const object = self.file(elf_file).?.object;
5454 return object.shdrs.items[self.input_section_index];
5555}
......@@ -272,7 +272,7 @@ pub fn free(self: *Atom, elf_file: *Elf) void {
272272 self.* = .{};
273273}
274274
275pub fn relocs(self: Atom, elf_file: *Elf) error{Overflow}![]align(1) const elf.Elf64_Rela {
275pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela {
276276 return switch (self.file(elf_file).?) {
277277 .zig_module => |x| x.relocs.items[self.relocs_section_index].items,
278278 .object => |x| x.getRelocs(self.relocs_section_index),
......@@ -280,6 +280,18 @@ pub fn relocs(self: Atom, elf_file: *Elf) error{Overflow}![]align(1) const elf.E
280280 };
281281}
282282
283pub fn fdes(self: Atom, elf_file: *Elf) []Fde {
284 if (self.fde_start == self.fde_end) return &[0]Fde{};
285 const object = self.file(elf_file).?.object;
286 return object.fdes.items[self.fde_start..self.fde_end];
287}
288
289pub fn markFdesDead(self: Atom, elf_file: *Elf) void {
290 for (self.fdes(elf_file)) |*fde| {
291 fde.alive = false;
292 }
293}
294
283295pub fn addReloc(self: Atom, elf_file: *Elf, reloc: elf.Elf64_Rela) !void {
284296 const gpa = elf_file.base.allocator;
285297 const file_ptr = self.file(elf_file).?;
......@@ -296,8 +308,8 @@ pub fn freeRelocs(self: Atom, elf_file: *Elf) void {
296308 zig_module.relocs.items[self.relocs_section_index].clearRetainingCapacity();
297309}
298310
299pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) error{Overflow}!bool {
300 for (try self.relocs(elf_file)) |rel| {
311pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool {
312 for (self.relocs(elf_file)) |rel| {
301313 if (rel.r_type() == elf.R_X86_64_GOTTPOFF) return true;
302314 }
303315 return false;
......@@ -306,7 +318,7 @@ pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) error{Overflow}!bool {
306318pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype) !void {
307319 const is_dyn_lib = elf_file.isDynLib();
308320 const file_ptr = self.file(elf_file).?;
309 const rels = try self.relocs(elf_file);
321 const rels = self.relocs(elf_file);
310322 var i: usize = 0;
311323 while (i < rels.len) : (i += 1) {
312324 const rel = rels[i];
......@@ -456,7 +468,7 @@ pub fn resolveRelocs(self: Atom, elf_file: *Elf, code: []u8) !void {
456468 var stream = std.io.fixedBufferStream(code);
457469 const cwriter = stream.writer();
458470
459 const rels = try self.relocs(elf_file);
471 const rels = self.relocs(elf_file);
460472 var i: usize = 0;
461473 while (i < rels.len) : (i += 1) {
462474 const rel = rels[i];
......@@ -841,11 +853,14 @@ const x86_64 = struct {
841853const std = @import("std");
842854const assert = std.debug.assert;
843855const elf = std.elf;
856const eh_frame = @import("eh_frame.zig");
844857const log = std.log.scoped(.link);
845858const relocs_log = std.log.scoped(.link_relocs);
846859
847860const Allocator = std.mem.Allocator;
848861const Atom = @This();
849862const Elf = @import("../Elf.zig");
863const Fde = eh_frame.Fde;
850864const File = @import("file.zig").File;
865const Object = @import("Object.zig");
851866const Symbol = @import("Symbol.zig");
src/link/Elf/Object.zig+72-34
......@@ -4,7 +4,7 @@ data: []const u8,
44index: File.Index,
55
66header: ?elf.Elf64_Ehdr = null,
7shdrs: std.ArrayListUnmanaged(elf.Elf64_Shdr) = .{},
7shdrs: std.ArrayListUnmanaged(ElfShdr) = .{},
88strings: StringTable(.object_strings) = .{},
99symtab: []align(1) const elf.Elf64_Sym = &[0]elf.Elf64_Sym{},
1010strtab: []const u8 = &[0]u8{},
......@@ -64,8 +64,13 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
6464 [*]align(1) const elf.Elf64_Shdr,
6565 @ptrCast(self.data.ptr + shoff),
6666 )[0..self.header.?.e_shnum];
67 try self.shdrs.appendUnalignedSlice(gpa, shdrs);
68 try self.strings.buffer.appendSlice(gpa, try self.shdrContents(self.header.?.e_shstrndx));
67 try self.shdrs.ensureTotalCapacityPrecise(gpa, shdrs.len);
68
69 for (shdrs) |shdr| {
70 self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr));
71 }
72
73 try self.strings.buffer.appendSlice(gpa, self.shdrContents(self.header.?.e_shstrndx));
6974
7075 const symtab_index = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) {
7176 elf.SHT_SYMTAB => break @as(u16, @intCast(i)),
......@@ -76,21 +81,21 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
7681 const shdr = shdrs[index];
7782 self.first_global = shdr.sh_info;
7883
79 const symtab = try self.shdrContents(index);
84 const symtab = self.shdrContents(index);
8085 const nsyms = @divExact(symtab.len, @sizeOf(elf.Elf64_Sym));
8186 self.symtab = @as([*]align(1) const elf.Elf64_Sym, @ptrCast(symtab.ptr))[0..nsyms];
82 self.strtab = try self.shdrContents(@as(u16, @intCast(shdr.sh_link)));
87 self.strtab = self.shdrContents(@as(u16, @intCast(shdr.sh_link)));
8388 }
8489
8590 try self.initAtoms(elf_file);
8691 try self.initSymtab(elf_file);
8792
88 // for (self.shdrs.items, 0..) |shdr, i| {
89 // const atom = elf_file.atom(self.atoms.items[i]) orelse continue;
90 // if (!atom.alive) continue;
91 // if (shdr.sh_type == elf.SHT_X86_64_UNWIND or mem.eql(u8, atom.name(elf_file), ".eh_frame"))
92 // try self.parseEhFrame(@as(u16, @intCast(i)), elf_file);
93 // }
93 for (self.shdrs.items, 0..) |shdr, i| {
94 const atom = elf_file.atom(self.atoms.items[i]) orelse continue;
95 if (!atom.flags.alive) continue;
96 if (shdr.sh_type == elf.SHT_X86_64_UNWIND or mem.eql(u8, atom.name(elf_file), ".eh_frame"))
97 try self.parseEhFrame(@as(u16, @intCast(i)), elf_file);
98 }
9499}
95100
96101fn initAtoms(self: *Object, elf_file: *Elf) !void {
......@@ -120,7 +125,7 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void {
120125 };
121126
122127 const shndx = @as(u16, @intCast(i));
123 const group_raw_data = try self.shdrContents(shndx);
128 const group_raw_data = self.shdrContents(shndx);
124129 const group_nmembers = @divExact(group_raw_data.len, @sizeOf(u32));
125130 const group_members = @as([*]align(1) const u32, @ptrCast(group_raw_data.ptr))[0..group_nmembers];
126131
......@@ -173,11 +178,11 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void {
173178
174179fn addAtom(
175180 self: *Object,
176 shdr: elf.Elf64_Shdr,
181 shdr: ElfShdr,
177182 shndx: u16,
178183 name: [:0]const u8,
179184 elf_file: *Elf,
180) error{ OutOfMemory, Overflow }!void {
185) error{OutOfMemory}!void {
181186 const atom_index = try elf_file.addAtom();
182187 const atom = elf_file.atom(atom_index).?;
183188 atom.atom_index = atom_index;
......@@ -188,7 +193,7 @@ fn addAtom(
188193 self.atoms.items[shndx] = atom_index;
189194
190195 if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) {
191 const data = try self.shdrContents(shndx);
196 const data = self.shdrContents(shndx);
192197 const chdr = @as(*align(1) const elf.Elf64_Chdr, @ptrCast(data.ptr)).*;
193198 atom.size = chdr.ch_size;
194199 atom.alignment = Alignment.fromNonzeroByteUnits(chdr.ch_addralign);
......@@ -198,7 +203,7 @@ fn addAtom(
198203 }
199204}
200205
201fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{OutOfMemory}!u16 {
206fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMemory}!u16 {
202207 const name = blk: {
203208 const name = self.strings.getAssumeExists(shdr.sh_name);
204209 if (shdr.sh_flags & elf.SHF_MERGE != 0) break :blk name;
......@@ -244,7 +249,6 @@ fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{O
244249}
245250
246251fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool {
247 _ = elf_file;
248252 const shdr = self.shdrs.items[index];
249253 const name = self.strings.getAssumeExists(shdr.sh_name);
250254 const ignore = blk: {
......@@ -252,9 +256,8 @@ fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool {
252256 if (mem.startsWith(u8, name, ".comment")) break :blk true;
253257 if (mem.startsWith(u8, name, ".llvm_addrsig")) break :blk true;
254258 if (mem.startsWith(u8, name, ".eh_frame")) break :blk true;
255 // if (elf_file.base.options.strip and shdr.sh_flags & elf.SHF_ALLOC == 0 and
256 // mem.startsWith(u8, name, ".debug")) break :blk true;
257 if (shdr.sh_flags & elf.SHF_ALLOC == 0 and mem.startsWith(u8, name, ".debug")) break :blk true;
259 if (elf_file.base.options.strip and shdr.sh_flags & elf.SHF_ALLOC == 0 and
260 mem.startsWith(u8, name, ".debug")) break :blk true;
258261 break :blk false;
259262 };
260263 return ignore;
......@@ -303,8 +306,8 @@ fn parseEhFrame(self: *Object, shndx: u16, elf_file: *Elf) !void {
303306 };
304307
305308 const gpa = elf_file.base.allocator;
306 const raw = try self.shdrContents(shndx);
307 const relocs = try self.getRelocs(relocs_shndx);
309 const raw = self.shdrContents(shndx);
310 const relocs = self.getRelocs(relocs_shndx);
308311 const fdes_start = self.fdes.items.len;
309312 const cies_start = self.cies.items.len;
310313
......@@ -408,7 +411,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
408411 const shdr = atom.inputShdr(elf_file);
409412 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
410413 if (shdr.sh_type == elf.SHT_NOBITS) continue;
411 if (try atom.scanRelocsRequiresCode(elf_file)) {
414 if (atom.scanRelocsRequiresCode(elf_file)) {
412415 // TODO ideally, we don't have to decompress at this stage (should already be done)
413416 // and we just fetch the code slice.
414417 const code = try self.codeDecompressAlloc(elf_file, atom_index);
......@@ -418,7 +421,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
418421 }
419422
420423 for (self.cies.items) |cie| {
421 for (try cie.relocs(elf_file)) |rel| {
424 for (cie.relocs(elf_file)) |rel| {
422425 const sym = elf_file.symbol(self.symbols.items[rel.r_sym()]);
423426 if (sym.flags.import) {
424427 if (sym.type(elf_file) != elf.STT_FUNC)
......@@ -518,6 +521,15 @@ pub fn markLive(self: *Object, elf_file: *Elf) void {
518521 }
519522}
520523
524pub fn markEhFrameAtomsDead(self: Object, elf_file: *Elf) void {
525 for (self.atoms.items) |atom_index| {
526 const atom = elf_file.atom(atom_index) orelse continue;
527 const is_eh_frame = atom.inputShdr(elf_file).sh_type == elf.SHT_X86_64_UNWIND or
528 mem.eql(u8, atom.name(elf_file), ".eh_frame");
529 if (atom.flags.alive and is_eh_frame) atom.flags.alive = false;
530 }
531}
532
521533pub fn checkDuplicates(self: *Object, elf_file: *Elf) void {
522534 const first_global = self.first_global orelse return;
523535 for (self.globals(), 0..) |index, i| {
......@@ -747,12 +759,10 @@ pub fn globals(self: Object) []const Symbol.Index {
747759 return self.symbols.items[start..];
748760}
749761
750fn shdrContents(self: Object, index: u32) error{Overflow}![]const u8 {
762pub fn shdrContents(self: Object, index: u32) []const u8 {
751763 assert(index < self.shdrs.items.len);
752764 const shdr = self.shdrs.items[index];
753 const offset = math.cast(usize, shdr.sh_offset) orelse return error.Overflow;
754 const size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
755 return self.data[offset..][0..size];
765 return self.data[shdr.sh_offset..][0..shdr.sh_size];
756766}
757767
758768/// Returns atom's code and optionally uncompresses data if required (for compressed sections).
......@@ -761,7 +771,7 @@ pub fn codeDecompressAlloc(self: Object, elf_file: *Elf, atom_index: Atom.Index)
761771 const gpa = elf_file.base.allocator;
762772 const atom_ptr = elf_file.atom(atom_index).?;
763773 assert(atom_ptr.file_index == self.index);
764 const data = try self.shdrContents(atom_ptr.input_section_index);
774 const data = self.shdrContents(atom_ptr.input_section_index);
765775 const shdr = atom_ptr.inputShdr(elf_file);
766776 if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) {
767777 const chdr = @as(*align(1) const elf.Elf64_Chdr, @ptrCast(data.ptr)).*;
......@@ -789,8 +799,8 @@ fn getString(self: *Object, off: u32) [:0]const u8 {
789799 return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.ptr + off)), 0);
790800}
791801
792pub fn comdatGroupMembers(self: *Object, index: u16) error{Overflow}![]align(1) const u32 {
793 const raw = try self.shdrContents(index);
802pub fn comdatGroupMembers(self: *Object, index: u16) []align(1) const u32 {
803 const raw = self.shdrContents(index);
794804 const nmembers = @divExact(raw.len, @sizeOf(u32));
795805 const members = @as([*]align(1) const u32, @ptrCast(raw.ptr))[1..nmembers];
796806 return members;
......@@ -800,8 +810,8 @@ pub fn asFile(self: *Object) File {
800810 return .{ .object = self };
801811}
802812
803pub fn getRelocs(self: *Object, shndx: u32) error{Overflow}![]align(1) const elf.Elf64_Rela {
804 const raw = try self.shdrContents(shndx);
813pub fn getRelocs(self: *Object, shndx: u32) []align(1) const elf.Elf64_Rela {
814 const raw = self.shdrContents(shndx);
805815 const num = @divExact(raw.len, @sizeOf(elf.Elf64_Rela));
806816 return @as([*]align(1) const elf.Elf64_Rela, @ptrCast(raw.ptr))[0..num];
807817}
......@@ -941,7 +951,7 @@ fn formatComdatGroups(
941951 const cg = elf_file.comdatGroup(cg_index);
942952 const cg_owner = elf_file.comdatGroupOwner(cg.owner);
943953 if (cg_owner.file != object.index) continue;
944 const cg_members = object.comdatGroupMembers(cg.shndx) catch continue;
954 const cg_members = object.comdatGroupMembers(cg.shndx);
945955 for (cg_members) |shndx| {
946956 const atom_index = object.atoms.items[shndx];
947957 const atom = elf_file.atom(atom_index) orelse continue;
......@@ -970,6 +980,34 @@ fn formatPath(
970980 } else try writer.writeAll(object.path);
971981}
972982
983pub const ElfShdr = struct {
984 sh_name: u32,
985 sh_type: u32,
986 sh_flags: u64,
987 sh_addr: u64,
988 sh_offset: usize,
989 sh_size: usize,
990 sh_link: u32,
991 sh_info: u32,
992 sh_addralign: u64,
993 sh_entsize: u64,
994
995 fn fromElf64Shdr(shdr: elf.Elf64_Shdr) error{Overflow}!ElfShdr {
996 return .{
997 .sh_name = shdr.sh_name,
998 .sh_type = shdr.sh_type,
999 .sh_flags = shdr.sh_flags,
1000 .sh_addr = shdr.sh_addr,
1001 .sh_offset = math.cast(usize, shdr.sh_offset) orelse return error.Overflow,
1002 .sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow,
1003 .sh_link = shdr.sh_link,
1004 .sh_info = shdr.sh_info,
1005 .sh_addralign = shdr.sh_addralign,
1006 .sh_entsize = shdr.sh_entsize,
1007 };
1008 }
1009};
1010
9731011const Object = @This();
9741012
9751013const std = @import("std");
src/link/Elf/ZigModule.zig+1-1
......@@ -145,7 +145,7 @@ pub fn scanRelocs(self: *ZigModule, elf_file: *Elf, undefs: anytype) !void {
145145 for (self.atoms.items) |atom_index| {
146146 const atom = elf_file.atom(atom_index) orelse continue;
147147 if (!atom.flags.alive) continue;
148 if (try atom.scanRelocsRequiresCode(elf_file)) {
148 if (atom.scanRelocsRequiresCode(elf_file)) {
149149 // TODO ideally we don't have to fetch the code here.
150150 // Perhaps it would make sense to save the code until flushModule where we
151151 // would free all of generated code?
src/link/Elf/eh_frame.zig+24-26
......@@ -20,9 +20,9 @@ pub const Fde = struct {
2020 return base + fde.out_offset;
2121 }
2222
23 pub fn data(fde: Fde, elf_file: *Elf) error{Overflow}![]const u8 {
23 pub fn data(fde: Fde, elf_file: *Elf) []const u8 {
2424 const object = elf_file.file(fde.file_index).?.object;
25 const contents = try object.shdrContents(fde.input_section_index);
25 const contents = object.shdrContents(fde.input_section_index);
2626 return contents[fde.offset..][0..fde.calcSize()];
2727 }
2828
......@@ -32,24 +32,25 @@ pub const Fde = struct {
3232 }
3333
3434 pub fn ciePointer(fde: Fde, elf_file: *Elf) u32 {
35 return std.mem.readIntLittle(u32, fde.data(elf_file)[4..8]);
35 const fde_data = fde.data(elf_file);
36 return std.mem.readIntLittle(u32, fde_data[4..8]);
3637 }
3738
3839 pub fn calcSize(fde: Fde) u64 {
3940 return fde.size + 4;
4041 }
4142
42 pub fn atom(fde: Fde, elf_file: *Elf) error{Overflow}!*Atom {
43 pub fn atom(fde: Fde, elf_file: *Elf) *Atom {
4344 const object = elf_file.file(fde.file_index).?.object;
44 const rel = (try fde.relocs(elf_file))[0];
45 const rel = fde.relocs(elf_file)[0];
4546 const sym = object.symtab[rel.r_sym()];
4647 const atom_index = object.atoms.items[sym.st_shndx];
4748 return elf_file.atom(atom_index).?;
4849 }
4950
50 pub fn relocs(fde: Fde, elf_file: *Elf) error{Overflow}![]align(1) const elf.Elf64_Rela {
51 pub fn relocs(fde: Fde, elf_file: *Elf) []align(1) const elf.Elf64_Rela {
5152 const object = elf_file.file(fde.file_index).?.object;
52 return (try object.getRelocs(fde.rel_section_index))[fde.rel_index..][0..fde.rel_num];
53 return object.getRelocs(fde.rel_section_index)[fde.rel_index..][0..fde.rel_num];
5354 }
5455
5556 pub fn format(
......@@ -88,10 +89,7 @@ pub const Fde = struct {
8889 const fde = ctx.fde;
8990 const elf_file = ctx.elf_file;
9091 const base_addr = fde.address(elf_file);
91 const atom_name = if (fde.atom(elf_file)) |atom_ptr|
92 atom_ptr.name(elf_file)
93 else |_|
94 "";
92 const atom_name = fde.atom(elf_file).name(elf_file);
9593 try writer.print("@{x} : size({x}) : cie({d}) : {s}", .{
9694 base_addr + fde.out_offset,
9795 fde.calcSize(),
......@@ -123,9 +121,9 @@ pub const Cie = struct {
123121 return base + cie.out_offset;
124122 }
125123
126 pub fn data(cie: Cie, elf_file: *Elf) error{Overflow}![]const u8 {
124 pub fn data(cie: Cie, elf_file: *Elf) []const u8 {
127125 const object = elf_file.file(cie.file_index).?.object;
128 const contents = try object.shdrContents(cie.input_section_index);
126 const contents = object.shdrContents(cie.input_section_index);
129127 return contents[cie.offset..][0..cie.calcSize()];
130128 }
131129
......@@ -133,16 +131,16 @@ pub const Cie = struct {
133131 return cie.size + 4;
134132 }
135133
136 pub fn relocs(cie: Cie, elf_file: *Elf) error{Overflow}![]align(1) const elf.Elf64_Rela {
134 pub fn relocs(cie: Cie, elf_file: *Elf) []align(1) const elf.Elf64_Rela {
137135 const object = elf_file.file(cie.file_index).?.object;
138 return (try object.getRelocs(cie.rel_section_index))[cie.rel_index..][0..cie.rel_num];
136 return object.getRelocs(cie.rel_section_index)[cie.rel_index..][0..cie.rel_num];
139137 }
140138
141 pub fn eql(cie: Cie, other: Cie, elf_file: *Elf) error{Overflow}!bool {
142 if (!std.mem.eql(u8, try cie.data(elf_file), try other.data(elf_file))) return false;
139 pub fn eql(cie: Cie, other: Cie, elf_file: *Elf) bool {
140 if (!std.mem.eql(u8, cie.data(elf_file), other.data(elf_file))) return false;
143141
144 const cie_relocs = try cie.relocs(elf_file);
145 const other_relocs = try other.relocs(elf_file);
142 const cie_relocs = cie.relocs(elf_file);
143 const other_relocs = other.relocs(elf_file);
146144 if (cie_relocs.len != other_relocs.len) return false;
147145
148146 for (cie_relocs, other_relocs) |cie_rel, other_rel| {
......@@ -152,8 +150,8 @@ pub const Cie = struct {
152150
153151 const cie_object = elf_file.file(cie.file_index).?.object;
154152 const other_object = elf_file.file(other.file_index).?.object;
155 const cie_sym = cie_object.symbol(cie_rel.r_sym(), elf_file);
156 const other_sym = other_object.symbol(other_rel.r_sym(), elf_file);
153 const cie_sym = cie_object.symbols.items[cie_rel.r_sym()];
154 const other_sym = other_object.symbols.items[other_rel.r_sym()];
157155 if (!std.mem.eql(u8, std.mem.asBytes(&cie_sym), std.mem.asBytes(&other_sym))) return false;
158156 }
159157 return true;
......@@ -319,10 +317,10 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
319317 for (object.cies.items) |cie| {
320318 if (!cie.alive) continue;
321319
322 const contents = try gpa.dupe(u8, try cie.data(elf_file));
320 const contents = try gpa.dupe(u8, cie.data(elf_file));
323321 defer gpa.free(contents);
324322
325 for (try cie.relocs(elf_file)) |rel| {
323 for (cie.relocs(elf_file)) |rel| {
326324 const sym = object.symbol(rel.r_sym(), elf_file);
327325 try resolveReloc(cie, sym, rel, elf_file, contents);
328326 }
......@@ -337,7 +335,7 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
337335 for (object.fdes.items) |fde| {
338336 if (!fde.alive) continue;
339337
340 const contents = try gpa.dupe(u8, try fde.data(elf_file));
338 const contents = try gpa.dupe(u8, fde.data(elf_file));
341339 defer gpa.free(contents);
342340
343341 std.mem.writeIntLittle(
......@@ -346,7 +344,7 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
346344 @as(i32, @truncate(@as(i64, @intCast(fde.out_offset + 4)) - @as(i64, @intCast(fde.cie(elf_file).out_offset)))),
347345 );
348346
349 for (try fde.relocs(elf_file)) |rel| {
347 for (fde.relocs(elf_file)) |rel| {
350348 const sym = object.symbol(rel.r_sym(), elf_file);
351349 try resolveReloc(fde, sym, rel, elf_file, contents);
352350 }
......@@ -395,7 +393,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {
395393 for (object.fdes.items) |fde| {
396394 if (!fde.alive) continue;
397395
398 const relocs = try fde.relocs(elf_file);
396 const relocs = fde.relocs(elf_file);
399397 assert(relocs.len > 0); // Should this be an error? Things are completely broken anyhow if this trips...
400398 const rel = relocs[0];
401399 const sym = object.symbol(rel.r_sym(), elf_file);