[llvm] hwasan: Fix relocation errors by adjusting `NewGV` alias address calculation (PR #164876)
Martin Nordholts via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 23 12:05:26 PDT 2025
https://github.com/Enselic created https://github.com/llvm/llvm-project/pull/164876
We don't want to apply `PointerTagShift` to the alias address of `NewGV` that replaces the `GV` we are instrumenting, because that makes the address huge and results in relocation errors such as:
hwaddress.7rcbfp3g-cgu.0:(.text.main+0x7c): \
relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 against `.data.rel.ro..L.hwasan'
unless optimizations happens get rid of the faulty calculation.
I am not 100% sure this is the correct fix, but when I [verified the fix](https://github.com/rust-lang/rust/pull/148032#issuecomment-3438561294) with a Rust test we have, the test passed. LLVM have many more HWAsan tests however, so it would be useful to see if they pass with this fix. Maybe someone can help me trigger HWAsan CI?
CC @pcc who added the logic I change in 0930643ff6f1684. Maybe you can quickly determine if this patch is right or wrong?
FWIW, here are [some backtraces](https://gist.github.com/Enselic/ae9fe91a83e35a556f2e35834123ab4a) I collected while debugging this.
## Rust bug
In https://github.com/rust-lang/rust/issues/83989 we get a linker error due to the addend being huge:
```console
$ rustc +nightly -Clinker=aarch64-linux-gnu-gcc --target=aarch64-unknown-linux-gnu tests/ui/sanitizer/hwaddress.rs -Z sanitizer=hwaddress -O -g -C codegen-units=16 -C unsafe-allow-abi-mismatch=sanitizer -Clto=no
error: linking with `aarch64-linux-gnu-gcc` failed: exit status: 1
|
= note: hwaddress.hwaddress.71eeac658309bde7-cgu.2.rcgu.o: in function `std::rt::lang_start':
/home/martin/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:205:(.text._ZN3std2rt10lang_start17hae1e7d092f980101E+0x38): relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 against `.data.rel.ro..L.hwasan'
collect2: error: ld returned 1 exit status
```
and the fix appears to work based on Rust CI as mentioned above
>From bf697b0293cc0272a33036fca0fb53e1bdcb0a93 Mon Sep 17 00:00:00 2001
From: Martin Nordholts <martin.nordholts at codetale.se>
Date: Thu, 23 Oct 2025 06:03:12 +0200
Subject: [PATCH] hwasan: Fix relocation errors by adjusting `NewGV` alias
address calculation
We don't want to apply `PointerTagShift` to the alias address of `NewGV`
that replaces the `GV` we are instrumenting, because that makes the
address huge and results in relocation errors such as:
hwaddress.7rcbfp3g-cgu.0:(.text.main+0x7c): \
relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 against `.data.rel.ro..L.hwasan'
unless optimizations happens get rid of the faulty calculation.
---
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 832592e7663b2..e12ca0404ee9c 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -1763,9 +1763,7 @@ void HWAddressSanitizer::instrumentGlobal(GlobalVariable *GV, uint8_t Tag) {
}
Constant *Aliasee = ConstantExpr::getIntToPtr(
- ConstantExpr::getAdd(
- ConstantExpr::getPtrToInt(NewGV, Int64Ty),
- ConstantInt::get(Int64Ty, uint64_t(Tag) << PointerTagShift)),
+ ConstantExpr::getPtrToInt(NewGV, Int64Ty),
GV->getType());
auto *Alias = GlobalAlias::create(GV->getValueType(), GV->getAddressSpace(),
GV->getLinkage(), "", Aliasee, &M);
More information about the llvm-commits
mailing list