aboutsummaryrefslogtreecommitdiff
path: root/src/link/Coff/Relocation.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2023-03-30 20:56:25 +0200
committerJakub Konka <kubkon@jakubkonka.com>2023-03-30 21:08:32 +0200
commitee0c4457657523e218c1e211c447d3e196575ddc (patch)
tree51c14da38f52ac7a0170485747d8b4f7bab37d95 /src/link/Coff/Relocation.zig
parent349349fa01f77fe3bf2b57dc821f889e2e869004 (diff)
downloadzig-ee0c4457657523e218c1e211c447d3e196575ddc.tar.gz
zig-ee0c4457657523e218c1e211c447d3e196575ddc.zip
coff: due to ASLR we need to dupe the code for relocating
In addition, we need to be careful not to mark the relocations as resolved prematurely as then we are risking malforming the binary as we need to resolve the relocs twice: once for in-memory writes, and once for in-file updates.
Diffstat (limited to 'src/link/Coff/Relocation.zig')
-rw-r--r--src/link/Coff/Relocation.zig14
1 files changed, 8 insertions, 6 deletions
diff --git a/src/link/Coff/Relocation.zig b/src/link/Coff/Relocation.zig
index 6b35de93f4..2fafa0bbdc 100644
--- a/src/link/Coff/Relocation.zig
+++ b/src/link/Coff/Relocation.zig
@@ -72,14 +72,18 @@ pub fn getTargetAddress(self: Relocation, coff_file: *const Coff) ?u32 {
}
}
-/// Returns `false` if obtaining the target address has been deferred until `flushModule`.
-/// This can happen when trying to resolve address of an import table entry ahead of time.
-pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, image_base: u64, coff_file: *Coff) bool {
+/// Returns true if and only if the reloc is dirty AND the target address is available.
+pub fn isResolvable(self: Relocation, coff_file: *Coff) bool {
+ _ = self.getTargetAddress(coff_file) orelse return false;
+ return self.dirty;
+}
+
+pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, image_base: u64, coff_file: *Coff) void {
const atom = coff_file.getAtom(atom_index);
const source_sym = atom.getSymbol(coff_file);
const source_vaddr = source_sym.value + self.offset;
- const target_vaddr = self.getTargetAddress(coff_file) orelse return false;
+ const target_vaddr = self.getTargetAddress(coff_file).?; // Oops, you didn't check if the relocation can be resolved with isResolvable().
const target_vaddr_with_addend = target_vaddr + self.addend;
log.debug(" ({x}: [() => 0x{x} ({s})) ({s}) ", .{
@@ -102,8 +106,6 @@ pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, image_base:
.x86, .x86_64 => self.resolveX86(ctx),
else => unreachable, // unhandled target architecture
}
-
- return true;
}
const Context = struct {