8000 Upstream arm64e and Pointer Authentication support by ahmedbougacha · Pull Request #14 · swiftlang/llvm-project · GitHub
[go: up one dir, main page]

Skip to content

Upstream arm64e and Pointer Authentication support #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

8000

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 45 commits into from
Oct 29, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
9e702b1
[AArch64][v8.3a] Add LDRA '[xN]!' alias.
ahmedbougacha Jun 26, 2019
5cb5475
[AArch64][v8.3a] Add missing imp-defs on RETA*.
ahmedbougacha Jun 26, 2019
11d7d33
[AArch64] Add 'vortex' CPU.
ahmedbougacha Oct 21, 2019
5ed200f
[AArch64] Add 'lightning' CPU.
ahmedbougacha Oct 21, 2019
7bda9ff
[Triple] Add 'arm64e', an AArch64 sub-architecture.
ahmedbougacha Oct 21, 2019
ed270ad
[Object] Add MachO CPU_SUBTYPE_ARM64E.
ahmedbougacha Sep 6, 2019
b795126
[utils] Teach UpdateTestChecks about arm64e.
ahmedbougacha Jun 26, 2019
700888c
[AArch64] Support emitting arm64e MachO in Darwin AsmBackend.
ahmedbougacha Aug 8, 2019
d3d83e5
[AArch64] Add helper functions for mapping PAC keys and instructions.
ahmedbougacha Aug 8, 2019
13d4276
[AArch64] Support @AUTH symbol variant and MachO reloc.
ahmedbougacha Sep 6, 2019
481f2fd
[Docs] Document Pointer Authentication IR additions.
ahmedbougacha Aug 8, 2019
e652bd4
[IR] Define new llvm.ptrauth intrinsics.
ahmedbougacha Aug 8, 2019
aad6348
[AArch64] Lower llvm.ptrauth.sign intrinsics.
ahmedbougacha Sep 16, 2019
9622ba4
[AArch64] Lower llvm.ptrauth.auth/resign intrinsics.
ahmedbougacha Sep 16, 2019
2a06c80
[AArch64] Lower llvm.ptrauth.strip intrinsics.
ahmedbougacha Sep 16, 2019
08678ef
[AArch64] Lower llvm.ptrauth.blend intrinsics.
ahmedbougacha Sep 16, 2019
9f1a12c
[AArch64] Lower auth calls/tail-calls.
ahmedbougacha Sep 16, 2019
cf672d9
[AArch64] Fold auth + load sequences into LDRA.
ahmedbougacha Aug 8, 2019
8198c13
[AArch64] Support emitting "hardened" jump-tables.
ahmedbougacha Aug 8, 2019
5b022b2
[IR] Define "ptrauth" operand bundles.
ahmedbougacha Aug 8, 2019
a90507b
[InstCombine] Combine ptrauth intrinsics into call operand bundles.
ahmedbougacha Aug 8, 2019
41c9f47
[AArch64] Lower "llvm.ptrauth" signed global wrappers.
ahmedbougacha Aug 8, 2019
646d0c9
[AArch64] Lower calls with ptrauth operand bundles.
ahmedbougacha Aug 8, 2019
4fdcd96
[AArch64] For arm64e Darwin TLS, sign the access thunk pointer.
ahmedbougacha Aug 8, 2019
0b6fe15
[AArch64] Support return address authentication.
ahmedbougacha Aug 8, 2019
af247a2
[Transforms] Add pass for software expansion of ptrauth.
ahmedbougacha Jun 26, 2019
b7c83ad
[DebugInfo] Add 'ptrauth' qualifier support.
adrian-prantl Jun 26, 2019
46088d1
Basic ptrauth command-line flags.
rjmccall Sep 18, 2019
4ec8ebf
Add an API for computing an ABI-stable hash of a string.
rjmccall Sep 18, 2019
a9dd959
Add support for the new pointer authentication builtins.
rjmccall Sep 18, 2019
2c01c33
IRGen preliminaries for pointer authentication, hopefully NFC.
rjmccall Sep 18, 2019
181e261
Implement pointer authentication for function pointers.
rjmccall Sep 18, 2019
fad0aa4
Pointer authentication for blocks.
rjmccall Sep 18, 2019
ea40099
Pointer authentication support for ObjC method lists.
rjmccall Sep 18, 2019
c077762
Record the original declaration for which a v-table slot was created.
rjmccall Sep 18, 2019
a018339
Implement pointer authentication for C++ virtual functions,
rjmccall Sep 18, 2019
8c97618
Pointer authentication support for C++ member function pointers.
rjmccall Sep 18, 2019
25e71b4
Add IR attributes to functions compiled under pointer authentication.
rjmccall Sep 18, 2019
6ac1ad0
Sign function pointers passed to atexit and __cxa_atexit.
rjmccall Sep 18, 2019
21d1be0
Sign the destructor pointer passed to __cxa_throw.
rjmccall Sep 18, 2019
a8e307f
Sign the v-table pointer in ObjC exception RTTI.
rjmccall Sep 18, 2019
e004081
Add prototype support for software pointer authentication.
rjmccall Sep 18, 2019
f58c74f
Implement the __ptrauth type qualifier.
rjmccall Sep 18, 2019
34229b5
Make the CGPointerAuthInfo parameter to the general CGCallee
rjmccall Sep 18, 2019
e398fa8
Language documentation for the pointer authentication feature.
rjmccall Sep 18, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[InstCombine] Combine ptrauth intrinsics into call operand bundles.
Since the "ptrauth" call operand bundles really describe a folded
"llvm.ptrauth.auth" operation, there are optimizations we can
make to elide redundant sign/auth pairs.

