LLVM  10.0.0svn
MetaRenamer.cpp
Go to the documentation of this file.
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"
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/Pass.h"
31 #include "llvm/Transforms/Utils.h"
32 
33 using namespace llvm;
34 
35 static const char *const metaNames[] = {
36  // See http://en.wikipedia.org/wiki/Metasyntactic_variable
37  "foo", "bar", "baz", "quux", "barney", "snork", "zot", "blam", "hoge",
38  "wibble", "wobble", "widget", "wombat", "ham", "eggs", "pluto", "spam"
39 };
40 
41 namespace {
42 
43  // This PRNG is from the ISO C spec. It is intentionally simple and
44  // unsuitable for cryptographic use. We're just looking for enough
45  // variety to surprise and delight users.
46  struct PRNG {
47  unsigned long next;
48 
49  void srand(unsigned int seed) {
50  next = seed;
51  }
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) {
61  prng.srand(seed);
62  }
63 
64  const char *newName() {
65  return metaNames[prng.rand() % array_lengthof(metaNames)];
66  }
67 
68  PRNG prng;
69  };
70 
71  struct MetaRenamer : public ModulePass {
72  // Pass identification, replacement for typeid
73  static char ID;
74 
75  MetaRenamer() : ModulePass(ID) {
77  }
78 
79  void getAnalysisUsage(AnalysisUsage &AU) const override {
81  AU.setPreservesAll();
82  }
83 
84  bool runOnModule(Module &M) override {
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 (auto GI = M.global_begin(), GE = M.global_end(); GI != GE; ++GI) {
105  StringRef Name = GI->getName();
106  if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1))
107  continue;
108 
109  GI->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()) continue;
117 
118  SmallString<128> NameStorage;
119  STy->setName((Twine("struct.") +
120  renamer.newName()).toStringRef(NameStorage));
121  }
122 
123  // Rename all functions
124  for (auto &F : M) {
125  StringRef Name = F.getName();
126  LibFunc Tmp;
127  // Leave library functions alone because their presence or absence could
128  // affect the behavior of other passes.
129  if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) ||
130  getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F).getLibFunc(
131  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  runOnFunction(F);
140  }
141  return true;
142  }
143 
144  bool runOnFunction(Function &F) {
145  for (auto AI = F.arg_begin(), AE = F.arg_end(); AI != AE; ++AI)
146  if (!AI->getType()->isVoidTy())
147  AI->setName("arg");
148 
149  for (auto &BB : F) {
150  BB.setName("bb");
151 
152  for (auto &I : BB)
153  if (!I.getType()->isVoidTy())
154  I.setName("tmp");
155  }
156  return true;
157  }
158  };
159 
160 } // end anonymous namespace
161 
162 char MetaRenamer::ID = 0;
163 
164 INITIALIZE_PASS_BEGIN(MetaRenamer, "metarenamer",
165  "Assign new names to everything", false, false)
168  "Assign new names to everything", false, false)
169 
170 //===----------------------------------------------------------------------===//
171 //
172 // MetaRenamer - Rename everything with metasyntactic names.
173 //
175  return new MetaRenamer();
176 }
uint64_t CallInst * C
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
Definition: AllocatorList.h:23
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:270
arg_iterator arg_end()
Definition: Function.h:704
F(f)
static const char *const metaNames[]
Definition: MetaRenamer.cpp:35
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:50
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
Class to represent struct types.
Definition: DerivedTypes.h:233
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:140
global_iterator global_begin()
Definition: Module.h:581
ModulePass * createMetaRenamerPass()
static bool runOnFunction(Function &F, bool PostInlining)
alias_iterator alias_end()
Definition: Module.h:622
Represent the analysis usage information of a pass.
arg_iterator arg_begin()
Definition: Function.h:695
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
Definition: StringExtras.h:52
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition: Module.h:210
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
global_iterator global_end()
Definition: Module.h:583
void run(const Module &M, bool onlyNamed)
Definition: TypeFinder.cpp:31
Module.h This file contains the declarations for the Module class.
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:1023
alias_iterator alias_begin()
Definition: Module.h:620
void setPreservesAll()
Set by analyses that do not transform their input at all.
#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:224
Assign new names to everything
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
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:30
metarenamer