//===- subzero/src/IceASanInstrumentation.cpp - ASan ------------*- C++ -*-===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Implements the AddressSanitizer instrumentation class.
///
//===----------------------------------------------------------------------===//

#include "IceASanInstrumentation.h"

#include "IceBuildDefs.h"
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceGlobalInits.h"
#include "IceInst.h"
#include "IceTargetLowering.h"
#include "IceTypes.h"

#include <sstream>
#include <unordered_map>
#include <unordered_set>
#include <vector>

namespace Ice {

namespace {

constexpr SizeT BytesPerWord = sizeof(uint32_t);
constexpr SizeT RzSize = 32;
constexpr SizeT ShadowScaleLog2 = 3;
constexpr SizeT ShadowScale = 1 << ShadowScaleLog2;
constexpr SizeT ShadowLength32 = 1 << (32 - ShadowScaleLog2);
constexpr int32_t StackPoisonVal = -1;
constexpr const char *ASanPrefix = "__asan";
constexpr const char *RzPrefix = "__$rz";
constexpr const char *RzArrayName = "__$rz_array";
constexpr const char *RzSizesName = "__$rz_sizes";
const llvm::NaClBitcodeRecord::RecordVector RzContents =
    llvm::NaClBitcodeRecord::RecordVector(RzSize, 'R');

// In order to instrument the code correctly, the .pexe must not have had its
// symbols stripped.
using StringMap = std::unordered_map<std::string, std::string>;
using StringSet = std::unordered_set<std::string>;
// TODO(tlively): Handle all allocation functions
const StringMap FuncSubstitutions = {{"malloc", "__asan_malloc"},
                                     {"free", "__asan_free"},
                                     {"calloc", "__asan_calloc"},
                                     {"__asan_dummy_calloc", "__asan_calloc"},
                                     {"realloc", "__asan_realloc"}};
const StringSet FuncIgnoreList = {"_Balloc"};

llvm::NaClBitcodeRecord::RecordVector sizeToByteVec(SizeT Size) {
  llvm::NaClBitcodeRecord::RecordVector SizeContents;
  for (unsigned i = 0; i < sizeof(Size); ++i) {
    SizeContents.emplace_back(Size % (1 << CHAR_BIT));
    Size >>= CHAR_BIT;
  }
  return SizeContents;
}

} // end of anonymous namespace

ICE_TLS_DEFINE_FIELD(VarSizeMap *, ASanInstrumentation, LocalVars);
ICE_TLS_DEFINE_FIELD(std::vector<InstStore *> *, ASanInstrumentation,
                     LocalDtors);
ICE_TLS_DEFINE_FIELD(CfgNode *, ASanInstrumentation, CurNode);
ICE_TLS_DEFINE_FIELD(VarSizeMap *, ASanInstrumentation, CheckedVars);

bool ASanInstrumentation::isInstrumentable(Cfg *Func) {
  std::string FuncName = Func->getFunctionName().toStringOrEmpty();
  return FuncName == "" || (FuncIgnoreList.count(FuncName) == 0 &&
                            FuncName.find(ASanPrefix) != 0);
}

// Create redzones around all global variables, ensuring that the initializer
// types of the redzones and their associated globals match so that they are
// laid out together in memory.
void ASanInstrumentation::instrumentGlobals(VariableDeclarationList &Globals) {
  std::unique_lock<std::mutex> _(GlobalsMutex);
  if (DidProcessGlobals)
    return;
  VariableDeclarationList NewGlobals;
  // Global holding pointers to all redzones
  auto *RzArray = VariableDeclaration::create(&NewGlobals);
  // Global holding sizes of all redzones
  auto *RzSizes = VariableDeclaration::create(&NewGlobals);

  RzArray->setName(Ctx, RzArrayName);
  RzSizes->setName(Ctx, RzSizesName);
  RzArray->setIsConstant(true);
  RzSizes->setIsConstant(true);
  NewGlobals.push_back(RzArray);
  NewGlobals.push_back(RzSizes);

  using PrototypeMap = std::unordered_map<std::string, FunctionDeclaration *>;
  PrototypeMap ProtoSubstitutions;
  for (VariableDeclaration *Global : Globals) {
    assert(Global->getAlignment() <= RzSize);
    VariableDeclaration *RzLeft = VariableDeclaration::create(&NewGlobals);
    VariableDeclaration *NewGlobal = Global;
    VariableDeclaration *RzRight = VariableDeclaration::create(&NewGlobals);
    RzLeft->setName(Ctx, nextRzName());
    RzRight->setName(Ctx, nextRzName());
    SizeT Alignment = std::max(RzSize, Global->getAlignment());
    SizeT RzLeftSize = Alignment;
    SizeT RzRightSize =
        RzSize + Utils::OffsetToAlignment(Global->getNumBytes(), Alignment);
    if (!Global->hasNonzeroInitializer()) {
      RzLeft->addInitializer(VariableDeclaration::ZeroInitializer::create(
          &NewGlobals, RzLeftSize));
      RzRight->addInitializer(VariableDeclaration::ZeroInitializer::create(
          &NewGlobals, RzRightSize));
    } else {
      RzLeft->addInitializer(VariableDeclaration::DataInitializer::create(
          &NewGlobals, llvm::NaClBitcodeRecord::RecordVector(RzLeftSize, 'R')));
      RzRight->addInitializer(VariableDeclaration::DataInitializer::create(
          &NewGlobals,
          llvm::NaClBitcodeRecord::RecordVector(RzRightSize, 'R')));

      // replace any pointers to allocator functions
      NewGlobal = VariableDeclaration::create(&NewGlobals);
      NewGlobal->setName(Global->getName());
      std::vector<VariableDeclaration::Initializer *> GlobalInits =
          Global->getInitializers();
      for (VariableDeclaration::Initializer *Init : GlobalInits) {
        auto *RelocInit =
            llvm::dyn_cast<VariableDeclaration::RelocInitializer>(Init);
        if (RelocInit == nullptr) {
          NewGlobal->addInitializer(Init);
          continue;
        }
        const GlobalDeclaration *TargetDecl = RelocInit->getDeclaration();
        const auto *TargetFunc =
            llvm::dyn_cast<FunctionDeclaration>(TargetDecl);
        if (TargetFunc == nullptr) {
          NewGlobal->addInitializer(Init);
          continue;
        }
        std::string TargetName = TargetDecl->getName().toStringOrEmpty();
        StringMap::const_iterator Subst = FuncSubstitutions.find(TargetName);
        if (Subst == FuncSubstitutions.end()) {
          NewGlobal->addInitializer(Init);
          continue;
        }
        std::string SubstName = Subst->second;
        PrototypeMap::iterator SubstProtoEntry =
            ProtoSubstitutions.find(SubstName);
        FunctionDeclaration *SubstProto;
        if (SubstProtoEntry != ProtoSubstitutions.end())
          SubstProto = SubstProtoEntry->second;
        else {
          constexpr bool IsProto = true;
          SubstProto = FunctionDeclaration::create(
              Ctx, TargetFunc->getSignature(), TargetFunc->getCallingConv(),
              llvm::GlobalValue::ExternalLinkage, IsProto);
          SubstProto->setName(Ctx, SubstName);
          ProtoSubstitutions.insert({SubstName, SubstProto});
        }

        NewGlobal->addInitializer(VariableDeclaration::RelocInitializer::create(
            &NewGlobals, SubstProto, RelocOffsetArray(0)));
      }
    }

    RzLeft->setIsConstant(Global->getIsConstant());
    NewGlobal->setIsConstant(Global->getIsConstant());
    RzRight->setIsConstant(Global->getIsConstant());
    RzLeft->setAlignment(Alignment);
    NewGlobal->setAlignment(Alignment);
    RzRight->setAlignment(1);
    RzArray->addInitializer(VariableDeclaration::RelocInitializer::create(
        &NewGlobals, RzLeft, RelocOffsetArray(0)));
    RzArray->addInitializer(VariableDeclaration::RelocInitializer::create(
        &NewGlobals, RzRight, RelocOffsetArray(0)));
    RzSizes->addInitializer(VariableDeclaration::DataInitializer::create(
        &NewGlobals, sizeToByteVec(RzLeftSize)));
    RzSizes->addInitializer(VariableDeclaration::DataInitializer::create(
        &NewGlobals, sizeToByteVec(RzRightSize)));

    NewGlobals.push_back(RzLeft);
    NewGlobals.push_back(NewGlobal);
    NewGlobals.push_back(RzRight);
    RzGlobalsNum += 2;

    GlobalSizes.insert({NewGlobal->getName(), NewGlobal->getNumBytes()});
  }

  // Replace old list of globals, without messing up arena allocators
  Globals.clear();
  Globals.merge(&NewGlobals);
  DidProcessGlobals = true;

  // Log the new set of globals
  if (BuildDefs::dump() && (getFlags().getVerbose() & IceV_GlobalInit)) {
    OstreamLocker _(Ctx);
    Ctx->getStrDump() << "========= Instrumented Globals =========\n";
    for (VariableDeclaration *Global : Globals) {
      Global->dump(Ctx->getStrDump());
    }
  }
}

std::string ASanInstrumentation::nextRzName() {
  std::stringstream Name;
  Name << RzPrefix << RzNum++;
  return Name.str();
}

// Check for an alloca signaling the presence of local variables and add a
// redzone if it is found
void ASanInstrumentation::instrumentFuncStart(LoweringContext &Context) {
  if (ICE_TLS_GET_FIELD(LocalDtors) == nullptr) {
    ICE_TLS_SET_FIELD(LocalDtors, new std::vector<InstStore *>());
    ICE_TLS_SET_FIELD(LocalVars, new VarSizeMap());
  }
  Cfg *Func = Context.getNode()->getCfg();
  using Entry = std::pair<SizeT, int32_t>;
  std::vector<InstAlloca *> NewAllocas;
  std::vector<Entry> PoisonVals;
  Variable *FirstShadowLocVar;
  InstArithmetic *ShadowIndexCalc;
  InstArithmetic *ShadowLocCalc;
  InstAlloca *Cur;
  ConstantInteger32 *VarSizeOp;
  while (!Context.atEnd()) {
    Cur = llvm::dyn_cast<InstAlloca>(iteratorToInst(Context.getCur()));
    VarSizeOp = (Cur == nullptr)
                    ? nullptr
                    : llvm::dyn_cast<ConstantInteger32>(Cur->getSizeInBytes());
    if (Cur == nullptr || VarSizeOp == nullptr) {
      Context.advanceCur();
      Context.advanceNext();
      continue;
    }

    Cur->setDeleted();

    if (PoisonVals.empty()) {
      // insert leftmost redzone
      auto *LastRzVar = Func->makeVariable(IceType_i32);
      LastRzVar->setName(Func, nextRzName());
      auto *ByteCount = ConstantInteger32::create(Ctx, IceType_i32, RzSize);
      constexpr SizeT Alignment = 8;
      NewAllocas.emplace_back(
          InstAlloca::create(Func, LastRzVar, ByteCount, Alignment));
      PoisonVals.emplace_back(Entry{RzSize >> ShadowScaleLog2, StackPoisonVal});

      // Calculate starting address for poisoning
      FirstShadowLocVar = Func->makeVariable(IceType_i32);
      FirstShadowLocVar->setName(Func, "firstShadowLoc");
      auto *ShadowIndexVar = Func->makeVariable(IceType_i32);
      ShadowIndexVar->setName(Func, "shadowIndex");

      auto *ShadowScaleLog2Const =
          ConstantInteger32::create(Ctx, IceType_i32, ShadowScaleLog2);
      auto *ShadowMemLocConst =
          ConstantInteger32::create(Ctx, IceType_i32, ShadowLength32);

      ShadowIndexCalc =
          InstArithmetic::create(Func, InstArithmetic::Lshr, ShadowIndexVar,
                                 LastRzVar, ShadowScaleLog2Const);
      ShadowLocCalc =
          InstArithmetic::create(Func, InstArithmetic::Add, FirstShadowLocVar,
                                 ShadowIndexVar, ShadowMemLocConst);
    }

    // create the new alloca that includes a redzone
    SizeT VarSize = VarSizeOp->getValue();
    Variable *Dest = Cur->getDest();
    ICE_TLS_GET_FIELD(LocalVars)->insert({Dest, VarSize});
    SizeT RzPadding = RzSize + Utils::OffsetToAlignment(VarSize, RzSize);
    auto *ByteCount =
        ConstantInteger32::create(Ctx, IceType_i32, VarSize + RzPadding);
    constexpr SizeT Alignment = 8;
    NewAllocas.emplace_back(
        InstAlloca::create(Func, Dest, ByteCount, Alignment));

    const SizeT Zeros = VarSize >> ShadowScaleLog2;
    const SizeT Offset = VarSize % ShadowScale;
    const SizeT PoisonBytes =
        ((VarSize + RzPadding) >> ShadowScaleLog2) - Zeros - 1;
    if (Zeros > 0)
      PoisonVals.emplace_back(Entry{Zeros, 0});
    PoisonVals.emplace_back(Entry{1, (Offset == 0) ? StackPoisonVal : Offset});
    PoisonVals.emplace_back(Entry{PoisonBytes, StackPoisonVal});
    Context.advanceCur();
    Context.advanceNext();
  }

  Context.rewind();
  if (PoisonVals.empty()) {
    Context.advanceNext();
    return;
  }
  for (InstAlloca *RzAlloca : NewAllocas) {
    Context.insert(RzAlloca);
  }
  Context.insert(ShadowIndexCalc);
  Context.insert(ShadowLocCalc);

  // Poison redzones
  std::vector<Entry>::iterator Iter = PoisonVals.begin();
  for (SizeT Offset = 0; Iter != PoisonVals.end(); Offset += BytesPerWord) {
    int32_t CurVals[BytesPerWord] = {0};
    for (uint32_t i = 0; i < BytesPerWord; ++i) {
      if (Iter == PoisonVals.end())
        break;
      Entry Val = *Iter;
      CurVals[i] = Val.second;
      --Val.first;
      if (Val.first > 0)
        *Iter = Val;
      else
        ++Iter;
    }
    int32_t Poison = ((CurVals[3] & 0xff) << 24) | ((CurVals[2] & 0xff) << 16) |
                     ((CurVals[1] & 0xff) << 8) | (CurVals[0] & 0xff);
    if (Poison == 0)
      continue;
    auto *PoisonConst = ConstantInteger32::create(Ctx, IceType_i32, Poison);
    auto *ZeroConst = ConstantInteger32::create(Ctx, IceType_i32, 0);
    auto *OffsetConst = ConstantInteger32::create(Ctx, IceType_i32, Offset);
    auto *PoisonAddrVar = Func->makeVariable(IceType_i32);
    Context.insert(InstArithmetic::create(Func, InstArithmetic::Add,
                                          PoisonAddrVar, FirstShadowLocVar,
                                          OffsetConst));
    Context.insert(InstStore::create(Func, PoisonConst, PoisonAddrVar));
    ICE_TLS_GET_FIELD(LocalDtors)
        ->emplace_back(InstStore::create(Func, ZeroConst, PoisonAddrVar));
  }
  Context.advanceNext();
}

void ASanInstrumentation::instrumentCall(LoweringContext &Context,
                                         InstCall *Instr) {
  auto *CallTarget =
      llvm::dyn_cast<ConstantRelocatable>(Instr->getCallTarget());
  if (CallTarget == nullptr)
    return;

  std::string TargetName = CallTarget->getName().toStringOrEmpty();
  auto Subst = FuncSubstitutions.find(TargetName);
  if (Subst == FuncSubstitutions.end())
    return;

  std::string SubName = Subst->second;
  Constant *NewFunc = Ctx->getConstantExternSym(Ctx->getGlobalString(SubName));
  auto *NewCall =
      InstCall::create(Context.getNode()->getCfg(), Instr->getNumArgs(),
                       Instr->getDest(), NewFunc, Instr->isTailcall());
  for (SizeT I = 0, Args = Instr->getNumArgs(); I < Args; ++I)
    NewCall->addArg(Instr->getArg(I));
  Context.insert(NewCall);
  Instr->setDeleted();
}

void ASanInstrumentation::instrumentLoad(LoweringContext &Context,
                                         InstLoad *Instr) {
  Operand *Src = Instr->getSourceAddress();
  if (auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
    auto *NewLoad = InstLoad::create(Context.getNode()->getCfg(),
                                     Instr->getDest(), instrumentReloc(Reloc));
    Instr->setDeleted();
    Context.insert(NewLoad);
    Instr = NewLoad;
  }
  Constant *Func =
      Ctx->getConstantExternSym(Ctx->getGlobalString("__asan_check_load"));
  instrumentAccess(Context, Instr->getSourceAddress(),
                   typeWidthInBytes(Instr->getDest()->getType()), Func);
}

void ASanInstrumentation::instrumentStore(LoweringContext &Context,
                                          InstStore *Instr) {
  Operand *Data = Instr->getData();
  if (auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Data)) {
    auto *NewStore = InstStore::create(
        Context.getNode()->getCfg(), instrumentReloc(Reloc), Instr->getAddr());
    Instr->setDeleted();
    Context.insert(NewStore);
    Instr = NewStore;
  }
  Constant *Func =
      Ctx->getConstantExternSym(Ctx->getGlobalString("__asan_check_store"));
  instrumentAccess(Context, Instr->getAddr(),
                   typeWidthInBytes(Instr->getData()->getType()), Func);
}

