Skip to content

Fix: Support R_X86_64_PC32 relocations to absolute addresses - #2050

Merged
davidlattimore merged 1 commit into
wild-linker:mainfrom
deepakshirkem:fix/1420-pc32-absolute-relocation
Jun 12, 2026
Merged

davidlattimore merged 1 commit into
wild-linker:mainfrom
deepakshirkem:fix/1420-pc32-absolute-relocation

Conversation

@deepakshirkem

Copy link
Copy Markdown
Member

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.

Comment thread libwild/src/elf_writer.rs Outdated
_ => {}
}

if rel.symbol().is_none() && rel.raw_type() == object::elf::R_X86_64_PC32 {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

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.

@deepakshirkem
deepakshirkem force-pushed the fix/1420-pc32-absolute-relocation branch from 5479e00 to 32189b6 Compare June 11, 2026 20:06
Comment thread libwild/src/elf_writer.rs Outdated

if rel.symbol().is_none() {
let rel_info = A::relocation_from_raw(rel.raw_type())?;
if matches!(rel_info.kind, RelocationKind::Relative) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
@deepakshirkem
deepakshirkem force-pushed the fix/1420-pc32-absolute-relocation branch from 32189b6 to 30f23db Compare June 12, 2026 09:56

@davidlattimore davidlattimore left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this :)

@davidlattimore
davidlattimore merged commit c671fa4 into wild-linker:main Jun 12, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Failed to apply relocation of type R_X86_64_PC32 to absolute

2 participants