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 (C.getName() == Name) 149 continue; 150 151 if (Value *V = (M.*Get)(Name)) 152 C.setValueName(V->getValueName()); 153 else 154 C.setName(Name); 155 156 Changed = true; 157 } 158 return Changed; 159 } 160 161 /// Represents a rewrite for an explicitly named (function) symbol. Both the 162 /// source function name and target function name of the transformation are 163 /// explicitly spelt out. 164 typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function, 165 llvm::Function, &llvm::Module::getFunction> 166 ExplicitRewriteFunctionDescriptor; 167 168 /// Represents a rewrite for an explicitly named (global variable) symbol. Both 169 /// the source variable name and target variable name are spelt out. This 170 /// applies only to module level variables. 171 typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable, 172 llvm::GlobalVariable, 173 &llvm::Module::getGlobalVariable> 174 ExplicitRewriteGlobalVariableDescriptor; 175 176 /// Represents a rewrite for an explicitly named global alias. Both the source 177 /// and target name are explicitly spelt out. 178 typedef ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, 179 llvm::GlobalAlias, 180 &llvm::Module::getNamedAlias> 181 ExplicitRewriteNamedAliasDescriptor; 182 183 /// Represents a rewrite for a regular expression based pattern for functions. 184 /// A pattern for the function name is provided and a transformation for that 185 /// pattern to determine the target function name create the rewrite rule. 186 typedef PatternRewriteDescriptor<RewriteDescriptor::Type::Function, 187 llvm::Function, &llvm::Module::getFunction, 188 &llvm::Module::functions> 189 PatternRewriteFunctionDescriptor; 190 191 /// Represents a rewrite for a global variable based upon a matching pattern. 192 /// Each global variable matching the provided pattern will be transformed as 193 /// described in the transformation pattern for the target. Applies only to 194 /// module level variables. 195 typedef PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable, 196 llvm::GlobalVariable, 197 &llvm::Module::getGlobalVariable, 198 &llvm::Module::globals> 199 PatternRewriteGlobalVariableDescriptor; 200 201 /// PatternRewriteNamedAliasDescriptor - represents a rewrite for global 202 /// aliases which match a given pattern. The provided transformation will be 203 /// applied to each of the matching names. 204 typedef PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, 205 llvm::GlobalAlias, 206 &llvm::Module::getNamedAlias, 207 &llvm::Module::aliases> 208 PatternRewriteNamedAliasDescriptor; 209 210 bool RewriteMapParser::parse(const std::string &MapFile, 211 RewriteDescriptorList *DL) { 212 ErrorOr<std::unique_ptr<MemoryBuffer>> Mapping = 213 MemoryBuffer::getFile(MapFile); 214 215 if (!Mapping) 216 report_fatal_error("unable to read rewrite map '" + MapFile + "': " + 217 Mapping.getError().message()); 218 219 if (!parse(*Mapping, DL)) 220 report_fatal_error("unable to parse rewrite map '" + MapFile + "'"); 221 222 return true; 223 } 224 225 bool RewriteMapParser::parse(std::unique_ptr<MemoryBuffer> &MapFile, 226 RewriteDescriptorList *DL) { 227 SourceMgr SM; 228 yaml::Stream YS(MapFile->getBuffer(), SM); 229 230 for (auto &Document : YS) { 231 yaml::MappingNode *DescriptorList; 232 233 // ignore empty documents 234 if (isa<yaml::NullNode>(Document.getRoot())) 235 continue; 236 237 DescriptorList = dyn_cast<yaml::MappingNode>(Document.getRoot()); 238 if (!DescriptorList) { 239 YS.printError(Document.getRoot(), "DescriptorList node must be a map"); 240 return false; 241 } 242 243 for (auto &Descriptor : *DescriptorList) 244 if (!parseEntry(YS, Descriptor, DL)) 245 return false; 246 } 247 248 return true; 249 } 250 251 bool RewriteMapParser::parseEntry(yaml::Stream &YS, yaml::KeyValueNode &Entry, 252 RewriteDescriptorList *DL) { 253 yaml::ScalarNode *Key; 254 yaml::MappingNode *Value; 255 SmallString<32> KeyStorage; 256 StringRef RewriteType; 257 258 Key = dyn_cast<yaml::ScalarNode>(Entry.getKey()); 259 if (!Key) { 260 YS.printError(Entry.getKey(), "rewrite type must be a scalar"); 261 return false; 262 } 263 264 Value = dyn_cast<yaml::MappingNode>(Entry.getValue()); 265 if (!Value) { 266 YS.printError(Entry.getValue(), "rewrite descriptor must be a map"); 267 return false; 268 } 269 270 RewriteType = Key->getValue(KeyStorage); 271 if (RewriteType.equals("function")) 272 return parseRewriteFunctionDescriptor(YS, Key, Value, DL); 273 else if (RewriteType.equals("global variable")) 274 return parseRewriteGlobalVariableDescriptor(YS, Key, Value, DL); 275 else if (RewriteType.equals("global alias")) 276 return parseRewriteGlobalAliasDescriptor(YS, Key, Value, DL); 277 278 YS.printError(Entry.getKey(), "unknown rewrite type"); 279 return false; 280 } 281 282 bool RewriteMapParser:: 283 parseRewriteFunctionDescriptor(yaml::Stream &YS, yaml::ScalarNode *K, 284 yaml::MappingNode *Descriptor, 285 RewriteDescriptorList *DL) { 286 bool Naked = false; 287 std::string Source; 288 std::string Target; 289 std::string Transform; 290 291 for (auto &Field : *Descriptor) { 292 yaml::ScalarNode *Key; 293 yaml::ScalarNode *Value; 294 SmallString<32> KeyStorage; 295 SmallString<32> ValueStorage; 296 StringRef KeyValue; 297 298 Key = dyn_cast<yaml::ScalarNode>(Field.getKey()); 299 if (!Key) { 300 YS.printError(Field.getKey(), "descriptor key must be a scalar"); 301 return false; 302 } 303 304 Value = dyn_cast<yaml::ScalarNode>(Field.getValue()); 305 if (!Value) { 306 YS.printError(Field.getValue(), "descriptor value must be a scalar"); 307 return false; 308 } 309 310 KeyValue = Key->getValue(KeyStorage); 311 if (KeyValue.equals("source")) { 312 std::string Error; 313 314 Source = Value->getValue(ValueStorage); 315 if (!Regex(Source).isValid(Error)) { 316 YS.printError(Field.getKey(), "invalid regex: " + Error); 317 return false; 318 } 319 } else if (KeyValue.equals("target")) { 320 Target = Value->getValue(ValueStorage); 321 } else if (KeyValue.equals("transform")) { 322 Transform = Value->getValue(ValueStorage); 323 } else if (KeyValue.equals("naked")) { 324 std::string Undecorated; 325 326 Undecorated = Value->getValue(ValueStorage); 327 Naked = StringRef(Undecorated).lower() == "true" || Undecorated == "1"; 328 } else { 329 YS.printError(Field.getKey(), "unknown key for function"); 330 return false; 331 } 332 } 333 334 if (Transform.empty() == Target.empty()) { 335 YS.printError(Descriptor, 336 "exactly one of transform or target must be specified"); 337 return false; 338 } 339 340 // TODO see if there is a more elegant solution to selecting the rewrite 341 // descriptor type 342 if (!Target.empty()) 343 DL->push_back(new ExplicitRewriteFunctionDescriptor(Source, Target, Naked)); 344 else 345 DL->push_back(new PatternRewriteFunctionDescriptor(Source, Transform)); 346 347 return true; 348 } 349 350 bool RewriteMapParser:: 351 parseRewriteGlobalVariableDescriptor(yaml::Stream &YS, yaml::ScalarNode *K, 352 yaml::MappingNode *Descriptor, 353 RewriteDescriptorList *DL) { 354 std::string Source; 355 std::string Target; 356 std::string Transform; 357 358 for (auto &Field : *Descriptor) { 359 yaml::ScalarNode *Key; 360 yaml::ScalarNode *Value; 361 SmallString<32> KeyStorage; 362 SmallString<32> ValueStorage; 363 StringRef KeyValue; 364 365 Key = dyn_cast<yaml::ScalarNode>(Field.getKey()); 366 if (!Key) { 367 YS.printError(Field.getKey(), "descriptor Key must be a scalar"); 368 return false; 369 } 370 371 Value = dyn_cast<yaml::ScalarNode>(Field.getValue()); 372 if (!Value) { 373 YS.printError(Field.getValue(), "descriptor value must be a scalar"); 374 return false; 375 } 376 377 KeyValue = Key->getValue(KeyStorage); 378 if (KeyValue.equals("source")) { 379 std::string Error; 380 381 Source = Value->getValue(ValueStorage); 382 if (!Regex(Source).isValid(Error)) { 383 YS.printError(Field.getKey(), "invalid regex: " + Error); 384 return false; 385 } 386 } else if (KeyValue.equals("target")) { 387 Target = Value->getValue(ValueStorage); 388 } else if (KeyValue.equals("transform")) { 389 Transform = Value->getValue(ValueStorage); 390 } else { 391 YS.printError(Field.getKey(), "unknown Key for Global Variable"); 392 return false; 393 } 394 } 395 396 if (Transform.empty() == Target.empty()) { 397 YS.printError(Descriptor, 398 "exactly one of transform or target must be specified"); 399 return false; 400 } 401 402 if (!Target.empty()) 403 DL->push_back(new ExplicitRewriteGlobalVariableDescriptor(Source, Target, 404 /*Naked*/false)); 405 else 406 DL->push_back(new PatternRewriteGlobalVariableDescriptor(Source, 407 Transform)); 408 409 return true; 410 } 411 412 bool RewriteMapParser:: 413 parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K, 414 yaml::MappingNode *Descriptor, 415 RewriteDescriptorList *DL) { 416 std::string Source; 417 std::string Target; 418 std::string Transform; 419 420 for (auto &Field : *Descriptor) { 421 yaml::ScalarNode *Key; 422 yaml::ScalarNode *Value; 423 SmallString<32> KeyStorage; 424 SmallString<32> ValueStorage; 425 StringRef KeyValue; 426 427 Key = dyn_cast<yaml::ScalarNode>(Field.getKey()); 428 if (!Key) { 429 YS.printError(Field.getKey(), "descriptor key must be a scalar"); 430 return false; 431 } 432 433 Value = dyn_cast<yaml::ScalarNode>(Field.getValue()); 434 if (!Value) { 435 YS.printError(Field.getValue(), "descriptor value must be a scalar"); 436 return false; 437 } 438 439 KeyValue = Key->getValue(KeyStorage); 440 if (KeyValue.equals("source")) { 441 std::string Error; 442 443 Source = Value->getValue(ValueStorage); 444 if (!Regex(Source).isValid(Error)) { 445 YS.printError(Field.getKey(), "invalid regex: " + Error); 446 return false; 447 } 448 } else if (KeyValue.equals("target")) { 449 Target = Value->getValue(ValueStorage); 450 } else if (KeyValue.equals("transform")) { 451 Transform = Value->getValue(ValueStorage); 452 } else { 453 YS.printError(Field.getKey(), "unknown key for Global Alias"); 454 return false; 455 } 456 } 457 458 if (Transform.empty() == Target.empty()) { 459 YS.printError(Descriptor, 460 "exactly one of transform or target must be specified"); 461 return false; 462 } 463 464 if (!Target.empty()) 465 DL->push_back(new ExplicitRewriteNamedAliasDescriptor(Source, Target, 466 /*Naked*/false)); 467 else 468 DL->push_back(new PatternRewriteNamedAliasDescriptor(Source, Transform)); 469 470 return true; 471 } 472 } 473 } 474 475 namespace { 476 class RewriteSymbols : public ModulePass { 477 public: 478 static char ID; // Pass identification, replacement for typeid 479 480 RewriteSymbols(); 481 RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL); 482 483 bool runOnModule(Module &M) override; 484 485 private: 486 void loadAndParseMapFiles(); 487 488 SymbolRewriter::RewriteDescriptorList Descriptors; 489 }; 490 491 char RewriteSymbols::ID = 0; 492 493 RewriteSymbols::RewriteSymbols() : ModulePass(ID) { 494 initializeRewriteSymbolsPass(*PassRegistry::getPassRegistry()); 495 loadAndParseMapFiles(); 496 } 497 498 RewriteSymbols::RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL) 499 : ModulePass(ID) { 500 Descriptors.splice(Descriptors.begin(), DL); 501 } 502 503 bool RewriteSymbols::runOnModule(Module &M) { 504 bool Changed; 505 506 Changed = false; 507 for (auto &Descriptor : Descriptors) 508 Changed |= Descriptor.performOnModule(M); 509 510 return Changed; 511 } 512 513 void RewriteSymbols::loadAndParseMapFiles() { 514 const std::vector<std::string> MapFiles(RewriteMapFiles); 515 SymbolRewriter::RewriteMapParser parser; 516 517 for (const auto &MapFile : MapFiles) 518 parser.parse(MapFile, &Descriptors); 519 } 520 } 521 522 INITIALIZE_PASS(RewriteSymbols, "rewrite-symbols", "Rewrite Symbols", false, 523 false) 524 525 ModulePass *llvm::createRewriteSymbolsPass() { return new RewriteSymbols(); } 526 527 ModulePass * 528 llvm::createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &DL) { 529 return new RewriteSymbols(DL); 530 } 531