Skip to content

Commit 464fa3b

Browse files
committed
[AArch64][MachO] Encode @AUTH to ARM64_RELOC_AUTHENTICATED_POINTER.
This adds MachO support for emission of authenticated pointer relocations. We already support AArch64AuthMCExpr, to represent assembly expressions such as: .quad <symbol>@AUTH(<key>, <discriminator> [, addr]) For example: .quad _g3@AUTH(ib, 1234, addr) These @AUTH expressions lower to a new kind of MachO relocation: ARM64_RELOC_AUTHENTICATED_POINTER (11) The relocation points to the referenced symbol. The other data, describing the signing scheme and original addend (only 32 bits instead of 64), is encoded into the addend (in the relocated location): |63|62|61-51|50-49| 48 |47 - 32|31 - 0| | 1| 0| 0 | key | addr | discriminator | addend |
1 parent e6b9f12 commit 464fa3b

File tree

4 files changed

+174
-1
lines changed

4 files changed

+174
-1
lines changed

llvm/docs/PointerAuth.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,19 @@ For example:
374374
.quad _sym@AUTH(ia,12,addr)
375375
```
376376

377+
#### MachO Object File Representation
378+
379+
At the object file level, authenticated relocations are represented using the
380+
``ARM64_RELOC_AUTHENTICATED_POINTER`` relocation kind (with value ``11``).
381+
382+
The pointer authentication information is encoded into the addend as follows:
383+
384+
```
385+
| 63 | 62 | 61-51 | 50-49 | 48 | 47 - 32 | 31 - 0 |
386+
| -- | -- | ----- | ----- | ------ | --------------- | -------- |
387+
| 1 | 0 | 0 | key | addr | discriminator | addend |
388+
```
389+
377390
#### ELF Object File Representation
378391

379392
At the object file level, authenticated relocations are represented

llvm/lib/Object/MachOObjectFile.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2341,7 +2341,7 @@ void MachOObjectFile::getRelocationTypeName(
23412341
"ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
23422342
"ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
23432343
"ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
2344-
"ARM64_RELOC_ADDEND"
2344+
"ARM64_RELOC_ADDEND", "ARM64_RELOC_AUTHENTICATED_POINTER"
23452345
};
23462346

23472347
if (RType >= std::size(Table))

llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "MCTargetDesc/AArch64FixupKinds.h"
10+
#include "MCTargetDesc/AArch64MCExpr.h"
1011
#include "MCTargetDesc/AArch64MCTargetDesc.h"
1112
#include "llvm/ADT/Twine.h"
1213
#include "llvm/BinaryFormat/MachO.h"
@@ -394,6 +395,46 @@ void AArch64MachObjectWriter::recordRelocation(
394395
Value = 0;
395396
}
396397

398+
if (Target.getRefKind() == AArch64MCExpr::VK_AUTH ||
399+
Target.getRefKind() == AArch64MCExpr::VK_AUTHADDR) {
400+
auto *Expr = cast<AArch64AuthMCExpr>(Fixup.getValue());
401+
402+
assert(Type == MachO::ARM64_RELOC_UNSIGNED);
403+
404+
if (IsPCRel) {
405+
Asm.getContext().reportError(Fixup.getLoc(),
406+
"invalid PC relative auth relocation");
407+
return;
408+
}
409+
410+
if (Log2Size != 3) {
411+
Asm.getContext().reportError(
412+
Fixup.getLoc(), "invalid auth relocation size, must be 8 bytes");
413+
return;
414+
}
415+
416+
if (Target.getSymB()) {
417+
Asm.getContext().reportError(
418+
Fixup.getLoc(),
419+
"invalid auth relocation, can't reference two symbols");
420+
return;
421+
}
422+
423+
uint16_t Discriminator = Expr->getDiscriminator();
424+
AArch64PACKey::ID Key = Expr->getKey();
425+
426+
if (!isInt<32>(Value)) {
427+
Asm.getContext().reportError(Fixup.getLoc(),
428+
"addend too big for relocation");
429+
return;
430+
}
431+
432+
Type = MachO::ARM64_RELOC_AUTHENTICATED_POINTER;
433+
Value = (uint32_t(Value)) | (uint64_t(Discriminator) << 32) |
434+
(uint64_t(Expr->hasAddressDiversity()) << 48) |
435+
(uint64_t(Key) << 49) | (1ULL << 63);
436+
}
437+
397438
// If there's any addend left to handle, encode it in the instruction.
398439
FixedValue = Value;
399440

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// RUN: llvm-mc -triple=arm64-apple-darwin < %s | \
2+
// RUN: FileCheck %s --check-prefix=ASM
3+
4+
// RUN: llvm-mc -triple=arm64-apple-darwin -filetype=obj < %s | \
5+
// RUN: llvm-readobj --expand-relocs --sections \
6+
// RUN: --section-relocations --section-data - | \
7+
// RUN: FileCheck %s --check-prefix=RELOC
8+
9+
10+
11+
// RELOC: Sections [
12+
// RELOC-LABEL: Section {
13+
// RELOC-LABEL: Section {
14+
// RELOC-NEXT: Index: 1
15+
// RELOC-NEXT: Name: __const (5F 5F 63 6F 6E 73 74 00 00 00 00 00 00 00 00 00)
16+
// RELOC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
17+
18+
.section __DATA,__const
19+
.p2align 3
20+
21+
// RELOC-LABEL: Relocations [
22+
// RELOC-NEXT: Relocation {
23+
// RELOC-NEXT: Offset: 0x70
24+
// RELOC-NEXT: PCRel: 0
25+
// RELOC-NEXT: Length: 3
26+
// RELOC-NEXT: Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
27+
// RELOC-NEXT: Symbol: _g 7
28+
// RELOC-NEXT: }
29+
// RELOC-NEXT: Relocation {
30+
// RELOC-NEXT: Offset: 0x60
31+
// RELOC-NEXT: PCRel: 0
32+
// RELOC-NEXT: Length: 3
33+
// RELOC-NEXT: Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
34+
// RELOC-NEXT: Symbol: _g 6
35+
// RELOC-NEXT: }
36+
// RELOC-NEXT: Relocation {
37+
// RELOC-NEXT: Offset: 0x50
38+
// RELOC-NEXT: PCRel: 0
39+
// RELOC-NEXT: Length: 3
40+
// RELOC-NEXT: Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
41+
// RELOC-NEXT: Symbol: _g5
42+
// RELOC-NEXT: }
43+
// RELOC-NEXT: Relocation {
44+
// RELOC-NEXT: Offset: 0x40
45+
// RELOC-NEXT: PCRel: 0
46+
// RELOC-NEXT: Length: 3
47+
// RELOC-NEXT: Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
48+
// RELOC-NEXT: Symbol: _g4
49+
// RELOC-NEXT: }
50+
// RELOC-NEXT: Relocation {
51+
// RELOC-NEXT: Offset: 0x30
52+
// RELOC-NEXT: PCRel: 0
53+
// RELOC-NEXT: Length: 3
54+
// RELOC-NEXT: Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
55+
// RELOC-NEXT: Symbol: _g3
56+
// RELOC-NEXT: }
57+
// RELOC-NEXT: Relocation {
58+
// RELOC-NEXT: Offset: 0x20
59+
// RELOC-NEXT: PCRel: 0
60+
// RELOC-NEXT: Length: 3
61+
// RELOC-NEXT: Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
62+
// RELOC-NEXT: Symbol: _g2
63+
// RELOC-NEXT: }
64+
// RELOC-NEXT: Relocation {
65+
// RELOC-NEXT: Offset: 0x10
66+
// RELOC-NEXT: PCRel: 0
67+
// RELOC-NEXT: Length: 3
68+
// RELOC-NEXT: Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
69+
// RELOC-NEXT: Symbol: _g1
70+
// RELOC-NEXT: }
71+
// RELOC-NEXT: Relocation {
72+
// RELOC-NEXT: Offset: 0x0
73+
// RELOC-NEXT: PCRel: 0
74+
// RELOC-NEXT: Length: 3
75+
// RELOC-NEXT: Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
76+
// RELOC-NEXT: Symbol: _g0
77+
// RELOC-NEXT: }
78+
// RELOC-NEXT: ]
79+
// RELOC-NEXT: SectionData (
80+
81+
// RELOC-NEXT: 0000: 00000000 2A000080
82+
// ASM: .quad _g0@AUTH(ia,42)
83+
.quad _g0@AUTH(ia,42)
84+
.quad 0
85+
86+
// RELOC-NEXT: 0010: 00000000 00000280
87+
// ASM: .quad _g1@AUTH(ib,0)
88+
.quad _g1@AUTH(ib,0)
89+
.quad 0
90+
91+
// RELOC-NEXT: 0020: 00000000 05000580
92+
// ASM: .quad _g2@AUTH(da,5,addr)
93+
.quad _g2@AUTH(da,5,addr)
94+
.quad 0
95+
96+
// RELOC-NEXT: 0030: 00000000 FFFF0780
97+
// ASM: .quad _g3@AUTH(db,65535,addr)
98+
.quad _g3@AUTH(db,0xffff,addr)
99+
.quad 0
100+
101+
// RELOC-NEXT: 0040: 07000000 00000080
102+
// ASM: .quad (_g4+7)@AUTH(ia,0)
103+
.quad (_g4 + 7)@AUTH(ia,0)
104+
.quad 0
105+
106+
// RELOC-NEXT: 0050: FDFFFFFF 00DE0280
107+
// ASM: .quad (_g5-3)@AUTH(ib,56832)
108+
.quad (_g5 - 3)@AUTH(ib,0xde00)
109+
.quad 0
110+
111+
// RELOC-NEXT: 0060: 00000000 FF000780
112+
// ASM: .quad "_g 6"@AUTH(db,255,addr)
113+
.quad "_g 6"@AUTH(db,0xff,addr)
114+
.quad 0
115+
116+
// RELOC-NEXT: 0070: 07000000 10000080
117+
// ASM: .quad ("_g 7"+7)@AUTH(ia,16)
118+
.quad ("_g 7" + 7)@AUTH(ia,16)
119+
.quad 0

0 commit comments

Comments
 (0)