Skip to content

Commit 1fac945

Browse files
ahmedbougachadtapuska
authored andcommitted
[IR] Autoupgrade llvm.ptrauth globals to ptrauth constant.
1 parent efbbd08 commit 1fac945

File tree

4 files changed

+79
-10
lines changed

4 files changed

+79
-10
lines changed

llvm/include/llvm/IR/AutoUpgrade.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ namespace llvm {
5555

5656
/// This checks for global variables which should be upgraded. If it requires
5757
/// upgrading, returns a pointer to the upgraded variable.
58-
GlobalVariable *UpgradeGlobalVariable(GlobalVariable *GV);
58+
bool UpgradeGlobalVariable(GlobalVariable *GV, GlobalVariable *&NewGV);
5959

6060
/// This checks for module flags which should be upgraded. It returns true if
6161
/// module is modified.

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3977,12 +3977,15 @@ Error BitcodeReader::globalCleanup() {
39773977

39783978
// Look for global variables which need to be renamed.
39793979
std::vector<std::pair<GlobalVariable *, GlobalVariable *>> UpgradedVariables;
3980-
for (GlobalVariable &GV : TheModule->globals())
3981-
if (GlobalVariable *Upgraded = UpgradeGlobalVariable(&GV))
3980+
for (GlobalVariable &GV : TheModule->globals()) {
3981+
GlobalVariable *Upgraded = nullptr;
3982+
if (UpgradeGlobalVariable(&GV, Upgraded))
39823983
UpgradedVariables.emplace_back(&GV, Upgraded);
3984+
}
39833985
for (auto &Pair : UpgradedVariables) {
39843986
Pair.first->eraseFromParent();
3985-
TheModule->insertGlobalVariable(Pair.second);
3987+
if (Pair.second)
3988+
TheModule->insertGlobalVariable(Pair.second);
39863989
}
39873990

39883991
// Force deallocation of memory for these vectors to favor the client that

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,17 +1521,62 @@ bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn,
15211521
return Upgraded;
15221522
}
15231523

1524-
GlobalVariable *llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
1524+
bool llvm::UpgradeGlobalVariable(GlobalVariable *GV, GlobalVariable *&NewGV) {
1525+
if (GV->getSection() == "llvm.ptrauth") {
1526+
auto &Ctx = GV->getContext();
1527+
1528+
if (!GV->hasInitializer())
1529+
return false;
1530+
1531+
auto *Init = GV->getInitializer();
1532+
auto *Ty = dyn_cast<StructType>(GV->getInitializer()->getType());
1533+
if (!Ty)
1534+
return false;
1535+
1536+
auto *I64Ty = Type::getInt64Ty(Ctx);
1537+
auto *I32Ty = Type::getInt32Ty(Ctx);
1538+
auto *PtrTy = PointerType::get(Ctx, 0);
1539+
// Check that the struct matches its expected shape:
1540+
// { ptr, i32, i64, i64 }
1541+
if (!Ty->isLayoutIdentical(
1542+
StructType::get(Ctx, {PtrTy, I32Ty, I64Ty, I64Ty})))
1543+
return false;
1544+
1545+
auto Pointer = cast<Constant>(Init->getOperand(0));
1546+
Pointer = Pointer->stripPointerCasts();
1547+
1548+
auto *Key = dyn_cast<ConstantInt>(Init->getOperand(1));
1549+
if (!Key)
1550+
return false;
1551+
1552+
auto *AddrDiscriminator = cast<Constant>(Init->getOperand(2));
1553+
if (!isa<ConstantInt>(AddrDiscriminator) &&
1554+
!isa<ConstantExpr>(AddrDiscriminator))
1555+
return false;
1556+
1557+
auto *Discriminator = dyn_cast<ConstantInt>(Init->getOperand(3));
1558+
if (!Discriminator)
1559+
return false;
1560+
1561+
AddrDiscriminator = ConstantExpr::getIntToPtr(AddrDiscriminator, PtrTy);
1562+
Discriminator = ConstantInt::get(I64Ty, Discriminator->getZExtValue());
1563+
auto *SP =
1564+
ConstantPtrAuth::get(Pointer, Key, Discriminator, AddrDiscriminator);
1565+
1566+
GV->replaceAllUsesWith(ConstantExpr::getBitCast(SP, GV->getType()));
1567+
return true;
1568+
}
1569+
15251570
if (!(GV->hasName() && (GV->getName() == "llvm.global_ctors" ||
15261571
GV->getName() == "llvm.global_dtors")) ||
15271572
!GV->hasInitializer())
1528-
return nullptr;
1573+
return false;
15291574
ArrayType *ATy = dyn_cast<ArrayType>(GV->getValueType());
15301575
if (!ATy)
1531-
return nullptr;
1576+
return false;
15321577
StructType *STy = dyn_cast<StructType>(ATy->getElementType());
15331578
if (!STy || STy->getNumElements() != 2)
1534-
return nullptr;
1579+
return false;
15351580

15361581
LLVMContext &C = GV->getContext();
15371582
IRBuilder<> IRB(C);
@@ -1548,8 +1593,9 @@ GlobalVariable *llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
15481593
}
15491594
Constant *NewInit = ConstantArray::get(ArrayType::get(EltTy, N), NewCtors);
15501595

1551-
return new GlobalVariable(NewInit->getType(), false, GV->getLinkage(),
1552-
NewInit, GV->getName());
1596+
NewGV = new GlobalVariable(NewInit->getType(), false, GV->getLinkage(),
1597+
NewInit, GV->getName());
1598+
return true;
15531599
}
15541600

15551601
// Handles upgrading SSE2/AVX2/AVX512BW PSLLDQ intrinsics by converting them
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
2+
3+
@var = global i32 0
4+
5+
@var.ptrauth1 = constant { i8*, i32, i64, i64 } { i8* bitcast(i32* @var to i8*),
6+
i32 0,
7+
i64 0,
8+
i64 1234 }, section "llvm.ptrauth"
9+
@var_auth1 = global i32* bitcast({i8*, i32, i64, i64}* @var.ptrauth1 to i32*)
10+
; CHECK: @var_auth1 = global ptr ptrauth (ptr @var, i32 0, i64 1234)
11+
12+
13+
@dummy_addrdisc = global i64* null
14+
15+
@var.ptrauth2 = constant { i8*, i32, i64, i64 } { i8* bitcast(i32* @var to i8*),
16+
i32 2,
17+
i64 ptrtoint(i64** @dummy_addrdisc to i64),
18+
i64 5678 }, section "llvm.ptrauth"
19+
@var_auth2 = global i32* bitcast({i8*, i32, i64, i64}* @var.ptrauth2 to i32*)
20+
; CHECK: @var_auth2 = global ptr ptrauth (ptr @var, i32 2, i64 5678, ptr @dummy_addrdisc)

0 commit comments

Comments
 (0)