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/Transforms/Utils/MetaRenamer.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/SmallString.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/ADT/Twine.h" 21 #include "llvm/Analysis/TargetLibraryInfo.h" 22 #include "llvm/IR/Argument.h" 23 #include "llvm/IR/BasicBlock.h" 24 #include "llvm/IR/DerivedTypes.h" 25 #include "llvm/IR/Function.h" 26 #include "llvm/IR/GlobalAlias.h" 27 #include "llvm/IR/GlobalVariable.h" 28 #include "llvm/IR/Instruction.h" 29 #include "llvm/IR/Module.h" 30 #include "llvm/IR/PassManager.h" 31 #include "llvm/IR/Type.h" 32 #include "llvm/IR/TypeFinder.h" 33 #include "llvm/InitializePasses.h" 34 #include "llvm/Pass.h" 35 #include "llvm/Support/CommandLine.h" 36 #include "llvm/Transforms/Utils.h" 37 38 using namespace llvm; 39 40 static cl::opt<std::string> RenameExcludeFunctionPrefixes( 41 "rename-exclude-function-prefixes", 42 cl::desc("Prefixes for functions that don't need to be renamed, separated " 43 "by a comma"), 44 cl::Hidden); 45 46 static cl::opt<std::string> RenameExcludeAliasPrefixes( 47 "rename-exclude-alias-prefixes", 48 cl::desc("Prefixes for aliases that don't need to be renamed, separated " 49 "by a comma"), 50 cl::Hidden); 51 52 static cl::opt<std::string> RenameExcludeGlobalPrefixes( 53 "rename-exclude-global-prefixes", 54 cl::desc( 55 "Prefixes for global values that don't need to be renamed, separated " 56 "by a comma"), 57 cl::Hidden); 58 59 static cl::opt<std::string> RenameExcludeStructPrefixes( 60 "rename-exclude-struct-prefixes", 61 cl::desc("Prefixes for structs that don't need to be renamed, separated " 62 "by a comma"), 63 cl::Hidden); 64 65 static const char *const metaNames[] = { 66 // See http://en.wikipedia.org/wiki/Metasyntactic_variable 67 "foo", "bar", "baz", "quux", "barney", "snork", "zot", "blam", "hoge", 68 "wibble", "wobble", "widget", "wombat", "ham", "eggs", "pluto", "spam" 69 }; 70 71 namespace { 72 // This PRNG is from the ISO C spec. It is intentionally simple and 73 // unsuitable for cryptographic use. We're just looking for enough 74 // variety to surprise and delight users. 75 struct PRNG { 76 unsigned long next; 77 78 void srand(unsigned int seed) { next = seed; } 79 80 int rand() { 81 next = next * 1103515245 + 12345; 82 return (unsigned int)(next / 65536) % 32768; 83 } 84 }; 85 86 struct Renamer { 87 Renamer(unsigned int seed) { prng.srand(seed); } 88 89 const char *newName() { 90 return metaNames[prng.rand() % std::size(metaNames)]; 91 } 92 93 PRNG prng; 94 }; 95 96 static void 97 parseExcludedPrefixes(StringRef PrefixesStr, 98 SmallVectorImpl<StringRef> &ExcludedPrefixes) { 99 for (;;) { 100 auto PrefixesSplit = PrefixesStr.split(','); 101 if (PrefixesSplit.first.empty()) 102 break; 103 ExcludedPrefixes.push_back(PrefixesSplit.first); 104 PrefixesStr = PrefixesSplit.second; 105 } 106 } 107 108 void MetaRename(Function &F) { 109 for (Argument &Arg : F.args()) 110 if (!Arg.getType()->isVoidTy()) 111 Arg.setName("arg"); 112 113 for (auto &BB : F) { 114 BB.setName("bb"); 115 116 for (auto &I : BB) 117 if (!I.getType()->isVoidTy()) 118 I.setName("tmp"); 119 } 120 } 121 122 void MetaRename(Module &M, 123 function_ref<TargetLibraryInfo &(Function &)> GetTLI) { 124 // Seed our PRNG with simple additive sum of ModuleID. We're looking to 125 // simply avoid always having the same function names, and we need to 126 // remain deterministic. 127 unsigned int randSeed = 0; 128 for (auto C : M.getModuleIdentifier()) 129 randSeed += C; 130 131 Renamer renamer(randSeed); 132 133 SmallVector<StringRef, 8> ExcludedAliasesPrefixes; 134 SmallVector<StringRef, 8> ExcludedGlobalsPrefixes; 135 SmallVector<StringRef, 8> ExcludedStructsPrefixes; 136 SmallVector<StringRef, 8> ExcludedFuncPrefixes; 137 parseExcludedPrefixes(RenameExcludeAliasPrefixes, ExcludedAliasesPrefixes); 138 parseExcludedPrefixes(RenameExcludeGlobalPrefixes, ExcludedGlobalsPrefixes); 139 parseExcludedPrefixes(RenameExcludeStructPrefixes, ExcludedStructsPrefixes); 140 parseExcludedPrefixes(RenameExcludeFunctionPrefixes, ExcludedFuncPrefixes); 141 142 auto IsNameExcluded = [](StringRef &Name, 143 SmallVectorImpl<StringRef> &ExcludedPrefixes) { 144 return any_of(ExcludedPrefixes, 145 [&Name](auto &Prefix) { return Name.startswith(Prefix); }); 146 }; 147 148 // Rename all aliases 149 for (GlobalAlias &GA : M.aliases()) { 150 StringRef Name = GA.getName(); 151 if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) || 152 IsNameExcluded(Name, ExcludedAliasesPrefixes)) 153 continue; 154 155 GA.setName("alias"); 156 } 157 158 // Rename all global variables 159 for (GlobalVariable &GV : M.globals()) { 160 StringRef Name = GV.getName(); 161 if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) || 162 IsNameExcluded(Name, ExcludedGlobalsPrefixes)) 163 continue; 164 165 GV.setName("global"); 166 } 167 168 // Rename all struct types 169 TypeFinder StructTypes; 170 StructTypes.run(M, true); 171 for (StructType *STy : StructTypes) { 172 StringRef Name = STy->getName(); 173 if (STy->isLiteral() || Name.empty() || 174 IsNameExcluded(Name, ExcludedStructsPrefixes)) 175 continue; 176 177 SmallString<128> NameStorage; 178 STy->setName( 179 (Twine("struct.") + renamer.newName()).toStringRef(NameStorage)); 180 } 181 182 // Rename all functions 183 for (auto &F : M) { 184 StringRef Name = F.getName(); 185 LibFunc Tmp; 186 // Leave library functions alone because their presence or absence could 187 // affect the behavior of other passes. 188 if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) || 189 GetTLI(F).getLibFunc(F, Tmp) || 190 IsNameExcluded(Name, ExcludedFuncPrefixes)) 191 continue; 192 193 // Leave @main alone. The output of -metarenamer might be passed to 194 // lli for execution and the latter needs a main entry point. 195 if (Name != "main") 196 F.setName(renamer.newName()); 197 198 MetaRename(F); 199 } 200 } 201 202 struct MetaRenamer : public ModulePass { 203 // Pass identification, replacement for typeid 204 static char ID; 205 206 MetaRenamer() : ModulePass(ID) { 207 initializeMetaRenamerPass(*PassRegistry::getPassRegistry()); 208 } 209 210 void getAnalysisUsage(AnalysisUsage &AU) const override { 211 AU.addRequired<TargetLibraryInfoWrapperPass>(); 212 AU.setPreservesAll(); 213 } 214 215 bool runOnModule(Module &M) override { 216 auto GetTLI = [this](Function &F) -> TargetLibraryInfo & { 217 return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F); 218 }; 219 MetaRename(M, GetTLI); 220 return true; 221 } 222 }; 223 224 } // end anonymous namespace 225 226 char MetaRenamer::ID = 0; 227 228 INITIALIZE_PASS_BEGIN(MetaRenamer, "metarenamer", 229 "Assign new names to everything", false, false) 230 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 231 INITIALIZE_PASS_END(MetaRenamer, "metarenamer", 232 "Assign new names to everything", false, false) 233 234 //===----------------------------------------------------------------------===// 235 // 236 // MetaRenamer - Rename everything with metasyntactic names. 237 // 238 ModulePass *llvm::createMetaRenamerPass() { 239 return new MetaRenamer(); 240 } 241 242 PreservedAnalyses MetaRenamerPass::run(Module &M, ModuleAnalysisManager &AM) { 243 FunctionAnalysisManager &FAM = 244 AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); 245 auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & { 246 return FAM.getResult<TargetLibraryAnalysis>(F); 247 }; 248 MetaRename(M, GetTLI); 249 250 return PreservedAnalyses::all(); 251 } 252