1 //===- SymbolRewriter.cpp - Symbol Rewriter ---------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // SymbolRewriter is a LLVM pass which can rewrite symbols transparently within 11 // existing code. It is implemented as a compiler pass and is configured via a 12 // YAML configuration file. 13 // 14 // The YAML configuration file format is as follows: 15 // 16 // RewriteMapFile := RewriteDescriptors 17 // RewriteDescriptors := RewriteDescriptor | RewriteDescriptors 18 // RewriteDescriptor := RewriteDescriptorType ':' '{' RewriteDescriptorFields '}' 19 // RewriteDescriptorFields := RewriteDescriptorField | RewriteDescriptorFields 20 // RewriteDescriptorField := FieldIdentifier ':' FieldValue ',' 21 // RewriteDescriptorType := Identifier 22 // FieldIdentifier := Identifier 23 // FieldValue := Identifier 24 // Identifier := [0-9a-zA-Z]+ 25 // 26 // Currently, the following descriptor types are supported: 27 // 28 // - function: (function rewriting) 29 // + Source (original name of the function) 30 // + Target (explicit transformation) 31 // + Transform (pattern transformation) 32 // + Naked (boolean, whether the function is undecorated) 33 // - global variable: (external linkage global variable rewriting) 34 // + Source (original name of externally visible variable) 35 // + Target (explicit transformation) 36 // + Transform (pattern transformation) 37 // - global alias: (global alias rewriting) 38 // + Source (original name of the aliased name) 39 // + Target (explicit transformation) 40 // + Transform (pattern transformation) 41 // 42 // Note that source and exactly one of [Target, Transform] must be provided 43 // 44 // New rewrite descriptors can be created. Addding a new rewrite descriptor 45 // involves: 46 // 47 // a) extended the rewrite descriptor kind enumeration 48 // (<anonymous>::RewriteDescriptor::RewriteDescriptorType) 49 // b) implementing the new descriptor 50 // (c.f. <anonymous>::ExplicitRewriteFunctionDescriptor) 51 // c) extending the rewrite map parser 52 // (<anonymous>::RewriteMapParser::parseEntry) 53 // 54 // Specify to rewrite the symbols using the `-rewrite-symbols` option, and 55 // specify the map file to use for the rewriting via the `-rewrite-map-file` 56 // option. 57 // 58 //===----------------------------------------------------------------------===// 59 60 #define DEBUG_TYPE "symbol-rewriter" 61 #include "llvm/CodeGen/Passes.h" 62 #include "llvm/Pass.h" 63 #include "llvm/PassManager.h" 64 #include "llvm/Support/CommandLine.h" 65 #include "llvm/Support/Debug.h" 66 #include "llvm/Support/MemoryBuffer.h" 67 #include "llvm/Support/Regex.h" 68 #include "llvm/Support/SourceMgr.h" 69 #include "llvm/Support/YAMLParser.h" 70 #include "llvm/Support/raw_ostream.h" 71 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 72 #include "llvm/Transforms/Utils/SymbolRewriter.h" 73 74 using namespace llvm; 75 76 static cl::list<std::string> RewriteMapFiles("rewrite-map-file", 77 cl::desc("Symbol Rewrite Map"), 78 cl::value_desc("filename")); 79 80 namespace llvm { 81 namespace SymbolRewriter { 82 template <RewriteDescriptor::Type DT, typename ValueType, 83 ValueType *(llvm::Module::*Get)(StringRef) const> 84 class ExplicitRewriteDescriptor : public RewriteDescriptor { 85 public: 86 const std::string Source; 87 const std::string Target; 88 89 ExplicitRewriteDescriptor(StringRef S, StringRef T, const bool Naked) 90 : RewriteDescriptor(DT), Source(Naked ? StringRef("\01" + S.str()) : S), 91 Target(T) {} 92 93 bool performOnModule(Module &M) override; 94 95 static bool classof(const RewriteDescriptor *RD) { 96 return RD->getType() == DT; 97 } 98 }; 99 100 template <RewriteDescriptor::Type DT, typename ValueType, 101 ValueType *(llvm::Module::*Get)(StringRef) const> 102 bool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) { 103 bool Changed = false; 104 if (ValueType *S = (M.*Get)(Source)) { 105 if (Value *T = (M.*Get)(Target)) 106 S->setValueName(T->getValueName()); 107 else 108 S->setName(Target); 109 Changed = true; 110 } 111 return Changed; 112 } 113 114 template <RewriteDescriptor::Type DT, typename ValueType, 115 ValueType *(llvm::Module::*Get)(StringRef) const, 116 iterator_range<typename iplist<ValueType>::iterator> 117 (llvm::Module::*Iterator)()> 118 class PatternRewriteDescriptor : public RewriteDescriptor { 119 public: 120 const std::string Pattern; 121 const std::string Transform; 122 123 PatternRewriteDescriptor(StringRef P, StringRef T) 124 : RewriteDescriptor(DT), Pattern(P), Transform(T) { } 125 126 bool performOnModule(Module &M) override; 127 128 static bool classof(const RewriteDescriptor *RD) { 129 return RD->getType() == DT; 130 } 131 }; 132 133 template <RewriteDescriptor::Type DT, typename ValueType, 134 ValueType *(llvm::Module::*Get)(StringRef) const, 135 iterator_range<typename iplist<ValueType>::iterator> 136 (llvm::Module::*Iterator)()> 137 bool PatternRewriteDescriptor<DT, ValueType, Get, Iterator>:: 138 performOnModule(Module &M) { 139 bool Changed = false; 140 for (auto &C : (M.*Iterator)()) { 141 std::string Error; 142 143 std::string Name = Regex(Pattern).sub(Transform, C.getName(), &Error); 144 if (!Error.empty()) 145 report_fatal_error("unable to transforn " + C.getName() + " in " + 146 M.getModuleIdentifier() + ": " + Error); 147 148 if (Value *V = (M.*Get)(Name)) 149 C.setValueName(V->getValueName()); 150 else 151 C.setName(Name); 152 153 Changed = true; 154 } 155 return Changed; 156 } 157 158 /// Represents a rewrite for an explicitly named (function) symbol. Both the 159 /// source function name and target function name of the transformation are 160 /// explicitly spelt out. 161 typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function, 162 llvm::Function, &llvm::Module::getFunction> 163 ExplicitRewriteFunctionDescriptor; 164 165 /// Represents a rewrite for an explicitly named (global variable) symbol. Both 166 /// the source variable name and target variable name are spelt out. This 167 /// applies only to module level variables. 168 typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable, 169 llvm::GlobalVariable, 170 &llvm::Module::getGlobalVariable> 171 ExplicitRewriteGlobalVariableDescriptor; 172 173 /// Represents a rewrite for an explicitly named global alias. Both the source 174 /// and target name are explicitly spelt out. 175 typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, 176 llvm::GlobalAlias, 177 &llvm::Module::getNamedAlias> 178 ExplicitRewriteNamedAliasDescriptor; 179 180 /// Represents a rewrite for a regular expression based pattern for functions. 181 /// A pattern for the function name is provided and a transformation for that 182 /// pattern to determine the target function name create the rewrite rule. 183 typedef PatternRewriteDescriptor<RewriteDescriptor::Type::Function, 184 llvm::Function, &llvm::Module::getFunction, 185 &llvm::Module::functions> 186 PatternRewriteFunctionDescriptor; 187 188 /// Represents a rewrite for a global variable based upon a matching pattern. 189 /// Each global variable matching the provided pattern will be transformed as 190 /// described in the transformation pattern for the target. Applies only to 191 /// module level variables. 192 typedef PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable, 193 llvm::GlobalVariable, 194 &llvm::Module::getGlobalVariable, 195 &llvm::Module::globals> 196 PatternRewriteGlobalVariableDescriptor; 197 198 /// PatternRewriteNamedAliasDescriptor - represents a rewrite for global 199 /// aliases which match a given pattern. The provided transformation will be 200 /// applied to each of the matching names. 201 typedef PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, 202 llvm::GlobalAlias, 203 &llvm::Module::getNamedAlias, 204 &llvm::Module::aliases> 205 PatternRewriteNamedAliasDescriptor; 206 207 bool RewriteMapParser::parse(const std::string &MapFile, 208 RewriteDescriptorList *DL) { 209 ErrorOr<std::unique_ptr<MemoryBuffer>> Mapping = 210 MemoryBuffer::getFile(MapFile); 211 212 if (!Mapping) 213 report_fatal_error("unable to read rewrite map '" + MapFile + "': " + 214 Mapping.getError().message()); 215 216 if (!parse(*Mapping, DL)) 217 report_fatal_error("unable to parse rewrite map '" + MapFile + "'"); 218 219 return true; 220 } 221 222 bool RewriteMapParser::parse(std::unique_ptr<MemoryBuffer> &MapFile, 223 RewriteDescriptorList *DL) { 224 SourceMgr SM; 225 yaml::Stream YS(MapFile->getBuffer(), SM); 226 227 for (auto &Document : YS) { 228 yaml::MappingNode *DescriptorList; 229 230 // ignore empty documents 231 if (isa<yaml::NullNode>(Document.getRoot())) 232 continue; 233 234 DescriptorList = dyn_cast<yaml::MappingNode>(Document.getRoot()); 235 if (!DescriptorList) { 236 YS.printError(Document.getRoot(), "DescriptorList node must be a map"); 237 return false; 238 } 239 240 for (auto &Descriptor : *DescriptorList) 241 if (!parseEntry(YS, Descriptor, DL)) 242 return false; 243 } 244 245 return true; 246 } 247 248 bool RewriteMapParser::parseEntry(yaml::Stream &YS, yaml::KeyValueNode &Entry, 249 RewriteDescriptorList *DL) { 250 yaml::ScalarNode *Key; 251 yaml::MappingNode *Value; 252 SmallString<32> KeyStorage; 253 StringRef RewriteType; 254 255 Key = dyn_cast<yaml::ScalarNode>(Entry.getKey()); 256 if (!Key) { 257 YS.printError(Entry.getKey(), "rewrite type must be a scalar"); 258 return false; 259 } 260 261 Value = dyn_cast<yaml::MappingNode>(Entry.getValue()); 262 if (!Value) { 263 YS.printError(Entry.getValue(), "rewrite descriptor must be a map"); 264 return false; 265 } 266 267 RewriteType = Key->getValue(KeyStorage); 268 if (RewriteType.equals("function")) 269 return parseRewriteFunctionDescriptor(YS, Key, Value, DL); 270 else if (RewriteType.equals("global variable")) 271 return parseRewriteGlobalVariableDescriptor(YS, Key, Value, DL); 272 else if (RewriteType.equals("global alias")) 273 return parseRewriteGlobalAliasDescriptor(YS, Key, Value, DL); 274 275 YS.printError(Entry.getKey(), "unknown rewrite type"); 276 return false; 277 } 278 279 bool RewriteMapParser:: 280 parseRewriteFunctionDescriptor(yaml::Stream &YS, yaml::ScalarNode *K, 281 yaml::MappingNode *Descriptor, 282 RewriteDescriptorList *DL) { 283 bool Naked = false; 284 std::string Source; 285 std::string Target; 286 std::string Transform; 287 288 for (auto &Field : *Descriptor) { 289 yaml::ScalarNode *Key; 290 yaml::ScalarNode *Value; 291 SmallString<32> KeyStorage; 292 SmallString<32> ValueStorage; 293 StringRef KeyValue; 294 295 Key = dyn_cast<yaml::ScalarNode>(Field.getKey()); 296 if (!Key) { 297 YS.printError(Field.getKey(), "descriptor key must be a scalar"); 298 return false; 299 } 300 301 Value = dyn_cast<yaml::ScalarNode>(Field.getValue()); 302 if (!Value) { 303 YS.printError(Field.getValue(), "descriptor value must be a scalar"); 304 return false; 305 } 306 307 KeyValue = Key->getValue(KeyStorage); 308 if (KeyValue.equals("source")) { 309 std::string Error; 310 311 Source = Value->getValue(ValueStorage); 312 if (!Regex(Source).isValid(Error)) { 313 YS.printError(Field.getKey(), "invalid regex: " + Error); 314 return false; 315 } 316 } else if (KeyValue.equals("target")) { 317 Target = Value->getValue(ValueStorage); 318 } else if (KeyValue.equals("transform")) { 319 Transform = Value->getValue(ValueStorage); 320 } else if (KeyValue.equals("naked")) { 321 std::string Undecorated; 322 323 Undecorated = Value->getValue(ValueStorage); 324 Naked = StringRef(Undecorated).lower() == "true" || Undecorated == "1"; 325 } else { 326 YS.printError(Field.getKey(), "unknown key for function"); 327 return false; 328 } 329 } 330 331 if (Transform.empty() == Target.empty()) { 332 YS.printError(Descriptor, 333 "exactly one of transform or target must be specified"); 334 return false; 335 } 336 337 // TODO see if there is a more elegant solution to selecting the rewrite 338 // descriptor type 339 if (!Target.empty()) 340 DL->push_back(new ExplicitRewriteFunctionDescriptor(Source, Target, Naked)); 341 else 342 DL->push_back(new PatternRewriteFunctionDescriptor(Source, Transform)); 343 344 return true; 345 } 346 347 bool RewriteMapParser:: 348 parseRewriteGlobalVariableDescriptor(yaml::Stream &YS, yaml::ScalarNode *K, 349 yaml::MappingNode *Descriptor, 350 RewriteDescriptorList *DL) { 351 std::string Source; 352 std::string Target; 353 std::string Transform; 354 355 for (auto &Field : *Descriptor) { 356 yaml::ScalarNode *Key; 357 yaml::ScalarNode *Value; 358 SmallString<32> KeyStorage; 359 SmallString<32> ValueStorage; 360 StringRef KeyValue; 361 362 Key = dyn_cast<yaml::ScalarNode>(Field.getKey()); 363 if (!Key) { 364 YS.printError(Field.getKey(), "descriptor Key must be a scalar"); 365 return false; 366 } 367 368 Value = dyn_cast<yaml::ScalarNode>(Field.getValue()); 369 if (!Value) { 370 YS.printError(Field.getValue(), "descriptor value must be a scalar"); 371 return false; 372 } 373 374 KeyValue = Key->getValue(KeyStorage); 375 if (KeyValue.equals("source")) { 376 std::string Error; 377 378 Source = Value->getValue(ValueStorage); 379 if (!Regex(Source).isValid(Error)) { 380 YS.printError(Field.getKey(), "invalid regex: " + Error); 381 return false; 382 } 383 } else if (KeyValue.equals("target")) { 384 Target = Value->getValue(ValueStorage); 385 } else if (KeyValue.equals("transform")) { 386 Transform = Value->getValue(ValueStorage); 387 } else { 388 YS.printError(Field.getKey(), "unknown Key for Global Variable"); 389 return false; 390 } 391 } 392 393 if (Transform.empty() == Target.empty()) { 394 YS.printError(Descriptor, 395 "exactly one of transform or target must be specified"); 396 return false; 397 } 398 399 if (!Target.empty()) 400 DL->push_back(new ExplicitRewriteGlobalVariableDescriptor(Source, Target, 401 /*Naked*/false)); 402 else 403 DL->push_back(new PatternRewriteGlobalVariableDescriptor(Source, 404 Transform)); 405 406 return true; 407 } 408 409 bool RewriteMapParser:: 410 parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K, 411 yaml::MappingNode *Descriptor, 412 RewriteDescriptorList *DL) { 413 std::string Source; 414 std::string Target; 415 std::string Transform; 416 417 for (auto &Field : *Descriptor) { 418 yaml::ScalarNode *Key; 419 yaml::ScalarNode *Value; 420 SmallString<32> KeyStorage; 421 SmallString<32> ValueStorage; 422 StringRef KeyValue; 423 424 Key = dyn_cast<yaml::ScalarNode>(Field.getKey()); 425 if (!Key) { 426 YS.printError(Field.getKey(), "descriptor key must be a scalar"); 427 return false; 428 } 429 430 Value = dyn_cast<yaml::ScalarNode>(Field.getValue()); 431 if (!Value) { 432 YS.printError(Field.getValue(), "descriptor value must be a scalar"); 433 return false; 434 } 435 436 KeyValue = Key->getValue(KeyStorage); 437 if (KeyValue.equals("source")) { 438 std::string Error; 439 440 Source = Value->getValue(ValueStorage); 441 if (!Regex(Source).isValid(Error)) { 442 YS.printError(Field.getKey(), "invalid regex: " + Error); 443 return false; 444 } 445 } else if (KeyValue.equals("target")) { 446 Target = Value->getValue(ValueStorage); 447 } else if (KeyValue.equals("transform")) { 448 Transform = Value->getValue(ValueStorage); 449 } else { 450 YS.printError(Field.getKey(), "unknown key for Global Alias"); 451 return false; 452 } 453 } 454 455 if (Transform.empty() == Target.empty()) { 456 YS.printError(Descriptor, 457 "exactly one of transform or target must be specified"); 458 return false; 459 } 460 461 if (!Target.empty()) 462 DL->push_back(new ExplicitRewriteNamedAliasDescriptor(Source, Target, 463 /*Naked*/false)); 464 else 465 DL->push_back(new PatternRewriteNamedAliasDescriptor(Source, Transform)); 466 467 return true; 468 } 469 } 470 } 471 472 namespace { 473 class RewriteSymbols : public ModulePass { 474 public: 475 static char ID; // Pass identification, replacement for typeid 476 477 RewriteSymbols(); 478 RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL); 479 480 bool runOnModule(Module &M) override; 481 482 private: 483 void loadAndParseMapFiles(); 484 485 SymbolRewriter::RewriteDescriptorList Descriptors; 486 }; 487 488 char RewriteSymbols::ID = 0; 489 490 RewriteSymbols::RewriteSymbols() : ModulePass(ID) { 491 initializeRewriteSymbolsPass(*PassRegistry::getPassRegistry()); 492 loadAndParseMapFiles(); 493 } 494 495 RewriteSymbols::RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL) 496 : ModulePass(ID) { 497 std::swap(Descriptors, DL); 498 } 499 500 bool RewriteSymbols::runOnModule(Module &M) { 501 bool Changed; 502 503 Changed = false; 504 for (auto &Descriptor : Descriptors) 505 Changed |= Descriptor.performOnModule(M); 506 507 return Changed; 508 } 509 510 void RewriteSymbols::loadAndParseMapFiles() { 511 const std::vector<std::string> MapFiles(RewriteMapFiles); 512 SymbolRewriter::RewriteMapParser parser; 513 514 for (const auto &MapFile : MapFiles) 515 parser.parse(MapFile, &Descriptors); 516 } 517 } 518 519 INITIALIZE_PASS(RewriteSymbols, "rewrite-symbols", "Rewrite Symbols", false, 520 false) 521 522 ModulePass *llvm::createRewriteSymbolsPass() { return new RewriteSymbols(); } 523 524 ModulePass * 525 llvm::createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &DL) { 526 return new RewriteSymbols(DL); 527 } 528