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 &section)
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*> &regexList, std::map<Regex*, std::string> &regexMap)
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*> &regexList, std::map<Regex*, std::string> &regexMap, 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> &regexMap, std::vector<Regex*> &regexList, 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