Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 859d3b8

Browse files
authored
[ELF][AArch64][PAC][MTE] Handle Memtag globals for R_AARCH64_AUTH_ABS64
Currently, R_AARCH64_AUTH_ABS64 against a tagged global just ignores the tagging and so, if out of the symbol's bounds, does not write the negated original addend for the loader to determine which granule's tag to use for it. Handle the composition of the two. Note that R_AARCH64_AUTH_ABS64/RELATIVE encode the signing schema in the upper 32 bits of the value at the relocation target, and so only the lower 32 bits are available for use as an addend, including for Memtag's disambiguation, and so if a wildly out-of-bounds PAuth relocation against a tagged global is used we have no choice but to error out with the current ABI. Reviewers: MaskRay, kovdan01, smithp35, asl Reviewed By: smithp35 Pull Request: #173291
1 parent a6032d2 commit 859d3b8

3 files changed

Lines changed: 57 additions & 1 deletion

File tree

lld/ELF/Relocations.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1005,9 +1005,11 @@ void RelocScan::process(RelExpr expr, RelType type, uint64_t offset,
10051005
// For a preemptible symbol, we can't use a relative relocation. For an
10061006
// undefined symbol, we can't compute offset at link-time and use a
10071007
// relative relocation. Use a symbolic relocation instead.
1008+
// Handle the composition with Memtag like addRelativeReloc.
10081009
if (ctx.arg.emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64 &&
10091010
!sym.isPreemptible) {
1010-
if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0) {
1011+
if (!sym.isTagged() && part.relrAuthDyn && sec->addralign >= 2 &&
1012+
offset % 2 == 0) {
10111013
// When symbol values are determined in
10121014
// finalizeAddressDependentContent, some .relr.auth.dyn relocations
10131015
// may be moved to .rela.dyn.
@@ -1016,6 +1018,9 @@ void RelocScan::process(RelExpr expr, RelType type, uint64_t offset,
10161018
} else {
10171019
part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset, false,
10181020
sym, addend, R_ABS});
1021+
if (sym.isTagged() &&
1022+
(addend < 0 || static_cast<uint64_t>(addend) >= sym.getSize()))
1023+
sec->addReloc({R_ADDEND_NEG, type, offset, addend, &sym});
10191024
}
10201025
return;
10211026
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# REQUIRES: aarch64
2+
# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-android %s -o %t.o
3+
# RUN: not ld.lld --shared --android-memtag-mode=sync %t.o -o /dev/null 2>&1 | \
4+
# RUN: FileCheck %s --implicit-check-not=error:
5+
6+
## Verify that, when composing PAuth and Memtag ABIs, we error if trying to
7+
## emit an R_AARCH64_AUTH_RELATIVE for a tagged global using an original addend
8+
## that's not within the bounds of the symbol and, when negated, does not fit
9+
## in a signed 32-bit integer, since the signing schema uses the upper 32 bits.
10+
11+
# CHECK: error: {{.*}}aarch64-memtag-pauth-globals-out-of-range.s.tmp.o:(.data+0x0): relocation R_AARCH64_AUTH_ABS64 out of range: 2147483648 is not in [-2147483648, 2147483647]; references 'foo'
12+
# CHECK: error: {{.*}}aarch64-memtag-pauth-globals-out-of-range.s.tmp.o:(.data+0x8): relocation R_AARCH64_AUTH_ABS64 out of range: -2147483649 is not in [-2147483648, 2147483647]; references 'foo'
13+
14+
.data
15+
.balign 16
16+
.memtag foo
17+
.type foo, @object
18+
foo:
19+
.quad (foo - 0x80000000)@AUTH(da,42)
20+
.quad (foo + 0x80000001)@AUTH(da,42)
21+
## These are just in bounds
22+
.quad (foo - 0x7fffffff)@AUTH(da,42)
23+
.quad (foo + 0x80000000)@AUTH(da,42)
24+
.size foo, 32
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# REQUIRES: aarch64
2+
# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-android %s -o %t.o
3+
# RUN: ld.lld --shared --android-memtag-mode=sync %t.o -o %t
4+
# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELA
5+
# RUN: llvm-readelf -x.data %t | FileCheck %s --check-prefix=DATA
6+
7+
## Verify that, when composing PAuth and Memtag ABIs, R_AARCH64_AUTH_RELATIVE
8+
## relocations follow R_AARCH64_RELATIVE in emitting the (negated) original
9+
## addend at the relocated target for tagged globals when not within the
10+
## symbol's bounds.
11+
12+
# RELA-LABEL: .rela.dyn {
13+
# RELA-NEXT: 0x303C0 R_AARCH64_AUTH_RELATIVE - 0x303BF
14+
# RELA-NEXT: 0x303C8 R_AARCH64_AUTH_RELATIVE - 0x303D0
15+
# RELA-NEXT: }
16+
17+
# DATA-LABEL: Hex dump of section '.data':
18+
# DATA-NEXT: 0x000303c0 01000000 2a000020 f0ffffff 2a000020
19+
20+
.data
21+
.balign 16
22+
.memtag foo
23+
.type foo, @object
24+
foo:
25+
.quad (foo - 1)@AUTH(da,42)
26+
.quad (foo + 16)@AUTH(da,42)
27+
.size foo, 16

0 commit comments

Comments
 (0)