diff --git a/minix/llvm/passes/include/sectionify/SectionifyPass.h b/minix/llvm/passes/include/sectionify/SectionifyPass.h new file mode 100644 index 000000000..2d764f7c9 --- /dev/null +++ b/minix/llvm/passes/include/sectionify/SectionifyPass.h @@ -0,0 +1,37 @@ +#ifndef SECTIONIFY_PASS_H + +#define SECTIONIFY_PASS_H + +#define DEBUG_TYPE "sectionify" +#include + +using namespace llvm; + +namespace llvm { + +class SectionifyPass : public ModulePass { + + public: + static char ID; + + SectionifyPass(); + + virtual bool runOnModule(Module &M); + + private: + std::map functionRegexMap; + std::vector functionRegexList; + std::map dataRegexMap; + std::vector dataRegexList; + std::string moduleName; + + bool sectionifyFromRegex(GlobalValue *value, Regex *regex, std::string §ion); + bool sectionify(GlobalValue *value, std::vector ®exList, std::map ®exMap); + void parseAndInitRegexMap(cl::list &stringListOpt, std::vector ®exList, std::map ®exMap, std::string regexType); + bool initRegexMap(std::map ®exMap, std::vector ®exList, std::map &stringMap, std::vector &stringList, std::string regexType); + bool parseStringMapOpt(std::map &map, std::vector &keyList, std::vector &stringList); +}; + +} + +#endif diff --git a/minix/llvm/passes/sectionify/Makefile b/minix/llvm/passes/sectionify/Makefile new file mode 100644 index 000000000..24012f10e --- /dev/null +++ b/minix/llvm/passes/sectionify/Makefile @@ -0,0 +1,6 @@ +PASSNAME:= sectionify + +OBJS := SectionifyPass.o +HEADERS = $(wildcard ../include/magic/support/*.h) + +include ../Makefile.inc diff --git a/minix/llvm/passes/sectionify/SectionifyPass.cpp b/minix/llvm/passes/sectionify/SectionifyPass.cpp new file mode 100644 index 000000000..e9a4bad7c --- /dev/null +++ b/minix/llvm/passes/sectionify/SectionifyPass.cpp @@ -0,0 +1,238 @@ +#include + +using namespace llvm; + +static cl::list +sectionMapOpt("sectionify-section-map", + cl::desc("Specify all the comma-separated symbol_regex/section pairs which need to be sectionified. \"NULL\" section doesn't sectionify."), + cl::ZeroOrMore, cl::CommaSeparated, cl::NotHidden, cl::ValueRequired); + +static cl::list +functionSectionMapOpt("sectionify-function-section-map", + cl::desc("Specify all the comma-separated function_regex/section pairs which need to be sectionified"), + cl::ZeroOrMore, cl::CommaSeparated, cl::NotHidden, cl::ValueRequired); + +static cl::list +dataSectionMapOpt("sectionify-data-section-map", + cl::desc("Specify all the comma-separated data_regex/section pairs which need to be sectionified"), + cl::ZeroOrMore, cl::CommaSeparated, cl::NotHidden, cl::ValueRequired); + +static cl::opt +prefixOpt("sectionify-prefix", + cl::desc("Specify the prefix-string for prefixing names of global variables and functions"), + cl::Optional, cl::NotHidden, cl::ValueRequired); + +static cl::opt +sectionifyExternalFunctions("sectionify-function-external", + llvm::cl::desc("Also sectionify external functions"), + cl::init(false)); + +static cl::opt +sectionifyExternalData("sectionify-data-external", + llvm::cl::desc("Also sectionify external data"), + cl::init(false)); + +static cl::opt +sectionifySkipReadOnlyData("sectionify-data-skip-read-only", + llvm::cl::desc("Don't sectionify read-only data"), + cl::init(false)); + +static cl::opt +sectionifyTLSData("sectionify-data-tls", + llvm::cl::desc("Also sectionify tls data"), + cl::init(false)); + +static cl::opt +sectionifyNoOverride("sectionify-no-override", + llvm::cl::desc("Do not override existing sections"), + cl::init(false)); + +STATISTIC(numSectionifiedGVs, "Number of sectionified global variables"); +STATISTIC(numSectionifiedFuncs, "Number of sectionified functions"); + +namespace llvm { + +//===----------------------------------------------------------------------===// +// Constructors, destructor, and operators +//===----------------------------------------------------------------------===// + +SectionifyPass::SectionifyPass() : ModulePass(ID) {} +//===----------------------------------------------------------------------===// +// Public methods +//===----------------------------------------------------------------------===// + +bool SectionifyPass::runOnModule(Module &M) { + bool sectionified = false; + Module::GlobalListType &globalList = M.getGlobalList(); + Module::FunctionListType &functionList = M.getFunctionList(); + + functionSectionMapOpt.insert(functionSectionMapOpt.end(), sectionMapOpt.begin(), sectionMapOpt.end()); + dataSectionMapOpt.insert(dataSectionMapOpt.end(), sectionMapOpt.begin(), sectionMapOpt.end()); + parseAndInitRegexMap(functionSectionMapOpt, functionRegexList, functionRegexMap, "function"); + parseAndInitRegexMap(dataSectionMapOpt, dataRegexList, dataRegexMap, "data"); + + moduleName = ""; + if ("" != prefixOpt && "%MODULE_NAME%" == prefixOpt) + { + PassUtil::getModuleName(M, NULL, NULL, &moduleName); + } + + for (Module::global_iterator it = globalList.begin(); it != globalList.end(); ++it) { + GlobalVariable *GV = it; + if (GV->isDeclaration() && !sectionifyExternalData) { + DEBUG(errs() << "Skipping external GlobalVariable " << GV->getName() << "\n"); + continue; + } + if (GV->isConstant() && sectionifySkipReadOnlyData) { + DEBUG(errs() << "Skipping read-only GlobalVariable " << GV->getName() << "\n"); + continue; + } + if (GV->isThreadLocal() && !sectionifyTLSData) { + DEBUG(errs() << "Skipping TLS GlobalVariable " << GV->getName() << "\n"); + continue; + } + if (GV->hasSection() && sectionifyNoOverride) { + DEBUG(errs() << "Skipping sectionified GlobalVariable " << GV->getName() << "\n"); + continue; + } + if (GV->getName().startswith("llvm.")) { + DEBUG(errs() << "Skipping LLVM instrinsic GlobalVariable " << GV->getName() << "\n"); + continue; + } + if (sectionify(GV, dataRegexList, dataRegexMap)) { + numSectionifiedGVs++; + sectionified = true; + } + } + for (Module::iterator it = functionList.begin(); it != functionList.end(); ++it) { + Function *F = it; + if (F->isDeclaration() && !sectionifyExternalFunctions) { + DEBUG(errs() << "Skipping external Function " << F->getName() << "\n"); + continue; + } + if (F->hasSection() && sectionifyNoOverride) { + DEBUG(errs() << "Skipping sectionified Function " << F->getName() << "\n"); + continue; + } + if (F->getName().startswith("llvm.")) { + DEBUG(errs() << "Skipping LLVM instrinsic Function " << F->getName() << "\n"); + continue; + } + if (sectionify(F, functionRegexList, functionRegexMap)) { + numSectionifiedFuncs++; + sectionified = true; + } + } + + return sectionified; +} + +bool SectionifyPass::sectionifyFromRegex(GlobalValue *value, Regex *regex, std::string §ion) +{ + bool returnValue = false; + + if("NULL" != section && regex->match(value->getName(), NULL)) { + std::string trgSection = section; + std::string valueStrPrefix = ""; + GlobalVariable *GV = dyn_cast(value); + if (GV && GV->isConstant()) { + trgSection += "_ro"; + valueStrPrefix = "read-only "; + } + DEBUG(errs() << "Sectionified " << valueStrPrefix << (isa(value) ? "Function " : "GlobalVariable ") << value->getName() << " with section " << trgSection << "\n"); + value->setSection(trgSection); + if (value->hasCommonLinkage()) { + value->setLinkage(GlobalValue::WeakAnyLinkage); + } + returnValue = true; + } + if ("" != prefixOpt) + { + std::string originalName = value->getName(); + std::string prefixString = ""; + if ("" != moduleName) + { + prefixString = moduleName; + } + else + { + prefixString = prefixOpt; + } + DEBUG(errs() << "Prefixing the " << (isa(value) ? "Function name " : "GlobalVariable name ") << originalName << " with " << prefixString << "\n"); + std::string prefixedName = prefixString + originalName; + value->setName(prefixedName); + returnValue = true; + } + + return returnValue; +} + +bool SectionifyPass::sectionify(GlobalValue *value, std::vector ®exList, std::map ®exMap) +{ + std::map::iterator regexMapIt; + for (std::vector::iterator it = regexList.begin(); it != regexList.end(); ++it) { + Regex *regex = *it; + regexMapIt = regexMap.find(regex); + assert(regexMapIt != regexMap.end()); + std::string section = regexMapIt->second; + if (sectionifyFromRegex(value, regex, section)) { + return true; + } + } + + return false; +} + +bool SectionifyPass::parseStringMapOpt(std::map &map, std::vector &keyList, std::vector &stringList) +{ + for (std::vector::iterator it = stringList.begin(); it != stringList.end(); ++it) { + StringRef token = *it; + SmallVector< StringRef, 2 > tokenVector; + token.split(tokenVector, "/"); + if(tokenVector.size() != 2) { + return false; + } + StringRef value = tokenVector.pop_back_val(); + StringRef key = tokenVector.pop_back_val(); + map.insert( std::pair(key, value) ); + keyList.push_back(key); + } + + return true; +} + +void SectionifyPass::parseAndInitRegexMap(cl::list &stringListOpt, std::vector ®exList, std::map ®exMap, std::string regexType) +{ + std::map sectionMap; + std::vector sectionList; + if (!parseStringMapOpt(sectionMap, sectionList, stringListOpt) || !initRegexMap(regexMap, regexList, sectionMap, sectionList, regexType)) { + stringListOpt.error("Invalid format!"); + exit(1); + } +} + +bool SectionifyPass::initRegexMap(std::map ®exMap, std::vector ®exList, std::map &stringMap, std::vector &stringList, std::string regexType) +{ + std::map::iterator stringMapIt; + for (std::vector::iterator it = stringList.begin(); it != stringList.end(); ++it) { + std::string key = *it; + stringMapIt = stringMap.find(key); + assert(stringMapIt != stringMap.end()); + std::string value = stringMapIt->second; + std::string error; + Regex *regex = new Regex(key, 0); + if(!regex->isValid(error)) { + return false; + } + DEBUG(errs() << "Using " << regexType << " regex " << key << " with section " << value << "\n"); + regexMap.insert(std::pair(regex, value)); + regexList.push_back(regex); + } + + return true; +} + +} // end namespace + +char SectionifyPass::ID = 1; +static RegisterPass AP("sectionify", "Sectionify Pass");