ConstantRelocatable *
ASanInstrumentation::instrumentReloc(ConstantRelocatable *Reloc) {
  std::string DataName = Reloc->getName().toString();
  StringMap::const_iterator DataSub = FuncSubstitutions.find(DataName);
  if (DataSub != FuncSubstitutions.end()) {
    return ConstantRelocatable::create(
        Ctx, Reloc->getType(),
        RelocatableTuple(Reloc->getOffset(), RelocOffsetArray(0),
                         Ctx->getGlobalString(DataSub->second),
                         Reloc->getEmitString()));
  }
  return Reloc;
}

void ASanInstrumentation::instrumentAccess(LoweringContext &Context,
                                           Operand *Op, SizeT Size,
                                           Constant *CheckFunc) {
  // Skip redundant checks within basic blocks
  VarSizeMap *Checked = ICE_TLS_GET_FIELD(CheckedVars);
  if (ICE_TLS_GET_FIELD(CurNode) != Context.getNode()) {
    ICE_TLS_SET_FIELD(CurNode, Context.getNode());
    if (Checked == NULL) {
      Checked = new VarSizeMap();
      ICE_TLS_SET_FIELD(CheckedVars, Checked);
    }
    Checked->clear();
  }
  VarSizeMap::iterator PrevCheck = Checked->find(Op);
  if (PrevCheck != Checked->end() && PrevCheck->second >= Size)
    return;
  else
    Checked->insert({Op, Size});

  // check for known good local access
  VarSizeMap::iterator LocalSize = ICE_TLS_GET_FIELD(LocalVars)->find(Op);
  if (LocalSize != ICE_TLS_GET_FIELD(LocalVars)->end() &&
      LocalSize->second >= Size)
    return;
  if (isOkGlobalAccess(Op, Size))
    return;
  constexpr SizeT NumArgs = 2;
  constexpr Variable *Void = nullptr;
  constexpr bool NoTailCall = false;
  auto *Call = InstCall::create(Context.getNode()->getCfg(), NumArgs, Void,
                                CheckFunc, NoTailCall);
  Call->addArg(Op);
  Call->addArg(ConstantInteger32::create(Ctx, IceType_i32, Size));
  // play games to insert the call before the access instruction
  InstList::iterator Next = Context.getNext();
  Context.setInsertPoint(Context.getCur());
  Context.insert(Call);
  Context.setNext(Next);
}

