LLVM  11.0.0git
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/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) {
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  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)
169  "Assign new names to everything", false, false)
170 
171 //===----------------------------------------------------------------------===//
172 //
173 // MetaRenamer - Rename everything with metasyntactic names.
174 //
176  return new MetaRenamer();
177 }
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:67
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:289
arg_iterator arg_end()
Definition: Function.h:729
F(f)
static const char *const metaNames[]
Definition: MetaRenamer.cpp:36
AnalysisUsage & addRequired()
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:218
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:156
global_iterator global_begin()
Definition: Module.h:592
ModulePass * createMetaRenamerPass()
static bool runOnFunction(Function &F, bool PostInlining)
alias_iterator alias_end()
Definition: Module.h:634
Represent the analysis usage information of a pass.
arg_iterator arg_begin()
Definition: Function.h:720
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:219
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
global_iterator global_end()
Definition: Module.h:594
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:1335
alias_iterator alias_begin()
Definition: Module.h:632
void setPreservesAll()
Set by analyses that do not transform their input at all.
#define I(x, y, z)
Definition: MD5.cpp:59
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:224
unique internal linkage names
Assign new names to everything
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
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
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)