//===- bolt/Target/RISCV/RISCVMCSymbolizer.cpp ----------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "RISCVMCSymbolizer.h"
#include "MCTargetDesc/RISCVMCTargetDesc.h"
#include "bolt/Core/BinaryContext.h"
#include "bolt/Core/BinaryFunction.h"
#include "bolt/Core/MCPlusBuilder.h"
#include "bolt/Core/Relocation.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInst.h"

#define DEBUG_TYPE "bolt-symbolizer"

namespace llvm {
namespace bolt {

static bool isValidControlTransferAUIPC(const MCInst &Inst) {
  if (Inst.getOpcode() != RISCV::AUIPC ||
      MCPlus::getNumPrimeOperands(Inst) != 2)
    return false;

  const MCOperand &Base = Inst.getOperand(0);
  return Base.isReg() && Base.getReg() != RISCV::X0 &&
         Inst.getOperand(1).isImm();
}

static bool isValidControlTransferJALR(const MCInst &Inst) {
  if (Inst.getOpcode() != RISCV::JALR || MCPlus::getNumPrimeOperands(Inst) != 3)
    return false;

  return Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
         Inst.getOperand(2).isImm();
}

static bool isLinkerResolvedControlTransfer(const MCInst &AUIPC,
                                            const MCInst &JALR) {
  if (!isValidControlTransferAUIPC(AUIPC) || !isValidControlTransferJALR(JALR))
    return false;

  const MCRegister Base = AUIPC.getOperand(0).getReg();
  if (JALR.getOperand(1).getReg() != Base)
    return false;

  const MCRegister Link = JALR.getOperand(0).getReg();
  return Link == RISCV::X0 || Link == Base;
}

static int64_t getLinkerResolvedControlTransferOffset(const MCInst &AUIPC,
                                                      const MCInst &JALR) {
  // The symbolic AUIPC decoder passes the sign-extended 20-bit U-immediate
  // already shifted left by 12. JALR adds its sign-extended 12-bit immediate
  // and clears target bit zero.
  return (AUIPC.getOperand(1).getImm() + JALR.getOperand(2).getImm()) & ~1LL;
}

RISCVMCSymbolizer::RISCVMCSymbolizer(BinaryFunction &Function,
                                     bool CreateNewSymbols)
    : MCSymbolizer(*Function.getBinaryContext().Ctx, nullptr),
      Function(Function), CreateNewSymbols(CreateNewSymbols) {
  BinaryContext &BC = Function.getBinaryContext();
  const RelocationHandler &RH = BC.getRelocationHandler();
  // Discover instruction references before decoding starts. This lets us
  // attach a label while decoding the referenced %pcrel_hi instruction even
  // though its %pcrel_lo user is normally decoded later.
  for (uint64_t SearchOffset = 0; SearchOffset < Function.getSize();) {
    const Relocation *Rel =
        Function.getRelocationInRange(SearchOffset, Function.getSize());
    if (!Rel)
      break;

    if (RH.isInstructionReference(Rel->Type)) {
      assert(Rel->Value >= Function.getAddress() &&
             Rel->Value < Function.getAddress() + Function.getSize() &&
             "RISC-V instruction reference outside of function");
      const uint64_t ReferencedOffset = Rel->Value - Function.getAddress();
      InstructionReferences.try_emplace(ReferencedOffset,
                                        InstructionReferenceInfo{Rel, nullptr});
    }

    SearchOffset = Rel->Offset + 1;
  }
}

RISCVMCSymbolizer::~RISCVMCSymbolizer() {}

MCSymbol *RISCVMCSymbolizer::getOrCreateInstructionLabel(
    InstructionReferenceInfo &ReferenceInfo) {
  if (!ReferenceInfo.Label)
    ReferenceInfo.Label = Ctx.createNamedTempSymbol();
  return ReferenceInfo.Label;
}

uint64_t RISCVMCSymbolizer::getGOTValue(const Relocation &Rel) const {
  BinaryContext &BC = Function.getBinaryContext();
  const RelocationHandler &RH = BC.getRelocationHandler();
  const uint64_t HiAddress = Function.getAddress() + Rel.Offset;

  // A GOT high relocation records a combined high/low value. Locate the low
  // relocation by its reference back to this AUIPC instead of assuming that
  // the low instruction is adjacent.
  auto It = InstructionReferences.find(Rel.Offset);
  if (It != InstructionReferences.end() && It->second.LowRelocation) {
    const Relocation *LoRel = It->second.LowRelocation;
    ErrorOr<uint64_t> HiContents = BC.getUnsignedValueAtAddress(HiAddress, 4);
    ErrorOr<uint64_t> LoContents = BC.getUnsignedValueAtAddress(
        Function.getAddress() + LoRel->Offset, RH.getSizeForType(LoRel->Type));
    assert(HiContents && LoContents &&
           "cannot read RISC-V GOT relocation pair");

    return RH.extractValue(ELF::R_RISCV_PCREL_HI20, *HiContents, HiAddress) +
           RH.extractValue(LoRel->Type, *LoContents,
                           Function.getAddress() + LoRel->Offset);
  }

  return Rel.Value;
}

bool RISCVMCSymbolizer::trySymbolizeLinkerResolvedControlTransfer(
    MCInst &Inst, int64_t Value, uint64_t InstAddress) {
  BinaryContext &BC = Function.getBinaryContext();
  MCContext *Ctx = BC.Ctx.get();
  const uint64_t InstOffset = InstAddress - Function.getAddress();

  // Recover RV64 linker-resolved intra-section calls and tail calls without
  // relocations. Decode the following JALR and attach a call expression to the
  // AUIPC before function reordering can move the caller relative to the
  // callee.
  if (Inst.getOpcode() != RISCV::AUIPC || !CreateNewSymbols ||
      !BC.TheTriple->isRISCV64() || InstOffset + 8 > Function.getSize() ||
      Function.getRelocationInRange(InstOffset, InstOffset + 8))
    return false;

  ErrorOr<ArrayRef<uint8_t>> FunctionData = Function.getData();
  if (!FunctionData)
    return false;

  MCInst JALR;
  uint64_t JALRSize = 0;
  if (!BC.DisAsm->getInstruction(JALR, JALRSize,
                                 FunctionData->slice(InstOffset + 4),
                                 InstAddress + 4, nulls()) ||
      JALRSize != 4)
    return false;

  MCInst AUIPC = Inst;
  AUIPC.addOperand(MCOperand::createImm(Value));
  if (!isLinkerResolvedControlTransfer(AUIPC, JALR))
    return false;

  const uint64_t Target =
      InstAddress + getLinkerResolvedControlTransferOffset(AUIPC, JALR);
  BinaryFunction *TargetBF = BC.getBinaryFunctionContainingAddress(Target);
  if (!TargetBF)
    return false;

  // JALR with rd=x0 is a no-link jump. It is a tail call only when it
  // transfers control to another function; a target in the current function
  // is an intraprocedural long jump and must not be represented as a call.
  if (JALR.getOperand(0).getReg() == RISCV::X0 && TargetBF == &Function)
    return false;

  BC.addInterproceduralReference(&Function, Target);
  MCSymbol *TargetSymbol =
      BC.handleExternalBranchTarget(Target, Function, *TargetBF);
  if (!TargetSymbol)
    return false;

  const MCExpr *Expr = MCSymbolRefExpr::create(TargetSymbol, *Ctx);
  Inst.addOperand(MCOperand::createExpr(
      BC.MIB->getTargetExprFor(Inst, Expr, *Ctx, ELF::R_RISCV_CALL_PLT)));
  return true;
}

bool RISCVMCSymbolizer::tryAddingSymbolicOperand(
    MCInst &Inst, raw_ostream &CStream, int64_t Value, uint64_t InstAddress,
    bool IsBranch, uint64_t ImmOffset, uint64_t ImmSize, uint64_t InstSize) {
  BinaryContext &BC = Function.getBinaryContext();
  const RelocationHandler &RH = BC.getRelocationHandler();
  MCContext *Ctx = BC.Ctx.get();
  const uint64_t InstOffset = InstAddress - Function.getAddress();

  // Branches and calls are resolved by BinaryFunction's target-independent
  // control-flow handling.
  if (BC.MIB->isBranch(Inst) || BC.MIB->isCall(Inst))
    return false;

  // Linker processing of R_RISCV_ALIGN can leave emitted relocations at an
  // offset inside the instruction they apply to. Match the whole instruction
  // range, as BinaryFunction::disassemble() did before this target-specific
  // handling moved into the symbolizer.
  const Relocation *Rel =
      Function.getRelocationInRange(InstOffset, InstOffset + InstSize);
  if (!Rel)
    return trySymbolizeLinkerResolvedControlTransfer(Inst, Value, InstAddress);

  MCSymbol *Symbol = Rel->Symbol;
  uint64_t Addend = Rel->Addend;

  if (RH.isInstructionReference(Rel->Type)) {
    if (!CreateNewSymbols)
      return false;
    auto [It, _] =
        InstructionReferences.try_emplace(Rel->Value - Function.getAddress());
    Symbol = getOrCreateInstructionLabel(It->second);
    // The input addend reflects the original AUIPC location. The label now
    // follows the instruction, so the assembler must derive the low bits from
    // its new location.
    Addend = 0;
  }

  // GOT high relocations name the object stored in the GOT, not the GOT entry
  // addressed by AUIPC. Preserve the actual entry address using a zero-based
  // symbol, as the RISC-V emitter reuses the input GOT.
  if (RH.isGOT(Rel->Type)) {
    assert(RH.isPCRelative(Rel->Type) &&
           "GOT relocation must be PC-relative on RISC-V");
    Symbol = BC.registerNameAtAddress("__BOLT_got_zero", 0, 0, 0);
    Addend = getGOTValue(*Rel) + InstAddress;
  }

  assert(Symbol && "RISC-V relocation without a symbol");
  const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, *Ctx);
  if (Addend)
    Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Addend, *Ctx),
                                   *Ctx);
  Inst.addOperand(MCOperand::createExpr(
      BC.MIB->getTargetExprFor(Inst, Expr, *Ctx, Rel->Type)));

  // MC annotations must follow every real operand. Attach the instruction
  // label only after the symbolized immediate has been appended.
  if (CreateNewSymbols) {
    auto It = InstructionReferences.find(InstOffset);
    if (It != InstructionReferences.end())
      BC.MIB->setInstLabel(Inst, getOrCreateInstructionLabel(It->second));
  }

  return true;
}

void RISCVMCSymbolizer::tryAddingPcLoadReferenceComment(raw_ostream &CStream,
                                                        int64_t Value,
                                                        uint64_t Address) {}

} // namespace bolt
} // namespace llvm
