//===- SanitizerBinaryMetadata.cpp - binary analysis sanitizers metadata --===//
//
// 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 file is a part of SanitizerBinaryMetadata.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/SpecialCaseList.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

#include <array>
#include <cstdint>
#include <memory>

using namespace llvm;

#define DEBUG_TYPE "sanmd"

namespace {

//===--- Constants --------------------------------------------------------===//

constexpr uint32_t kVersionBase = 2;                // occupies lower 16 bits
constexpr uint32_t kVersionPtrSizeRel = (1u << 16); // offsets are pointer-sized
constexpr int kCtorDtorPriority = 2;

// Pairs of names of initialization callback functions and which section
// contains the relevant metadata.
class MetadataInfo {
public:
  const StringRef FunctionPrefix;
  const StringRef SectionSuffix;

  static const MetadataInfo Covered;
  static const MetadataInfo Atomics;

private:
  // Forbid construction elsewhere.
  explicit constexpr MetadataInfo(StringRef FunctionPrefix,
                                  StringRef SectionSuffix)
      : FunctionPrefix(FunctionPrefix), SectionSuffix(SectionSuffix) {}
};
const MetadataInfo MetadataInfo::Covered{
    "__sanitizer_metadata_covered", kSanitizerBinaryMetadataCoveredSection};
const MetadataInfo MetadataInfo::Atomics{
    "__sanitizer_metadata_atomics", kSanitizerBinaryMetadataAtomicsSection};

// The only instances of MetadataInfo are the constants above, so a set of
// them may simply store pointers to them. To deterministically generate code,
// we need to use a set with stable iteration order, such as SetVector.
using MetadataInfoSet = SetVector<const MetadataInfo *>;

//===--- Command-line options ---------------------------------------------===//

cl::opt<bool> ClWeakCallbacks(
    "sanitizer-metadata-weak-callbacks",
    cl::desc("Declare callbacks extern weak, and only call if non-null."),
    cl::Hidden, cl::init(true));
cl::opt<bool>
    ClNoSanitize("sanitizer-metadata-nosanitize-attr",
                 cl::desc("Mark some metadata features uncovered in functions "
                          "with associated no_sanitize attributes."),
                 cl::Hidden, cl::init(true));

cl::opt<bool> ClEmitCovered("sanitizer-metadata-covered",
                            cl::desc("Emit PCs for covered functions."),
                            cl::Hidden, cl::init(false));
cl::opt<bool> ClEmitAtomics("sanitizer-metadata-atomics",
                            cl::desc("Emit PCs for atomic operations."),
                            cl::Hidden, cl::init(false));
cl::opt<bool> ClEmitUAR("sanitizer-metadata-uar",
                        cl::desc("Emit PCs for start of functions that are "
                                 "subject for use-after-return checking"),
                        cl::Hidden, cl::init(false));

//===--- Statistics -------------------------------------------------------===//

STATISTIC(NumMetadataCovered, "Metadata attached to covered functions");
STATISTIC(NumMetadataAtomics, "Metadata attached to atomics");
STATISTIC(NumMetadataUAR, "Metadata attached to UAR functions");

//===----------------------------------------------------------------------===//

// Apply opt overrides.
SanitizerBinaryMetadataOptions &&
transformOptionsFromCl(SanitizerBinaryMetadataOptions &&Opts) {
  Opts.Covered |= ClEmitCovered;
  Opts.Atomics |= ClEmitAtomics;
  Opts.UAR |= ClEmitUAR;
  return std::move(Opts);
}

class SanitizerBinaryMetadata {
public:
  SanitizerBinaryMetadata(Module &M, SanitizerBinaryMetadataOptions Opts,
                          std::unique_ptr<SpecialCaseList> Ignorelist)
      : Mod(M), Options(transformOptionsFromCl(std::move(Opts))),
        Ignorelist(std::move(Ignorelist)), TargetTriple(M.getTargetTriple()),
        VersionStr(utostr(getVersion())), IRB(M) {
    // FIXME: Make it work with other formats.
    assert(TargetTriple.isOSBinFormatELF() && "ELF only");
    assert(!TargetTriple.isGPU() && "Device targets are not supported");
  }

  bool run();

private:
  uint32_t getVersion() const {
    uint32_t Version = kVersionBase;
    const auto CM = Mod.getCodeModel();
    if (CM.has_value() && (*CM == CodeModel::Medium || *CM == CodeModel::Large))
      Version |= kVersionPtrSizeRel;
    return Version;
  }

  void runOn(Function &F, MetadataInfoSet &MIS);

  // Determines which set of metadata to collect for this instruction.
  //
  // Returns true if covered metadata is required to unambiguously interpret
  // other metadata. For example, if we are interested in atomics metadata, any
  // function with memory operations (atomic or not) requires covered metadata
  // to determine if a memory operation is atomic or not in modules compiled
  // with SanitizerBinaryMetadata.
  bool runOn(Instruction &I, MetadataInfoSet &MIS, MDBuilder &MDB,
             uint64_t &FeatureMask);

