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/InitializePasses.h" 31 #include "llvm/Pass.h" 32 #include "llvm/Transforms/Utils.h" 33 34 using namespace llvm; 35 36 static const char *const metaNames[] = { 37 // See http://en.wikipedia.org/wiki/Metasyntactic_variable 38 "foo", "bar", "baz", "quux", "barney", "snork", "zot", "blam", "hoge", 39 "wibble", "wobble", "widget", "wombat", "ham", "eggs", "pluto", "spam" 40 }; 41 42 namespace { 43 44 // This PRNG is from the ISO C spec. It is intentionally simple and 45 // unsuitable for cryptographic use. We're just looking for enough 46 // variety to surprise and delight users. 47 struct PRNG { 48 unsigned long next; 49 50 void srand(unsigned int seed) { 51 next = seed; 52 } 53 54 int rand() { 55 next = next * 1103515245 + 12345; 56 return (unsigned int)(next / 65536) % 32768; 57 } 58 }; 59 60 struct Renamer { 61 Renamer(unsigned int seed) { 62 prng.srand(seed); 63 } 64 65 const char *newName() { 66 return metaNames[prng.rand() % array_lengthof(metaNames)]; 67 } 68 69 PRNG prng; 70 }; 71 72 struct MetaRenamer : public ModulePass { 73 // Pass identification, replacement for typeid 74 static char ID; 75 76 MetaRenamer() : ModulePass(ID) { 77 initializeMetaRenamerPass(*PassRegistry::getPassRegistry()); 78 } 79 80 void getAnalysisUsage(AnalysisUsage &AU) const override { 81 AU.addRequired<TargetLibraryInfoWrapperPass>(); 82 AU.setPreservesAll(); 83 } 84 85 bool runOnModule(Module &M) override { 86 // Seed our PRNG with simple additive sum of ModuleID. We're looking to 87 // simply avoid always having the same function names, and we need to 88 // remain deterministic. 89 unsigned int randSeed = 0; 90 for (auto C : M.getModuleIdentifier()) 91 randSeed += C; 92 93 Renamer renamer(randSeed); 94 95 // Rename all aliases 96 for (auto AI = M.alias_begin(), AE = M.alias_end(); AI != AE; ++AI) { 97 StringRef Name = AI->getName(); 98 if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1)) 99 continue; 100 101 AI->setName("alias"); 102 } 103 104 // Rename all global variables 105 for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE; ++GI) { 106 StringRef Name = GI->getName(); 107 if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1)) 108 continue; 109 110 GI->setName("global"); 111 } 112 113 // Rename all struct types 114 TypeFinder StructTypes; 115 StructTypes.run(M, true); 116 for (StructType *STy : StructTypes) { 117 if (STy->isLiteral() || STy->getName().empty()) continue; 118 119 SmallString<128> NameStorage; 120 STy->setName((Twine("struct.") + 121 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 getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F).getLibFunc( 132 F, Tmp)) 133 continue; 134 135 // Leave @main alone. The output of -metarenamer might be passed to 136 // lli for execution and the latter needs a main entry point. 137 if (Name != "main") 138 F.setName(renamer.newName()); 139 140 runOnFunction(F); 141 } 142 return true; 143 } 144 145 bool runOnFunction(Function &F) { 146 for (auto AI = F.arg_begin(), AE = F.arg_end(); AI != AE; ++AI) 147 if (!AI->getType()->isVoidTy()) 148 AI->setName("arg"); 149 150 for (auto &BB : F) { 151 BB.setName("bb"); 152 153 for (auto &I : BB) 154 if (!I.getType()->isVoidTy()) 155 I.setName("tmp"); 156 } 157 return true; 158 } 159 }; 160 161 } // end anonymous namespace 162 163 char MetaRenamer::ID = 0; 164 165 INITIALIZE_PASS_BEGIN(MetaRenamer, "metarenamer", 166 "Assign new names to everything", false, false) 167 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 168 INITIALIZE_PASS_END(MetaRenamer, "metarenamer", 169 "Assign new names to everything", false, false) 170 171 //===----------------------------------------------------------------------===// 172 // 173 // MetaRenamer - Rename everything with metasyntactic names. 174 // 175 ModulePass *llvm::createMetaRenamerPass() { 176 return new MetaRenamer(); 177 } 178