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