bool GlobalMerge::doInitialization(Module &M) { DenseMap<unsigned, SmallVector<GlobalVariable*, 16> > Globals, ConstGlobals, BSSGlobals; const DataLayout *TD = TLI->getDataLayout(); unsigned MaxOffset = TLI->getMaximalGlobalOffset(); bool Changed = false; // Grab all non-const globals. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { // Merge is safe for "normal" internal globals only if (!I->hasLocalLinkage() || I->isThreadLocal() || I->hasSection()) continue; PointerType *PT = dyn_cast<PointerType>(I->getType()); assert(PT && "Global variable is not a pointer!"); unsigned AddressSpace = PT->getAddressSpace(); // Ignore fancy-aligned globals for now. unsigned Alignment = TD->getPreferredAlignment(I); Type *Ty = I->getType()->getElementType(); if (Alignment > TD->getABITypeAlignment(Ty)) continue; // Ignore all 'special' globals. if (I->getName().startswith("llvm.") || I->getName().startswith(".llvm.")) continue; if (TD->getTypeAllocSize(Ty) < MaxOffset) { if (TargetLoweringObjectFile::getKindForGlobal(I, TLI->getTargetMachine()) .isBSSLocal()) BSSGlobals[AddressSpace].push_back(I); else if (I->isConstant()) ConstGlobals[AddressSpace].push_back(I); else Globals[AddressSpace].push_back(I); } } for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator I = Globals.begin(), E = Globals.end(); I != E; ++I) if (I->second.size() > 1) Changed |= doMerge(I->second, M, false, I->first); for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator I = BSSGlobals.begin(), E = BSSGlobals.end(); I != E; ++I) if (I->second.size() > 1) Changed |= doMerge(I->second, M, false, I->first); // FIXME: This currently breaks the EH processing due to way how the // typeinfo detection works. We might want to detect the TIs and ignore // them in the future. // if (ConstGlobals.size() > 1) // Changed |= doMerge(ConstGlobals, M, true); return Changed; }
bool ARMGlobalMerge::doInitialization(Module &M) { SmallVector<GlobalVariable*, 16> Globals, ConstGlobals, BSSGlobals; const TargetData *TD = TLI->getTargetData(); unsigned MaxOffset = TLI->getMaximalGlobalOffset(); bool Changed = false; // Disable this pass on darwin. The debugger is not yet ready to extract // variable's info from a merged global. if (TLI->getTargetMachine().getSubtarget<ARMSubtarget>().isTargetDarwin()) return false; // Grab all non-const globals. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { // Merge is safe for "normal" internal globals only if (!I->hasLocalLinkage() || I->isThreadLocal() || I->hasSection()) continue; // Ignore fancy-aligned globals for now. if (I->getAlignment() != 0) continue; // Ignore all 'special' globals. if (I->getName().startswith("llvm.") || I->getName().startswith(".llvm.")) continue; if (TD->getTypeAllocSize(I->getType()->getElementType()) < MaxOffset) { const TargetLoweringObjectFile &TLOF = TLI->getObjFileLowering(); if (TLOF.getKindForGlobal(I, TLI->getTargetMachine()).isBSSLocal()) BSSGlobals.push_back(I); else if (I->isConstant()) ConstGlobals.push_back(I); else Globals.push_back(I); } } if (Globals.size() > 1) Changed |= doMerge(Globals, M, false); if (BSSGlobals.size() > 1) Changed |= doMerge(BSSGlobals, M, false); // FIXME: This currently breaks the EH processing due to way how the // typeinfo detection works. We might want to detect the TIs and ignore // them in the future. // if (ConstGlobals.size() > 1) // Changed |= doMerge(ConstGlobals, M, true); return Changed; }
/// SplitFunctionsOutOfModule - Given a module and a list of functions in the /// module, split the functions OUT of the specified module, and place them in /// the new module. Module * llvm::SplitFunctionsOutOfModule(Module *M, const std::vector<Function*> &F, DenseMap<const Value*, Value*> &ValueMap) { // Make sure functions & globals are all external so that linkage // between the two modules will work. for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) I->setLinkage(GlobalValue::ExternalLinkage); for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { if (I->hasName() && I->getName()[0] == '\01') I->setName(I->getName().substr(1)); I->setLinkage(GlobalValue::ExternalLinkage); } DenseMap<const Value*, Value*> NewValueMap; Module *New = CloneModule(M, NewValueMap); // Make sure global initializers exist only in the safe module (CBE->.so) for (Module::global_iterator I = New->global_begin(), E = New->global_end(); I != E; ++I) I->setInitializer(0); // Delete the initializer to make it external // Remove the Test functions from the Safe module std::set<Function *> TestFunctions; for (unsigned i = 0, e = F.size(); i != e; ++i) { Function *TNOF = cast<Function>(ValueMap[F[i]]); DEBUG(errs() << "Removing function "); DEBUG(WriteAsOperand(errs(), TNOF, false)); DEBUG(errs() << "\n"); TestFunctions.insert(cast<Function>(NewValueMap[TNOF])); DeleteFunctionBody(TNOF); // Function is now external in this module! } // Remove the Safe functions from the Test module for (Module::iterator I = New->begin(), E = New->end(); I != E; ++I) if (!TestFunctions.count(I)) DeleteFunctionBody(I); // Make sure that there is a global ctor/dtor array in both halves of the // module if they both have static ctor/dtor functions. SplitStaticCtorDtor("llvm.global_ctors", M, New, NewValueMap); SplitStaticCtorDtor("llvm.global_dtors", M, New, NewValueMap); return New; }
/// GetAllUndefinedSymbols - calculates the set of undefined symbols that still /// exist in an LLVM module. This is a bit tricky because there may be two /// symbols with the same name but different LLVM types that will be resolved to /// each other but aren't currently (thus we need to treat it as resolved). /// /// Inputs: /// M - The module in which to find undefined symbols. /// /// Outputs: /// UndefinedSymbols - A set of C++ strings containing the name of all /// undefined symbols. /// static void GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) { std::set<std::string> DefinedSymbols; UndefinedSymbols.clear(); // If the program doesn't define a main, try pulling one in from a .a file. // This is needed for programs where the main function is defined in an // archive, such f2c'd programs. Function *Main = M->getFunction("main"); if (Main == 0 || Main->isDeclaration()) UndefinedSymbols.insert("main"); for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (I->hasName()) { if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); else if (!I->hasLocalLinkage()) { assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!"); DefinedSymbols.insert(I->getName()); } } for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) if (I->hasName()) { if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); else if (!I->hasLocalLinkage()) { assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!"); DefinedSymbols.insert(I->getName()); } } for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) if (I->hasName()) DefinedSymbols.insert(I->getName()); // Prune out any defined symbols from the undefined symbols set... for (std::set<std::string>::iterator I = UndefinedSymbols.begin(); I != UndefinedSymbols.end(); ) if (DefinedSymbols.count(*I)) UndefinedSymbols.erase(I++); // This symbol really is defined! else ++I; // Keep this symbol in the undefined symbols list }
void MemoryInstrumenter::instrumentGlobals(Module &M) { TargetData &TD = getAnalysis<TargetData>(); IDAssigner &IDA = getAnalysis<IDAssigner>(); // Function HookGlobalsAlloc contains only one basic block. // The BB iterates through all global variables, and calls HookMemAlloc // for each of them. BasicBlock *BB = BasicBlock::Create(M.getContext(), "entry", GlobalsAllocHook); Instruction *Ret = ReturnInst::Create(M.getContext(), BB); for (Module::global_iterator GI = M.global_begin(), E = M.global_end(); GI != E; ++GI) { // We are going to delete llvm.global_ctors. // Therefore, don't instrument it. if (GI->getName() == "llvm.global_ctors") continue; // Prevent global variables from sharing the same address, because it // breaks the assumption that global variables do not alias. // The same goes to functions. if (GI->hasUnnamedAddr()) { GI->setUnnamedAddr(false); } uint64_t TypeSize = TD.getTypeStoreSize(GI->getType()->getElementType()); instrumentMemoryAllocation(GI, ConstantInt::get(LongType, TypeSize), NULL, Ret); instrumentPointer(GI, NULL, Ret); } for (Module::iterator F = M.begin(); F != M.end(); ++F) { // These hooks added by us don't have a value ID. if (MemAllocHook == F || MainArgsAllocHook == F || TopLevelHook == F || AddrTakenHook == F || CallHook == F || ReturnHook == F || GlobalsAllocHook == F || MemHooksIniter == F || AfterForkHook == F || BeforeForkHook == F) { continue; } // InvalidID: maybe this is inserted by alias checker in hybrid mode. if (IDA.getValueID(F) == IDAssigner::InvalidID) continue; // Ignore intrinsic functions because we cannot take the address of // an intrinsic. Also, no function pointers will point to instrinsic // functions. if (F->isIntrinsic()) continue; // Prevent functions from sharing the same address. if (F->hasUnnamedAddr()) { F->setUnnamedAddr(false); } uint64_t TypeSize = TD.getTypeStoreSize(F->getType()); assert(TypeSize == TD.getPointerSize()); instrumentMemoryAllocation(F, ConstantInt::get(LongType, TypeSize), NULL, Ret); instrumentPointer(F, NULL, Ret); } }
/// StripSymbolNames - Strip symbol names. static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { SmallPtrSet<const GlobalValue*, 8> llvmUsedValues; findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues); findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues); for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) I->setName(""); // Internal symbols can't participate in linkage } for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) I->setName(""); // Internal symbols can't participate in linkage StripSymtab(I->getValueSymbolTable(), PreserveDbgInfo); } // Remove all names from types. StripTypeSymtab(M.getTypeSymbolTable(), PreserveDbgInfo); return true; }
void LTOCodeGenerator::applyScopeRestrictions() { if ( !_scopeRestrictionsDone ) { Module* mergedModule = _linker.getModule(); // Start off with a verification pass. PassManager passes; passes.add(createVerifierPass()); // mark which symbols can not be internalized if ( !_mustPreserveSymbols.empty() ) { Mangler mangler(*mergedModule, _target->getTargetAsmInfo()->getGlobalPrefix()); std::vector<const char*> mustPreserveList; for (Module::iterator f = mergedModule->begin(), e = mergedModule->end(); f != e; ++f) { if ( !f->isDeclaration() && _mustPreserveSymbols.count(mangler.getValueName(f)) ) mustPreserveList.push_back(::strdup(f->getName().c_str())); } for (Module::global_iterator v = mergedModule->global_begin(), e = mergedModule->global_end(); v != e; ++v) { if ( !v->isDeclaration() && _mustPreserveSymbols.count(mangler.getValueName(v)) ) mustPreserveList.push_back(::strdup(v->getName().c_str())); } passes.add(createInternalizePass(mustPreserveList)); } // apply scope restrictions passes.run(*mergedModule); _scopeRestrictionsDone = true; } }
void AndroidBitcodeLinker::GetAllSymbols(Module *M, std::set<std::string> &UndefinedSymbols, std::set<std::string> &DefinedSymbols) { UndefinedSymbols.clear(); DefinedSymbols.clear(); Function *Main = M->getFunction("main"); if (Main == 0 || Main->isDeclaration()) UndefinedSymbols.insert("main"); for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (I->hasName()) { if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); else if (!I->hasLocalLinkage()) { assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!"); DefinedSymbols.insert(I->getName()); } } for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) if (I->hasName()) { if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); else if (!I->hasLocalLinkage()) { assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!"); DefinedSymbols.insert(I->getName()); } } for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) if (I->hasName()) DefinedSymbols.insert(I->getName()); for (std::set<std::string>::iterator I = UndefinedSymbols.begin(); I != UndefinedSymbols.end(); ) if (DefinedSymbols.count(*I)) UndefinedSymbols.erase(I++); else ++I; }
static void getSymbols(Module*M, std::vector<std::string>& symbols) { // Loop over global variables for (Module::global_iterator GI = M->global_begin(), GE=M->global_end(); GI != GE; ++GI) if (!GI->isDeclaration() && !GI->hasLocalLinkage()) if (!GI->getName().empty()) symbols.push_back(GI->getName()); // Loop over functions for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) if (!FI->isDeclaration() && !FI->hasLocalLinkage()) if (!FI->getName().empty()) symbols.push_back(FI->getName()); // Loop over aliases for (Module::alias_iterator AI = M->alias_begin(), AE = M->alias_end(); AI != AE; ++AI) { if (AI->hasName()) symbols.push_back(AI->getName()); } }
bool ARMGlobalMerge::doInitialization(Module &M) { SmallVector<GlobalVariable*, 16> Globals, ConstGlobals; const TargetData *TD = TLI->getTargetData(); unsigned MaxOffset = TLI->getMaximalGlobalOffset(); bool Changed = false; // Grab all non-const globals. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { // Merge is safe for "normal" internal globals only if (!I->hasLocalLinkage() || I->isThreadLocal() || I->hasSection()) continue; // Ignore fancy-aligned globals for now. if (I->getAlignment() != 0) continue; // Ignore all 'special' globals. if (I->getName().startswith("llvm.") || I->getName().startswith(".llvm.")) continue; if (TD->getTypeAllocSize(I->getType()) < MaxOffset) { if (I->isConstant()) ConstGlobals.push_back(I); else Globals.push_back(I); } } if (Globals.size() > 1) Changed |= doMerge(Globals, M, false); // FIXME: This currently breaks the EH processing due to way how the // typeinfo detection works. We might want to detect the TIs and ignore // them in the future. // if (ConstGlobals.size() > 1) // Changed |= doMerge(ConstGlobals, M, true); return Changed; }
/// DisambiguateGlobalSymbols - Mangle symbols to guarantee uniqueness by /// modifying predominantly internal symbols rather than external ones. /// static void DisambiguateGlobalSymbols(Module *M) { // Try not to cause collisions by minimizing chances of renaming an // already-external symbol, so take in external globals and functions as-is. // The code should work correctly without disambiguation (assuming the same // mangler is used by the two code generators), but having symbols with the // same name causes warnings to be emitted by the code generator. Mangler Mang(*M); // Agree with the CBE on symbol naming Mang.markCharUnacceptable('.'); for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { // Don't mangle asm names. if (!I->hasName() || I->getName()[0] != 1) I->setName(Mang.getMangledName(I)); } for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { // Don't mangle asm names or intrinsics. if ((!I->hasName() || I->getName()[0] != 1) && I->getIntrinsicID() == 0) I->setName(Mang.getMangledName(I)); } }
bool InternalizePass::runOnModule(Module &M) { CallGraph *CG = getAnalysisIfAvailable<CallGraph>(); CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0; bool Changed = false; // Never internalize functions which code-gen might insert. // FIXME: We should probably add this (and the __stack_chk_guard) via some // type of call-back in CodeGen. ExternalNames.insert("__stack_chk_fail"); // Mark all functions not in the api as internal. // FIXME: maybe use private linkage? for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration() && // Function must be defined here // Available externally is really just a "declaration with a body". !I->hasAvailableExternallyLinkage() && !I->hasLocalLinkage() && // Can't already have internal linkage !ExternalNames.count(I->getName())) {// Not marked to keep external? I->setLinkage(GlobalValue::InternalLinkage); // Remove a callgraph edge from the external node to this function. if (ExternalNode) ExternalNode->removeOneAbstractEdgeTo((*CG)[I]); Changed = true; ++NumFunctions; DEBUG(dbgs() << "Internalizing func " << I->getName() << "\n"); } // Never internalize the llvm.used symbol. It is used to implement // attribute((used)). // FIXME: Shouldn't this just filter on llvm.metadata section?? ExternalNames.insert("llvm.used"); ExternalNames.insert("llvm.compiler.used"); // Never internalize anchors used by the machine module info, else the info // won't find them. (see MachineModuleInfo.) ExternalNames.insert("llvm.global_ctors"); ExternalNames.insert("llvm.global_dtors"); ExternalNames.insert("llvm.global.annotations"); // Never internalize symbols code-gen inserts. ExternalNames.insert("__stack_chk_guard"); // Mark all global variables with initializers that are not in the api as // internal as well. // FIXME: maybe use private linkage? for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (!I->isDeclaration() && !I->hasLocalLinkage() && // Available externally is really just a "declaration with a body". !I->hasAvailableExternallyLinkage() && !ExternalNames.count(I->getName())) { I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumGlobals; DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n"); } // Mark all aliases that are not in the api as internal as well. for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) if (!I->isDeclaration() && !I->hasInternalLinkage() && // Available externally is really just a "declaration with a body". !I->hasAvailableExternallyLinkage() && !ExternalNames.count(I->getName())) { I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumAliases; DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n"); } return Changed; }
/// SplitFunctionsOutOfModule - Given a module and a list of functions in the /// module, split the functions OUT of the specified module, and place them in /// the new module. Module * llvm::SplitFunctionsOutOfModule(Module *M, const std::vector<Function*> &F, ValueToValueMapTy &VMap) { // Make sure functions & globals are all external so that linkage // between the two modules will work. for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) I->setLinkage(GlobalValue::ExternalLinkage); for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { if (I->hasName() && I->getName()[0] == '\01') I->setName(I->getName().substr(1)); I->setLinkage(GlobalValue::ExternalLinkage); } ValueToValueMapTy NewVMap; Module *New = CloneModule(M, NewVMap); // Remove the Test functions from the Safe module std::set<Function *> TestFunctions; for (unsigned i = 0, e = F.size(); i != e; ++i) { Function *TNOF = cast<Function>(VMap[F[i]]); DEBUG(errs() << "Removing function "); DEBUG(WriteAsOperand(errs(), TNOF, false)); DEBUG(errs() << "\n"); TestFunctions.insert(cast<Function>(NewVMap[TNOF])); DeleteFunctionBody(TNOF); // Function is now external in this module! } // Remove the Safe functions from the Test module for (Module::iterator I = New->begin(), E = New->end(); I != E; ++I) if (!TestFunctions.count(I)) DeleteFunctionBody(I); // Try to split the global initializers evenly for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *GV = cast<GlobalVariable>(NewVMap[I]); if (Function *TestFn = globalInitUsesExternalBA(I)) { if (Function *SafeFn = globalInitUsesExternalBA(GV)) { errs() << "*** Error: when reducing functions, encountered " "the global '"; WriteAsOperand(errs(), GV, false); errs() << "' with an initializer that references blockaddresses " "from safe function '" << SafeFn->getName() << "' and from test function '" << TestFn->getName() << "'.\n"; exit(1); } I->setInitializer(0); // Delete the initializer to make it external } else { // If we keep it in the safe module, then delete it in the test module GV->setInitializer(0); } } // Make sure that there is a global ctor/dtor array in both halves of the // module if they both have static ctor/dtor functions. SplitStaticCtorDtor("llvm.global_ctors", M, New, NewVMap); SplitStaticCtorDtor("llvm.global_dtors", M, New, NewVMap); return New; }
int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm extractor\n"); // Use lazy loading, since we only care about selected global values. SMDiagnostic Err; std::auto_ptr<Module> M; M.reset(getLazyIRFileModule(InputFilename, Err, Context)); if (M.get() == 0) { Err.print(argv[0], errs()); return 1; } // Use SetVector to avoid duplicates. SetVector<GlobalValue *> GVs; // Figure out which globals we should extract. for (size_t i = 0, e = ExtractGlobals.size(); i != e; ++i) { GlobalValue *GV = M.get()->getNamedGlobal(ExtractGlobals[i]); if (!GV) { errs() << argv[0] << ": program doesn't contain global named '" << ExtractGlobals[i] << "'!\n"; return 1; } GVs.insert(GV); } // Extract globals via regular expression matching. for (size_t i = 0, e = ExtractRegExpGlobals.size(); i != e; ++i) { std::string Error; Regex RegEx(ExtractRegExpGlobals[i]); if (!RegEx.isValid(Error)) { errs() << argv[0] << ": '" << ExtractRegExpGlobals[i] << "' " "invalid regex: " << Error; } bool match = false; for (Module::global_iterator GV = M.get()->global_begin(), E = M.get()->global_end(); GV != E; GV++) { if (RegEx.match(GV->getName())) { GVs.insert(&*GV); match = true; } } if (!match) { errs() << argv[0] << ": program doesn't contain global named '" << ExtractRegExpGlobals[i] << "'!\n"; return 1; } } // Figure out which functions we should extract. for (size_t i = 0, e = ExtractFuncs.size(); i != e; ++i) { GlobalValue *GV = M.get()->getFunction(ExtractFuncs[i]); if (!GV) { errs() << argv[0] << ": program doesn't contain function named '" << ExtractFuncs[i] << "'!\n"; return 1; } GVs.insert(GV); } // Extract functions via regular expression matching. for (size_t i = 0, e = ExtractRegExpFuncs.size(); i != e; ++i) { std::string Error; StringRef RegExStr = ExtractRegExpFuncs[i]; Regex RegEx(RegExStr); if (!RegEx.isValid(Error)) { errs() << argv[0] << ": '" << ExtractRegExpFuncs[i] << "' " "invalid regex: " << Error; } bool match = false; for (Module::iterator F = M.get()->begin(), E = M.get()->end(); F != E; F++) { if (RegEx.match(F->getName())) { GVs.insert(&*F); match = true; } } if (!match) { errs() << argv[0] << ": program doesn't contain global named '" << ExtractRegExpFuncs[i] << "'!\n"; return 1; } } // Materialize requisite global values. if (!DeleteFn) for (size_t i = 0, e = GVs.size(); i != e; ++i) { GlobalValue *GV = GVs[i]; if (GV->isMaterializable()) { std::string ErrInfo; if (GV->Materialize(&ErrInfo)) { errs() << argv[0] << ": error reading input: " << ErrInfo << "\n"; return 1; } } } else { // Deleting. Materialize every GV that's *not* in GVs. SmallPtrSet<GlobalValue *, 8> GVSet(GVs.begin(), GVs.end()); for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *G = I; if (!GVSet.count(G) && G->isMaterializable()) { std::string ErrInfo; if (G->Materialize(&ErrInfo)) { errs() << argv[0] << ": error reading input: " << ErrInfo << "\n"; return 1; } } } for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { Function *F = I; if (!GVSet.count(F) && F->isMaterializable()) { std::string ErrInfo; if (F->Materialize(&ErrInfo)) { errs() << argv[0] << ": error reading input: " << ErrInfo << "\n"; return 1; } } } } // In addition to deleting all other functions, we also want to spiff it // up a little bit. Do this now. PassManager Passes; Passes.add(new TargetData(M.get())); // Use correct TargetData std::vector<GlobalValue*> Gvs(GVs.begin(), GVs.end()); Passes.add(createGVExtractionPass(Gvs, DeleteFn)); if (!DeleteFn) Passes.add(createGlobalDCEPass()); // Delete unreachable globals Passes.add(createStripDeadDebugInfoPass()); // Remove dead debug info Passes.add(createStripDeadPrototypesPass()); // Remove dead func decls std::string ErrorInfo; tool_output_file Out(OutputFilename.c_str(), ErrorInfo, raw_fd_ostream::F_Binary); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } if (OutputAssembly) Passes.add(createPrintModulePass(&Out.os())); else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true)) Passes.add(createBitcodeWriterPass(Out.os())); Passes.run(*M.get()); // Declare success. Out.keep(); return 0; }
static PointerType *buildTlsTemplate(Module &M, std::vector<VarInfo> *TlsVars) { std::vector<Type*> FieldBssTypes; std::vector<Type*> FieldInitTypes; std::vector<Constant*> FieldInitValues; PassState State(&M); for (Module::global_iterator GV = M.global_begin(); GV != M.global_end(); ++GV) { if (GV->isThreadLocal()) { if (!GV->hasInitializer()) { // Since this is a whole-program transformation, "extern" TLS // variables are not allowed at this point. report_fatal_error(std::string("TLS variable without an initializer: ") + GV->getName()); } if (!GV->getInitializer()->isNullValue()) { addVarToTlsTemplate(&State, &FieldInitTypes, &FieldInitValues, GV); VarInfo Info; Info.TlsVar = GV; Info.IsBss = false; Info.TemplateIndex = FieldInitTypes.size() - 1; TlsVars->push_back(Info); } } } // Handle zero-initialized TLS variables in a second pass, because // these should follow non-zero-initialized TLS variables. for (Module::global_iterator GV = M.global_begin(); GV != M.global_end(); ++GV) { if (GV->isThreadLocal() && GV->getInitializer()->isNullValue()) { addVarToTlsTemplate(&State, &FieldBssTypes, NULL, GV); VarInfo Info; Info.TlsVar = GV; Info.IsBss = true; Info.TemplateIndex = FieldBssTypes.size() - 1; TlsVars->push_back(Info); } } // Add final alignment padding so that // (struct tls_struct *) __nacl_read_tp() - 1 // gives the correct, aligned start of the TLS variables given the // x86-style layout we are using. This requires some more bytes to // be memset() to zero at runtime. This wastage doesn't seem // important gives that we're not trying to optimize packing by // reordering to put similarly-aligned variables together. padToAlignment(&State, &FieldBssTypes, NULL, State.Alignment); // We create the TLS template structs as "packed" because we insert // alignment padding ourselves, and LLVM's implicit insertion of // padding would interfere with ours. tls_bss_template can start at // a non-aligned address immediately following the last field in // tls_init_template. StructType *InitTemplateType = StructType::create(M.getContext(), "tls_init_template"); InitTemplateType->setBody(FieldInitTypes, /*isPacked=*/true); StructType *BssTemplateType = StructType::create(M.getContext(), "tls_bss_template"); BssTemplateType->setBody(FieldBssTypes, /*isPacked=*/true); StructType *TemplateType = StructType::create(M.getContext(), "tls_struct"); SmallVector<Type*, 2> TemplateTopFields; TemplateTopFields.push_back(InitTemplateType); TemplateTopFields.push_back(BssTemplateType); TemplateType->setBody(TemplateTopFields, /*isPacked=*/true); PointerType *TemplatePtrType = PointerType::get(TemplateType, 0); // We define the following symbols, which are the same as those // defined by NaCl's original customized binutils linker scripts: // __tls_template_start // __tls_template_tdata_end // __tls_template_end // We also define __tls_template_alignment, which was not defined by // the original linker scripts. const char *StartSymbol = "__tls_template_start"; Constant *TemplateData = ConstantStruct::get(InitTemplateType, FieldInitValues); GlobalVariable *TemplateDataVar = new GlobalVariable(M, InitTemplateType, /*isConstant=*/true, GlobalValue::InternalLinkage, TemplateData); setGlobalVariableValue(M, StartSymbol, TemplateDataVar); TemplateDataVar->setName(StartSymbol); Constant *TdataEnd = ConstantExpr::getGetElementPtr( TemplateDataVar, ConstantInt::get(M.getContext(), APInt(32, 1))); setGlobalVariableValue(M, "__tls_template_tdata_end", TdataEnd); Constant *TotalEnd = ConstantExpr::getGetElementPtr( ConstantExpr::getBitCast(TemplateDataVar, TemplatePtrType), ConstantInt::get(M.getContext(), APInt(32, 1))); setGlobalVariableValue(M, "__tls_template_end", TotalEnd); const char *AlignmentSymbol = "__tls_template_alignment"; Type *i32 = Type::getInt32Ty(M.getContext()); GlobalVariable *AlignmentVar = new GlobalVariable( M, i32, /*isConstant=*/true, GlobalValue::InternalLinkage, ConstantInt::get(M.getContext(), APInt(32, State.Alignment))); setGlobalVariableValue(M, AlignmentSymbol, AlignmentVar); AlignmentVar->setName(AlignmentSymbol); return TemplatePtrType; }
bool GlobalMerge::doInitialization(Module &M) { if (!EnableGlobalMerge) return false; auto &DL = M.getDataLayout(); DenseMap<unsigned, SmallVector<GlobalVariable*, 16> > Globals, ConstGlobals, BSSGlobals; bool Changed = false; setMustKeepGlobalVariables(M); // Grab all non-const globals. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { // Merge is safe for "normal" internal or external globals only if (I->isDeclaration() || I->isThreadLocal() || I->hasSection()) continue; if (!(EnableGlobalMergeOnExternal && I->hasExternalLinkage()) && !I->hasInternalLinkage()) continue; PointerType *PT = dyn_cast<PointerType>(I->getType()); assert(PT && "Global variable is not a pointer!"); unsigned AddressSpace = PT->getAddressSpace(); // Ignore fancy-aligned globals for now. unsigned Alignment = DL.getPreferredAlignment(I); Type *Ty = I->getType()->getElementType(); if (Alignment > DL.getABITypeAlignment(Ty)) continue; // Ignore all 'special' globals. if (I->getName().startswith("llvm.") || I->getName().startswith(".llvm.")) continue; // Ignore all "required" globals: if (isMustKeepGlobalVariable(I)) continue; if (DL.getTypeAllocSize(Ty) < MaxOffset) { if (TargetLoweringObjectFile::getKindForGlobal(I, *TM).isBSSLocal()) BSSGlobals[AddressSpace].push_back(I); else if (I->isConstant()) ConstGlobals[AddressSpace].push_back(I); else Globals[AddressSpace].push_back(I); } } for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator I = Globals.begin(), E = Globals.end(); I != E; ++I) if (I->second.size() > 1) Changed |= doMerge(I->second, M, false, I->first); for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator I = BSSGlobals.begin(), E = BSSGlobals.end(); I != E; ++I) if (I->second.size() > 1) Changed |= doMerge(I->second, M, false, I->first); if (EnableGlobalMergeOnConst) for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator I = ConstGlobals.begin(), E = ConstGlobals.end(); I != E; ++I) if (I->second.size() > 1) Changed |= doMerge(I->second, M, true, I->first); return Changed; }
/// InputFilename is a LLVM bitcode file. Read it using bitcode reader. /// Collect global functions and symbol names in symbols vector. /// Collect external references in references vector. /// Return LTO_READ_SUCCESS if there is no error. enum LTOStatus LTO::readLLVMObjectFile(const std::string &InputFilename, NameToSymbolMap &symbols, std::set<std::string> &references) { Module *m = getModule(InputFilename); if (!m) return LTO_READ_FAILURE; // Collect Target info getTarget(m); if (!Target) return LTO_READ_FAILURE; // Use mangler to add GlobalPrefix to names to match linker names. // FIXME : Instead of hard coding "-" use GlobalPrefix. Mangler mangler(*m, Target->getTargetAsmInfo()->getGlobalPrefix()); modules.push_back(m); for (Module::iterator f = m->begin(), e = m->end(); f != e; ++f) { LTOLinkageTypes lt = getLTOLinkageType(f); LTOVisibilityTypes vis = getLTOVisibilityType(f); if (!f->isDeclaration() && lt != LTOInternalLinkage && strncmp (f->getName().c_str(), "llvm.", 5)) { int alignment = ( 16 > f->getAlignment() ? 16 : f->getAlignment()); LLVMSymbol *newSymbol = new LLVMSymbol(lt, vis, f, f->getName(), mangler.getValueName(f), Log2_32(alignment)); symbols[newSymbol->getMangledName()] = newSymbol; allSymbols[newSymbol->getMangledName()] = newSymbol; } // Collect external symbols referenced by this function. for (Function::iterator b = f->begin(), fe = f->end(); b != fe; ++b) for (BasicBlock::iterator i = b->begin(), be = b->end(); i != be; ++i) { for (unsigned count = 0, total = i->getNumOperands(); count != total; ++count) findExternalRefs(i->getOperand(count), references, mangler); } } for (Module::global_iterator v = m->global_begin(), e = m->global_end(); v != e; ++v) { LTOLinkageTypes lt = getLTOLinkageType(v); LTOVisibilityTypes vis = getLTOVisibilityType(v); if (!v->isDeclaration() && lt != LTOInternalLinkage && strncmp (v->getName().c_str(), "llvm.", 5)) { const TargetData *TD = Target->getTargetData(); LLVMSymbol *newSymbol = new LLVMSymbol(lt, vis, v, v->getName(), mangler.getValueName(v), TD->getPreferredAlignmentLog(v)); symbols[newSymbol->getMangledName()] = newSymbol; allSymbols[newSymbol->getMangledName()] = newSymbol; for (unsigned count = 0, total = v->getNumOperands(); count != total; ++count) findExternalRefs(v->getOperand(count), references, mangler); } } return LTO_READ_SUCCESS; }
/// Based on GetAllUndefinedSymbols() from LLVM3.2 /// /// GetAllUndefinedSymbols - calculates the set of undefined symbols that still /// exist in an LLVM module. This is a bit tricky because there may be two /// symbols with the same name but different LLVM types that will be resolved to /// each other but aren't currently (thus we need to treat it as resolved). /// /// Inputs: /// M - The module in which to find undefined symbols. /// /// Outputs: /// UndefinedSymbols - A set of C++ strings containing the name of all /// undefined symbols. /// static void GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) { static const std::string llvmIntrinsicPrefix="llvm."; std::set<std::string> DefinedSymbols; UndefinedSymbols.clear(); KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "*** Computing undefined symbols ***\n"); for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (I->hasName()) { if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); else if (!I->hasLocalLinkage()) { #if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!"); #else assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!"); #endif DefinedSymbols.insert(I->getName()); } } for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) if (I->hasName()) { if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); else if (!I->hasLocalLinkage()) { #if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) assert(!I->hasDLLImportLinkage() && "Found dllimported non-external symbol!"); #else assert(!I->hasDLLImportStorageClass() && "Found dllimported non-external symbol!"); #endif DefinedSymbols.insert(I->getName()); } } for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) if (I->hasName()) DefinedSymbols.insert(I->getName()); // Prune out any defined symbols from the undefined symbols set // and other symbols we don't want to treat as an undefined symbol std::vector<std::string> SymbolsToRemove; for (std::set<std::string>::iterator I = UndefinedSymbols.begin(); I != UndefinedSymbols.end(); ++I ) { if (DefinedSymbols.count(*I)) { SymbolsToRemove.push_back(*I); continue; } // Strip out llvm intrinsics if ( (I->size() >= llvmIntrinsicPrefix.size() ) && (I->compare(0, llvmIntrinsicPrefix.size(), llvmIntrinsicPrefix) == 0) ) { KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "LLVM intrinsic " << *I << " has will be removed from undefined symbols"<< "\n"); SymbolsToRemove.push_back(*I); continue; } // Symbol really is undefined KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "Symbol " << *I << " is undefined.\n"); } // Remove KLEE intrinsics from set of undefined symbols for (SpecialFunctionHandler::const_iterator sf = SpecialFunctionHandler::begin(), se = SpecialFunctionHandler::end(); sf != se; ++sf) { if (UndefinedSymbols.find(sf->name) == UndefinedSymbols.end()) continue; SymbolsToRemove.push_back(sf->name); KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "KLEE intrinsic " << sf->name << " has will be removed from undefined symbols"<< "\n"); } // Now remove the symbols from undefined set. for (size_t i = 0, j = SymbolsToRemove.size(); i < j; ++i ) UndefinedSymbols.erase(SymbolsToRemove[i]); KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "*** Finished computing undefined symbols ***\n"); }
bool InternalizePass::runOnModule(Module &M) { CallGraph *CG = getAnalysisIfAvailable<CallGraph>(); CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0; if (ExternalNames.empty()) { // Return if we're not in 'all but main' mode and have no external api if (!AllButMain) return false; // If no list or file of symbols was specified, check to see if there is a // "main" symbol defined in the module. If so, use it, otherwise do not // internalize the module, it must be a library or something. // Function *MainFunc = M.getFunction("main"); if (MainFunc == 0 || MainFunc->isDeclaration()) return false; // No main found, must be a library... // Preserve main, internalize all else. ExternalNames.insert(MainFunc->getName()); } bool Changed = false; // Never internalize functions which code-gen might insert. ExternalNames.insert("__stack_chk_fail"); // Mark all functions not in the api as internal. // FIXME: maybe use private linkage? for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration() && // Function must be defined here // Available externally is really just a "declaration with a body". !I->hasAvailableExternallyLinkage() && !I->hasLocalLinkage() && // Can't already have internal linkage !ExternalNames.count(I->getName())) {// Not marked to keep external? I->setLinkage(GlobalValue::InternalLinkage); // Remove a callgraph edge from the external node to this function. if (ExternalNode) ExternalNode->removeOneAbstractEdgeTo((*CG)[I]); Changed = true; ++NumFunctions; DEBUG(dbgs() << "Internalizing func " << I->getName() << "\n"); } // Never internalize the llvm.used symbol. It is used to implement // attribute((used)). // FIXME: Shouldn't this just filter on llvm.metadata section?? ExternalNames.insert("llvm.used"); ExternalNames.insert("llvm.compiler.used"); // Never internalize anchors used by the machine module info, else the info // won't find them. (see MachineModuleInfo.) ExternalNames.insert("llvm.global_ctors"); ExternalNames.insert("llvm.global_dtors"); ExternalNames.insert("llvm.global.annotations"); // Never internalize symbols code-gen inserts. ExternalNames.insert("__stack_chk_guard"); // Mark all global variables with initializers that are not in the api as // internal as well. // FIXME: maybe use private linkage? for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (!I->isDeclaration() && !I->hasLocalLinkage() && // Available externally is really just a "declaration with a body". !I->hasAvailableExternallyLinkage() && !ExternalNames.count(I->getName())) { I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumGlobals; DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n"); } // Mark all aliases that are not in the api as internal as well. for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) if (!I->isDeclaration() && !I->hasInternalLinkage() && // Available externally is really just a "declaration with a body". !I->hasAvailableExternallyLinkage() && !ExternalNames.count(I->getName())) { I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumAliases; DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n"); } return Changed; }
bool InternalizePass::runOnModule(Module &M) { CallGraphWrapperPass *CGPass = getAnalysisIfAvailable<CallGraphWrapperPass>(); CallGraph *CG = CGPass ? &CGPass->getCallGraph() : 0; CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0; bool Changed = false; SmallPtrSet<GlobalValue *, 8> Used; collectUsedGlobalVariables(M, Used, false); // We must assume that globals in llvm.used have a reference that not even // the linker can see, so we don't internalize them. // For llvm.compiler.used the situation is a bit fuzzy. The assembler and // linker can drop those symbols. If this pass is running as part of LTO, // one might think that it could just drop llvm.compiler.used. The problem // is that even in LTO llvm doesn't see every reference. For example, // we don't see references from function local inline assembly. To be // conservative, we internalize symbols in llvm.compiler.used, but we // keep llvm.compiler.used so that the symbol is not deleted by llvm. for (SmallPtrSet<GlobalValue *, 8>::iterator I = Used.begin(), E = Used.end(); I != E; ++I) { GlobalValue *V = *I; ExternalNames.insert(V->getName()); } // Mark all functions not in the api as internal. for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (!shouldInternalize(*I, ExternalNames, OnlyHidden)) continue; I->setLinkage(GlobalValue::InternalLinkage); if (ExternalNode) // Remove a callgraph edge from the external node to this function. ExternalNode->removeOneAbstractEdgeTo((*CG)[I]); Changed = true; ++NumFunctions; DEBUG(dbgs() << "Internalizing func " << I->getName() << "\n"); } // Never internalize the llvm.used symbol. It is used to implement // attribute((used)). // FIXME: Shouldn't this just filter on llvm.metadata section?? ExternalNames.insert("llvm.used"); ExternalNames.insert("llvm.compiler.used"); // Never internalize anchors used by the machine module info, else the info // won't find them. (see MachineModuleInfo.) ExternalNames.insert("llvm.global_ctors"); ExternalNames.insert("llvm.global_dtors"); ExternalNames.insert("llvm.global.annotations"); // Never internalize symbols code-gen inserts. // FIXME: We should probably add this (and the __stack_chk_guard) via some // type of call-back in CodeGen. ExternalNames.insert("__stack_chk_fail"); ExternalNames.insert("__stack_chk_guard"); // Mark all global variables with initializers that are not in the api as // internal as well. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (!shouldInternalize(*I, ExternalNames, OnlyHidden)) continue; I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumGlobals; DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n"); } // Mark all aliases that are not in the api as internal as well. for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) { if (!shouldInternalize(*I, ExternalNames, OnlyHidden)) continue; I->setLinkage(GlobalValue::InternalLinkage); Changed = true; ++NumAliases; DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n"); } return Changed; }