//===-- AArch64BranchTargets.cpp -- Harden code using v8.5-A BTI extension -==//
//
// 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 inserts BTI instructions at the start of every function and basic
// block which could be indirectly called. The hardware will (when enabled)
// trap when an indirect branch or call instruction targets an instruction
// which is not a valid BTI instruction. This is intended to guard against
// control-flow hijacking attacks. Note that this does not do anything for RET
// instructions, as they can be more precisely protected by return address
// signing.
//
//===----------------------------------------------------------------------===//

#include "AArch64MachineFunctionInfo.h"
#include "AArch64Subtarget.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/Support/Debug.h"

using namespace llvm;

#define DEBUG_TYPE "aarch64-branch-targets"
#define AARCH64_BRANCH_TARGETS_NAME "AArch64 Branch Targets"

namespace {
class AArch64BranchTargets : public MachineFunctionPass {
public:
  static char ID;
  AArch64BranchTargets() : MachineFunctionPass(ID) {}
  void getAnalysisUsage(AnalysisUsage &AU) const override;
  bool runOnMachineFunction(MachineFunction &MF) override;
  StringRef getPassName() const override { return AARCH64_BRANCH_TARGETS_NAME; }

private:
  void addBTI(MachineBasicBlock &MBB, bool CouldCall, bool CouldJump);
};
} // end anonymous namespace

char AArch64BranchTargets::ID = 0;

INITIALIZE_PASS(AArch64BranchTargets, "aarch64-branch-targets",
                AARCH64_BRANCH_TARGETS_NAME, false, false)

void AArch64BranchTargets::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesCFG();
  MachineFunctionPass::getAnalysisUsage(AU);
}

FunctionPass *llvm::createAArch64BranchTargetsPass() {
  return new AArch64BranchTargets();
}

bool AArch64BranchTargets::runOnMachineFunction(MachineFunction &MF) {
  if (!MF.getInfo<AArch64FunctionInfo>()->branchTargetEnforcement())
    return false;

  LLVM_DEBUG(
      dbgs() << "********** AArch64 Branch Targets  **********\n"
             << "********** Function: " << MF.getName() << '\n');
  const Function &F = MF.getFunction();

  // LLVM does not consider basic blocks which are the targets of jump tables
  // to be address-taken (the address can't escape anywhere else), but they are
  // used for indirect branches, so need BTI instructions.
  SmallPtrSet<MachineBasicBlock *, 8> JumpTableTargets;
  if (auto *JTI = MF.getJumpTableInfo())
    for (auto &JTE : JTI->getJumpTables())
      for (auto *MBB : JTE.MBBs)
        JumpTableTargets.insert(MBB);

  bool MadeChange = false;
  for (MachineBasicBlock &MBB : MF) {
    bool CouldCall = false, CouldJump = false;
    // If the function is address-taken or externally-visible, it could be
    // indirectly called. PLT entries and tail-calls use BR, but when they are
    // are in guarded pages should all use x16 or x17 to hold the called
    // address, so we don't need to set CouldJump here. BR instructions in
    // non-guarded pages (which might be non-BTI-aware code) are allowed to
    // branch to a "BTI c" using any register.
    if (&MBB == &*MF.begin() && (F.hasAddressTaken() || !F.hasLocalLinkage()))
      CouldCall = true;

    // If the block itself is address-taken, it could be indirectly branched
    // to, but not called.
    if (MBB.hasAddressTaken() || JumpTableTargets.count(&MBB))
      CouldJump = true;

    if (CouldCall || CouldJump) {
      addBTI(MBB, CouldCall, CouldJump);
      MadeChange = true;
    }
  }

  return MadeChange;
}

void AArch64BranchTargets::addBTI(MachineBasicBlock &MBB, bool CouldCall,
                                  bool CouldJump) {
  LLVM_DEBUG(dbgs() << "Adding BTI " << (CouldJump ? "j" : "")
                    << (CouldCall ? "c" : "") << " to " << MBB.getName()
                    << "\n");

  const AArch64InstrInfo *TII = static_cast<const AArch64InstrInfo *>(
      MBB.getParent()->getSubtarget().getInstrInfo());

  unsigned HintNum = 32;
  if (CouldCall)
    HintNum |= 2;
  if (CouldJump)
    HintNum |= 4;
  assert(HintNum != 32 && "No target kinds!");

  auto MBBI = MBB.begin();

  // Skip the meta instuctions, those will be removed anyway.
  for (; MBBI != MBB.end() && MBBI->isMetaInstruction(); ++MBBI)
    ;

  // SCTLR_EL1.BT[01] is set to 0 by default which means
  // PACI[AB]SP are implicitly BTI C so no BTI C instruction is needed there.
  if (MBBI != MBB.end() && HintNum == 34 &&
      (MBBI->getOpcode() == AArch64::PACIASP ||
       MBBI->getOpcode() == AArch64::PACIBSP))
    return;

  BuildMI(MBB, MBB.begin(), MBB.findDebugLoc(MBB.begin()),
          TII->get(AArch64::HINT))
      .addImm(HintNum);
}
