1292915Sdim//===- lib/MC/MCFragment.cpp - Assembler Fragment Implementation ----------===// 2292915Sdim// 3292915Sdim// The LLVM Compiler Infrastructure 4292915Sdim// 5292915Sdim// This file is distributed under the University of Illinois Open Source 6292915Sdim// License. See LICENSE.TXT for details. 7292915Sdim// 8292915Sdim//===----------------------------------------------------------------------===// 9292915Sdim 10292915Sdim#include "llvm/MC/MCFragment.h" 11292915Sdim#include "llvm/ADT/StringExtras.h" 12292915Sdim#include "llvm/ADT/Twine.h" 13292915Sdim#include "llvm/MC/MCAsmBackend.h" 14292915Sdim#include "llvm/MC/MCAsmInfo.h" 15292915Sdim#include "llvm/MC/MCAsmLayout.h" 16292915Sdim#include "llvm/MC/MCContext.h" 17292915Sdim#include "llvm/MC/MCDwarf.h" 18292915Sdim#include "llvm/MC/MCExpr.h" 19292915Sdim#include "llvm/MC/MCFixupKindInfo.h" 20292915Sdim#include "llvm/MC/MCSection.h" 21292915Sdim#include "llvm/MC/MCSectionELF.h" 22292915Sdim#include "llvm/MC/MCSymbol.h" 23292915Sdim#include "llvm/MC/MCValue.h" 24292915Sdim#include "llvm/Support/ErrorHandling.h" 25292915Sdim#include "llvm/Support/LEB128.h" 26292915Sdim#include "llvm/Support/TargetRegistry.h" 27292915Sdim#include "llvm/Support/raw_ostream.h" 28292915Sdim#include <tuple> 29292915Sdimusing namespace llvm; 30292915Sdim 31292915SdimMCAsmLayout::MCAsmLayout(MCAssembler &Asm) 32292915Sdim : Assembler(Asm), LastValidFragment() 33292915Sdim { 34292915Sdim // Compute the section layout order. Virtual sections must go last. 35292915Sdim for (MCSection &Sec : Asm) 36292915Sdim if (!Sec.isVirtualSection()) 37292915Sdim SectionOrder.push_back(&Sec); 38292915Sdim for (MCSection &Sec : Asm) 39292915Sdim if (Sec.isVirtualSection()) 40292915Sdim SectionOrder.push_back(&Sec); 41292915Sdim} 42292915Sdim 43292915Sdimbool MCAsmLayout::isFragmentValid(const MCFragment *F) const { 44292915Sdim const MCSection *Sec = F->getParent(); 45292915Sdim const MCFragment *LastValid = LastValidFragment.lookup(Sec); 46292915Sdim if (!LastValid) 47292915Sdim return false; 48292915Sdim assert(LastValid->getParent() == Sec); 49292915Sdim return F->getLayoutOrder() <= LastValid->getLayoutOrder(); 50292915Sdim} 51292915Sdim 52292915Sdimvoid MCAsmLayout::invalidateFragmentsFrom(MCFragment *F) { 53292915Sdim // If this fragment wasn't already valid, we don't need to do anything. 54292915Sdim if (!isFragmentValid(F)) 55292915Sdim return; 56292915Sdim 57292915Sdim // Otherwise, reset the last valid fragment to the previous fragment 58292915Sdim // (if this is the first fragment, it will be NULL). 59292915Sdim LastValidFragment[F->getParent()] = F->getPrevNode(); 60292915Sdim} 61292915Sdim 62292915Sdimvoid MCAsmLayout::ensureValid(const MCFragment *F) const { 63292915Sdim MCSection *Sec = F->getParent(); 64292915Sdim MCSection::iterator I; 65292915Sdim if (MCFragment *Cur = LastValidFragment[Sec]) 66292915Sdim I = ++MCSection::iterator(Cur); 67292915Sdim else 68292915Sdim I = Sec->begin(); 69292915Sdim 70292915Sdim // Advance the layout position until the fragment is valid. 71292915Sdim while (!isFragmentValid(F)) { 72292915Sdim assert(I != Sec->end() && "Layout bookkeeping error"); 73292915Sdim const_cast<MCAsmLayout *>(this)->layoutFragment(&*I); 74292915Sdim ++I; 75292915Sdim } 76292915Sdim} 77292915Sdim 78292915Sdimuint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const { 79292915Sdim ensureValid(F); 80292915Sdim assert(F->Offset != ~UINT64_C(0) && "Address not set!"); 81292915Sdim return F->Offset; 82292915Sdim} 83292915Sdim 84292915Sdim// Simple getSymbolOffset helper for the non-varibale case. 85292915Sdimstatic bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S, 86292915Sdim bool ReportError, uint64_t &Val) { 87292915Sdim if (!S.getFragment()) { 88292915Sdim if (ReportError) 89292915Sdim report_fatal_error("unable to evaluate offset to undefined symbol '" + 90292915Sdim S.getName() + "'"); 91292915Sdim return false; 92292915Sdim } 93292915Sdim Val = Layout.getFragmentOffset(S.getFragment()) + S.getOffset(); 94292915Sdim return true; 95292915Sdim} 96292915Sdim 97292915Sdimstatic bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbol &S, 98292915Sdim bool ReportError, uint64_t &Val) { 99292915Sdim if (!S.isVariable()) 100292915Sdim return getLabelOffset(Layout, S, ReportError, Val); 101292915Sdim 102292915Sdim // If SD is a variable, evaluate it. 103292915Sdim MCValue Target; 104292915Sdim if (!S.getVariableValue()->evaluateAsValue(Target, Layout)) 105292915Sdim report_fatal_error("unable to evaluate offset for variable '" + 106292915Sdim S.getName() + "'"); 107292915Sdim 108292915Sdim uint64_t Offset = Target.getConstant(); 109292915Sdim 110292915Sdim const MCSymbolRefExpr *A = Target.getSymA(); 111292915Sdim if (A) { 112292915Sdim uint64_t ValA; 113292915Sdim if (!getLabelOffset(Layout, A->getSymbol(), ReportError, ValA)) 114292915Sdim return false; 115292915Sdim Offset += ValA; 116292915Sdim } 117292915Sdim 118292915Sdim const MCSymbolRefExpr *B = Target.getSymB(); 119292915Sdim if (B) { 120292915Sdim uint64_t ValB; 121292915Sdim if (!getLabelOffset(Layout, B->getSymbol(), ReportError, ValB)) 122292915Sdim return false; 123292915Sdim Offset -= ValB; 124292915Sdim } 125292915Sdim 126292915Sdim Val = Offset; 127292915Sdim return true; 128292915Sdim} 129292915Sdim 130292915Sdimbool MCAsmLayout::getSymbolOffset(const MCSymbol &S, uint64_t &Val) const { 131292915Sdim return getSymbolOffsetImpl(*this, S, false, Val); 132292915Sdim} 133292915Sdim 134292915Sdimuint64_t MCAsmLayout::getSymbolOffset(const MCSymbol &S) const { 135292915Sdim uint64_t Val; 136292915Sdim getSymbolOffsetImpl(*this, S, true, Val); 137292915Sdim return Val; 138292915Sdim} 139292915Sdim 140292915Sdimconst MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const { 141292915Sdim if (!Symbol.isVariable()) 142292915Sdim return &Symbol; 143292915Sdim 144292915Sdim const MCExpr *Expr = Symbol.getVariableValue(); 145292915Sdim MCValue Value; 146292915Sdim if (!Expr->evaluateAsValue(Value, *this)) { 147292915Sdim Assembler.getContext().reportError( 148292915Sdim SMLoc(), "expression could not be evaluated"); 149292915Sdim return nullptr; 150292915Sdim } 151292915Sdim 152292915Sdim const MCSymbolRefExpr *RefB = Value.getSymB(); 153292915Sdim if (RefB) { 154292915Sdim Assembler.getContext().reportError( 155292915Sdim SMLoc(), Twine("symbol '") + RefB->getSymbol().getName() + 156292915Sdim "' could not be evaluated in a subtraction expression"); 157292915Sdim return nullptr; 158292915Sdim } 159292915Sdim 160292915Sdim const MCSymbolRefExpr *A = Value.getSymA(); 161292915Sdim if (!A) 162292915Sdim return nullptr; 163292915Sdim 164292915Sdim const MCSymbol &ASym = A->getSymbol(); 165292915Sdim const MCAssembler &Asm = getAssembler(); 166292915Sdim if (ASym.isCommon()) { 167292915Sdim // FIXME: we should probably add a SMLoc to MCExpr. 168292915Sdim Asm.getContext().reportError(SMLoc(), 169292915Sdim "Common symbol '" + ASym.getName() + 170292915Sdim "' cannot be used in assignment expr"); 171292915Sdim return nullptr; 172292915Sdim } 173292915Sdim 174292915Sdim return &ASym; 175292915Sdim} 176292915Sdim 177292915Sdimuint64_t MCAsmLayout::getSectionAddressSize(const MCSection *Sec) const { 178292915Sdim // The size is the last fragment's end offset. 179292915Sdim const MCFragment &F = Sec->getFragmentList().back(); 180292915Sdim return getFragmentOffset(&F) + getAssembler().computeFragmentSize(*this, F); 181292915Sdim} 182292915Sdim 183292915Sdimuint64_t MCAsmLayout::getSectionFileSize(const MCSection *Sec) const { 184292915Sdim // Virtual sections have no file size. 185292915Sdim if (Sec->isVirtualSection()) 186292915Sdim return 0; 187292915Sdim 188292915Sdim // Otherwise, the file size is the same as the address space size. 189292915Sdim return getSectionAddressSize(Sec); 190292915Sdim} 191292915Sdim 192292915Sdimuint64_t llvm::computeBundlePadding(const MCAssembler &Assembler, 193292915Sdim const MCFragment *F, 194292915Sdim uint64_t FOffset, uint64_t FSize) { 195292915Sdim uint64_t BundleSize = Assembler.getBundleAlignSize(); 196292915Sdim assert(BundleSize > 0 && 197292915Sdim "computeBundlePadding should only be called if bundling is enabled"); 198292915Sdim uint64_t BundleMask = BundleSize - 1; 199292915Sdim uint64_t OffsetInBundle = FOffset & BundleMask; 200292915Sdim uint64_t EndOfFragment = OffsetInBundle + FSize; 201292915Sdim 202292915Sdim // There are two kinds of bundling restrictions: 203292915Sdim // 204292915Sdim // 1) For alignToBundleEnd(), add padding to ensure that the fragment will 205292915Sdim // *end* on a bundle boundary. 206292915Sdim // 2) Otherwise, check if the fragment would cross a bundle boundary. If it 207292915Sdim // would, add padding until the end of the bundle so that the fragment 208292915Sdim // will start in a new one. 209292915Sdim if (F->alignToBundleEnd()) { 210292915Sdim // Three possibilities here: 211292915Sdim // 212292915Sdim // A) The fragment just happens to end at a bundle boundary, so we're good. 213292915Sdim // B) The fragment ends before the current bundle boundary: pad it just 214292915Sdim // enough to reach the boundary. 215292915Sdim // C) The fragment ends after the current bundle boundary: pad it until it 216292915Sdim // reaches the end of the next bundle boundary. 217292915Sdim // 218292915Sdim // Note: this code could be made shorter with some modulo trickery, but it's 219292915Sdim // intentionally kept in its more explicit form for simplicity. 220292915Sdim if (EndOfFragment == BundleSize) 221292915Sdim return 0; 222292915Sdim else if (EndOfFragment < BundleSize) 223292915Sdim return BundleSize - EndOfFragment; 224292915Sdim else { // EndOfFragment > BundleSize 225292915Sdim return 2 * BundleSize - EndOfFragment; 226292915Sdim } 227292915Sdim } else if (OffsetInBundle > 0 && EndOfFragment > BundleSize) 228292915Sdim return BundleSize - OffsetInBundle; 229292915Sdim else 230292915Sdim return 0; 231292915Sdim} 232292915Sdim 233292915Sdim/* *** */ 234292915Sdim 235292915Sdimvoid ilist_node_traits<MCFragment>::deleteNode(MCFragment *V) { 236292915Sdim V->destroy(); 237292915Sdim} 238292915Sdim 239292915SdimMCFragment::MCFragment() : Kind(FragmentType(~0)), HasInstructions(false), 240292915Sdim AlignToBundleEnd(false), BundlePadding(0) { 241292915Sdim} 242292915Sdim 243292915SdimMCFragment::~MCFragment() { } 244292915Sdim 245292915SdimMCFragment::MCFragment(FragmentType Kind, bool HasInstructions, 246292915Sdim uint8_t BundlePadding, MCSection *Parent) 247292915Sdim : Kind(Kind), HasInstructions(HasInstructions), AlignToBundleEnd(false), 248292915Sdim BundlePadding(BundlePadding), Parent(Parent), Atom(nullptr), 249292915Sdim Offset(~UINT64_C(0)) { 250292915Sdim if (Parent && !isDummy()) 251292915Sdim Parent->getFragmentList().push_back(this); 252292915Sdim} 253292915Sdim 254292915Sdimvoid MCFragment::destroy() { 255292915Sdim // First check if we are the sentinal. 256292915Sdim if (Kind == FragmentType(~0)) { 257292915Sdim delete this; 258292915Sdim return; 259292915Sdim } 260292915Sdim 261292915Sdim switch (Kind) { 262292915Sdim case FT_Align: 263292915Sdim delete cast<MCAlignFragment>(this); 264292915Sdim return; 265292915Sdim case FT_Data: 266292915Sdim delete cast<MCDataFragment>(this); 267292915Sdim return; 268292915Sdim case FT_CompactEncodedInst: 269292915Sdim delete cast<MCCompactEncodedInstFragment>(this); 270292915Sdim return; 271292915Sdim case FT_Fill: 272292915Sdim delete cast<MCFillFragment>(this); 273292915Sdim return; 274292915Sdim case FT_Relaxable: 275292915Sdim delete cast<MCRelaxableFragment>(this); 276292915Sdim return; 277292915Sdim case FT_Org: 278292915Sdim delete cast<MCOrgFragment>(this); 279292915Sdim return; 280292915Sdim case FT_Dwarf: 281292915Sdim delete cast<MCDwarfLineAddrFragment>(this); 282292915Sdim return; 283292915Sdim case FT_DwarfFrame: 284292915Sdim delete cast<MCDwarfCallFrameFragment>(this); 285292915Sdim return; 286292915Sdim case FT_LEB: 287292915Sdim delete cast<MCLEBFragment>(this); 288292915Sdim return; 289292915Sdim case FT_SafeSEH: 290292915Sdim delete cast<MCSafeSEHFragment>(this); 291292915Sdim return; 292292915Sdim case FT_Dummy: 293292915Sdim delete cast<MCDummyFragment>(this); 294292915Sdim return; 295292915Sdim } 296292915Sdim} 297292915Sdim 298292915Sdim/* *** */ 299292915Sdim 300292915Sdim// Debugging methods 301292915Sdim 302292915Sdimnamespace llvm { 303292915Sdim 304292915Sdimraw_ostream &operator<<(raw_ostream &OS, const MCFixup &AF) { 305292915Sdim OS << "<MCFixup" << " Offset:" << AF.getOffset() 306292915Sdim << " Value:" << *AF.getValue() 307292915Sdim << " Kind:" << AF.getKind() << ">"; 308292915Sdim return OS; 309292915Sdim} 310292915Sdim 311292915Sdim} 312292915Sdim 313292915Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 314292915Sdimvoid MCFragment::dump() { 315292915Sdim raw_ostream &OS = llvm::errs(); 316292915Sdim 317292915Sdim OS << "<"; 318292915Sdim switch (getKind()) { 319292915Sdim case MCFragment::FT_Align: OS << "MCAlignFragment"; break; 320292915Sdim case MCFragment::FT_Data: OS << "MCDataFragment"; break; 321292915Sdim case MCFragment::FT_CompactEncodedInst: 322292915Sdim OS << "MCCompactEncodedInstFragment"; break; 323292915Sdim case MCFragment::FT_Fill: OS << "MCFillFragment"; break; 324292915Sdim case MCFragment::FT_Relaxable: OS << "MCRelaxableFragment"; break; 325292915Sdim case MCFragment::FT_Org: OS << "MCOrgFragment"; break; 326292915Sdim case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break; 327292915Sdim case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break; 328292915Sdim case MCFragment::FT_LEB: OS << "MCLEBFragment"; break; 329292915Sdim case MCFragment::FT_SafeSEH: OS << "MCSafeSEHFragment"; break; 330292915Sdim case MCFragment::FT_Dummy: 331292915Sdim OS << "MCDummyFragment"; 332292915Sdim break; 333292915Sdim } 334292915Sdim 335292915Sdim OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder 336292915Sdim << " Offset:" << Offset 337292915Sdim << " HasInstructions:" << hasInstructions() 338292915Sdim << " BundlePadding:" << static_cast<unsigned>(getBundlePadding()) << ">"; 339292915Sdim 340292915Sdim switch (getKind()) { 341292915Sdim case MCFragment::FT_Align: { 342292915Sdim const MCAlignFragment *AF = cast<MCAlignFragment>(this); 343292915Sdim if (AF->hasEmitNops()) 344292915Sdim OS << " (emit nops)"; 345292915Sdim OS << "\n "; 346292915Sdim OS << " Alignment:" << AF->getAlignment() 347292915Sdim << " Value:" << AF->getValue() << " ValueSize:" << AF->getValueSize() 348292915Sdim << " MaxBytesToEmit:" << AF->getMaxBytesToEmit() << ">"; 349292915Sdim break; 350292915Sdim } 351292915Sdim case MCFragment::FT_Data: { 352292915Sdim const MCDataFragment *DF = cast<MCDataFragment>(this); 353292915Sdim OS << "\n "; 354292915Sdim OS << " Contents:["; 355292915Sdim const SmallVectorImpl<char> &Contents = DF->getContents(); 356292915Sdim for (unsigned i = 0, e = Contents.size(); i != e; ++i) { 357292915Sdim if (i) OS << ","; 358292915Sdim OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF); 359292915Sdim } 360292915Sdim OS << "] (" << Contents.size() << " bytes)"; 361292915Sdim 362292915Sdim if (DF->fixup_begin() != DF->fixup_end()) { 363292915Sdim OS << ",\n "; 364292915Sdim OS << " Fixups:["; 365292915Sdim for (MCDataFragment::const_fixup_iterator it = DF->fixup_begin(), 366292915Sdim ie = DF->fixup_end(); it != ie; ++it) { 367292915Sdim if (it != DF->fixup_begin()) OS << ",\n "; 368292915Sdim OS << *it; 369292915Sdim } 370292915Sdim OS << "]"; 371292915Sdim } 372292915Sdim break; 373292915Sdim } 374292915Sdim case MCFragment::FT_CompactEncodedInst: { 375292915Sdim const MCCompactEncodedInstFragment *CEIF = 376292915Sdim cast<MCCompactEncodedInstFragment>(this); 377292915Sdim OS << "\n "; 378292915Sdim OS << " Contents:["; 379292915Sdim const SmallVectorImpl<char> &Contents = CEIF->getContents(); 380292915Sdim for (unsigned i = 0, e = Contents.size(); i != e; ++i) { 381292915Sdim if (i) OS << ","; 382292915Sdim OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF); 383292915Sdim } 384292915Sdim OS << "] (" << Contents.size() << " bytes)"; 385292915Sdim break; 386292915Sdim } 387292915Sdim case MCFragment::FT_Fill: { 388292915Sdim const MCFillFragment *FF = cast<MCFillFragment>(this); 389292915Sdim OS << " Value:" << FF->getValue() << " ValueSize:" << FF->getValueSize() 390292915Sdim << " Size:" << FF->getSize(); 391292915Sdim break; 392292915Sdim } 393292915Sdim case MCFragment::FT_Relaxable: { 394292915Sdim const MCRelaxableFragment *F = cast<MCRelaxableFragment>(this); 395292915Sdim OS << "\n "; 396292915Sdim OS << " Inst:"; 397292915Sdim F->getInst().dump_pretty(OS); 398292915Sdim break; 399292915Sdim } 400292915Sdim case MCFragment::FT_Org: { 401292915Sdim const MCOrgFragment *OF = cast<MCOrgFragment>(this); 402292915Sdim OS << "\n "; 403292915Sdim OS << " Offset:" << OF->getOffset() << " Value:" << OF->getValue(); 404292915Sdim break; 405292915Sdim } 406292915Sdim case MCFragment::FT_Dwarf: { 407292915Sdim const MCDwarfLineAddrFragment *OF = cast<MCDwarfLineAddrFragment>(this); 408292915Sdim OS << "\n "; 409292915Sdim OS << " AddrDelta:" << OF->getAddrDelta() 410292915Sdim << " LineDelta:" << OF->getLineDelta(); 411292915Sdim break; 412292915Sdim } 413292915Sdim case MCFragment::FT_DwarfFrame: { 414292915Sdim const MCDwarfCallFrameFragment *CF = cast<MCDwarfCallFrameFragment>(this); 415292915Sdim OS << "\n "; 416292915Sdim OS << " AddrDelta:" << CF->getAddrDelta(); 417292915Sdim break; 418292915Sdim } 419292915Sdim case MCFragment::FT_LEB: { 420292915Sdim const MCLEBFragment *LF = cast<MCLEBFragment>(this); 421292915Sdim OS << "\n "; 422292915Sdim OS << " Value:" << LF->getValue() << " Signed:" << LF->isSigned(); 423292915Sdim break; 424292915Sdim } 425292915Sdim case MCFragment::FT_SafeSEH: { 426292915Sdim const MCSafeSEHFragment *F = cast<MCSafeSEHFragment>(this); 427292915Sdim OS << "\n "; 428292915Sdim OS << " Sym:" << F->getSymbol(); 429292915Sdim break; 430292915Sdim } 431292915Sdim case MCFragment::FT_Dummy: 432292915Sdim break; 433292915Sdim } 434292915Sdim OS << ">"; 435292915Sdim} 436292915Sdim 437292915Sdimvoid MCAssembler::dump() { 438292915Sdim raw_ostream &OS = llvm::errs(); 439292915Sdim 440292915Sdim OS << "<MCAssembler\n"; 441292915Sdim OS << " Sections:[\n "; 442292915Sdim for (iterator it = begin(), ie = end(); it != ie; ++it) { 443292915Sdim if (it != begin()) OS << ",\n "; 444292915Sdim it->dump(); 445292915Sdim } 446292915Sdim OS << "],\n"; 447292915Sdim OS << " Symbols:["; 448292915Sdim 449292915Sdim for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) { 450292915Sdim if (it != symbol_begin()) OS << ",\n "; 451292915Sdim OS << "("; 452292915Sdim it->dump(); 453292915Sdim OS << ", Index:" << it->getIndex() << ", "; 454292915Sdim OS << ")"; 455292915Sdim } 456292915Sdim OS << "]>\n"; 457292915Sdim} 458292915Sdim#endif 459