//===- MetaRenamer.cpp - Rename everything with metasyntatic names --------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This pass renames everything with metasyntatic names. The intent is to use
// this pass after llvm-reduce reduction to conceal the nature of the original
// program.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/MetaRenamer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/TypeFinder.h"
#include "llvm/Support/CommandLine.h"

using namespace llvm;

static cl::opt<std::string> RenameExcludeFunctionPrefixes(
    "rename-exclude-function-prefixes",
    cl::desc("Prefixes for functions that don't need to be renamed, separated "
             "by a comma"),
    cl::Hidden);

static cl::opt<std::string> RenameExcludeAliasPrefixes(
    "rename-exclude-alias-prefixes",
    cl::desc("Prefixes for aliases that don't need to be renamed, separated "
             "by a comma"),
    cl::Hidden);

static cl::opt<std::string> RenameExcludeGlobalPrefixes(
    "rename-exclude-global-prefixes",
    cl::desc(
        "Prefixes for global values that don't need to be renamed, separated "
        "by a comma"),
    cl::Hidden);

static cl::opt<std::string> RenameExcludeStructPrefixes(
    "rename-exclude-struct-prefixes",
    cl::desc("Prefixes for structs that don't need to be renamed, separated "
             "by a comma"),
    cl::Hidden);

static cl::opt<bool>
    RenameOnlyInst("rename-only-inst", cl::init(false),
                   cl::desc("only rename the instructions in the function"),
                   cl::Hidden);

static const char *const metaNames[] = {
  // See http://en.wikipedia.org/wiki/Metasyntactic_variable
  "foo", "bar", "baz", "quux", "barney", "snork", "zot", "blam", "hoge",
  "wibble", "wobble", "widget", "wombat", "ham", "eggs", "pluto", "spam"
};

namespace {
// This PRNG is from the ISO C spec. It is intentionally simple and
// unsuitable for cryptographic use. We're just looking for enough
// variety to surprise and delight users.
struct PRNG {
  unsigned long next;

  void srand(unsigned int seed) { next = seed; }

  int rand() {
    next = next * 1103515245 + 12345;
    return (unsigned int)(next / 65536) % 32768;
  }
};

struct Renamer {
  Renamer(unsigned int seed) { prng.srand(seed); }

  const char *newName() {
    return metaNames[prng.rand() % std::size(metaNames)];
  }

  PRNG prng;
};

static void
parseExcludedPrefixes(StringRef PrefixesStr,
                      SmallVectorImpl<StringRef> &ExcludedPrefixes) {
  for (;;) {
    auto PrefixesSplit = PrefixesStr.split(',');
    if (PrefixesSplit.first.empty())
      break;
    ExcludedPrefixes.push_back(PrefixesSplit.first);
    PrefixesStr = PrefixesSplit.second;
  }
}

void MetaRenameOnlyInstructions(Function &F) {
  for (auto &I : instructions(F))
    if (!I.getType()->isVoidTy() && I.getName().empty())
      I.setName(I.getOpcodeName());
}

void MetaRename(Function &F) {
  for (Argument &Arg : F.args())
    if (!Arg.getType()->isVoidTy())
      Arg.setName("arg");

  for (auto &BB : F) {
    BB.setName("bbl");

    for (auto &I : BB)
      if (!I.getType()->isVoidTy())
        I.setName(I.getOpcodeName());
  }
}

void MetaRename(Module &M,
                function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
  // Seed our PRNG with simple additive sum of ModuleID. We're looking to
  // simply avoid always having the same function names, and we need to
  // remain deterministic.
  unsigned int randSeed = 0;
  for (auto C : M.getModuleIdentifier())
    randSeed += C;

  Renamer renamer(randSeed);

  SmallVector<StringRef, 8> ExcludedAliasesPrefixes;
  SmallVector<StringRef, 8> ExcludedGlobalsPrefixes;
  SmallVector<StringRef, 8> ExcludedStructsPrefixes;
  SmallVector<StringRef, 8> ExcludedFuncPrefixes;
  parseExcludedPrefixes(RenameExcludeAliasPrefixes, ExcludedAliasesPrefixes);
  parseExcludedPrefixes(RenameExcludeGlobalPrefixes, ExcludedGlobalsPrefixes);
  parseExcludedPrefixes(RenameExcludeStructPrefixes, ExcludedStructsPrefixes);
  parseExcludedPrefixes(RenameExcludeFunctionPrefixes, ExcludedFuncPrefixes);

  auto IsNameExcluded = [](StringRef &Name,
                           SmallVectorImpl<StringRef> &ExcludedPrefixes) {
    return any_of(ExcludedPrefixes,
                  [&Name](auto &Prefix) { return Name.starts_with(Prefix); });
  };

  // Leave library functions alone because their presence or absence could
  // affect the behavior of other passes.
  auto ExcludeLibFuncs = [&](Function &F) {
    StringRef Name = F.getName();
    return F.isIntrinsic() || (!Name.empty() && Name[0] == 1) ||
           GetTLI(F).getLibFunc(F) != NotLibFunc ||
           IsNameExcluded(Name, ExcludedFuncPrefixes);
  };

  if (RenameOnlyInst) {
    // Rename all functions
    for (auto &F : M) {
      if (ExcludeLibFuncs(F))
        continue;
      MetaRenameOnlyInstructions(F);
    }
    return;
  }

  // Rename all aliases
  for (GlobalAlias &GA : M.aliases()) {
    StringRef Name = GA.getName();
    if (Name.starts_with("llvm.") || (!Name.empty() && Name[0] == 1) ||
        IsNameExcluded(Name, ExcludedAliasesPrefixes))
      continue;

    GA.setName("alias");
  }

  // Rename all global variables
  for (GlobalVariable &GV : M.globals()) {
    StringRef Name = GV.getName();
    if (Name.starts_with("llvm.") || (!Name.empty() && Name[0] == 1) ||
        IsNameExcluded(Name, ExcludedGlobalsPrefixes))
      continue;

    GV.setName("global");
  }

  // Rename all struct types
  TypeFinder StructTypes;
  StructTypes.run(M, true);
  for (StructType *STy : StructTypes) {
    StringRef Name = STy->getName();
    if (STy->isLiteral() || Name.empty() ||
        IsNameExcluded(Name, ExcludedStructsPrefixes))
      continue;

    SmallString<128> NameStorage;
    STy->setName(
        (Twine("struct.") + renamer.newName()).toStringRef(NameStorage));
  }

  // Rename all functions
  for (auto &F : M) {
    if (ExcludeLibFuncs(F))
      continue;

    // Leave @main alone. The output of -metarenamer might be passed to
    // lli for execution and the latter needs a main entry point.
    if (F.getName() != "main")
      F.setName(renamer.newName());

    MetaRename(F);
  }
}

} // end anonymous namespace

PreservedAnalyses MetaRenamerPass::run(Module &M, ModuleAnalysisManager &AM) {
  FunctionAnalysisManager &FAM =
      AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
  auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
    return FAM.getResult<TargetLibraryAnalysis>(F);
  };
  MetaRename(M, GetTLI);

  return PreservedAnalyses::all();
}