Note that this needs to be careful about preserving the integrity
of the intermediate unauthenticated values, as that's the sole
purpose of having operand bundles in the first place.
  • Loading branch information
ahmedbougacha committed Oct 29, 2019
commit a90507b2d353b243e3ee755f981ff4544b3908be
80 changes: 80 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4214,6 +4214,81 @@ static IntrinsicInst *findInitTrampoline(Value *Callee) {
return nullptr;
}

Instruction *InstCombiner::tryCombinePtrAuthCall(CallBase &Call) {
Value *Callee = Call.getCalledValue();
auto *IPC = dyn_cast<IntToPtrInst>(Callee);
if (!IPC || !IPC->isNoopCast(DL))
return nullptr;

IntrinsicInst *II = dyn_cast<IntrinsicInst>(IPC->getOperand(0));
if (!II)
return nullptr;

auto PtrAuthBundleOrNone = Call.getOperandBundle(LLVMContext::OB_ptrauth);
assert(Call.getNumOperandBundles() <= 1 &&
"unimplemented support for ptrauth and other bundle");

Value *NewCallee = nullptr;
SmallVector<OperandBundleDef, 1> NewBundles;
switch (II->getIntrinsicID()) {
default:
return nullptr;

// call(ptrauth_resign(p)), ["ptrauth"()] -> call p, ["ptrauth"()]
// assuming the call bundle and the sign operands match.
case Intrinsic::ptrauth_resign: {
if (!PtrAuthBundleOrNone)
return nullptr;
auto PtrAuthBundle = *PtrAuthBundleOrNone;
if (II->getOperand(3) != PtrAuthBundle.Inputs[0] ||
II->getOperand(4) != PtrAuthBundle.Inputs[1])
return nullptr;

Value *NewBundleOps[] = {II->getOperand(1), II->getOperand(2)};
NewBundles.emplace_back("ptrauth", NewBundleOps);
NewCallee = II->getOperand(0);
break;
}

// call(ptrauth_sign(p)), ["ptrauth"()] -> call p
// assuming the call bundle and the sign operands match.
case Intrinsic::ptrauth_sign: {
if (!PtrAuthBundleOrNone)
return nullptr;
auto PtrAuthBundle = *PtrAuthBundleOrNone;
if (II->getOperand(1) != PtrAuthBundle.Inputs[0] ||
II->getOperand(2) != PtrAuthBundle.Inputs[1])
return nullptr;
NewCallee = II->getOperand(0);
break;
}

// call(ptrauth_auth(p)) -> call p, ["ptrauth"()]
case Intrinsic::ptrauth_auth: {
if (PtrAuthBundleOrNone)
return nullptr;
Value *NewBundleOps[] = {II->getOperand(1), II->getOperand(2)};
NewBundles.emplace_back("ptrauth", NewBundleOps);
NewCallee = II->getOperand(0);
break;
}
}

if (!NewCallee)
return nullptr;

NewCallee = Builder.CreateBitOrPointerCast(NewCallee, Callee->getType());
CallBase *NewCall = nullptr;
if (auto *CI = dyn_cast<CallInst>(&Call)) {
NewCall = CallInst::Create(CI, NewBundles);
} else {
auto *IKI = cast<InvokeInst>(&Call);
NewCall = InvokeInst::Create(IKI, NewBundles);
}
NewCall->setCalledOperand(NewCallee);
return NewCall;
}

