From 95c3abe17bcaa0e41330c52a8bcddaa21754472d Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 20 Sep 2024 07:50:15 +0200 Subject: [PATCH] elf: fix resolving relocs targets --- src/Elf.zig | 6 +----- src/Elf/Atom.zig | 15 +++++++++------ src/Elf/synthetic.zig | 30 ++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/Elf.zig b/src/Elf.zig index 4dec945e..2118b985 100644 --- a/src/Elf.zig +++ b/src/Elf.zig @@ -2794,11 +2794,7 @@ fn fmtDumpState( try writer.print("thunk({d}) : {}\n", .{ index, thunk.fmt(self) }); } try writer.print("GOT\n{}\n", .{self.got.fmt(self)}); - try writer.writeAll("PLT\n"); - for (self.plt.symbols.items, 0..) |ref, i| { - try writer.print(" {d} => {} '{s}'\n", .{ i, ref, self.getSymbol(ref).?.getName(self) }); - } - try writer.writeByte('\n'); + try writer.print("PLT\n{}\n", .{self.plt.fmt(self)}); try writer.writeAll("PLTGOT\n"); for (self.plt_got.symbols.items, 0..) |ref, i| { try writer.print(" {d} => {} '{s}'\n", .{ i, ref, self.getSymbol(ref).?.getName(self) }); diff --git a/src/Elf/Atom.zig b/src/Elf/Atom.zig index 203cb257..e5869d93 100644 --- a/src/Elf/Atom.zig +++ b/src/Elf/Atom.zig @@ -146,7 +146,8 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El const cpu_arch = elf_file.options.cpu_arch.?; const object = self.getObject(elf_file); for (self.getRelocs(elf_file)) |rel| { - const target = object.symbols.items[rel.r_sym()]; + const target_ref = object.resolveSymbol(rel.r_sym(), elf_file); + const target = elf_file.getSymbol(target_ref).?; const r_type = rel.r_type(); const r_offset: u64 = @intCast(self.value + @as(i64, @intCast(rel.r_offset))); var r_addend = rel.r_addend; @@ -475,7 +476,8 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, writer: anytype) !void { const r_kind = relocation.decode(rel.r_type(), cpu_arch); if (r_kind == .none) continue; - const target = object.symbols.items[rel.r_sym()]; + const target_ref = object.resolveSymbol(rel.r_sym(), elf_file); + const target = elf_file.getSymbol(target_ref).?; // We will use equation format to resolve relocations: // https://intezer.com/blog/malware-analysis/executable-and-linkable-format-101-part-3-relocations/ @@ -509,15 +511,15 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, writer: anytype) !void { const args = ResolveArgs{ P, A, S, GOT, G, TP, DTP }; switch (cpu_arch) { - .x86_64 => x86_64.resolveRelocAlloc(self, elf_file, rel, target, args, &it, code, &stream) catch |err| switch (err) { + .x86_64 => x86_64.resolveRelocAlloc(self, elf_file, rel, target.*, args, &it, code, &stream) catch |err| switch (err) { error.RelocError => has_reloc_errors = true, else => |e| return e, }, - .aarch64 => aarch64.resolveRelocAlloc(self, elf_file, rel, target, args, &it, code, &stream) catch |err| switch (err) { + .aarch64 => aarch64.resolveRelocAlloc(self, elf_file, rel, target.*, args, &it, code, &stream) catch |err| switch (err) { error.RelocError => has_reloc_errors = true, else => |e| return e, }, - .riscv64 => riscv.resolveRelocAlloc(self, elf_file, rel, target, args, &it, code, &stream) catch |err| switch (err) { + .riscv64 => riscv.resolveRelocAlloc(self, elf_file, rel, target.*, args, &it, code, &stream) catch |err| switch (err) { error.RelocError => has_reloc_errors = true, else => |e| return e, }, @@ -1759,7 +1761,8 @@ const riscv = struct { return error.RelocError; }; it.pos = pos; - const target_ = object.symbols.items[pair.r_sym()]; + const target_ref_ = object.resolveSymbol(pair.r_sym(), elf_file); + const target_ = elf_file.getSymbol(target_ref_).?; const S_ = target_.getAddress(.{}, elf_file); const A_ = pair.r_addend; const P_ = atom_addr + @as(i64, @intCast(pair.r_offset)); diff --git a/src/Elf/synthetic.zig b/src/Elf/synthetic.zig index 0c5775dd..133e542b 100644 --- a/src/Elf/synthetic.zig +++ b/src/Elf/synthetic.zig @@ -1084,6 +1084,36 @@ pub const PltSection = struct { } } + const FormatCtx = struct { + plt: PltSection, + elf_file: *Elf, + }; + + pub fn fmt(plt: PltSection, elf_file: *Elf) std.fmt.Formatter(format2) { + return .{ .data = .{ .plt = plt, .elf_file = elf_file } }; + } + + pub fn format2( + ctx: FormatCtx, + comptime unused_fmt_string: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, + ) !void { + _ = options; + _ = unused_fmt_string; + const plt = ctx.plt; + const elf_file = ctx.elf_file; + for (plt.symbols.items, 0..) |ref, i| { + const symbol = elf_file.getSymbol(ref).?; + try writer.print(" {d}@0x{x} => {} ({s})\n", .{ + i, + symbol.getAddress(.{}, elf_file), + ref, + symbol.getName(elf_file), + }); + } + } + const x86_64 = struct { fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void { const plt_addr = elf_file.sections.items(.shdr)[elf_file.plt_sect_index.?].sh_addr;