Fix: Support R_X86_64_PC32 relocations to absolute addresses - #2050
davidlattimore merged 1 commit into
Conversation
| _ => {} | ||
| } | ||
|
|
||
| if rel.symbol().is_none() && rel.raw_type() == object::elf::R_X86_64_PC32 { |
There was a problem hiding this comment.
There's overlap in the numeric values for relocation types for different architectures, so using the raw X86_64 relocation type from generic ELF code means this will likely do the wrong thing when linking for non-x86-64 CPUs. It'd also be better if we could fold this into the match above.
There was a problem hiding this comment.
You're right. I've updated the fix to use RelocationKind::Relative instead of the raw relocation type check.
While testing, I also noticed that RISC-V jal ra, 0 triggers the same code path, but it fails with a range overflow because Wild's default load address of 0x400000 is outside the 21-bit JAL range. GNU ld appears to use 0x10000 for RISC-V, which keeps it within range.
I'm not sure whether this is an actual issue or just a difference in defaults. Do you think it's worth creating an issue for this.
There was a problem hiding this comment.
While testing, I also noticed that
RISC-Vjal ra, 0triggers the same code path, but it fails with a range overflow because Wild's default load address of0x400000is outside the 21-bit JAL range. GNU ld appears to use0x10000for RISC-V, which keeps it within range.
Sure, sounds worthwhile investigating. I think I used a default load address of 0x400000 because that's what I observed GNU ld doing (at least on x86_64), but I think possibly lld uses a different load address, so it'd probably be fine for us to do so. Or, we could make it arch-dependent.
5479e00 to
32189b6
Compare
|
|
||
| if rel.symbol().is_none() { | ||
| let rel_info = A::relocation_from_raw(rel.raw_type())?; | ||
| if matches!(rel_info.kind, RelocationKind::Relative) { |
There was a problem hiding this comment.
I think the code would be simpler if this were moved into the match above. Possibly something like RelocationKind::Relative if rel.symbol().is_none() => {...}
For non-PIE executables, compute PC-relative offset to absolute address instead of erroring. For PIE/shared objects, emit a clear error message similar to mold. Fixes wild-linker#1420
32189b6 to
30f23db
Compare
davidlattimore
left a comment
There was a problem hiding this comment.
Thanks for working on this :)
Fixes #1420
Previously, Wild would error with "Unsupported absolute relocation" when encountering a PC-relative relocation to an absolute address (e.g.
callq 0). lld and GNU ld both handle this for non-PIE executables by computing the PC-relative offset to the absolute target address. For PIE/shared objects, we now emit a clearer error message similar to mold.