Skip to content

Commit 1504c88

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.6-beta.1
2 parents e20413c + 0de912a commit 1504c88

File tree

73 files changed

+1287
-120
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1287
-120
lines changed

clang/lib/CodeGen/CGPointerAuth.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,9 +440,9 @@ CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key,
440440
IntegerDiscriminator = llvm::ConstantInt::get(Int64Ty, 0);
441441
}
442442

443-
return llvm::ConstantPtrAuth::get(Pointer,
444-
llvm::ConstantInt::get(Int32Ty, Key),
445-
IntegerDiscriminator, AddressDiscriminator);
443+
return llvm::ConstantPtrAuth::get(
444+
Pointer, llvm::ConstantInt::get(Int32Ty, Key), IntegerDiscriminator,
445+
AddressDiscriminator, llvm::Constant::getNullValue(UnqualPtrTy));
446446
}
447447

448448
/// Does a given PointerAuthScheme require us to sign a value

lld/ELF/Arch/AArch64.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ AArch64::AArch64(Ctx &ctx) : TargetInfo(ctx) {
114114
copyRel = R_AARCH64_COPY;
115115
relativeRel = R_AARCH64_RELATIVE;
116116
iRelativeRel = R_AARCH64_IRELATIVE;
117+
iRelSymbolicRel = R_AARCH64_FUNCINIT64;
117118
gotRel = R_AARCH64_GLOB_DAT;
118119
pltRel = R_AARCH64_JUMP_SLOT;
119120
symbolicRel = R_AARCH64_ABS64;
@@ -137,6 +138,7 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
137138
case R_AARCH64_ABS16:
138139
case R_AARCH64_ABS32:
139140
case R_AARCH64_ABS64:
141+
case R_AARCH64_FUNCINIT64:
140142
case R_AARCH64_ADD_ABS_LO12_NC:
141143
case R_AARCH64_LDST128_ABS_LO12_NC:
142144
case R_AARCH64_LDST16_ABS_LO12_NC:
@@ -154,6 +156,12 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
154156
case R_AARCH64_MOVW_UABS_G2_NC:
155157
case R_AARCH64_MOVW_UABS_G3:
156158
return R_ABS;
159+
case R_AARCH64_PATCHINST:
160+
if (!isAbsolute(s))
161+
Err(ctx) << getErrorLoc(ctx, loc)
162+
<< "R_AARCH64_PATCHINST relocation against non-absolute symbol "
163+
<< &s;
164+
return R_ABS;
157165
case R_AARCH64_AUTH_ABS64:
158166
return RE_AARCH64_AUTH;
159167
case R_AARCH64_TLSDESC_ADR_PAGE21:
@@ -261,7 +269,8 @@ bool AArch64::usesOnlyLowPageBits(RelType type) const {
261269
}
262270

263271
RelType AArch64::getDynRel(RelType type) const {
264-
if (type == R_AARCH64_ABS64 || type == R_AARCH64_AUTH_ABS64)
272+
if (type == R_AARCH64_ABS64 || type == R_AARCH64_AUTH_ABS64 ||
273+
type == R_AARCH64_FUNCINIT64)
265274
return type;
266275
return R_AARCH64_NONE;
267276
}
@@ -506,6 +515,12 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
506515
checkIntUInt(ctx, loc, val, 32, rel);
507516
write32(ctx, loc, val);
508517
break;
518+
case R_AARCH64_PATCHINST:
519+
if (!rel.sym->isUndefined()) {
520+
checkUInt(ctx, loc, val, 32, rel);
521+
write32le(loc, val);
522+
}
523+
break;
509524
case R_AARCH64_PLT32:
510525
case R_AARCH64_GOTPCREL32:
511526
checkInt(ctx, loc, val, 32, rel);

lld/ELF/Relocations.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ static RelType getMipsPairType(RelType type, bool isLocal) {
176176

177177
// True if non-preemptable symbol always has the same value regardless of where
178178
// the DSO is loaded.
179-
static bool isAbsolute(const Symbol &sym) {
179+
bool elf::isAbsolute(const Symbol &sym) {
180180
if (sym.isUndefined())
181181
return true;
182182
if (const auto *dr = dyn_cast<Defined>(&sym))
@@ -989,8 +989,8 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
989989
// only the low bits are used.
990990
if (e == R_GOT || e == R_PLT)
991991
return ctx.target->usesOnlyLowPageBits(type) || !ctx.arg.isPic;
992-
// R_AARCH64_AUTH_ABS64 requires a dynamic relocation.
993-
if (e == RE_AARCH64_AUTH)
992+
// R_AARCH64_AUTH_ABS64 and iRelSymbolicRel require a dynamic relocation.
993+
if (e == RE_AARCH64_AUTH || type == ctx.target->iRelSymbolicRel)
994994
return false;
995995

996996
// The behavior of an undefined weak reference is implementation defined.
@@ -1163,6 +1163,24 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
11631163
}
11641164
return;
11651165
}
1166+
if (LLVM_UNLIKELY(type == ctx.target->iRelSymbolicRel)) {
1167+
if (sym.isPreemptible) {
1168+
auto diag = Err(ctx);
1169+
diag << "relocation " << type
1170+
<< " cannot be used against preemptible symbol '" << &sym << "'";
1171+
printLocation(diag, *sec, sym, offset);
1172+
} else if (isIfunc) {
1173+
auto diag = Err(ctx);
1174+
diag << "relocation " << type
1175+
<< " cannot be used against ifunc symbol '" << &sym << "'";
1176+
printLocation(diag, *sec, sym, offset);
1177+
} else {
1178+
part.relaDyn->addReloc({ctx.target->iRelativeRel, sec, offset,
1179+
DynamicReloc::AddendOnlyWithTargetVA, sym,
1180+
addend, R_ABS});
1181+
return;
1182+
}
1183+
}
11661184
part.relaDyn->addSymbolReloc(rel, *sec, offset, sym, addend, type);
11671185

11681186
// MIPS ABI turns using of GOT and dynamic relocations inside out.

lld/ELF/Relocations.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ void addGotEntry(Ctx &ctx, Symbol &sym);
165165
void hexagonTLSSymbolUpdate(Ctx &ctx);
166166
bool hexagonNeedsTLSSymbol(ArrayRef<OutputSection *> outputSections);
167167

168+
bool isAbsolute(const Symbol &sym);
169+
168170
class ThunkSection;
169171
class Thunk;
170172
class InputSectionDescription;

lld/ELF/Target.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class TargetInfo {
131131
RelType relativeRel = 0;
132132
RelType iRelativeRel = 0;
133133
RelType symbolicRel = 0;
134+
RelType iRelSymbolicRel = 0;
134135
RelType tlsDescRel = 0;
135136
RelType tlsGotRel = 0;
136137
RelType tlsModuleIndexRel = 0;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# REQUIRES: aarch64
2+
3+
# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
4+
# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck --check-prefix=ERR %s
5+
6+
.rodata
7+
# ERR: relocation R_AARCH64_FUNCINIT64 cannot be used against local symbol
8+
.8byte func@FUNCINIT
9+
10+
.data
11+
# ERR: relocation R_AARCH64_FUNCINIT64 cannot be used against ifunc symbol 'ifunc'
12+
.8byte ifunc@FUNCINIT
13+
14+
.text
15+
func:
16+
.type ifunc, @gnu_indirect_function
17+
ifunc:
18+
ret

lld/test/ELF/aarch64-funcinit64.s

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# REQUIRES: aarch64
2+
3+
# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
4+
# RUN: ld.lld %t.o -o %t
5+
# RUN: llvm-readelf -s -r %t | FileCheck %s
6+
# RUN: ld.lld %t.o -o %t -pie
7+
# RUN: llvm-readelf -s -r %t | FileCheck %s
8+
# RUN: not ld.lld %t.o -o %t -shared 2>&1 | FileCheck --check-prefix=ERR %s
9+
10+
.data
11+
# CHECK: R_AARCH64_IRELATIVE [[FOO:[0-9a-f]*]]
12+
# ERR: relocation R_AARCH64_FUNCINIT64 cannot be used against preemptible symbol 'foo'
13+
.8byte foo@FUNCINIT
14+
15+
.text
16+
# CHECK: {{0*}}[[FOO]] {{.*}} foo
17+
.globl foo
18+
foo:
19+
ret

lld/test/ELF/aarch64-patchinst.s

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# RUN: rm -rf %t && split-file %s %t
2+
# RUN: llvm-mc -filetype=obj -triple=aarch64 %t/use.s -o %t/use-le.o
3+
# RUN: llvm-mc -filetype=obj -triple=aarch64 %t/def.s -o %t/def-le.o
4+
# RUN: llvm-mc -filetype=obj -triple=aarch64 %t/rel.s -o %t/rel-le.o
5+
6+
## Deactivation symbol used without being defined: instruction emitted as usual.
7+
# RUN: ld.lld -o %t/undef-le %t/use-le.o --emit-relocs
8+
# RUN: llvm-objdump -r %t/undef-le | FileCheck --check-prefix=RELOC %s
9+
# RUN: llvm-objdump -d %t/undef-le | FileCheck --check-prefix=UNDEF %s
10+
# RUN: ld.lld -pie -o %t/undef-le %t/use-le.o --emit-relocs
11+
# RUN: llvm-objdump -r %t/undef-le | FileCheck --check-prefix=RELOC %s
12+
# RUN: llvm-objdump -d %t/undef-le | FileCheck --check-prefix=UNDEF %s
13+
14+
## Deactivation symbol defined: instructions overwritten with NOPs.
15+
# RUN: ld.lld -o %t/def-le %t/use-le.o %t/def-le.o --emit-relocs
16+
# RUN: llvm-objdump -r %t/def-le | FileCheck --check-prefix=RELOC %s
17+
# RUN: llvm-objdump -d %t/def-le | FileCheck --check-prefix=DEF %s
18+
# RUN: ld.lld -pie -o %t/def-le %t/use-le.o %t/def-le.o --emit-relocs
19+
# RUN: llvm-objdump -r %t/def-le | FileCheck --check-prefix=RELOC %s
20+
# RUN: llvm-objdump -d %t/def-le | FileCheck --check-prefix=DEF %s
21+
22+
## Relocation pointing to a non-SHN_UNDEF non-SHN_ABS symbol is an error.
23+
# RUN: not ld.lld -o %t/rel-le %t/use-le.o %t/rel-le.o 2>&1 | FileCheck --check-prefix=ERROR %s
24+
# RUN: not ld.lld -pie -o %t/rel-le %t/use-le.o %t/rel-le.o 2>&1 | FileCheck --check-prefix=ERROR %s
25+
26+
## Behavior unchanged by endianness: relocation always written as little endian.
27+
# RUN: llvm-mc -filetype=obj -triple=aarch64_be %t/use.s -o %t/use-be.o
28+
# RUN: llvm-mc -filetype=obj -triple=aarch64_be %t/def.s -o %t/def-be.o
29+
# RUN: llvm-mc -filetype=obj -triple=aarch64_be %t/rel.s -o %t/rel-be.o
30+
# RUN: ld.lld -o %t/undef-be %t/use-be.o --emit-relocs
31+
# RUN: llvm-objdump -r %t/undef-be | FileCheck --check-prefix=RELOC %s
32+
# RUN: llvm-objdump -d %t/undef-be | FileCheck --check-prefix=UNDEF %s
33+
# RUN: ld.lld -pie -o %t/undef-be %t/use-be.o --emit-relocs
34+
# RUN: llvm-objdump -r %t/undef-be | FileCheck --check-prefix=RELOC %s
35+
# RUN: llvm-objdump -d %t/undef-be | FileCheck --check-prefix=UNDEF %s
36+
# RUN: ld.lld -o %t/def-be %t/use-be.o %t/def-be.o --emit-relocs
37+
# RUN: llvm-objdump -r %t/def-be | FileCheck --check-prefix=RELOC %s
38+
# RUN: llvm-objdump -d %t/def-be | FileCheck --check-prefix=DEF %s
39+
# RUN: ld.lld -pie -o %t/def-be %t/use-be.o %t/def-be.o --emit-relocs
40+
# RUN: llvm-objdump -r %t/def-be | FileCheck --check-prefix=RELOC %s
41+
# RUN: llvm-objdump -d %t/def-be | FileCheck --check-prefix=DEF %s
42+
# RUN: not ld.lld -o %t/rel-be %t/use-be.o %t/rel-be.o 2>&1 | FileCheck --check-prefix=ERROR %s
43+
# RUN: not ld.lld -pie -o %t/rel-be %t/use-be.o %t/rel-be.o 2>&1 | FileCheck --check-prefix=ERROR %s
44+
45+
# RELOC: R_AARCH64_JUMP26
46+
# RELOC-NEXT: R_AARCH64_PATCHINST ds
47+
# RELOC-NEXT: R_AARCH64_PATCHINST ds
48+
# RELOC-NEXT: R_AARCH64_PATCHINST ds0+0xd503201f
49+
50+
#--- use.s
51+
.weak ds
52+
.weak ds0
53+
# This instruction has a single relocation: the DS relocation.
54+
# UNDEF: add x0, x1, x2
55+
# DEF: nop
56+
# ERROR: R_AARCH64_PATCHINST relocation against non-absolute symbol ds
57+
.reloc ., R_AARCH64_PATCHINST, ds
58+
add x0, x1, x2
59+
# This instruction has two relocations: the DS relocation and the JUMP26 to f1.
60+
# Make sure that the DS relocation takes precedence.
61+
.reloc ., R_AARCH64_PATCHINST, ds
62+
# UNDEF: b {{.*}} <f1>
63+
# DEF: nop
64+
# ERROR: R_AARCH64_PATCHINST relocation against non-absolute symbol ds
65+
b f1
66+
# Alternative representation: instruction opcode stored in addend.
67+
# UNDEF: add x3, x4, x5
68+
# DEF: nop
69+
# ERROR: R_AARCH64_PATCHINST relocation against non-absolute symbol ds0
70+
.reloc ., R_AARCH64_PATCHINST, ds0 + 0xd503201f
71+
add x3, x4, x5
72+
73+
.section .text.f1,"ax",@progbits
74+
f1:
75+
ret
76+
77+
#--- def.s
78+
.globl ds
79+
ds = 0xd503201f
80+
.globl ds0
81+
ds0 = 0
82+
83+
#--- rel.s
84+
.globl ds
85+
ds:
86+
.globl ds0
87+
ds0:

llvm/docs/LangRef.rst

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3090,6 +3090,21 @@ A "convergencectrl" operand bundle is only valid on a ``convergent`` operation.
30903090
When present, the operand bundle must contain exactly one value of token type.
30913091
See the :doc:`ConvergentOperations` document for details.
30923092

3093+
Deactivation Symbol Operand Bundles
3094+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3095+
3096+
A ``"deactivation-symbol"`` operand bundle is valid on the following
3097+
instructions (AArch64 only):
3098+
3099+
- Call to a normal function with ``notail`` attribute.
3100+
- Call to ``llvm.ptrauth.sign`` or ``llvm.ptrauth.auth`` intrinsics.
3101+
3102+
This operand bundle specifies that if the deactivation symbol is defined
3103+
to a valid value for the target, the marked instruction will return the
3104+
value of its first argument instead of calling the specified function
3105+
or intrinsic. This is achieved with ``PATCHINST`` relocations on the
3106+
target instructions (see the AArch64 psABI for details).
3107+
30933108
.. _moduleasm:
30943109

30953110
Module-Level Inline Assembly
@@ -31146,3 +31161,57 @@ This intrinsic is assumed to execute in the default :ref:`floating-point
3114631161
environment <floatenv>` *except* for the rounding mode.
3114731162
This intrinsic is not supported on all targets. Some targets may not support
3114831163
all rounding modes.
31164+
31165+
'``llvm.protected.field.ptr``' Intrinsic
31166+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31167+
31168+
Syntax:
31169+
"""""""
31170+
31171+
::
31172+
31173+
declare ptr @llvm.protected.field.ptr(ptr ptr, i64 disc, i1 use_hw_encoding)
31174+
31175+
Overview:
31176+
"""""""""
31177+
31178+
The '``llvm.protected.field.ptr``' intrinsic returns a pointer to the
31179+
storage location of a pointer that has special properties as described
31180+
below.
31181+
31182+
Arguments:
31183+
""""""""""
31184+
31185+
The first argument is the pointer specifying the location to store the
31186+
pointer. The second argument is the discriminator, which is used as an
31187+
input for the pointer encoding. The third argument specifies whether to
31188+
use a target-specific mechanism to encode the pointer.
31189+
31190+
Semantics:
31191+
""""""""""
31192+
31193+
This intrinsic returns a pointer which may be used to store a
31194+
pointer at the specified address that is encoded using the specified
31195+
discriminator. Stores via the pointer will cause the stored pointer to be
31196+
blended with the second argument before being stored. The blend operation
31197+
shall be either a weak but cheap and target-independent operation (if
31198+
the third argument is 0) or a stronger target-specific operation (if the
31199+
third argument is 1). When loading from the pointer, the inverse operation
31200+
is done on the loaded pointer after it is loaded. Specifically, when the
31201+
third argument is 1, the pointer is signed (using pointer authentication
31202+
instructions or emulated PAC if not supported by the hardware) using
31203+
the struct address before being stored, and authenticated after being
31204+
loaded. Note that it is currently unsupported to have the third argument
31205+
be 1 on targets other than AArch64. When the third argument is 0, it is
31206+
rotated left by 16 bits and the discriminator is subtracted before being
31207+
stored, and the discriminator is added and the pointer is rotated right
31208+
by 16 bits after being loaded.
31209+
31210+
If the pointer is used otherwise than for loading or storing (e.g. its
31211+
address escapes), that will disable all blending operations using
31212+
the deactivation symbol specified in the intrinsic's operand bundle.
31213+
The deactivation symbol operand bundle is copied onto any sign and auth
31214+
intrinsics that this intrinsic is lowered into. The intent is that the
31215+
deactivation symbol represents a field identifier.
31216+
31217+
This intrinsic is used to implement structure protection.

llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ ELF_RELOC(R_AARCH64_LD64_GOT_LO12_NC, 0x138)
6161
ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15, 0x139)
6262
ELF_RELOC(R_AARCH64_PLT32, 0x13a)
6363
ELF_RELOC(R_AARCH64_GOTPCREL32, 0x13b)
64+
ELF_RELOC(R_AARCH64_PATCHINST, 0x13c)
65+
ELF_RELOC(R_AARCH64_FUNCINIT64, 0x13d)
6466
// General dynamic TLS relocations
6567
ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21, 0x200)
6668
ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21, 0x201)

0 commit comments

Comments
 (0)