LLVM  6.0.0svn
MetaRenamer.cpp
Go to the documentation of this file.
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/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/Twine.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/Type.h"
30 #include "llvm/IR/TypeFinder.h"
31 #include "llvm/Pass.h"
32 #include "llvm/Transforms/IPO.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) {
78  }
79 
80  void getAnalysisUsage(AnalysisUsage &AU) const override {
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  const TargetLibraryInfo &TLI =
126  getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
127  for (auto &F : M) {
128  StringRef Name = F.getName();
129  LibFunc Tmp;
130  // Leave library functions alone because their presence or absence could
131  // affect the behavior of other passes.
132  if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) ||
133  TLI.getLibFunc(F, Tmp))
134  continue;
135 
136  // Leave @main alone. The output of -metarenamer might be passed to
137  // lli for execution and the latter needs a main entry point.
138  if (Name != "main")
139  F.setName(renamer.newName());
140 
141  runOnFunction(F);
142  }
143  return true;
144  }
145 
146  bool runOnFunction(Function &F) {
147  for (auto AI = F.arg_begin(), AE = F.arg_end(); AI != AE; ++AI)
148  if (!AI->getType()->isVoidTy())
149  AI->setName("arg");
150 
151  for (auto &BB : F) {
152  BB.setName("bb");
153 
154  for (auto &I : BB)
155  if (!I.getType()->isVoidTy())
156  I.setName("tmp");
157  }
158  return true;
159  }
160  };
161 
162 } // end anonymous namespace
163 
164 char MetaRenamer::ID = 0;
165 
166 INITIALIZE_PASS_BEGIN(MetaRenamer, "metarenamer",
167  "Assign new names to everything", false, false)
170  "Assign new names to everything", false, false)
171 
172 //===----------------------------------------------------------------------===//
173 //
174 // MetaRenamer - Rename everything with metasyntactic names.
175 //
177  return new MetaRenamer();
178 }
uint64_t CallInst * C
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:63
arg_iterator arg_end()
Definition: Function.h:612
F(f)
static const char *const metaNames[]
Definition: MetaRenamer.cpp:36
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:51
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
Class to represent struct types.
Definition: DerivedTypes.h:201
global_iterator global_begin()
Definition: Module.h:555
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:267
ModulePass * createMetaRenamerPass()
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
static bool runOnFunction(Function &F, bool PostInlining)
alias_iterator alias_end()
Definition: Module.h:596
Represent the analysis usage information of a pass.
arg_iterator arg_begin()
Definition: Function.h:603
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
Definition: StringExtras.h:43
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition: Module.h:208
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
global_iterator global_end()
Definition: Module.h:557
void run(const Module &M, bool onlyNamed)
Definition: TypeFinder.cpp:32
Module.h This file contains the declarations for the Module class.
Provides information about what library functions are available for the current target.
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:720
alias_iterator alias_begin()
Definition: Module.h:594
void setPreservesAll()
Set by analyses that do not transform their input at all.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
#define I(x, y, z)
Definition: MD5.cpp:58
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:225
Assign new names to everything
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
void initializeMetaRenamerPass(PassRegistry &)
INITIALIZE_PASS_BEGIN(MetaRenamer, "metarenamer", "Assign new names to everything", false, false) INITIALIZE_PASS_END(MetaRenamer
TypeFinder - Walk over a module, identifying all of the types that are used by the module...
Definition: TypeFinder.h:31
metarenamer