1 //===- MetaRenamer.cpp - Rename everything with metasyntatic names --------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This pass renames everything with metasyntatic names. The intent is to use 10 // this pass after bugpoint reduction to conceal the nature of the original 11 // program. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/ADT/STLExtras.h" 16 #include "llvm/ADT/SmallString.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/ADT/Twine.h" 19 #include "llvm/Analysis/TargetLibraryInfo.h" 20 #include "llvm/IR/Argument.h" 21 #include "llvm/IR/BasicBlock.h" 22 #include "llvm/IR/DerivedTypes.h" 23 #include "llvm/IR/Function.h" 24 #include "llvm/IR/GlobalAlias.h" 25 #include "llvm/IR/GlobalVariable.h" 26 #include "llvm/IR/Instruction.h" 27 #include "llvm/IR/Module.h" 28 #include "llvm/IR/Type.h" 29 #include "llvm/IR/TypeFinder.h" 30 #include "llvm/Pass.h" 31 #include "llvm/Transforms/Utils.h" 32 33 using namespace llvm; 34 35 static const char *const metaNames[] = { 36 // See http://en.wikipedia.org/wiki/Metasyntactic_variable 37 "foo", "bar", "baz", "quux", "barney", "snork", "zot", "blam", "hoge", 38 "wibble", "wobble", "widget", "wombat", "ham", "eggs", "pluto", "spam" 39 }; 40 41 namespace { 42 43 // This PRNG is from the ISO C spec. It is intentionally simple and 44 // unsuitable for cryptographic use. We're just looking for enough 45 // variety to surprise and delight users. 46 struct PRNG { 47 unsigned long next; 48 49 void srand(unsigned int seed) { 50 next = seed; 51 } 52 53 int rand() { 54 next = next * 1103515245 + 12345; 55 return (unsigned int)(next / 65536) % 32768; 56 } 57 }; 58 59 struct Renamer { 60 Renamer(unsigned int seed) { 61 prng.srand(seed); 62 } 63 64 const char *newName() { 65 return metaNames[prng.rand() % array_lengthof(metaNames)]; 66 } 67 68 PRNG prng; 69 }; 70 71 struct MetaRenamer : public ModulePass { 72 // Pass identification, replacement for typeid 73 static char ID; 74 75 MetaRenamer() : ModulePass(ID) { 76 initializeMetaRenamerPass(*PassRegistry::getPassRegistry()); 77 } 78 79 void getAnalysisUsage(AnalysisUsage &AU) const override { 80 AU.addRequired<TargetLibraryInfoWrapperPass>(); 81 AU.setPreservesAll(); 82 } 83 84 bool runOnModule(Module &M) override { 85 // Seed our PRNG with simple additive sum of ModuleID. We're looking to 86 // simply avoid always having the same function names, and we need to 87 // remain deterministic. 88 unsigned int randSeed = 0; 89 for (auto C : M.getModuleIdentifier()) 90 randSeed += C; 91 92 Renamer renamer(randSeed); 93 94 // Rename all aliases 95 for (auto AI = M.alias_begin(), AE = M.alias_end(); AI != AE; ++AI) { 96 StringRef Name = AI->getName(); 97 if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1)) 98 continue; 99 100 AI->setName("alias"); 101 } 102 103 // Rename all global variables 104 for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE; ++GI) { 105 StringRef Name = GI->getName(); 106 if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1)) 107 continue; 108 109 GI->setName("global"); 110 } 111 112 // Rename all struct types 113 TypeFinder StructTypes; 114 StructTypes.run(M, true); 115 for (StructType *STy : StructTypes) { 116 if (STy->isLiteral() || STy->getName().empty()) continue; 117 118 SmallString<128> NameStorage; 119 STy->setName((Twine("struct.") + 120 renamer.newName()).toStringRef(NameStorage)); 121 } 122 123 // Rename all functions 124 for (auto &F : M) { 125 StringRef Name = F.getName(); 126 LibFunc Tmp; 127 // Leave library functions alone because their presence or absence could 128 // affect the behavior of other passes. 129 if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) || 130 getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F).getLibFunc( 131 F, Tmp)) 132 continue; 133 134 // Leave @main alone. The output of -metarenamer might be passed to 135 // lli for execution and the latter needs a main entry point. 136 if (Name != "main") 137 F.setName(renamer.newName()); 138 139 runOnFunction(F); 140 } 141 return true; 142 } 143 144 bool runOnFunction(Function &F) { 145 for (auto AI = F.arg_begin(), AE = F.arg_end(); AI != AE; ++AI) 146 if (!AI->getType()->isVoidTy()) 147 AI->setName("arg"); 148 149 for (auto &BB : F) { 150 BB.setName("bb"); 151 152 for (auto &I : BB) 153 if (!I.getType()->isVoidTy()) 154 I.setName("tmp"); 155 } 156 return true; 157 } 158 }; 159 160 } // end anonymous namespace 161 162 char MetaRenamer::ID = 0; 163 164 INITIALIZE_PASS_BEGIN(MetaRenamer, "metarenamer", 165 "Assign new names to everything", false, false) 166 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 167 INITIALIZE_PASS_END(MetaRenamer, "metarenamer", 168 "Assign new names to everything", false, false) 169 170 //===----------------------------------------------------------------------===// 171 // 172 // MetaRenamer - Rename everything with metasyntactic names. 173 // 174 ModulePass *llvm::createMetaRenamerPass() { 175 return new MetaRenamer(); 176 } 177