Skip to content

Commit

Permalink
elf: fix resolving relocs targets
Browse files Browse the repository at this point in the history
  • Loading branch information
kubkon committed Sep 20, 2024
1 parent 7c8c9af commit 95c3abe
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 11 deletions.
6 changes: 1 addition & 5 deletions src/Elf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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) });
Expand Down
15 changes: 9 additions & 6 deletions src/Elf/Atom.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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/
Expand Down Expand Up @@ -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,
},
Expand Down Expand Up @@ -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));
Expand Down
30 changes: 30 additions & 0 deletions src/Elf/synthetic.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 95c3abe

Please sign in to comment.