Home | History | Annotate | Download | only in Utils
      1 //===- MetaRenamer.cpp - Rename everything with metasyntatic names --------===//
      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 // This pass renames everything with metasyntatic names. The intent is to use
     11 // this pass after bugpoint reduction to conceal the nature of the original
     12 // program.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "llvm/Transforms/IPO.h"
     17 #include "llvm/ADT/STLExtras.h"
     18 #include "llvm/ADT/SmallString.h"
     19 #include "llvm/IR/DerivedTypes.h"
     20 #include "llvm/IR/Function.h"
     21 #include "llvm/IR/Module.h"
     22 #include "llvm/IR/Type.h"
     23 #include "llvm/IR/TypeFinder.h"
     24 #include "llvm/Pass.h"
     25 using namespace llvm;
     26 
     27 namespace {
     28 
     29   // This PRNG is from the ISO C spec. It is intentionally simple and
     30   // unsuitable for cryptographic use. We're just looking for enough
     31   // variety to surprise and delight users.
     32   struct PRNG {
     33     unsigned long next;
     34 
     35     void srand(unsigned int seed) {
     36       next = seed;
     37     }
     38 
     39     int rand() {
     40       next = next * 1103515245 + 12345;
     41       return (unsigned int)(next / 65536) % 32768;
     42     }
     43   };
     44 
     45   static const char *const metaNames[] = {
     46     // See http://en.wikipedia.org/wiki/Metasyntactic_variable
     47     "foo", "bar", "baz", "quux", "barney", "snork", "zot", "blam", "hoge",
     48     "wibble", "wobble", "widget", "wombat", "ham", "eggs", "pluto", "spam"
     49   };
     50 
     51   struct Renamer {
     52     Renamer(unsigned int seed) {
     53       prng.srand(seed);
     54     }
     55 
     56     const char *newName() {
     57       return metaNames[prng.rand() % array_lengthof(metaNames)];
     58     }
     59 
     60     PRNG prng;
     61   };
     62 
     63   struct MetaRenamer : public ModulePass {
     64     static char ID; // Pass identification, replacement for typeid
     65     MetaRenamer() : ModulePass(ID) {
     66       initializeMetaRenamerPass(*PassRegistry::getPassRegistry());
     67     }
     68 
     69     void getAnalysisUsage(AnalysisUsage &AU) const override {
     70       AU.setPreservesAll();
     71     }
     72 
     73     bool runOnModule(Module &M) override {
     74       // Seed our PRNG with simple additive sum of ModuleID. We're looking to
     75       // simply avoid always having the same function names, and we need to
     76       // remain deterministic.
     77       unsigned int randSeed = 0;
     78       for (auto C : M.getModuleIdentifier())
     79         randSeed += C;
     80 
     81       Renamer renamer(randSeed);
     82 
     83       // Rename all aliases
     84       for (auto AI = M.alias_begin(), AE = M.alias_end(); AI != AE; ++AI) {
     85         StringRef Name = AI->getName();
     86         if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1))
     87           continue;
     88 
     89         AI->setName("alias");
     90       }
     91 
     92       // Rename all global variables
     93       for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE; ++GI) {
     94         StringRef Name = GI->getName();
     95         if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1))
     96           continue;
     97 
     98         GI->setName("global");
     99       }
    100 
    101       // Rename all struct types
    102       TypeFinder StructTypes;
    103       StructTypes.run(M, true);
    104       for (StructType *STy : StructTypes) {
    105         if (STy->isLiteral() || STy->getName().empty()) continue;
    106 
    107         SmallString<128> NameStorage;
    108         STy->setName((Twine("struct.") +
    109           renamer.newName()).toStringRef(NameStorage));
    110       }
    111 
    112       // Rename all functions
    113       for (auto &F : M) {
    114         StringRef Name = F.getName();
    115         if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1))
    116           continue;
    117 
    118         F.setName(renamer.newName());
    119         runOnFunction(F);
    120       }
    121       return true;
    122     }
    123 
    124     bool runOnFunction(Function &F) {
    125       for (auto AI = F.arg_begin(), AE = F.arg_end(); AI != AE; ++AI)
    126         if (!AI->getType()->isVoidTy())
    127           AI->setName("arg");
    128 
    129       for (auto &BB : F) {
    130         BB.setName("bb");
    131 
    132         for (auto &I : BB)
    133           if (!I.getType()->isVoidTy())
    134             I.setName("tmp");
    135       }
    136       return true;
    137     }
    138   };
    139 }
    140 
    141 char MetaRenamer::ID = 0;
    142 INITIALIZE_PASS(MetaRenamer, "metarenamer",
    143                 "Assign new names to everything", false, false)
    144 //===----------------------------------------------------------------------===//
    145 //
    146 // MetaRenamer - Rename everything with metasyntactic names.
    147 //
    148 ModulePass *llvm::createMetaRenamerPass() {
    149   return new MetaRenamer();
    150 }
    151