1 #include <sectionify/SectionifyPass.h> 2 3 using namespace llvm; 4 5 static cl::list<std::string> 6 sectionMapOpt("sectionify-section-map", 7 cl::desc("Specify all the comma-separated symbol_regex/section pairs which need to be sectionified. \"NULL\" section doesn't sectionify."), 8 cl::ZeroOrMore, cl::CommaSeparated, cl::NotHidden, cl::ValueRequired); 9 10 static cl::list<std::string> 11 functionSectionMapOpt("sectionify-function-section-map", 12 cl::desc("Specify all the comma-separated function_regex/section pairs which need to be sectionified"), 13 cl::ZeroOrMore, cl::CommaSeparated, cl::NotHidden, cl::ValueRequired); 14 15 static cl::list<std::string> 16 dataSectionMapOpt("sectionify-data-section-map", 17 cl::desc("Specify all the comma-separated data_regex/section pairs which need to be sectionified"), 18 cl::ZeroOrMore, cl::CommaSeparated, cl::NotHidden, cl::ValueRequired); 19 20 static cl::opt<std::string> 21 prefixOpt("sectionify-prefix", 22 cl::desc("Specify the prefix-string for prefixing names of global variables and functions"), 23 cl::Optional, cl::NotHidden, cl::ValueRequired); 24 25 static cl::opt<bool> 26 sectionifyExternalFunctions("sectionify-function-external", 27 llvm::cl::desc("Also sectionify external functions"), 28 cl::init(false)); 29 30 static cl::opt<bool> 31 sectionifyExternalData("sectionify-data-external", 32 llvm::cl::desc("Also sectionify external data"), 33 cl::init(false)); 34 35 static cl::opt<bool> 36 sectionifySkipReadOnlyData("sectionify-data-skip-read-only", 37 llvm::cl::desc("Don't sectionify read-only data"), 38 cl::init(false)); 39 40 static cl::opt<bool> 41 sectionifyTLSData("sectionify-data-tls", 42 llvm::cl::desc("Also sectionify tls data"), 43 cl::init(false)); 44 45 static cl::opt<bool> 46 sectionifyNoOverride("sectionify-no-override", 47 llvm::cl::desc("Do not override existing sections"), 48 cl::init(false)); 49 50 STATISTIC(numSectionifiedGVs, "Number of sectionified global variables"); 51 STATISTIC(numSectionifiedFuncs, "Number of sectionified functions"); 52 53 namespace llvm { 54 55 //===----------------------------------------------------------------------===// 56 // Constructors, destructor, and operators 57 //===----------------------------------------------------------------------===// 58 59 SectionifyPass::SectionifyPass() : ModulePass(ID) {} 60 //===----------------------------------------------------------------------===// 61 // Public methods 62 //===----------------------------------------------------------------------===// 63 64 bool SectionifyPass::runOnModule(Module &M) { 65 bool sectionified = false; 66 Module::GlobalListType &globalList = M.getGlobalList(); 67 Module::FunctionListType &functionList = M.getFunctionList(); 68 69 functionSectionMapOpt.insert(functionSectionMapOpt.end(), sectionMapOpt.begin(), sectionMapOpt.end()); 70 dataSectionMapOpt.insert(dataSectionMapOpt.end(), sectionMapOpt.begin(), sectionMapOpt.end()); 71 parseAndInitRegexMap(functionSectionMapOpt, functionRegexList, functionRegexMap, "function"); 72 parseAndInitRegexMap(dataSectionMapOpt, dataRegexList, dataRegexMap, "data"); 73 74 moduleName = ""; 75 if ("" != prefixOpt && "%MODULE_NAME%" == prefixOpt) 76 { 77 PassUtil::getModuleName(M, NULL, NULL, &moduleName); 78 } 79 80 for (Module::global_iterator it = globalList.begin(); it != globalList.end(); ++it) { 81 GlobalVariable *GV = it; 82 if (GV->isDeclaration() && !sectionifyExternalData) { 83 DEBUG(errs() << "Skipping external GlobalVariable " << GV->getName() << "\n"); 84 continue; 85 } 86 if (GV->isConstant() && sectionifySkipReadOnlyData) { 87 DEBUG(errs() << "Skipping read-only GlobalVariable " << GV->getName() << "\n"); 88 continue; 89 } 90 if (GV->isThreadLocal() && !sectionifyTLSData) { 91 DEBUG(errs() << "Skipping TLS GlobalVariable " << GV->getName() << "\n"); 92 continue; 93 } 94 if (GV->hasSection() && sectionifyNoOverride) { 95 DEBUG(errs() << "Skipping sectionified GlobalVariable " << GV->getName() << "\n"); 96 continue; 97 } 98 if (GV->getName().startswith("llvm.")) { 99 DEBUG(errs() << "Skipping LLVM instrinsic GlobalVariable " << GV->getName() << "\n"); 100 continue; 101 } 102 if (sectionify(GV, dataRegexList, dataRegexMap)) { 103 numSectionifiedGVs++; 104 sectionified = true; 105 } 106 } 107 for (Module::iterator it = functionList.begin(); it != functionList.end(); ++it) { 108 Function *F = it; 109 if (F->isDeclaration() && !sectionifyExternalFunctions) { 110 DEBUG(errs() << "Skipping external Function " << F->getName() << "\n"); 111 continue; 112 } 113 if (F->hasSection() && sectionifyNoOverride) { 114 DEBUG(errs() << "Skipping sectionified Function " << F->getName() << "\n"); 115 continue; 116 } 117 if (F->getName().startswith("llvm.")) { 118 DEBUG(errs() << "Skipping LLVM instrinsic Function " << F->getName() << "\n"); 119 continue; 120 } 121 if (sectionify(F, functionRegexList, functionRegexMap)) { 122 numSectionifiedFuncs++; 123 sectionified = true; 124 } 125 } 126 127 return sectionified; 128 } 129 130 bool SectionifyPass::sectionifyFromRegex(GlobalObject *value, Regex *regex, std::string §ion) 131 { 132 bool returnValue = false; 133 134 if("NULL" != section && regex->match(value->getName(), NULL)) { 135 std::string trgSection = section; 136 std::string valueStrPrefix = ""; 137 GlobalVariable *GV = dyn_cast<GlobalVariable>(value); 138 if (GV && GV->isConstant()) { 139 trgSection += "_ro"; 140 valueStrPrefix = "read-only "; 141 } 142 DEBUG(errs() << "Sectionified " << valueStrPrefix << (isa<Function>(value) ? "Function " : "GlobalVariable ") << value->getName() << " with section " << trgSection << "\n"); 143 value->setSection(trgSection); 144 if (value->hasCommonLinkage()) { 145 value->setLinkage(GlobalObject::WeakAnyLinkage); 146 } 147 returnValue = true; 148 } 149 if ("" != prefixOpt) 150 { 151 std::string originalName = value->getName(); 152 std::string prefixString = ""; 153 if ("" != moduleName) 154 { 155 prefixString = moduleName; 156 } 157 else 158 { 159 prefixString = prefixOpt; 160 } 161 DEBUG(errs() << "Prefixing the " << (isa<Function>(value) ? "Function name " : "GlobalVariable name ") << originalName << " with " << prefixString << "\n"); 162 std::string prefixedName = prefixString + originalName; 163 value->setName(prefixedName); 164 returnValue = true; 165 } 166 167 return returnValue; 168 } 169 170 bool SectionifyPass::sectionify(GlobalObject *value, std::vector<Regex*> ®exList, std::map<Regex*, std::string> ®exMap) 171 { 172 std::map<Regex*, std::string>::iterator regexMapIt; 173 for (std::vector<Regex*>::iterator it = regexList.begin(); it != regexList.end(); ++it) { 174 Regex *regex = *it; 175 regexMapIt = regexMap.find(regex); 176 assert(regexMapIt != regexMap.end()); 177 std::string section = regexMapIt->second; 178 if (sectionifyFromRegex(value, regex, section)) { 179 return true; 180 } 181 } 182 183 return false; 184 } 185 186 bool SectionifyPass::parseStringMapOpt(std::map<std::string, std::string> &map, std::vector<std::string> &keyList, std::vector<std::string> &stringList) 187 { 188 for (std::vector<std::string>::iterator it = stringList.begin(); it != stringList.end(); ++it) { 189 StringRef token = *it; 190 SmallVector< StringRef, 2 > tokenVector; 191 token.split(tokenVector, "/"); 192 if(tokenVector.size() != 2) { 193 return false; 194 } 195 StringRef value = tokenVector.pop_back_val(); 196 StringRef key = tokenVector.pop_back_val(); 197 map.insert( std::pair<std::string, std::string>(key, value) ); 198 keyList.push_back(key); 199 } 200 201 return true; 202 } 203 204 void SectionifyPass::parseAndInitRegexMap(cl::list<std::string> &stringListOpt, std::vector<Regex*> ®exList, std::map<Regex*, std::string> ®exMap, std::string regexType) 205 { 206 std::map<std::string, std::string> sectionMap; 207 std::vector<std::string> sectionList; 208 if (!parseStringMapOpt(sectionMap, sectionList, stringListOpt) || !initRegexMap(regexMap, regexList, sectionMap, sectionList, regexType)) { 209 stringListOpt.error("Invalid format!"); 210 exit(1); 211 } 212 } 213 214 bool SectionifyPass::initRegexMap(std::map<Regex*, std::string> ®exMap, std::vector<Regex*> ®exList, std::map<std::string, std::string> &stringMap, std::vector<std::string> &stringList, std::string regexType) 215 { 216 std::map<std::string, std::string>::iterator stringMapIt; 217 for (std::vector<std::string>::iterator it = stringList.begin(); it != stringList.end(); ++it) { 218 std::string key = *it; 219 stringMapIt = stringMap.find(key); 220 assert(stringMapIt != stringMap.end()); 221 std::string value = stringMapIt->second; 222 std::string error; 223 Regex *regex = new Regex(key, 0); 224 if(!regex->isValid(error)) { 225 return false; 226 } 227 DEBUG(errs() << "Using " << regexType << " regex " << key << " with section " << value << "\n"); 228 regexMap.insert(std::pair<Regex*, std::string>(regex, value)); 229 regexList.push_back(regex); 230 } 231 232 return true; 233 } 234 235 } // end namespace 236 237 char SectionifyPass::ID = 1; 238 static RegisterPass<SectionifyPass> AP("sectionify", "Sectionify Pass"); 239