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/StringRef.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/Analysis/TargetLibraryInfo.h" 21 #include "llvm/IR/Argument.h" 22 #include "llvm/IR/BasicBlock.h" 23 #include "llvm/IR/DerivedTypes.h" 24 #include "llvm/IR/Function.h" 25 #include "llvm/IR/GlobalAlias.h" 26 #include "llvm/IR/GlobalVariable.h" 27 #include "llvm/IR/Instruction.h" 28 #include "llvm/IR/Module.h" 29 #include "llvm/IR/PassManager.h" 30 #include "llvm/IR/Type.h" 31 #include "llvm/IR/TypeFinder.h" 32 #include "llvm/InitializePasses.h" 33 #include "llvm/Pass.h" 34 #include "llvm/Transforms/Utils.h" 35 36 using namespace llvm; 37 38 static const char *const metaNames[] = { 39 // See http://en.wikipedia.org/wiki/Metasyntactic_variable 40 "foo", "bar", "baz", "quux", "barney", "snork", "zot", "blam", "hoge", 41 "wibble", "wobble", "widget", "wombat", "ham", "eggs", "pluto", "spam" 42 }; 43 44 namespace { 45 // This PRNG is from the ISO C spec. It is intentionally simple and 46 // unsuitable for cryptographic use. We're just looking for enough 47 // variety to surprise and delight users. 48 struct PRNG { 49 unsigned long next; 50 51 void srand(unsigned int seed) { next = seed; } 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) { prng.srand(seed); } 61 62 const char *newName() { 63 return metaNames[prng.rand() % array_lengthof(metaNames)]; 64 } 65 66 PRNG prng; 67 }; 68 69 void MetaRename(Function &F) { 70 for (Argument &Arg : F.args()) 71 if (!Arg.getType()->isVoidTy()) 72 Arg.setName("arg"); 73 74 for (auto &BB : F) { 75 BB.setName("bb"); 76 77 for (auto &I : BB) 78 if (!I.getType()->isVoidTy()) 79 I.setName("tmp"); 80 } 81 } 82 83 void MetaRename(Module &M, 84 function_ref<TargetLibraryInfo &(Function &)> GetTLI) { 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 (GlobalVariable &GV : M.globals()) { 105 StringRef Name = GV.getName(); 106 if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1)) 107 continue; 108 109 GV.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()) 117 continue; 118 119 SmallString<128> NameStorage; 120 STy->setName( 121 (Twine("struct.") + renamer.newName()).toStringRef(NameStorage)); 122 } 123 124 // Rename all functions 125 for (auto &F : M) { 126 StringRef Name = F.getName(); 127 LibFunc Tmp; 128 // Leave library functions alone because their presence or absence could 129 // affect the behavior of other passes. 130 if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) || 131 GetTLI(F).getLibFunc(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 MetaRename(F); 140 } 141 } 142 143 struct MetaRenamer : public ModulePass { 144 // Pass identification, replacement for typeid 145 static char ID; 146 147 MetaRenamer() : ModulePass(ID) { 148 initializeMetaRenamerPass(*PassRegistry::getPassRegistry()); 149 } 150 151 void getAnalysisUsage(AnalysisUsage &AU) const override { 152 AU.addRequired<TargetLibraryInfoWrapperPass>(); 153 AU.setPreservesAll(); 154 } 155 156 bool runOnModule(Module &M) override { 157 auto GetTLI = [this](Function &F) -> TargetLibraryInfo & { 158 return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F); 159 }; 160 MetaRename(M, GetTLI); 161 return true; 162 } 163 }; 164 165 } // end anonymous namespace 166 167 char MetaRenamer::ID = 0; 168 169 INITIALIZE_PASS_BEGIN(MetaRenamer, "metarenamer", 170 "Assign new names to everything", false, false) 171 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 172 INITIALIZE_PASS_END(MetaRenamer, "metarenamer", 173 "Assign new names to everything", false, false) 174 175 //===----------------------------------------------------------------------===// 176 // 177 // MetaRenamer - Rename everything with metasyntactic names. 178 // 179 ModulePass *llvm::createMetaRenamerPass() { 180 return new MetaRenamer(); 181 } 182 183 PreservedAnalyses MetaRenamerPass::run(Module &M, ModuleAnalysisManager &AM) { 184 FunctionAnalysisManager &FAM = 185 AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); 186 auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & { 187 return FAM.getResult<TargetLibraryAnalysis>(F); 188 }; 189 MetaRename(M, GetTLI); 190 191 return PreservedAnalyses::all(); 192 } 193