MetaRenamer.cpp revision 360784
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
34using namespace llvm;
35
36static 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
42namespace {
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
163char MetaRenamer::ID = 0;
164
165INITIALIZE_PASS_BEGIN(MetaRenamer, "metarenamer",
166                      "Assign new names to everything", false, false)
167INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
168INITIALIZE_PASS_END(MetaRenamer, "metarenamer",
169                    "Assign new names to everything", false, false)
170
171//===----------------------------------------------------------------------===//
172//
173// MetaRenamer - Rename everything with metasyntactic names.
174//
175ModulePass *llvm::createMetaRenamerPass() {
176  return new MetaRenamer();
177}
178