//===- InstrOrderFile.cpp ---- Late IR instrumentation for order file ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/Statistic.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/PassRegistry.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Instrumentation/InstrOrderFile.h"
#include <fstream>
#include <map>
#include <mutex>
#include <set>
#include <sstream>

using namespace llvm;
#define DEBUG_TYPE "instrorderfile"

static cl::opt<std::string> ClOrderFileWriteMapping(
    "orderfile-write-mapping", cl::init(""),
    cl::desc(
        "Dump functions and their MD5 hash to deobfuscate profile data"),
    cl::Hidden);

namespace {

// We need a global bitmap to tell if a function is executed. We also
// need a global variable to save the order of functions. We can use a
// fixed-size buffer that saves the MD5 hash of the function. We need
// a global variable to save the index into the buffer.

std::mutex MappingMutex;

struct InstrOrderFile {
private:
  GlobalVariable *OrderFileBuffer;
  GlobalVariable *BufferIdx;
  GlobalVariable *BitMap;
  ArrayType *BufferTy;
  ArrayType *MapTy;

public:
  InstrOrderFile() {}

  void createOrderFileData(Module &M) {
    LLVMContext &Ctx = M.getContext();
    int NumFunctions = 0;
    for (Function &F : M) {
      if (!F.isDeclaration())
        NumFunctions++;
    }

    BufferTy =
        ArrayType::get(Type::getInt64Ty(Ctx), INSTR_ORDER_FILE_BUFFER_SIZE);
    Type *IdxTy = Type::getInt32Ty(Ctx);
    MapTy = ArrayType::get(Type::getInt8Ty(Ctx), NumFunctions);

    // Create the global variables.
    std::string SymbolName = INSTR_PROF_ORDERFILE_BUFFER_NAME_STR;
    OrderFileBuffer = new GlobalVariable(M, BufferTy, false, GlobalValue::LinkOnceODRLinkage,
                           Constant::getNullValue(BufferTy), SymbolName);
    Triple TT = Triple(M.getTargetTriple());
    OrderFileBuffer->setSection(
        getInstrProfSectionName(IPSK_orderfile, TT.getObjectFormat()));

    std::string IndexName = INSTR_PROF_ORDERFILE_BUFFER_IDX_NAME_STR;
    BufferIdx = new GlobalVariable(M, IdxTy, false, GlobalValue::LinkOnceODRLinkage,
                           Constant::getNullValue(IdxTy), IndexName);

    std::string BitMapName = "bitmap_0";
    BitMap = new GlobalVariable(M, MapTy, false, GlobalValue::PrivateLinkage,
                                Constant::getNullValue(MapTy), BitMapName);
  }

  // Generate the code sequence in the entry block of each function to
  // update the buffer.
  void generateCodeSequence(Module &M, Function &F, int FuncId) {
    if (!ClOrderFileWriteMapping.empty()) {
      std::lock_guard<std::mutex> LogLock(MappingMutex);
      std::error_code EC;
      llvm::raw_fd_ostream OS(ClOrderFileWriteMapping, EC,
                              llvm::sys::fs::OF_Append);
      if (EC) {
        report_fatal_error(Twine("Failed to open ") + ClOrderFileWriteMapping +
                           " to save mapping file for order file instrumentation\n");
      } else {
        std::stringstream stream;
        stream << std::hex << MD5Hash(F.getName());
        std::string singleLine = "MD5 " + stream.str() + " " +
                                 std::string(F.getName()) + '\n';
        OS << singleLine;
      }
    }

    BasicBlock *OrigEntry = &F.getEntryBlock();

    LLVMContext &Ctx = M.getContext();
    IntegerType *Int32Ty = Type::getInt32Ty(Ctx);
    IntegerType *Int8Ty = Type::getInt8Ty(Ctx);

    // Create a new entry block for instrumentation. We will check the bitmap
    // in this basic block.
    BasicBlock *NewEntry =
        BasicBlock::Create(M.getContext(), "order_file_entry", &F, OrigEntry);
    IRBuilder<> entryB(NewEntry);
    // Create a basic block for updating the circular buffer.
    BasicBlock *UpdateOrderFileBB =
        BasicBlock::Create(M.getContext(), "order_file_set", &F, OrigEntry);
    IRBuilder<> updateB(UpdateOrderFileBB);

    // Check the bitmap, if it is already 1, do nothing.
    // Otherwise, set the bit, grab the index, update the buffer.
    Value *IdxFlags[] = {ConstantInt::get(Int32Ty, 0),
                         ConstantInt::get(Int32Ty, FuncId)};
    Value *MapAddr = entryB.CreateGEP(MapTy, BitMap, IdxFlags, "");
    LoadInst *loadBitMap = entryB.CreateLoad(Int8Ty, MapAddr, "");
    entryB.CreateStore(ConstantInt::get(Int8Ty, 1), MapAddr);
    Value *IsNotExecuted =
        entryB.CreateICmpEQ(loadBitMap, ConstantInt::get(Int8Ty, 0));
    entryB.CreateCondBr(IsNotExecuted, UpdateOrderFileBB, OrigEntry);

    // Fill up UpdateOrderFileBB: grab the index, update the buffer!
    Value *IdxVal = updateB.CreateAtomicRMW(
        AtomicRMWInst::Add, BufferIdx, ConstantInt::get(Int32Ty, 1),
        AtomicOrdering::SequentiallyConsistent);
    // We need to wrap around the index to fit it inside the buffer.
    Value *WrappedIdx = updateB.CreateAnd(
        IdxVal, ConstantInt::get(Int32Ty, INSTR_ORDER_FILE_BUFFER_MASK));
    Value *BufferGEPIdx[] = {ConstantInt::get(Int32Ty, 0), WrappedIdx};
    Value *BufferAddr =
        updateB.CreateGEP(BufferTy, OrderFileBuffer, BufferGEPIdx, "");
    updateB.CreateStore(ConstantInt::get(Type::getInt64Ty(Ctx), MD5Hash(F.getName())),
                        BufferAddr);
    updateB.CreateBr(OrigEntry);
  }

  bool run(Module &M) {
    createOrderFileData(M);

    int FuncId = 0;
    for (Function &F : M) {
      if (F.isDeclaration())
        continue;
      generateCodeSequence(M, F, FuncId);
      ++FuncId;
    }

    return true;
  }

}; // End of InstrOrderFile struct

class InstrOrderFileLegacyPass : public ModulePass {
public:
  static char ID;

  InstrOrderFileLegacyPass() : ModulePass(ID) {
    initializeInstrOrderFileLegacyPassPass(
        *PassRegistry::getPassRegistry());
  }

  bool runOnModule(Module &M) override;
};

} // End anonymous namespace

bool InstrOrderFileLegacyPass::runOnModule(Module &M) {
  if (skipModule(M))
    return false;

  return InstrOrderFile().run(M);
}

PreservedAnalyses
InstrOrderFilePass::run(Module &M, ModuleAnalysisManager &AM) {
  if (InstrOrderFile().run(M))
    return PreservedAnalyses::none();
  return PreservedAnalyses::all();
}

INITIALIZE_PASS_BEGIN(InstrOrderFileLegacyPass, "instrorderfile",
                      "Instrumentation for Order File", false, false)
INITIALIZE_PASS_END(InstrOrderFileLegacyPass, "instrorderfile",
                    "Instrumentation for Order File", false, false)

char InstrOrderFileLegacyPass::ID = 0;

ModulePass *llvm::createInstrOrderFilePass() {
  return new InstrOrderFileLegacyPass();
}