static void annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
unsigned NumArgs = Call.getNumArgOperands();
ConstantInt *Op0C = dyn_cast<ConstantInt>(Call.getOperand(0));
Expand Down Expand Up @@ -4356,6 +4431,11 @@ Instruction *InstCombiner::visitCallBase(CallBase &Call) {
if (IntrinsicInst *II = findInitTrampoline(Callee))
return transformCallThroughTrampoline(Call, *II);

// Combine calls involving pointer authentication
if (Instruction *NewCall = tryCombinePtrAuthCall(Call))
return NewCall;


PointerType *PTy = cast<PointerType>(Callee->getType());
FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
if (FTy->isVarArg()) {
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner
bool transformConstExprCastCall(CallBase &Call);
Instruction *transformCallThroughTrampoline(CallBase &Call,
IntrinsicInst &Tramp);
Instruction *tryCombinePtrAuthCall(CallBase &Call);

Value *simplifyMaskedLoad(IntrinsicInst &II);
Instruction *simplifyMaskedStore(IntrinsicInst &II);
Expand Down
82 changes: 82 additions & 0 deletions llvm/test/Transforms/InstCombine/ptrauth-call.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s

define i32 @test_ptrauth_call_resign(i8* %p) {
; CHECK-LABEL: @test_ptrauth_call_resign(
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[P:%.*]] to i32 ()*
; CHECK-NEXT: [[TMP3:%.*]] = call i32 [[TMP1]]() [ "ptrauth"(i32 0, i64 1234) ]
; CHECK-NEXT: ret i32 [[TMP3]]
;
%tmp0 = ptrtoint i8* %p to i64
%tmp1 = call i64 @llvm.ptrauth.resign.i64(i64 %tmp0, i32 0, i64 1234, i32 2, i64 5678)
%tmp2 = inttoptr i64 %tmp1 to i32()*
%tmp3 = call i32 %tmp2() [ "ptrauth"(i32 2, i64 5678) ]
ret i32 %tmp3
}

define i32 @test_ptrauth_call_resign_blend(i8** %pp) {
; CHECK-LABEL: @test_ptrauth_call_resign_blend(
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8** [[PP:%.*]] to i32 ()**
; CHECK-NEXT: [[TMP012:%.*]] = load i32 ()*, i32 ()** [[TMP1]], align 8
; CHECK-NEXT: [[TMP6:%.*]] = call i32 [[TMP012]]() [ "ptrauth"(i32 0, i64 1234) ]
; CHECK-NEXT: ret i32 [[TMP6]]
;
%tmp0 = load i8*, i8** %pp, align 8
%tmp1 = ptrtoint i8** %pp to i64
%tmp2 = ptrtoint i8* %tmp0 to i64
%tmp3 = call i64 @llvm.ptrauth.blend.i64(i64 %tmp1, i64 5678)
%tmp4 = call i64 @llvm.ptrauth.resign.i64(i64 %tmp2, i32 0, i64 1234, i32 1, i64 %tmp3)
%tmp5 = inttoptr i64 %tmp4 to i32()*
%tmp6 = call i32 %tmp5() [ "ptrauth"(i32 1, i64 %tmp3) ]
ret i32 %tmp6
}

define i32 @test_ptrauth_call_resign_blend_2(i8** %pp) {
; CHECK-LABEL: @test_ptrauth_call_resign_blend_2(
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8** [[PP:%.*]] to i32 ()**
; CHECK-NEXT: [[TMP012:%.*]] = load i32 ()*, i32 ()** [[TMP1]], align 8
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint i8** [[PP]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.blend.i64(i64 [[TMP1]], i64 5678)
; CHECK-NEXT: [[TMP6:%.*]] = call i32 [[TMP012]]() [ "ptrauth"(i32 1, i64 [[TMP3]]) ]
; CHECK-NEXT: ret i32 [[TMP6]]
;
%tmp0 = load i8*, i8** %pp, align 8
%tmp1 = ptrtoint i8** %pp to i64
%tmp2 = ptrtoint i8* %tmp0 to i64
%tmp3 = call i64 @llvm.ptrauth.blend.i64(i64 %tmp1, i64 5678)
%tmp4 = call i64 @llvm.ptrauth.resign.i64(i64 %tmp2, i32 1, i64 %tmp3, i32 0, i64 1234)
%tmp5 = inttoptr i64 %tmp4 to i32()*
%tmp6 = call i32 %tmp5() [ "ptrauth"(i32 0, i64 1234) ]
ret i32 %tmp6
}

define i32 @test_ptrauth_call_auth(i8* %p) {
; CHECK-LABEL: @test_ptrauth_call_auth(
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[P:%.*]] to i32 ()*
; CHECK-NEXT: [[TMP3:%.*]] = call i32 [[TMP1]]() [ "ptrauth"(i32 2, i64 5678) ]
; CHECK-NEXT: ret i32 [[TMP3]]
;
%tmp0 = ptrtoint i8* %p to i64
%tmp1 = call i64 @llvm.ptrauth.auth.i64(i64 %tmp0, i32 2, i64 5678)
%tmp2 = inttoptr i64 %tmp1 to i32()*
%tmp3 = call i32 %tmp2()
ret i32 %tmp3
}

define i32 @test_ptrauth_call_sign(i8* %p) {
; CHECK-LABEL: @test_ptrauth_call_sign(
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[P:%.*]] to i32 ()*
; CHECK-NEXT: [[TMP3:%.*]] = call i32 [[TMP1]]()
; CHECK-NEXT: ret i32 [[TMP3]]
;
%tmp0 = ptrtoint i8* %p to i64
%tmp1 = call i64 @llvm.ptrauth.sign.i64(i64 %tmp0, i32 2, i64 5678)
%tmp2 = inttoptr i64 %tmp1 to i32()*
%tmp3 = call i32 %tmp2() [ "ptrauth"(i32 2, i64 5678) ]
ret i32 %tmp3
}

declare i64 @llvm.ptrauth.auth.i64(i64, i32, i64)
declare i64 @llvm.ptrauth.sign.i64(i64, i32, i64)
declare i64 @llvm.ptrauth.resign.i64(i64, i32, i64, i32, i64)
declare i64 @llvm.ptrauth.blend.i64(i64, i64)
0