Issue 125850
Summary Incorrect handling of `ARM64_RELOC_PAGEOFF12` by `RuntimeDyldMachOAArch64::resolveRelocation`
Labels new issue
Assignees
Reporter JohnReppy
    ## Summary
In certain situations, the `RuntimeDyldMachOAArch64::resolveRelocation` method patches an `add` instruction with an incorrect immediate operand.

## Details
The instruction being patched is an `add` with a 12-bit immediate that is paired with an `adrp` instruction to compute the address of a label.  The calculation use to compute the immediate is
```c++
(Value + RE.Addend) & 0xFFF
```
The value of `(Value + RE.Addend)` is the memory
The variable `Value` holds the base address of the memory allocated by the loader's memory manager to contain the Section, and `(Value + RE.Addend)` is the address of the label in
that memory.  The problem is that `Value` is not guaranteed to be 12-bit aligned and so the computed immediate may be incorrect.

My code generator is based on LLVM 18.1.8, but the implementation of `RuntimeDyldMachOAArch64::resolveRelocation` does not appear to have changed in 19.1.7.

## Proposed Fix

In debugging this issue, I've noticed that `RE.Addend` appears to always hold the correct patch value, so think the correct computation should either be
```c++
RE.Addend & 0xFFF
```
or
```c++
(Value - Section.getLoadAddress() + RE.Addend) & 0xFFF
```
With the caveat that in my code, I've only seen the `add` instruction patched, but I think that this also works for patching load/store instruction (the other use of `ARM64_RELOC_PAGEOFF12`).

An alternative fix might be to set the alignment requirement for the code section to $2^12$ in the call to `MemManager::reserveAllocationSpace`, but that seems more fragile.  I also noticed that the MCJIT execution engine avoids this bug because it page-aligns the memory allocated for sections.


_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to