llvm / llvm/llvm-project

[ELF][AArch64][PAC] Weak undefined symbols treated as symbol with value 0 and signed

Open
#173,296 26 comments 0 reactions 2 assignees Claimed by @atrosinenko View on GitHub
lld:ELF
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

The PAuthABI spec says the following:

> For a relocation that involves signing a pointer, if the target symbol is an undefined weak reference, the result of the relocation is 0 (nullptr) regardless of the signing schema.

However, this is not what's implemented. isStaticLinkTimeConstant has an early false return for RE_AARCH64_AUTH that ignores this case, and so will treat it like a defined non-preemptible symbol, emitting R_AARCH64_AUTH_RELATIVE with an addend of the symbol's VA (+ original addend), 0. See this failing test (FileCheck assertions derived from the output when dropping the `@AUTH(da,42)`, which is what the output should be the same as):

```asm
# REQUIRES: aarch64
# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
# RUN: ld.lld --static %t.o -o %t
# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELA
# RUN: llvm-readelf -x.data %t | FileCheck %s --check-prefix=DATA

## Verify that R_AARCH64_AUTH_ABS64 against a weak undefined symbol is resolved
## to NULL (plus addend).

# RELA-LABEL: Relocations [
# RELA-NEXT: ]

# DATA-LABEL: Hex dump of section '.data':
# DATA-NEXT: 0x00220158 00000000 00000000 10000000 00000000

.weak undef

.data
foo:
.quad undef@AUTH(da,42)
.quad (undef + 16)@AUTH(da,42)
```

We have a similar case in CHERI LLVM for capabilities, as those need run-time initialisation like PAuth signing, and use the following instead:

```cpp
if (e == R_ABS_CAP)
return !sym.isPreemptible && sym.isUndefWeak();
```

However, we're currently based on an older version of LLD, and there's been a little refactoring here (we predate moving `!config->isPic && sym.isUndefWeak()` from processAux into isStaticLinkTimeConstant), so that might not be quite the right change, and AArch64::relocate will need to know to write the full 64 bits to zero out the signing schema from the input (or replace it with the upper bits of the addend, especially if negative), so that's insufficient.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.