|
@@ -21,8 +21,8 @@
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
-static void appendToGlobalArray(const char *Array,
|
|
|
- Module &M, Function *F, int Priority) {
|
|
|
+static void appendToGlobalArray(const char *Array, Module &M, Function *F,
|
|
|
+ int Priority, Constant *Data) {
|
|
|
IRBuilder<> IRB(M.getContext());
|
|
|
FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false);
|
|
|
|
|
@@ -31,15 +31,26 @@ static void appendToGlobalArray(const char *Array,
|
|
|
SmallVector<Constant *, 16> CurrentCtors;
|
|
|
StructType *EltTy;
|
|
|
if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) {
|
|
|
- // If there is a global_ctors array, use the existing struct type, which can
|
|
|
- // have 2 or 3 fields.
|
|
|
ArrayType *ATy = cast<ArrayType>(GVCtor->getValueType());
|
|
|
- EltTy = cast<StructType>(ATy->getElementType());
|
|
|
+ StructType *OldEltTy = cast<StructType>(ATy->getElementType());
|
|
|
+ // Upgrade a 2-field global array type to the new 3-field format if needed.
|
|
|
+ if (Data && OldEltTy->getNumElements() < 3)
|
|
|
+ EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy),
|
|
|
+ IRB.getInt8PtrTy(), nullptr);
|
|
|
+ else
|
|
|
+ EltTy = OldEltTy;
|
|
|
if (Constant *Init = GVCtor->getInitializer()) {
|
|
|
unsigned n = Init->getNumOperands();
|
|
|
CurrentCtors.reserve(n + 1);
|
|
|
- for (unsigned i = 0; i != n; ++i)
|
|
|
- CurrentCtors.push_back(cast<Constant>(Init->getOperand(i)));
|
|
|
+ for (unsigned i = 0; i != n; ++i) {
|
|
|
+ auto Ctor = cast<Constant>(Init->getOperand(i));
|
|
|
+ if (EltTy != OldEltTy)
|
|
|
+ Ctor = ConstantStruct::get(
|
|
|
+ EltTy, Ctor->getAggregateElement((unsigned)0),
|
|
|
+ Ctor->getAggregateElement(1),
|
|
|
+ Constant::getNullValue(IRB.getInt8PtrTy()), nullptr);
|
|
|
+ CurrentCtors.push_back(Ctor);
|
|
|
+ }
|
|
|
}
|
|
|
GVCtor->eraseFromParent();
|
|
|
} else {
|
|
@@ -54,7 +65,8 @@ static void appendToGlobalArray(const char *Array,
|
|
|
CSVals[1] = F;
|
|
|
// FIXME: Drop support for the two element form in LLVM 4.0.
|
|
|
if (EltTy->getNumElements() >= 3)
|
|
|
- CSVals[2] = llvm::Constant::getNullValue(IRB.getInt8PtrTy());
|
|
|
+ CSVals[2] = Data ? ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy())
|
|
|
+ : Constant::getNullValue(IRB.getInt8PtrTy());
|
|
|
Constant *RuntimeCtorInit =
|
|
|
ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements()));
|
|
|
|
|
@@ -70,12 +82,12 @@ static void appendToGlobalArray(const char *Array,
|
|
|
GlobalValue::AppendingLinkage, NewInit, Array);
|
|
|
}
|
|
|
|
|
|
-void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority) {
|
|
|
- appendToGlobalArray("llvm.global_ctors", M, F, Priority);
|
|
|
+void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data) {
|
|
|
+ appendToGlobalArray("llvm.global_ctors", M, F, Priority, Data);
|
|
|
}
|
|
|
|
|
|
-void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority) {
|
|
|
- appendToGlobalArray("llvm.global_dtors", M, F, Priority);
|
|
|
+void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data) {
|
|
|
+ appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data);
|
|
|
}
|
|
|
|
|
|
GlobalVariable *
|
|
@@ -132,4 +144,3 @@ std::pair<Function *, Function *> llvm::createSanitizerCtorAndInitFunctions(
|
|
|
}
|
|
|
return std::make_pair(Ctor, InitFunction);
|
|
|
}
|
|
|
-
|