diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
commit | 01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch) | |
tree | 4def12e759965de927d963ac65840d663ef9d1ea /lib/Transforms/Utils/ModuleUtils.cpp | |
parent | f0f4822ed4b66e3579e92a89f368f8fb860e218e (diff) |
Notes
Diffstat (limited to 'lib/Transforms/Utils/ModuleUtils.cpp')
-rw-r--r-- | lib/Transforms/Utils/ModuleUtils.cpp | 57 |
1 files changed, 25 insertions, 32 deletions
diff --git a/lib/Transforms/Utils/ModuleUtils.cpp b/lib/Transforms/Utils/ModuleUtils.cpp index 9ec28a3f3d47..eb9188518624 100644 --- a/lib/Transforms/Utils/ModuleUtils.cpp +++ b/lib/Transforms/Utils/ModuleUtils.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/ModuleUtils.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" @@ -21,8 +20,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 +30,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->getType()->getElementType()); - EltTy = cast<StructType>(ATy->getElementType()); + ArrayType *ATy = cast<ArrayType>(GVCtor->getValueType()); + 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 +64,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,29 +81,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); -} - -GlobalVariable * -llvm::collectUsedGlobalVariables(Module &M, SmallPtrSetImpl<GlobalValue *> &Set, - bool CompilerUsed) { - const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used"; - GlobalVariable *GV = M.getGlobalVariable(Name); - if (!GV || !GV->hasInitializer()) - return GV; - - const ConstantArray *Init = cast<ConstantArray>(GV->getInitializer()); - for (unsigned I = 0, E = Init->getNumOperands(); I != E; ++I) { - Value *Op = Init->getOperand(I); - GlobalValue *G = cast<GlobalValue>(Op->stripPointerCastsNoFollowAliases()); - Set.insert(G); - } - return GV; +void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data) { + appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data); } Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) { @@ -132,4 +126,3 @@ std::pair<Function *, Function *> llvm::createSanitizerCtorAndInitFunctions( } return std::make_pair(Ctor, InitFunction); } - |