  // Get start/end section marker pointer.
  GlobalVariable *getSectionMarker(const Twine &MarkerName, Type *Ty);

  // Returns the target-dependent section name.
  StringRef getSectionName(StringRef SectionSuffix);

  // Returns the section start marker name.
  StringRef getSectionStart(StringRef SectionSuffix);

  // Returns the section end marker name.
  StringRef getSectionEnd(StringRef SectionSuffix);

  // Returns true if the access to the address should be considered "atomic".
  bool pretendAtomicAccess(const Value *Addr);

  Module &Mod;
  const SanitizerBinaryMetadataOptions Options;
  std::unique_ptr<SpecialCaseList> Ignorelist;
  const Triple TargetTriple;
  const std::string VersionStr;
  IRBuilder<> IRB;
  BumpPtrAllocator Alloc;
  UniqueStringSaver StringPool{Alloc};
};

bool SanitizerBinaryMetadata::run() {
  MetadataInfoSet MIS;

  for (Function &F : Mod)
    runOn(F, MIS);

  if (MIS.empty())
    return false;

  //
  // Setup constructors and call all initialization functions for requested
  // metadata features.
  //

  auto *PtrTy = IRB.getPtrTy();
  auto *Int32Ty = IRB.getInt32Ty();
  const std::array<Type *, 3> InitTypes = {Int32Ty, PtrTy, PtrTy};
  auto *Version = ConstantInt::get(Int32Ty, getVersion());

  for (const MetadataInfo *MI : MIS) {
    const std::array<Value *, InitTypes.size()> InitArgs = {
        Version,
        getSectionMarker(getSectionStart(MI->SectionSuffix), PtrTy),
        getSectionMarker(getSectionEnd(MI->SectionSuffix), PtrTy),
    };

    // Calls to the initialization functions with different versions cannot be
    // merged. Give the structors unique names based on the version, which will
    // also be used as the COMDAT key.
    const std::string StructorPrefix = (MI->FunctionPrefix + VersionStr).str();

    // We declare the _add and _del functions as weak, and only call them if
    // there is a valid symbol linked. This allows building binaries with
    // semantic metadata, but without having callbacks. When a tool that wants
    // the metadata is linked which provides the callbacks, they will be called.
    Function *Ctor =
        createSanitizerCtorAndInitFunctions(
            Mod, StructorPrefix + ".module_ctor",
            (MI->FunctionPrefix + "_add").str(), InitTypes, InitArgs,
            /*VersionCheckName=*/StringRef(), /*Weak=*/ClWeakCallbacks)
            .first;
    Function *Dtor =
        createSanitizerCtorAndInitFunctions(
            Mod, StructorPrefix + ".module_dtor",
            (MI->FunctionPrefix + "_del").str(), InitTypes, InitArgs,
            /*VersionCheckName=*/StringRef(), /*Weak=*/ClWeakCallbacks)
            .first;
    Constant *CtorComdatKey = nullptr;
    Constant *DtorComdatKey = nullptr;
    if (TargetTriple.supportsCOMDAT()) {
      // Use COMDAT to deduplicate constructor/destructor function. The COMDAT
      // key needs to be a non-local linkage.
      Ctor->setComdat(Mod.getOrInsertComdat(Ctor->getName()));
      Dtor->setComdat(Mod.getOrInsertComdat(Dtor->getName()));
      Ctor->setLinkage(GlobalValue::ExternalLinkage);
      Dtor->setLinkage(GlobalValue::ExternalLinkage);
      // DSOs should _not_ call another constructor/destructor!
      Ctor->setVisibility(GlobalValue::HiddenVisibility);
      Dtor->setVisibility(GlobalValue::HiddenVisibility);
      CtorComdatKey = Ctor;
      DtorComdatKey = Dtor;
    }
    appendToGlobalCtors(Mod, Ctor, kCtorDtorPriority, CtorComdatKey);
    appendToGlobalDtors(Mod, Dtor, kCtorDtorPriority, DtorComdatKey);
  }

  return true;
}

void SanitizerBinaryMetadata::runOn(Function &F, MetadataInfoSet &MIS) {
  if (F.empty())
    return;
  // Do not apply any instrumentation for naked functions.
  if (F.hasFnAttribute(Attribute::Naked))
    return;
  if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
    return;
  if (Ignorelist && Ignorelist->inSection("metadata", "fun", F.getName()))
    return;
  // Don't touch available_externally functions, their actual body is elsewhere.
  if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
    return;

  MDBuilder MDB(F.getContext());

  // The metadata features enabled for this function, stored along covered
  // metadata (if enabled).
  uint64_t FeatureMask = 0;
  // Don't emit unnecessary covered metadata for all functions to save space.
  bool RequiresCovered = false;

  if (Options.Atomics || Options.UAR) {
    for (BasicBlock &BB : F)
      for (Instruction &I : BB)
        RequiresCovered |= runOn(I, MIS, MDB, FeatureMask);
  }

  if (ClNoSanitize && F.hasFnAttribute("no_sanitize_thread"))
    FeatureMask &= ~kSanitizerBinaryMetadataAtomics;
  if (F.isVarArg())
    FeatureMask &= ~kSanitizerBinaryMetadataUAR;
  if (FeatureMask & kSanitizerBinaryMetadataUAR) {
    RequiresCovered = true;
    NumMetadataUAR++;
  }

  // Covered metadata is always emitted if explicitly requested, otherwise only
  // if some other metadata requires it to unambiguously interpret it for
  // modules compiled with SanitizerBinaryMetadata.
  if (Options.Covered || (FeatureMask && RequiresCovered)) {
    NumMetadataCovered++;
    const auto *MI = &MetadataInfo::Covered;
    MIS.insert(MI);
    const StringRef Section = getSectionName(MI->SectionSuffix);
    // The feature mask will be placed after the function size.
    Constant *CFM = IRB.getInt64(FeatureMask);
    F.setMetadata(LLVMContext::MD_pcsections,
                  MDB.createPCSections({{Section, {CFM}}}));
  }
}

bool isUARSafeCall(CallInst *CI) {
  auto *F = CI->getCalledFunction();
  // There are no intrinsic functions that leak arguments.
  // If the called function does not return, the current function
  // does not return as well, so no possibility of use-after-return.
  // Sanitizer function also don't leak or don't return.
  // It's safe to both pass pointers to local variables to them
  // and to tail-call them.
  return F && (F->isIntrinsic() || F->doesNotReturn() ||
               F->getName().starts_with("__asan_") ||
               F->getName().starts_with("__hwsan_") ||
               F->getName().starts_with("__ubsan_") ||
               F->getName().starts_with("__msan_") ||
               F->getName().starts_with("__tsan_"));
}

bool hasUseAfterReturnUnsafeUses(Value &V) {
  for (User *U : V.users()) {
    if (auto *I = dyn_cast<Instruction>(U)) {
      if (I->isLifetimeStartOrEnd() || I->isDroppable())
        continue;
      if (auto *CI = dyn_cast<CallInst>(U)) {
        if (isUARSafeCall(CI))
          continue;
      }
      if (isa<LoadInst>(U))
        continue;
      if (auto *SI = dyn_cast<StoreInst>(U)) {
        // If storing TO the alloca, then the address isn't taken.
        if (SI->getOperand(1) == &V)
          continue;
      }
      if (auto *GEPI = dyn_cast<GetElementPtrInst>(U)) {
        if (!hasUseAfterReturnUnsafeUses(*GEPI))
          continue;
      } else if (auto *BCI = dyn_cast<BitCastInst>(U)) {
        if (!hasUseAfterReturnUnsafeUses(*BCI))
          continue;
      }
    }
    return true;
  }
  return false;
}

bool useAfterReturnUnsafe(Instruction &I) {
  if (isa<AllocaInst>(I))
    return hasUseAfterReturnUnsafeUses(I);
  // Tail-called functions are not necessary intercepted
  // at runtime because there is no call instruction.
  // So conservatively mark the caller as requiring checking.
  else if (auto *CI = dyn_cast<CallInst>(&I))
    return CI->isTailCall() && !isUARSafeCall(CI);
  return false;
}

bool SanitizerBinaryMetadata::pretendAtomicAccess(const Value *Addr) {
  if (!Addr)
    return false;

  Addr = Addr->stripInBoundsOffsets();
  auto *GV = dyn_cast<GlobalVariable>(Addr);
  if (!GV)
    return false;

  // Some compiler-generated accesses are known racy, to avoid false positives
  // in data-race analysis pretend they're atomic.
  if (GV->hasSection()) {
    const auto OF = Mod.getTargetTriple().getObjectFormat();
    const auto ProfSec =
        getInstrProfSectionName(IPSK_cnts, OF, /*AddSegmentInfo=*/false);
    if (GV->getSection().ends_with(ProfSec))
      return true;
  }
  if (GV->getName().starts_with("__llvm_gcov") ||
      GV->getName().starts_with("__llvm_gcda"))
    return true;

  return false;
}

// Returns true if the memory at `Addr` may be shared with other threads.
bool maybeSharedMutable(const Value *Addr) {
  // By default assume memory may be shared.
  if (!Addr)
    return true;

  const AllocaInst *AI = findAllocaForValue(Addr);
  if (AI && !PointerMayBeCaptured(AI, /*ReturnCaptures=*/true))
    return false; // Object is on stack but does not escape.

  Addr = Addr->stripInBoundsOffsets();
  if (auto *GV = dyn_cast<GlobalVariable>(Addr)) {
    if (GV->isConstant())
      return false; // Shared, but not mutable.
  }

  return true;
}

bool SanitizerBinaryMetadata::runOn(Instruction &I, MetadataInfoSet &MIS,
                                    MDBuilder &MDB, uint64_t &FeatureMask) {
  SmallVector<const MetadataInfo *, 1> InstMetadata;
  bool RequiresCovered = false;

  // Only call if at least 1 type of metadata is requested.
  assert(Options.UAR || Options.Atomics);

  if (Options.UAR && !(FeatureMask & kSanitizerBinaryMetadataUAR)) {
    if (useAfterReturnUnsafe(I))
      FeatureMask |= kSanitizerBinaryMetadataUAR;
  }

  if (Options.Atomics) {
    const Value *Addr = nullptr;
    if (auto *SI = dyn_cast<StoreInst>(&I))
      Addr = SI->getPointerOperand();
    else if (auto *LI = dyn_cast<LoadInst>(&I))
      Addr = LI->getPointerOperand();

    if (I.mayReadOrWriteMemory() && maybeSharedMutable(Addr)) {
      auto SSID = getAtomicSyncScopeID(&I);
      if ((SSID.has_value() && *SSID != SyncScope::SingleThread) ||
          pretendAtomicAccess(Addr)) {
        NumMetadataAtomics++;
        InstMetadata.push_back(&MetadataInfo::Atomics);
      }
      FeatureMask |= kSanitizerBinaryMetadataAtomics;
      RequiresCovered = true;
    }
  }

  // Attach MD_pcsections to instruction.
  if (!InstMetadata.empty()) {
    MIS.insert_range(InstMetadata);
    SmallVector<MDBuilder::PCSection, 1> Sections;
    for (const auto &MI : InstMetadata)
      Sections.push_back({getSectionName(MI->SectionSuffix), {}});
    I.setMetadata(LLVMContext::MD_pcsections, MDB.createPCSections(Sections));
  }

  return RequiresCovered;
}

GlobalVariable *
SanitizerBinaryMetadata::getSectionMarker(const Twine &MarkerName, Type *Ty) {
  // Use ExternalWeak so that if all sections are discarded due to section
  // garbage collection, the linker will not report undefined symbol errors.
  auto *Marker = new GlobalVariable(Mod, Ty, /*isConstant=*/false,
                                    GlobalVariable::ExternalWeakLinkage,
                                    /*Initializer=*/nullptr, MarkerName);
  Marker->setVisibility(GlobalValue::HiddenVisibility);
  return Marker;
}

StringRef SanitizerBinaryMetadata::getSectionName(StringRef SectionSuffix) {
  // FIXME: Other TargetTriples.
  // Request ULEB128 encoding for all integer constants.
  return StringPool.save(SectionSuffix + VersionStr + "!C");
}

StringRef SanitizerBinaryMetadata::getSectionStart(StringRef SectionSuffix) {
  // Twine only concatenates 2 strings; with >2 strings, concatenating them
  // creates Twine temporaries, and returning the final Twine no longer works
  // because we'd end up with a stack-use-after-return. So here we also use the
  // StringPool to store the new string.
  return StringPool.save("__start_" + SectionSuffix + VersionStr);
}

StringRef SanitizerBinaryMetadata::getSectionEnd(StringRef SectionSuffix) {
  return StringPool.save("__stop_" + SectionSuffix + VersionStr);
}

} // namespace

SanitizerBinaryMetadataPass::SanitizerBinaryMetadataPass(
    SanitizerBinaryMetadataOptions Opts,
    IntrusiveRefCntPtr<vfs::FileSystem> VFS,
    ArrayRef<std::string> IgnorelistFiles)
    : Options(std::move(Opts)),
      VFS(VFS ? std::move(VFS) : vfs::getRealFileSystem()),
      IgnorelistFiles(std::move(IgnorelistFiles)) {}

PreservedAnalyses
SanitizerBinaryMetadataPass::run(Module &M, AnalysisManager<Module> &AM) {
  std::unique_ptr<SpecialCaseList> Ignorelist;
  if (!IgnorelistFiles.empty()) {
    Ignorelist = SpecialCaseList::createOrDie(IgnorelistFiles, *VFS);
    if (Ignorelist->inSection("metadata", "src", M.getSourceFileName()))
      return PreservedAnalyses::all();
  }

  SanitizerBinaryMetadata Pass(M, Options, std::move(Ignorelist));
  if (Pass.run())
    return PreservedAnalyses::none();
  return PreservedAnalyses::all();
}
