brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · f505bf7 Raw
87 lines · cpp
1//===- bolt/Core/MCInstUtils.cpp ------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "bolt/Core/MCInstUtils.h"10#include "bolt/Core/BinaryBasicBlock.h"11#include "bolt/Core/BinaryFunction.h"12 13#include <type_traits>14 15using namespace llvm;16using namespace llvm::bolt;17 18// It is assumed in a few places that BinaryBasicBlock stores its instructions19// in a contiguous vector.20using BasicBlockStorageIsVector =21    std::is_same<BinaryBasicBlock::const_iterator,22                 std::vector<MCInst>::const_iterator>;23static_assert(BasicBlockStorageIsVector::value);24 25MCInstReference MCInstReference::get(const MCInst &Inst,26                                     const BinaryFunction &BF) {27  if (BF.hasCFG()) {28    for (BinaryBasicBlock &BB : BF) {29      for (MCInst &MI : BB)30        if (&MI == &Inst)31          return MCInstReference(BB, Inst);32    }33    llvm_unreachable("Inst is not contained in BF");34  }35 36  for (auto I = BF.instrs().begin(), E = BF.instrs().end(); I != E; ++I) {37    if (&I->second == &Inst)38      return MCInstReference(BF, I);39  }40  llvm_unreachable("Inst is not contained in BF");41}42 43uint64_t MCInstReference::computeAddress(const MCCodeEmitter *Emitter) const {44  assert(!empty() && "Taking instruction address by empty reference");45 46  const BinaryContext &BC = getFunction()->getBinaryContext();47  if (auto *Ref = tryGetRefInBB()) {48    const uint64_t AddressOfBB =49        getFunction()->getAddress() + Ref->BB->getOffset();50    const MCInst *FirstInstInBB = &*Ref->BB->begin();51    const MCInst *ThisInst = &getMCInst();52 53    // Usage of plain 'const MCInst *' as iterators assumes the instructions54    // are stored in a vector, see BasicBlockStorageIsVector.55    const uint64_t OffsetInBB =56        BC.computeCodeSize(FirstInstInBB, ThisInst, Emitter);57 58    return AddressOfBB + OffsetInBB;59  }60 61  auto &Ref = getRefInBF();62  const uint64_t OffsetInBF = Ref.It->first;63 64  return getFunction()->getAddress() + OffsetInBF;65}66 67raw_ostream &MCInstReference::print(raw_ostream &OS) const {68  if (const RefInBB *Ref = tryGetRefInBB()) {69    OS << "MCInstBBRef<";70    if (Ref->BB == nullptr)71      OS << "BB:(null)";72    else73      OS << "BB:" << Ref->BB->getName() << ":" << Ref->Index;74    OS << ">";75    return OS;76  }77 78  const RefInBF &Ref = getRefInBF();79  OS << "MCInstBFRef<";80  if (Ref.BF == nullptr)81    OS << "BF:(null)";82  else83    OS << "BF:" << Ref.BF->getPrintName() << ":" << Ref.It->first;84  OS << ">";85  return OS;86}87