Skip to content

Commit 9360bbd

Browse files
committed
[IR] Allow uses of llvm.global_ctors and llvm.global_dtors
With PAuth enabled, signed function pointers in init/fini arrays are going to be represented with `ptrauth` constants (see llvm#96478). To support address discrimination for such signed pointers, we need to fill the storage address with `getelementptr` referencing the array (`llvm.global_ctors` or `llvm.global_dtors`) itself. Such uses of these special arrays were previously disallowed since `appendToGlobal{C|D}tors` did not update uses after construction of a new array. This patch implements such update logic. Test tools/llvm-reduce/remove-ifunc-program-addrspace.ll needs to be updated since otherwise the following assertion in `Value::doRAUW` is triggered: ``` assert(New->getType() == getType() && "replaceAllUses of value with new value of different type!"); ``` It's better not to omit `addrspace` in source IR.
1 parent 17e51d5 commit 9360bbd

File tree

5 files changed

+20
-23
lines changed

5 files changed

+20
-23
lines changed

llvm/lib/IR/Verifier.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -850,8 +850,6 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
850850
GV.getName() == "llvm.global_dtors")) {
851851
Check(!GV.hasInitializer() || GV.hasAppendingLinkage(),
852852
"invalid linkage for intrinsic global variable", &GV);
853-
Check(GV.materialized_use_empty(),
854-
"invalid uses of intrinsic global variable", &GV);
855853

856854
// Don't worry about emitting an error for it not being an array,
857855
// visitGlobalValue will complain on appending non-array.

llvm/lib/Transforms/Utils/ModuleUtils.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ static void appendToGlobalArray(StringRef ArrayName, Module &M, Function *F,
3535
// to the list.
3636
SmallVector<Constant *, 16> CurrentCtors;
3737
StructType *EltTy;
38-
if (GlobalVariable *GVCtor = M.getNamedGlobal(ArrayName)) {
38+
GlobalVariable *GVCtor = M.getNamedGlobal(ArrayName);
39+
if (GVCtor) {
3940
EltTy = cast<StructType>(GVCtor->getValueType()->getArrayElementType());
4041
if (Constant *Init = GVCtor->getInitializer()) {
4142
unsigned n = Init->getNumOperands();
4243
CurrentCtors.reserve(n + 1);
4344
for (unsigned i = 0; i != n; ++i)
4445
CurrentCtors.push_back(cast<Constant>(Init->getOperand(i)));
4546
}
46-
GVCtor->eraseFromParent();
4747
} else {
4848
EltTy = StructType::get(IRB.getInt32Ty(),
4949
PointerType::get(FnTy, F->getAddressSpace()),
@@ -67,8 +67,14 @@ static void appendToGlobalArray(StringRef ArrayName, Module &M, Function *F,
6767

6868
// Create the new global variable and replace all uses of
6969
// the old global variable with the new one.
70-
(void)new GlobalVariable(M, NewInit->getType(), false,
71-
GlobalValue::AppendingLinkage, NewInit, ArrayName);
70+
auto *NewGVCtor =
71+
new GlobalVariable(M, NewInit->getType(), false,
72+
GlobalValue::AppendingLinkage, NewInit, ArrayName);
73+
if (GVCtor) {
74+
NewGVCtor->takeName(GVCtor);
75+
GVCtor->replaceAllUsesWith(NewGVCtor);
76+
GVCtor->eraseFromParent();
77+
}
7278
}
7379

7480
void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data) {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
;; Run opt with asan to trigger `appendToGlobalArray` call which should update uses of `llvm.global_ctors`
2+
; RUN: opt -passes=asan -S %s -o - | FileCheck %s
3+
; CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, i32 0, i64 55764, ptr getelementptr inbounds ([1 x { i32, ptr, ptr }], ptr @llvm.global_ctors, i32 0, i32 0, i32 1)), ptr null }, { i32, ptr, ptr } { i32 1, ptr @asan.module_ctor, ptr @asan.module_ctor }]
4+
5+
@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, i32 0, i64 55764, ptr getelementptr inbounds ([1 x { i32, ptr, ptr }], ptr @llvm.global_ctors, i32 0, i32 0, i32 1)), ptr null }]
6+
7+
define void @foo() {
8+
ret void
9+
}

llvm/test/Verifier/global-ctors-dtors-uses.ll

Lines changed: 0 additions & 16 deletions
This file was deleted.

llvm/test/tools/llvm-reduce/remove-ifunc-program-addrspace.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ define void @existing_ctor() addrspace(1) {
1616
; CHECK-FINAL: [[TABLE:@[0-9]+]] = internal addrspace(2) global [6 x ptr addrspace(1)] poison, align 8
1717

1818
; CHECK-FINAL: @llvm.global_ctors = appending addrspace(2) global [2 x { i32, ptr addrspace(1), ptr }] [{ i32, ptr addrspace(1), ptr } { i32 0, ptr addrspace(1) @existing_ctor, ptr null }, { i32, ptr addrspace(1), ptr } { i32 10, ptr addrspace(1) [[TABLE_CTOR:@[0-9]+]], ptr null }]
19-
@llvm.global_ctors = appending global [1 x { i32, ptr addrspace(1), ptr }] [{ i32, ptr addrspace(1), ptr } { i32 0, ptr addrspace(1) @existing_ctor, ptr null }]
19+
@llvm.global_ctors = appending addrspace(2) global [1 x { i32, ptr addrspace(1), ptr }] [{ i32, ptr addrspace(1), ptr } { i32 0, ptr addrspace(1) @existing_ctor, ptr null }]
2020

2121

2222

0 commit comments

Comments
 (0)