// TODO(tlively): Trace back load and store addresses to find their real offsets
bool ASanInstrumentation::isOkGlobalAccess(Operand *Op, SizeT Size) {
  auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Op);
  if (Reloc == nullptr)
    return false;
  RelocOffsetT Offset = Reloc->getOffset();
  GlobalSizeMap::iterator GlobalSize = GlobalSizes.find(Reloc->getName());
  return GlobalSize != GlobalSizes.end() && GlobalSize->second - Offset >= Size;
}

void ASanInstrumentation::instrumentRet(LoweringContext &Context, InstRet *) {
  Cfg *Func = Context.getNode()->getCfg();
  Context.setInsertPoint(Context.getCur());
  for (InstStore *RzUnpoison : *ICE_TLS_GET_FIELD(LocalDtors)) {
    Context.insert(
        InstStore::create(Func, RzUnpoison->getData(), RzUnpoison->getAddr()));
  }
  Context.advanceCur();
  Context.advanceNext();
}

void ASanInstrumentation::instrumentStart(Cfg *Func) {
  Constant *ShadowMemInit =
      Ctx->getConstantExternSym(Ctx->getGlobalString("__asan_init"));
  constexpr SizeT NumArgs = 3;
  constexpr Variable *Void = nullptr;
  constexpr bool NoTailCall = false;
  auto *Call = InstCall::create(Func, NumArgs, Void, ShadowMemInit, NoTailCall);
  Func->getEntryNode()->getInsts().push_front(Call);

  instrumentGlobals(*getGlobals());

  Call->addArg(ConstantInteger32::create(Ctx, IceType_i32, RzGlobalsNum));
  Call->addArg(Ctx->getConstantSym(0, Ctx->getGlobalString(RzArrayName)));
  Call->addArg(Ctx->getConstantSym(0, Ctx->getGlobalString(RzSizesName)));
}

// TODO(tlively): make this more efficient with swap idiom
void ASanInstrumentation::finishFunc(Cfg *) {
  ICE_TLS_GET_FIELD(LocalVars)->clear();
  ICE_TLS_GET_FIELD(LocalDtors)->clear();
}

} // end of namespace Ice
