brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.3 KiB · 85d1c58 Raw
196 lines · cpp
1//===- lib/MC/MCFragment.cpp - Assembler Fragment Implementation ----------===//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 "llvm/ADT/SmallVector.h"10#include "llvm/ADT/StringExtras.h"11#include "llvm/ADT/Twine.h"12#include "llvm/Config/llvm-config.h"13#include "llvm/MC/MCContext.h"14#include "llvm/MC/MCFixup.h"15#include "llvm/MC/MCSection.h"16#include "llvm/MC/MCSectionMachO.h"17#include "llvm/MC/MCSymbol.h"18#include "llvm/Support/Casting.h"19#include "llvm/Support/Compiler.h"20#include "llvm/Support/raw_ostream.h"21#include <cassert>22#include <type_traits>23#include <utility>24 25using namespace llvm;26 27static_assert(std::is_trivially_destructible_v<MCFragment>,28              "fragment classes must be trivially destructible");29 30MCFragment::MCFragment(FragmentType Kind, bool HasInstructions)31    : Kind(Kind), LinkerRelaxable(false), HasInstructions(HasInstructions),32      AllowAutoPadding(false) {33  static_assert(sizeof(MCFragment::Tail) <= 16,34                "Keep the variable-size tail small");35}36 37const MCSymbol *MCFragment::getAtom() const {38  return static_cast<const MCSectionMachO *>(Parent)->getAtom(LayoutOrder);39}40 41#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)42LLVM_DUMP_METHOD void MCFragment::dump() const {43  raw_ostream &OS = errs();44 45  OS << Offset << ' ';46  switch (getKind()) {47    // clang-format off48  case MCFragment::FT_Align:         OS << "Align"; break;49  case MCFragment::FT_Data:          OS << "Data"; break;50  case MCFragment::FT_Fill:          OS << "Fill"; break;51  case MCFragment::FT_Nops:          OS << "Nops"; break;52  case MCFragment::FT_Relaxable:     OS << "Relaxable"; break;53  case MCFragment::FT_Org:           OS << "Org"; break;54  case MCFragment::FT_Dwarf:         OS << "Dwarf"; break;55  case MCFragment::FT_DwarfFrame:    OS << "DwarfCallFrame"; break;56  case MCFragment::FT_SFrame:        OS << "SFrame"; break;57  case MCFragment::FT_LEB:           OS << "LEB"; break;58  case MCFragment::FT_BoundaryAlign: OS<<"BoundaryAlign"; break;59  case MCFragment::FT_SymbolId:      OS << "SymbolId"; break;60  case MCFragment::FT_CVInlineLines: OS << "CVInlineLineTable"; break;61  case MCFragment::FT_CVDefRange:    OS << "CVDefRangeTable"; break;62    // clang-format on63  }64 65  auto printFixups = [&](llvm::ArrayRef<MCFixup> Fixups) {66    if (Fixups.empty())67      return;68    for (auto [I, F] : llvm::enumerate(Fixups)) {69      OS << "\n  Fixup @" << F.getOffset() << " Value:";70      F.getValue()->print(OS, nullptr);71      OS << " Kind:" << F.getKind();72      if (F.isLinkerRelaxable())73        OS << " LinkerRelaxable";74    }75  };76 77  switch (getKind()) {78  case MCFragment::FT_Data:79  case MCFragment::FT_Relaxable:80  case MCFragment::FT_Align:81  case MCFragment::FT_LEB:82  case MCFragment::FT_Dwarf:83  case MCFragment::FT_DwarfFrame:84  case MCFragment::FT_SFrame: {85    if (isLinkerRelaxable())86      OS << " LinkerRelaxable";87    auto Fixed = getContents();88    auto Var = getVarContents();89    OS << " Size:" << Fixed.size();90    if (getKind() != MCFragment::FT_Data) {91      OS << '+' << Var.size();92      // FT_Align uses getVarContents to track the size, but the content is93      // ignored and not useful.94      if (getKind() == MCFragment::FT_Align)95        Var = {};96    }97    OS << " [";98    for (unsigned i = 0, e = Fixed.size(); i != e; ++i) {99      if (i) OS << ",";100      OS << format("%02x", uint8_t(Fixed[i]));101    }102    for (unsigned i = 0, e = Var.size(); i != e; ++i) {103      if (Fixed.size() || i)104        OS << ",";105      OS << format("%02x", uint8_t(Var[i]));106    }107    OS << ']';108    switch (getKind()) {109    case MCFragment::FT_Data:110      break;111    case MCFragment::FT_Relaxable:112      OS << ' ';113      getInst().dump_pretty(OS);114      break;115    case MCFragment::FT_Align:116      OS << "\n  Align:" << getAlignment().value() << " Fill:" << getAlignFill()117         << " FillLen:" << unsigned(getAlignFillLen())118         << " MaxBytesToEmit:" << getAlignMaxBytesToEmit();119      if (hasAlignEmitNops())120        OS << " Nops";121      break;122    case MCFragment::FT_LEB: {123      OS << " Value:";124      getLEBValue().print(OS, nullptr);125      OS << " Signed:" << isLEBSigned();126      break;127    }128    case MCFragment::FT_Dwarf:129      OS << " AddrDelta:";130      getDwarfAddrDelta().print(OS, nullptr);131      OS << " LineDelta:" << getDwarfLineDelta();132      break;133    case MCFragment::FT_DwarfFrame:134    case MCFragment::FT_SFrame:135      OS << " AddrDelta:";136      getDwarfAddrDelta().print(OS, nullptr);137      break;138    default:139      llvm_unreachable("");140    }141    printFixups(getFixups());142    printFixups(getVarFixups());143    break;144  }145  case MCFragment::FT_Fill:  {146    const auto *FF = cast<MCFillFragment>(this);147    OS << " Value:" << static_cast<unsigned>(FF->getValue())148       << " ValueSize:" << static_cast<unsigned>(FF->getValueSize())149       << " NumValues:";150    FF->getNumValues().print(OS, nullptr);151    break;152  }153  case MCFragment::FT_Nops: {154    const auto *NF = cast<MCNopsFragment>(this);155    OS << " NumBytes:" << NF->getNumBytes()156       << " ControlledNopLength:" << NF->getControlledNopLength();157    break;158  }159  case MCFragment::FT_Org:  {160    const auto *OF = cast<MCOrgFragment>(this);161    OS << " Offset:";162    OF->getOffset().print(OS, nullptr);163    OS << " Value:" << static_cast<unsigned>(OF->getValue());164    break;165  }166  case MCFragment::FT_BoundaryAlign: {167    const auto *BF = cast<MCBoundaryAlignFragment>(this);168    OS << " BoundarySize:" << BF->getAlignment().value()169       << " LastFragment:" << BF->getLastFragment()170       << " Size:" << BF->getSize();171    break;172  }173  case MCFragment::FT_SymbolId: {174    const auto *F = cast<MCSymbolIdFragment>(this);175    OS << " Sym:" << F->getSymbol();176    break;177  }178  case MCFragment::FT_CVInlineLines: {179    const auto *F = cast<MCCVInlineLineTableFragment>(this);180    OS << " Sym:" << *F->getFnStartSym();181    break;182  }183  case MCFragment::FT_CVDefRange: {184    const auto *F = cast<MCCVDefRangeFragment>(this);185    OS << "\n   ";186    for (std::pair<const MCSymbol *, const MCSymbol *> RangeStartEnd :187         F->getRanges()) {188      OS << " RangeStart:" << RangeStartEnd.first;189      OS << " RangeEnd:" << RangeStartEnd.second;190    }191    break;192  }193  }194}195#endif196