1198090Srdivacky//===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===// 2198090Srdivacky// 3198090Srdivacky// The LLVM Compiler Infrastructure 4198090Srdivacky// 5198090Srdivacky// This file is distributed under the University of Illinois Open Source 6198090Srdivacky// License. See LICENSE.TXT for details. 7198090Srdivacky// 8198090Srdivacky//===----------------------------------------------------------------------===// 9198090Srdivacky 10198090Srdivacky#define DEBUG_TYPE "assembler" 11198090Srdivacky#include "llvm/MC/MCAssembler.h" 12252723Sdim#include "llvm/ADT/Statistic.h" 13252723Sdim#include "llvm/ADT/StringExtras.h" 14252723Sdim#include "llvm/ADT/Twine.h" 15252723Sdim#include "llvm/MC/MCAsmBackend.h" 16205218Srdivacky#include "llvm/MC/MCAsmLayout.h" 17205407Srdivacky#include "llvm/MC/MCCodeEmitter.h" 18218893Sdim#include "llvm/MC/MCContext.h" 19252723Sdim#include "llvm/MC/MCDwarf.h" 20198396Srdivacky#include "llvm/MC/MCExpr.h" 21235633Sdim#include "llvm/MC/MCFixupKindInfo.h" 22205407Srdivacky#include "llvm/MC/MCObjectWriter.h" 23218893Sdim#include "llvm/MC/MCSection.h" 24198396Srdivacky#include "llvm/MC/MCSymbol.h" 25198396Srdivacky#include "llvm/MC/MCValue.h" 26206083Srdivacky#include "llvm/Support/Debug.h" 27198090Srdivacky#include "llvm/Support/ErrorHandling.h" 28252723Sdim#include "llvm/Support/LEB128.h" 29252723Sdim#include "llvm/Support/TargetRegistry.h" 30198090Srdivacky#include "llvm/Support/raw_ostream.h" 31203954Srdivacky 32198090Srdivackyusing namespace llvm; 33198090Srdivacky 34206083Srdivackynamespace { 35206083Srdivackynamespace stats { 36252723SdimSTATISTIC(EmittedFragments, "Number of emitted assembler fragments - total"); 37252723SdimSTATISTIC(EmittedRelaxableFragments, 38252723Sdim "Number of emitted assembler fragments - relaxable"); 39252723SdimSTATISTIC(EmittedDataFragments, 40252723Sdim "Number of emitted assembler fragments - data"); 41252723SdimSTATISTIC(EmittedCompactEncodedInstFragments, 42252723Sdim "Number of emitted assembler fragments - compact encoded inst"); 43252723SdimSTATISTIC(EmittedAlignFragments, 44252723Sdim "Number of emitted assembler fragments - align"); 45252723SdimSTATISTIC(EmittedFillFragments, 46252723Sdim "Number of emitted assembler fragments - fill"); 47252723SdimSTATISTIC(EmittedOrgFragments, 48252723Sdim "Number of emitted assembler fragments - org"); 49235633SdimSTATISTIC(evaluateFixup, "Number of evaluated fixups"); 50206083SrdivackySTATISTIC(FragmentLayouts, "Number of fragment layouts"); 51206083SrdivackySTATISTIC(ObjectBytes, "Number of emitted object file bytes"); 52206083SrdivackySTATISTIC(RelaxationSteps, "Number of assembler layout and relaxation steps"); 53206083SrdivackySTATISTIC(RelaxedInstructions, "Number of relaxed instructions"); 54206083Srdivacky} 55206083Srdivacky} 56198090Srdivacky 57198090Srdivacky// FIXME FIXME FIXME: There are number of places in this file where we convert 58198090Srdivacky// what is a 64-bit assembler value used for computation into a value in the 59198090Srdivacky// object file, which may truncate it. We should detect that truncation where 60198090Srdivacky// invalid and report errors back. 61198090Srdivacky 62198090Srdivacky/* *** */ 63198090Srdivacky 64208599SrdivackyMCAsmLayout::MCAsmLayout(MCAssembler &Asm) 65218893Sdim : Assembler(Asm), LastValidFragment() 66208599Srdivacky { 67208599Srdivacky // Compute the section layout order. Virtual sections must go last. 68208599Srdivacky for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) 69218893Sdim if (!it->getSection().isVirtualSection()) 70208599Srdivacky SectionOrder.push_back(&*it); 71208599Srdivacky for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) 72218893Sdim if (it->getSection().isVirtualSection()) 73208599Srdivacky SectionOrder.push_back(&*it); 74208599Srdivacky} 75206083Srdivacky 76252723Sdimbool MCAsmLayout::isFragmentValid(const MCFragment *F) const { 77218893Sdim const MCSectionData &SD = *F->getParent(); 78218893Sdim const MCFragment *LastValid = LastValidFragment.lookup(&SD); 79218893Sdim if (!LastValid) 80218893Sdim return false; 81218893Sdim assert(LastValid->getParent() == F->getParent()); 82218893Sdim return F->getLayoutOrder() <= LastValid->getLayoutOrder(); 83208599Srdivacky} 84208599Srdivacky 85252723Sdimvoid MCAsmLayout::invalidateFragmentsFrom(MCFragment *F) { 86252723Sdim // If this fragment wasn't already valid, we don't need to do anything. 87252723Sdim if (!isFragmentValid(F)) 88208599Srdivacky return; 89208599Srdivacky 90252723Sdim // Otherwise, reset the last valid fragment to the previous fragment 91252723Sdim // (if this is the first fragment, it will be NULL). 92218893Sdim const MCSectionData &SD = *F->getParent(); 93252723Sdim LastValidFragment[&SD] = F->getPrevNode(); 94208599Srdivacky} 95206083Srdivacky 96252723Sdimvoid MCAsmLayout::ensureValid(const MCFragment *F) const { 97218893Sdim MCSectionData &SD = *F->getParent(); 98218893Sdim 99218893Sdim MCFragment *Cur = LastValidFragment[&SD]; 100218893Sdim if (!Cur) 101218893Sdim Cur = &*SD.begin(); 102218893Sdim else 103218893Sdim Cur = Cur->getNextNode(); 104218893Sdim 105252723Sdim // Advance the layout position until the fragment is valid. 106252723Sdim while (!isFragmentValid(F)) { 107252723Sdim assert(Cur && "Layout bookkeeping error"); 108252723Sdim const_cast<MCAsmLayout*>(this)->layoutFragment(Cur); 109218893Sdim Cur = Cur->getNextNode(); 110206083Srdivacky } 111206083Srdivacky} 112206083Srdivacky 113206083Srdivackyuint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const { 114252723Sdim ensureValid(F); 115206083Srdivacky assert(F->Offset != ~UINT64_C(0) && "Address not set!"); 116206083Srdivacky return F->Offset; 117206083Srdivacky} 118206083Srdivacky 119218893Sdimuint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const { 120221345Sdim const MCSymbol &S = SD->getSymbol(); 121221345Sdim 122221345Sdim // If this is a variable, then recursively evaluate now. 123221345Sdim if (S.isVariable()) { 124221345Sdim MCValue Target; 125221345Sdim if (!S.getVariableValue()->EvaluateAsRelocatable(Target, *this)) 126221345Sdim report_fatal_error("unable to evaluate offset for variable '" + 127221345Sdim S.getName() + "'"); 128221345Sdim 129221345Sdim // Verify that any used symbols are defined. 130221345Sdim if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined()) 131221345Sdim report_fatal_error("unable to evaluate offset to undefined symbol '" + 132221345Sdim Target.getSymA()->getSymbol().getName() + "'"); 133221345Sdim if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined()) 134221345Sdim report_fatal_error("unable to evaluate offset to undefined symbol '" + 135221345Sdim Target.getSymB()->getSymbol().getName() + "'"); 136235633Sdim 137221345Sdim uint64_t Offset = Target.getConstant(); 138221345Sdim if (Target.getSymA()) 139221345Sdim Offset += getSymbolOffset(&Assembler.getSymbolData( 140221345Sdim Target.getSymA()->getSymbol())); 141221345Sdim if (Target.getSymB()) 142221345Sdim Offset -= getSymbolOffset(&Assembler.getSymbolData( 143221345Sdim Target.getSymB()->getSymbol())); 144221345Sdim return Offset; 145221345Sdim } 146221345Sdim 147218893Sdim assert(SD->getFragment() && "Invalid getOffset() on undefined symbol!"); 148218893Sdim return getFragmentOffset(SD->getFragment()) + SD->getOffset(); 149206083Srdivacky} 150206083Srdivacky 151208599Srdivackyuint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const { 152208599Srdivacky // The size is the last fragment's end offset. 153208599Srdivacky const MCFragment &F = SD->getFragmentList().back(); 154235633Sdim return getFragmentOffset(&F) + getAssembler().computeFragmentSize(*this, F); 155206083Srdivacky} 156206083Srdivacky 157208599Srdivackyuint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const { 158208599Srdivacky // Virtual sections have no file size. 159218893Sdim if (SD->getSection().isVirtualSection()) 160208599Srdivacky return 0; 161208599Srdivacky 162208599Srdivacky // Otherwise, the file size is the same as the address space size. 163208599Srdivacky return getSectionAddressSize(SD); 164206083Srdivacky} 165206083Srdivacky 166252723Sdimuint64_t MCAsmLayout::computeBundlePadding(const MCFragment *F, 167252723Sdim uint64_t FOffset, uint64_t FSize) { 168252723Sdim uint64_t BundleSize = Assembler.getBundleAlignSize(); 169252723Sdim assert(BundleSize > 0 && 170252723Sdim "computeBundlePadding should only be called if bundling is enabled"); 171252723Sdim uint64_t BundleMask = BundleSize - 1; 172252723Sdim uint64_t OffsetInBundle = FOffset & BundleMask; 173252723Sdim uint64_t EndOfFragment = OffsetInBundle + FSize; 174252723Sdim 175252723Sdim // There are two kinds of bundling restrictions: 176252723Sdim // 177252723Sdim // 1) For alignToBundleEnd(), add padding to ensure that the fragment will 178252723Sdim // *end* on a bundle boundary. 179252723Sdim // 2) Otherwise, check if the fragment would cross a bundle boundary. If it 180252723Sdim // would, add padding until the end of the bundle so that the fragment 181252723Sdim // will start in a new one. 182252723Sdim if (F->alignToBundleEnd()) { 183252723Sdim // Three possibilities here: 184252723Sdim // 185252723Sdim // A) The fragment just happens to end at a bundle boundary, so we're good. 186252723Sdim // B) The fragment ends before the current bundle boundary: pad it just 187252723Sdim // enough to reach the boundary. 188252723Sdim // C) The fragment ends after the current bundle boundary: pad it until it 189252723Sdim // reaches the end of the next bundle boundary. 190252723Sdim // 191252723Sdim // Note: this code could be made shorter with some modulo trickery, but it's 192252723Sdim // intentionally kept in its more explicit form for simplicity. 193252723Sdim if (EndOfFragment == BundleSize) 194252723Sdim return 0; 195252723Sdim else if (EndOfFragment < BundleSize) 196252723Sdim return BundleSize - EndOfFragment; 197252723Sdim else { // EndOfFragment > BundleSize 198252723Sdim return 2 * BundleSize - EndOfFragment; 199252723Sdim } 200252723Sdim } else if (EndOfFragment > BundleSize) 201252723Sdim return BundleSize - OffsetInBundle; 202252723Sdim else 203252723Sdim return 0; 204252723Sdim} 205252723Sdim 206206083Srdivacky/* *** */ 207206083Srdivacky 208198090SrdivackyMCFragment::MCFragment() : Kind(FragmentType(~0)) { 209198090Srdivacky} 210198090Srdivacky 211212904SdimMCFragment::~MCFragment() { 212212904Sdim} 213212904Sdim 214198090SrdivackyMCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent) 215218893Sdim : Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0)) 216198090Srdivacky{ 217198090Srdivacky if (Parent) 218198090Srdivacky Parent->getFragmentList().push_back(this); 219198090Srdivacky} 220198090Srdivacky 221198090Srdivacky/* *** */ 222198090Srdivacky 223252723SdimMCEncodedFragment::~MCEncodedFragment() { 224252723Sdim} 225252723Sdim 226252723Sdim/* *** */ 227252723Sdim 228252723SdimMCEncodedFragmentWithFixups::~MCEncodedFragmentWithFixups() { 229252723Sdim} 230252723Sdim 231252723Sdim/* *** */ 232252723Sdim 233198090SrdivackyMCSectionData::MCSectionData() : Section(0) {} 234198090Srdivacky 235198090SrdivackyMCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) 236198090Srdivacky : Section(&_Section), 237218893Sdim Ordinal(~UINT32_C(0)), 238198090Srdivacky Alignment(1), 239252723Sdim BundleLockState(NotBundleLocked), BundleGroupBeforeFirstInst(false), 240203954Srdivacky HasInstructions(false) 241198090Srdivacky{ 242198090Srdivacky if (A) 243198090Srdivacky A->getSectionList().push_back(this); 244198090Srdivacky} 245198090Srdivacky 246252723SdimMCSectionData::iterator 247252723SdimMCSectionData::getSubsectionInsertionPoint(unsigned Subsection) { 248252723Sdim if (Subsection == 0 && SubsectionFragmentMap.empty()) 249252723Sdim return end(); 250252723Sdim 251252723Sdim SmallVectorImpl<std::pair<unsigned, MCFragment *> >::iterator MI = 252252723Sdim std::lower_bound(SubsectionFragmentMap.begin(), SubsectionFragmentMap.end(), 253252723Sdim std::make_pair(Subsection, (MCFragment *)0)); 254252723Sdim bool ExactMatch = false; 255252723Sdim if (MI != SubsectionFragmentMap.end()) { 256252723Sdim ExactMatch = MI->first == Subsection; 257252723Sdim if (ExactMatch) 258252723Sdim ++MI; 259252723Sdim } 260252723Sdim iterator IP; 261252723Sdim if (MI == SubsectionFragmentMap.end()) 262252723Sdim IP = end(); 263252723Sdim else 264252723Sdim IP = MI->second; 265252723Sdim if (!ExactMatch && Subsection != 0) { 266252723Sdim // The GNU as documentation claims that subsections have an alignment of 4, 267252723Sdim // although this appears not to be the case. 268252723Sdim MCFragment *F = new MCDataFragment(); 269252723Sdim SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F)); 270252723Sdim getFragmentList().insert(IP, F); 271252723Sdim F->setParent(this); 272252723Sdim } 273252723Sdim return IP; 274252723Sdim} 275252723Sdim 276198090Srdivacky/* *** */ 277198090Srdivacky 278198090SrdivackyMCSymbolData::MCSymbolData() : Symbol(0) {} 279198090Srdivacky 280198090SrdivackyMCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, 281198090Srdivacky uint64_t _Offset, MCAssembler *A) 282198090Srdivacky : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset), 283198090Srdivacky IsExternal(false), IsPrivateExtern(false), 284212904Sdim CommonSize(0), SymbolSize(0), CommonAlign(0), 285212904Sdim Flags(0), Index(0) 286198090Srdivacky{ 287198090Srdivacky if (A) 288198090Srdivacky A->getSymbolList().push_back(this); 289198090Srdivacky} 290198090Srdivacky 291198090Srdivacky/* *** */ 292198090Srdivacky 293226890SdimMCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, 294218893Sdim MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, 295218893Sdim raw_ostream &OS_) 296218893Sdim : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_), 297252723Sdim OS(OS_), BundleAlignSize(0), RelaxAll(false), NoExecStack(false), 298252723Sdim SubsectionsViaSymbols(false), ELFHeaderEFlags(0) { 299198090Srdivacky} 300198090Srdivacky 301198090SrdivackyMCAssembler::~MCAssembler() { 302198090Srdivacky} 303198090Srdivacky 304252723Sdimvoid MCAssembler::reset() { 305252723Sdim Sections.clear(); 306252723Sdim Symbols.clear(); 307252723Sdim SectionMap.clear(); 308252723Sdim SymbolMap.clear(); 309252723Sdim IndirectSymbols.clear(); 310252723Sdim DataRegions.clear(); 311252723Sdim ThumbFuncs.clear(); 312252723Sdim RelaxAll = false; 313252723Sdim NoExecStack = false; 314252723Sdim SubsectionsViaSymbols = false; 315252723Sdim ELFHeaderEFlags = 0; 316252723Sdim 317252723Sdim // reset objects owned by us 318252723Sdim getBackend().reset(); 319252723Sdim getEmitter().reset(); 320252723Sdim getWriter().reset(); 321252723Sdim} 322252723Sdim 323210299Sedbool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const { 324205407Srdivacky // Non-temporary labels should always be visible to the linker. 325210299Sed if (!Symbol.isTemporary()) 326205407Srdivacky return true; 327205407Srdivacky 328205407Srdivacky // Absolute temporary labels are never visible. 329210299Sed if (!Symbol.isInSection()) 330205407Srdivacky return false; 331205407Srdivacky 332205407Srdivacky // Otherwise, check if the section requires symbols even for temporary labels. 333210299Sed return getBackend().doesSectionRequireSymbols(Symbol.getSection()); 334205407Srdivacky} 335205407Srdivacky 336218893Sdimconst MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const { 337205407Srdivacky // Linker visible symbols define atoms. 338210299Sed if (isSymbolLinkerVisible(SD->getSymbol())) 339205407Srdivacky return SD; 340205407Srdivacky 341205407Srdivacky // Absolute and undefined symbols have no defining atom. 342205407Srdivacky if (!SD->getFragment()) 343205407Srdivacky return 0; 344205407Srdivacky 345208599Srdivacky // Non-linker visible symbols in sections which can't be atomized have no 346208599Srdivacky // defining atom. 347208599Srdivacky if (!getBackend().isSectionAtomizable( 348208599Srdivacky SD->getFragment()->getParent()->getSection())) 349208599Srdivacky return 0; 350208599Srdivacky 351208599Srdivacky // Otherwise, return the atom for the containing fragment. 352208599Srdivacky return SD->getFragment()->getAtom(); 353205407Srdivacky} 354205407Srdivacky 355235633Sdimbool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, 356208599Srdivacky const MCFixup &Fixup, const MCFragment *DF, 357205218Srdivacky MCValue &Target, uint64_t &Value) const { 358235633Sdim ++stats::evaluateFixup; 359206083Srdivacky 360218893Sdim if (!Fixup.getValue()->EvaluateAsRelocatable(Target, Layout)) 361235633Sdim getContext().FatalError(Fixup.getLoc(), "expected relocatable expression"); 362205218Srdivacky 363218893Sdim bool IsPCRel = Backend.getFixupKindInfo( 364218893Sdim Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; 365205218Srdivacky 366218893Sdim bool IsResolved; 367218893Sdim if (IsPCRel) { 368218893Sdim if (Target.getSymB()) { 369218893Sdim IsResolved = false; 370218893Sdim } else if (!Target.getSymA()) { 371218893Sdim IsResolved = false; 372218893Sdim } else { 373218893Sdim const MCSymbolRefExpr *A = Target.getSymA(); 374218893Sdim const MCSymbol &SA = A->getSymbol(); 375218893Sdim if (A->getKind() != MCSymbolRefExpr::VK_None || 376218893Sdim SA.AliasedSymbol().isUndefined()) { 377218893Sdim IsResolved = false; 378218893Sdim } else { 379218893Sdim const MCSymbolData &DataA = getSymbolData(SA); 380218893Sdim IsResolved = 381218893Sdim getWriter().IsSymbolRefDifferenceFullyResolvedImpl(*this, DataA, 382218893Sdim *DF, false, true); 383218893Sdim } 384218893Sdim } 385218893Sdim } else { 386218893Sdim IsResolved = Target.isAbsolute(); 387218893Sdim } 388218893Sdim 389205218Srdivacky Value = Target.getConstant(); 390205218Srdivacky 391205407Srdivacky if (const MCSymbolRefExpr *A = Target.getSymA()) { 392218893Sdim const MCSymbol &Sym = A->getSymbol().AliasedSymbol(); 393218893Sdim if (Sym.isDefined()) 394218893Sdim Value += Layout.getSymbolOffset(&getSymbolData(Sym)); 395205218Srdivacky } 396205407Srdivacky if (const MCSymbolRefExpr *B = Target.getSymB()) { 397218893Sdim const MCSymbol &Sym = B->getSymbol().AliasedSymbol(); 398218893Sdim if (Sym.isDefined()) 399218893Sdim Value -= Layout.getSymbolOffset(&getSymbolData(Sym)); 400205407Srdivacky } 401205218Srdivacky 402205407Srdivacky 403218893Sdim bool ShouldAlignPC = Backend.getFixupKindInfo(Fixup.getKind()).Flags & 404218893Sdim MCFixupKindInfo::FKF_IsAlignedDownTo32Bits; 405218893Sdim assert((ShouldAlignPC ? IsPCRel : true) && 406218893Sdim "FKF_IsAlignedDownTo32Bits is only allowed on PC-relative fixups!"); 407205407Srdivacky 408218893Sdim if (IsPCRel) { 409218893Sdim uint32_t Offset = Layout.getFragmentOffset(DF) + Fixup.getOffset(); 410235633Sdim 411218893Sdim // A number of ARM fixups in Thumb mode require that the effective PC 412218893Sdim // address be determined as the 32-bit aligned version of the actual offset. 413218893Sdim if (ShouldAlignPC) Offset &= ~0x3; 414218893Sdim Value -= Offset; 415205218Srdivacky } 416205218Srdivacky 417235633Sdim // Let the backend adjust the fixup value if necessary, including whether 418235633Sdim // we need a relocation. 419235633Sdim Backend.processFixupValue(*this, Layout, Fixup, DF, Target, Value, 420235633Sdim IsResolved); 421205218Srdivacky 422205218Srdivacky return IsResolved; 423205218Srdivacky} 424205218Srdivacky 425235633Sdimuint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, 426218893Sdim const MCFragment &F) const { 427208599Srdivacky switch (F.getKind()) { 428208599Srdivacky case MCFragment::FT_Data: 429252723Sdim case MCFragment::FT_Relaxable: 430252723Sdim case MCFragment::FT_CompactEncodedInst: 431252723Sdim return cast<MCEncodedFragment>(F).getContents().size(); 432208599Srdivacky case MCFragment::FT_Fill: 433208599Srdivacky return cast<MCFillFragment>(F).getSize(); 434198090Srdivacky 435218893Sdim case MCFragment::FT_LEB: 436218893Sdim return cast<MCLEBFragment>(F).getContents().size(); 437218893Sdim 438208599Srdivacky case MCFragment::FT_Align: { 439208599Srdivacky const MCAlignFragment &AF = cast<MCAlignFragment>(F); 440218893Sdim unsigned Offset = Layout.getFragmentOffset(&AF); 441218893Sdim unsigned Size = OffsetToAlignment(Offset, AF.getAlignment()); 442245431Sdim // If we are padding with nops, force the padding to be larger than the 443245431Sdim // minimum nop size. 444245431Sdim if (Size > 0 && AF.hasEmitNops()) { 445245431Sdim while (Size % getBackend().getMinimumNopSize()) 446245431Sdim Size += AF.getAlignment(); 447245431Sdim } 448208599Srdivacky if (Size > AF.getMaxBytesToEmit()) 449208599Srdivacky return 0; 450208599Srdivacky return Size; 451208599Srdivacky } 452198090Srdivacky 453208599Srdivacky case MCFragment::FT_Org: { 454252723Sdim const MCOrgFragment &OF = cast<MCOrgFragment>(F); 455208599Srdivacky int64_t TargetLocation; 456218893Sdim if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, Layout)) 457208599Srdivacky report_fatal_error("expected assembly-time absolute expression"); 458206083Srdivacky 459208599Srdivacky // FIXME: We need a way to communicate this error. 460218893Sdim uint64_t FragmentOffset = Layout.getFragmentOffset(&OF); 461218893Sdim int64_t Size = TargetLocation - FragmentOffset; 462218893Sdim if (Size < 0 || Size >= 0x40000000) 463208599Srdivacky report_fatal_error("invalid .org offset '" + Twine(TargetLocation) + 464218893Sdim "' (at offset '" + Twine(FragmentOffset) + "')"); 465218893Sdim return Size; 466218893Sdim } 467198396Srdivacky 468218893Sdim case MCFragment::FT_Dwarf: 469218893Sdim return cast<MCDwarfLineAddrFragment>(F).getContents().size(); 470218893Sdim case MCFragment::FT_DwarfFrame: 471218893Sdim return cast<MCDwarfCallFrameFragment>(F).getContents().size(); 472208599Srdivacky } 473198090Srdivacky 474235633Sdim llvm_unreachable("invalid fragment kind"); 475208599Srdivacky} 476198090Srdivacky 477252723Sdimvoid MCAsmLayout::layoutFragment(MCFragment *F) { 478208599Srdivacky MCFragment *Prev = F->getPrevNode(); 479206083Srdivacky 480252723Sdim // We should never try to recompute something which is valid. 481252723Sdim assert(!isFragmentValid(F) && "Attempt to recompute a valid fragment!"); 482252723Sdim // We should never try to compute the fragment layout if its predecessor 483252723Sdim // isn't valid. 484252723Sdim assert((!Prev || isFragmentValid(Prev)) && 485252723Sdim "Attempt to compute fragment before its predecessor!"); 486198090Srdivacky 487208599Srdivacky ++stats::FragmentLayouts; 488198396Srdivacky 489218893Sdim // Compute fragment offset and size. 490208599Srdivacky if (Prev) 491252723Sdim F->Offset = Prev->Offset + getAssembler().computeFragmentSize(*this, *Prev); 492252723Sdim else 493252723Sdim F->Offset = 0; 494252723Sdim LastValidFragment[F->getParent()] = F; 495198396Srdivacky 496252723Sdim // If bundling is enabled and this fragment has instructions in it, it has to 497252723Sdim // obey the bundling restrictions. With padding, we'll have: 498252723Sdim // 499252723Sdim // 500252723Sdim // BundlePadding 501252723Sdim // ||| 502252723Sdim // ------------------------------------- 503252723Sdim // Prev |##########| F | 504252723Sdim // ------------------------------------- 505252723Sdim // ^ 506252723Sdim // | 507252723Sdim // F->Offset 508252723Sdim // 509252723Sdim // The fragment's offset will point to after the padding, and its computed 510252723Sdim // size won't include the padding. 511252723Sdim // 512252723Sdim if (Assembler.isBundlingEnabled() && F->hasInstructions()) { 513252723Sdim assert(isa<MCEncodedFragment>(F) && 514252723Sdim "Only MCEncodedFragment implementations have instructions"); 515252723Sdim uint64_t FSize = Assembler.computeFragmentSize(*this, *F); 516252723Sdim 517252723Sdim if (FSize > Assembler.getBundleAlignSize()) 518252723Sdim report_fatal_error("Fragment can't be larger than a bundle size"); 519252723Sdim 520252723Sdim uint64_t RequiredBundlePadding = computeBundlePadding(F, F->Offset, FSize); 521252723Sdim if (RequiredBundlePadding > UINT8_MAX) 522252723Sdim report_fatal_error("Padding cannot exceed 255 bytes"); 523252723Sdim F->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding)); 524252723Sdim F->Offset += RequiredBundlePadding; 525252723Sdim } 526208599Srdivacky} 527198090Srdivacky 528252723Sdim/// \brief Write the contents of a fragment to the given object writer. Expects 529252723Sdim/// a MCEncodedFragment. 530252723Sdimstatic void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) { 531252723Sdim const MCEncodedFragment &EF = cast<MCEncodedFragment>(F); 532252723Sdim OW->WriteBytes(EF.getContents()); 533252723Sdim} 534252723Sdim 535252723Sdim/// \brief Write the fragment \p F to the output file. 536252723Sdimstatic void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, 537252723Sdim const MCFragment &F) { 538218893Sdim MCObjectWriter *OW = &Asm.getWriter(); 539252723Sdim 540252723Sdim // FIXME: Embed in fragments instead? 541252723Sdim uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F); 542252723Sdim 543252723Sdim // Should NOP padding be written out before this fragment? 544252723Sdim unsigned BundlePadding = F.getBundlePadding(); 545252723Sdim if (BundlePadding > 0) { 546252723Sdim assert(Asm.isBundlingEnabled() && 547252723Sdim "Writing bundle padding with disabled bundling"); 548252723Sdim assert(F.hasInstructions() && 549252723Sdim "Writing bundle padding for a fragment without instructions"); 550252723Sdim 551252723Sdim unsigned TotalLength = BundlePadding + static_cast<unsigned>(FragmentSize); 552252723Sdim if (F.alignToBundleEnd() && TotalLength > Asm.getBundleAlignSize()) { 553252723Sdim // If the padding itself crosses a bundle boundary, it must be emitted 554252723Sdim // in 2 pieces, since even nop instructions must not cross boundaries. 555252723Sdim // v--------------v <- BundleAlignSize 556252723Sdim // v---------v <- BundlePadding 557252723Sdim // ---------------------------- 558252723Sdim // | Prev |####|####| F | 559252723Sdim // ---------------------------- 560252723Sdim // ^-------------------^ <- TotalLength 561252723Sdim unsigned DistanceToBoundary = TotalLength - Asm.getBundleAlignSize(); 562252723Sdim if (!Asm.getBackend().writeNopData(DistanceToBoundary, OW)) 563252723Sdim report_fatal_error("unable to write NOP sequence of " + 564252723Sdim Twine(DistanceToBoundary) + " bytes"); 565252723Sdim BundlePadding -= DistanceToBoundary; 566252723Sdim } 567252723Sdim if (!Asm.getBackend().writeNopData(BundlePadding, OW)) 568252723Sdim report_fatal_error("unable to write NOP sequence of " + 569252723Sdim Twine(BundlePadding) + " bytes"); 570252723Sdim } 571252723Sdim 572252723Sdim // This variable (and its dummy usage) is to participate in the assert at 573252723Sdim // the end of the function. 574205407Srdivacky uint64_t Start = OW->getStream().tell(); 575198090Srdivacky (void) Start; 576198396Srdivacky 577206083Srdivacky ++stats::EmittedFragments; 578198090Srdivacky 579198090Srdivacky switch (F.getKind()) { 580198090Srdivacky case MCFragment::FT_Align: { 581252723Sdim ++stats::EmittedAlignFragments; 582252723Sdim const MCAlignFragment &AF = cast<MCAlignFragment>(F); 583263509Sdim assert(AF.getValueSize() && "Invalid virtual align in concrete fragment!"); 584263509Sdim 585206083Srdivacky uint64_t Count = FragmentSize / AF.getValueSize(); 586198090Srdivacky 587198090Srdivacky // FIXME: This error shouldn't actually occur (the front end should emit 588198090Srdivacky // multiple .align directives to enforce the semantics it wants), but is 589198090Srdivacky // severe enough that we want to report it. How to handle this? 590206083Srdivacky if (Count * AF.getValueSize() != FragmentSize) 591207618Srdivacky report_fatal_error("undefined .align directive, value size '" + 592198396Srdivacky Twine(AF.getValueSize()) + 593198090Srdivacky "' is not a divisor of padding size '" + 594206083Srdivacky Twine(FragmentSize) + "'"); 595198090Srdivacky 596204642Srdivacky // See if we are aligning with nops, and if so do that first to try to fill 597204642Srdivacky // the Count bytes. Then if that did not fill any bytes or there are any 598245431Sdim // bytes left to fill use the Value and ValueSize to fill the rest. 599206083Srdivacky // If we are aligning with nops, ask that target to emit the right data. 600208599Srdivacky if (AF.hasEmitNops()) { 601235633Sdim if (!Asm.getBackend().writeNopData(Count, OW)) 602207618Srdivacky report_fatal_error("unable to write nop sequence of " + 603206083Srdivacky Twine(Count) + " bytes"); 604206083Srdivacky break; 605204642Srdivacky } 606204642Srdivacky 607206083Srdivacky // Otherwise, write out in multiples of the value size. 608198090Srdivacky for (uint64_t i = 0; i != Count; ++i) { 609198090Srdivacky switch (AF.getValueSize()) { 610235633Sdim default: llvm_unreachable("Invalid size!"); 611205407Srdivacky case 1: OW->Write8 (uint8_t (AF.getValue())); break; 612205407Srdivacky case 2: OW->Write16(uint16_t(AF.getValue())); break; 613205407Srdivacky case 4: OW->Write32(uint32_t(AF.getValue())); break; 614205407Srdivacky case 8: OW->Write64(uint64_t(AF.getValue())); break; 615198090Srdivacky } 616198090Srdivacky } 617198090Srdivacky break; 618198090Srdivacky } 619198090Srdivacky 620252723Sdim case MCFragment::FT_Data: 621252723Sdim ++stats::EmittedDataFragments; 622252723Sdim writeFragmentContents(F, OW); 623198090Srdivacky break; 624198090Srdivacky 625252723Sdim case MCFragment::FT_Relaxable: 626252723Sdim ++stats::EmittedRelaxableFragments; 627252723Sdim writeFragmentContents(F, OW); 628252723Sdim break; 629252723Sdim 630252723Sdim case MCFragment::FT_CompactEncodedInst: 631252723Sdim ++stats::EmittedCompactEncodedInstFragments; 632252723Sdim writeFragmentContents(F, OW); 633252723Sdim break; 634252723Sdim 635198090Srdivacky case MCFragment::FT_Fill: { 636252723Sdim ++stats::EmittedFillFragments; 637252723Sdim const MCFillFragment &FF = cast<MCFillFragment>(F); 638208599Srdivacky 639208599Srdivacky assert(FF.getValueSize() && "Invalid virtual align in concrete fragment!"); 640208599Srdivacky 641208599Srdivacky for (uint64_t i = 0, e = FF.getSize() / FF.getValueSize(); i != e; ++i) { 642198090Srdivacky switch (FF.getValueSize()) { 643235633Sdim default: llvm_unreachable("Invalid size!"); 644205407Srdivacky case 1: OW->Write8 (uint8_t (FF.getValue())); break; 645205407Srdivacky case 2: OW->Write16(uint16_t(FF.getValue())); break; 646205407Srdivacky case 4: OW->Write32(uint32_t(FF.getValue())); break; 647205407Srdivacky case 8: OW->Write64(uint64_t(FF.getValue())); break; 648198090Srdivacky } 649198090Srdivacky } 650198090Srdivacky break; 651198090Srdivacky } 652198396Srdivacky 653218893Sdim case MCFragment::FT_LEB: { 654252723Sdim const MCLEBFragment &LF = cast<MCLEBFragment>(F); 655218893Sdim OW->WriteBytes(LF.getContents().str()); 656218893Sdim break; 657218893Sdim } 658218893Sdim 659198090Srdivacky case MCFragment::FT_Org: { 660252723Sdim ++stats::EmittedOrgFragments; 661252723Sdim const MCOrgFragment &OF = cast<MCOrgFragment>(F); 662198090Srdivacky 663206083Srdivacky for (uint64_t i = 0, e = FragmentSize; i != e; ++i) 664205407Srdivacky OW->Write8(uint8_t(OF.getValue())); 665198090Srdivacky 666198090Srdivacky break; 667198090Srdivacky } 668218893Sdim 669218893Sdim case MCFragment::FT_Dwarf: { 670218893Sdim const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F); 671218893Sdim OW->WriteBytes(OF.getContents().str()); 672218893Sdim break; 673198090Srdivacky } 674218893Sdim case MCFragment::FT_DwarfFrame: { 675218893Sdim const MCDwarfCallFrameFragment &CF = cast<MCDwarfCallFrameFragment>(F); 676218893Sdim OW->WriteBytes(CF.getContents().str()); 677218893Sdim break; 678218893Sdim } 679218893Sdim } 680198090Srdivacky 681252723Sdim assert(OW->getStream().tell() - Start == FragmentSize && 682252723Sdim "The stream should advance by fragment size"); 683198090Srdivacky} 684198090Srdivacky 685235633Sdimvoid MCAssembler::writeSectionData(const MCSectionData *SD, 686218893Sdim const MCAsmLayout &Layout) const { 687198090Srdivacky // Ignore virtual sections. 688218893Sdim if (SD->getSection().isVirtualSection()) { 689208599Srdivacky assert(Layout.getSectionFileSize(SD) == 0 && "Invalid size for section!"); 690208599Srdivacky 691208599Srdivacky // Check that contents are only things legal inside a virtual section. 692208599Srdivacky for (MCSectionData::const_iterator it = SD->begin(), 693208599Srdivacky ie = SD->end(); it != ie; ++it) { 694208599Srdivacky switch (it->getKind()) { 695235633Sdim default: llvm_unreachable("Invalid fragment in virtual section!"); 696212904Sdim case MCFragment::FT_Data: { 697212904Sdim // Check that we aren't trying to write a non-zero contents (or fixups) 698212904Sdim // into a virtual section. This is to support clients which use standard 699212904Sdim // directives to fill the contents of virtual sections. 700252723Sdim const MCDataFragment &DF = cast<MCDataFragment>(*it); 701212904Sdim assert(DF.fixup_begin() == DF.fixup_end() && 702212904Sdim "Cannot have fixups in virtual section!"); 703212904Sdim for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i) 704212904Sdim assert(DF.getContents()[i] == 0 && 705212904Sdim "Invalid data value for virtual section!"); 706212904Sdim break; 707212904Sdim } 708208599Srdivacky case MCFragment::FT_Align: 709212904Sdim // Check that we aren't trying to write a non-zero value into a virtual 710212904Sdim // section. 711263509Sdim assert((cast<MCAlignFragment>(it)->getValueSize() == 0 || 712263509Sdim cast<MCAlignFragment>(it)->getValue() == 0) && 713208599Srdivacky "Invalid align in virtual section!"); 714208599Srdivacky break; 715208599Srdivacky case MCFragment::FT_Fill: 716263509Sdim assert((cast<MCFillFragment>(it)->getValueSize() == 0 || 717263509Sdim cast<MCFillFragment>(it)->getValue() == 0) && 718208599Srdivacky "Invalid fill in virtual section!"); 719208599Srdivacky break; 720208599Srdivacky } 721208599Srdivacky } 722208599Srdivacky 723198090Srdivacky return; 724198090Srdivacky } 725198090Srdivacky 726218893Sdim uint64_t Start = getWriter().getStream().tell(); 727245431Sdim (void)Start; 728198396Srdivacky 729252723Sdim for (MCSectionData::const_iterator it = SD->begin(), ie = SD->end(); 730252723Sdim it != ie; ++it) 731252723Sdim writeFragment(*this, Layout, *it); 732198090Srdivacky 733218893Sdim assert(getWriter().getStream().tell() - Start == 734218893Sdim Layout.getSectionAddressSize(SD)); 735198090Srdivacky} 736198090Srdivacky 737212904Sdim 738235633Sdimuint64_t MCAssembler::handleFixup(const MCAsmLayout &Layout, 739218893Sdim MCFragment &F, 740218893Sdim const MCFixup &Fixup) { 741218893Sdim // Evaluate the fixup. 742218893Sdim MCValue Target; 743218893Sdim uint64_t FixedValue; 744235633Sdim if (!evaluateFixup(Layout, Fixup, &F, Target, FixedValue)) { 745218893Sdim // The fixup was unresolved, we need a relocation. Inform the object 746218893Sdim // writer of the relocation, and give it an opportunity to adjust the 747218893Sdim // fixup value if need be. 748218893Sdim getWriter().RecordRelocation(*this, Layout, &F, Fixup, Target, FixedValue); 749218893Sdim } 750218893Sdim return FixedValue; 751218893Sdim } 752212904Sdim 753218893Sdimvoid MCAssembler::Finish() { 754203954Srdivacky DEBUG_WITH_TYPE("mc-dump", { 755203954Srdivacky llvm::errs() << "assembler backend - pre-layout\n--\n"; 756203954Srdivacky dump(); }); 757203954Srdivacky 758208599Srdivacky // Create the layout object. 759208599Srdivacky MCAsmLayout Layout(*this); 760208599Srdivacky 761208599Srdivacky // Create dummy fragments and assign section ordinals. 762206083Srdivacky unsigned SectionIndex = 0; 763206083Srdivacky for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) { 764208599Srdivacky // Create dummy fragments to eliminate any empty sections, this simplifies 765208599Srdivacky // layout. 766210299Sed if (it->getFragmentList().empty()) 767218893Sdim new MCDataFragment(it); 768208599Srdivacky 769206083Srdivacky it->setOrdinal(SectionIndex++); 770208599Srdivacky } 771206083Srdivacky 772208599Srdivacky // Assign layout order indices to sections and fragments. 773208599Srdivacky for (unsigned i = 0, e = Layout.getSectionOrder().size(); i != e; ++i) { 774208599Srdivacky MCSectionData *SD = Layout.getSectionOrder()[i]; 775208599Srdivacky SD->setLayoutOrder(i); 776208599Srdivacky 777218893Sdim unsigned FragmentIndex = 0; 778252723Sdim for (MCSectionData::iterator iFrag = SD->begin(), iFragEnd = SD->end(); 779252723Sdim iFrag != iFragEnd; ++iFrag) 780252723Sdim iFrag->setLayoutOrder(FragmentIndex++); 781206083Srdivacky } 782206083Srdivacky 783205218Srdivacky // Layout until everything fits. 784235633Sdim while (layoutOnce(Layout)) 785205218Srdivacky continue; 786205218Srdivacky 787205218Srdivacky DEBUG_WITH_TYPE("mc-dump", { 788206083Srdivacky llvm::errs() << "assembler backend - post-relaxation\n--\n"; 789205218Srdivacky dump(); }); 790205218Srdivacky 791206083Srdivacky // Finalize the layout, including fragment lowering. 792235633Sdim finishLayout(Layout); 793206083Srdivacky 794206083Srdivacky DEBUG_WITH_TYPE("mc-dump", { 795206083Srdivacky llvm::errs() << "assembler backend - final-layout\n--\n"; 796206083Srdivacky dump(); }); 797206083Srdivacky 798206083Srdivacky uint64_t StartOffset = OS.tell(); 799205218Srdivacky 800205407Srdivacky // Allow the object writer a chance to perform post-layout binding (for 801205407Srdivacky // example, to set the index fields in the symbol data). 802218893Sdim getWriter().ExecutePostLayoutBinding(*this, Layout); 803205407Srdivacky 804205407Srdivacky // Evaluate and apply the fixups, generating relocation entries as necessary. 805205407Srdivacky for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) { 806205407Srdivacky for (MCSectionData::iterator it2 = it->begin(), 807205407Srdivacky ie2 = it->end(); it2 != ie2; ++it2) { 808252723Sdim MCEncodedFragmentWithFixups *F = 809252723Sdim dyn_cast<MCEncodedFragmentWithFixups>(it2); 810252723Sdim if (F) { 811252723Sdim for (MCEncodedFragmentWithFixups::fixup_iterator it3 = F->fixup_begin(), 812252723Sdim ie3 = F->fixup_end(); it3 != ie3; ++it3) { 813218893Sdim MCFixup &Fixup = *it3; 814252723Sdim uint64_t FixedValue = handleFixup(Layout, *F, Fixup); 815252723Sdim getBackend().applyFixup(Fixup, F->getContents().data(), 816252723Sdim F->getContents().size(), FixedValue); 817205407Srdivacky } 818205407Srdivacky } 819205407Srdivacky } 820205407Srdivacky } 821205407Srdivacky 822205407Srdivacky // Write the object file. 823218893Sdim getWriter().WriteObject(*this, Layout); 824206083Srdivacky 825206083Srdivacky stats::ObjectBytes += OS.tell() - StartOffset; 826205218Srdivacky} 827205218Srdivacky 828235633Sdimbool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup, 829252723Sdim const MCRelaxableFragment *DF, 830206083Srdivacky const MCAsmLayout &Layout) const { 831205218Srdivacky // If we cannot resolve the fixup value, it requires relaxation. 832205218Srdivacky MCValue Target; 833205218Srdivacky uint64_t Value; 834235633Sdim if (!evaluateFixup(Layout, Fixup, DF, Target, Value)) 835205218Srdivacky return true; 836205218Srdivacky 837235633Sdim return getBackend().fixupNeedsRelaxation(Fixup, Value, DF, Layout); 838205218Srdivacky} 839205218Srdivacky 840252723Sdimbool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F, 841206083Srdivacky const MCAsmLayout &Layout) const { 842206083Srdivacky // If this inst doesn't ever need relaxation, ignore it. This occurs when we 843206083Srdivacky // are intentionally pushing out inst fragments, or because we relaxed a 844206083Srdivacky // previous instruction to one that doesn't need relaxation. 845252723Sdim if (!getBackend().mayNeedRelaxation(F->getInst())) 846206083Srdivacky return false; 847206083Srdivacky 848252723Sdim for (MCRelaxableFragment::const_fixup_iterator it = F->fixup_begin(), 849252723Sdim ie = F->fixup_end(); it != ie; ++it) 850252723Sdim if (fixupNeedsRelaxation(*it, F, Layout)) 851206083Srdivacky return true; 852206083Srdivacky 853206083Srdivacky return false; 854206083Srdivacky} 855206083Srdivacky 856235633Sdimbool MCAssembler::relaxInstruction(MCAsmLayout &Layout, 857252723Sdim MCRelaxableFragment &F) { 858252723Sdim if (!fragmentNeedsRelaxation(&F, Layout)) 859218893Sdim return false; 860206083Srdivacky 861218893Sdim ++stats::RelaxedInstructions; 862198090Srdivacky 863218893Sdim // FIXME-PERF: We could immediately lower out instructions if we can tell 864218893Sdim // they are fully resolved, to avoid retesting on later passes. 865203954Srdivacky 866218893Sdim // Relax the fragment. 867198090Srdivacky 868218893Sdim MCInst Relaxed; 869252723Sdim getBackend().relaxInstruction(F.getInst(), Relaxed); 870205218Srdivacky 871218893Sdim // Encode the new instruction. 872218893Sdim // 873218893Sdim // FIXME-PERF: If it matters, we could let the target do this. It can 874218893Sdim // probably do so more efficiently in many cases. 875218893Sdim SmallVector<MCFixup, 4> Fixups; 876218893Sdim SmallString<256> Code; 877218893Sdim raw_svector_ostream VecOS(Code); 878218893Sdim getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups); 879218893Sdim VecOS.flush(); 880205218Srdivacky 881252723Sdim // Update the fragment. 882252723Sdim F.setInst(Relaxed); 883252723Sdim F.getContents() = Code; 884252723Sdim F.getFixups() = Fixups; 885205218Srdivacky 886218893Sdim return true; 887218893Sdim} 888205218Srdivacky 889235633Sdimbool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) { 890218893Sdim int64_t Value = 0; 891218893Sdim uint64_t OldSize = LF.getContents().size(); 892221345Sdim bool IsAbs = LF.getValue().EvaluateAsAbsolute(Value, Layout); 893221345Sdim (void)IsAbs; 894221345Sdim assert(IsAbs); 895218893Sdim SmallString<8> &Data = LF.getContents(); 896218893Sdim Data.clear(); 897218893Sdim raw_svector_ostream OSE(Data); 898218893Sdim if (LF.isSigned()) 899245431Sdim encodeSLEB128(Value, OSE); 900218893Sdim else 901245431Sdim encodeULEB128(Value, OSE); 902218893Sdim OSE.flush(); 903218893Sdim return OldSize != LF.getContents().size(); 904218893Sdim} 905205218Srdivacky 906235633Sdimbool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layout, 907235633Sdim MCDwarfLineAddrFragment &DF) { 908263509Sdim MCContext &Context = Layout.getAssembler().getContext(); 909218893Sdim int64_t AddrDelta = 0; 910218893Sdim uint64_t OldSize = DF.getContents().size(); 911218893Sdim bool IsAbs = DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout); 912218893Sdim (void)IsAbs; 913218893Sdim assert(IsAbs); 914218893Sdim int64_t LineDelta; 915218893Sdim LineDelta = DF.getLineDelta(); 916218893Sdim SmallString<8> &Data = DF.getContents(); 917218893Sdim Data.clear(); 918218893Sdim raw_svector_ostream OSE(Data); 919263509Sdim MCDwarfLineAddr::Encode(Context, LineDelta, AddrDelta, OSE); 920218893Sdim OSE.flush(); 921218893Sdim return OldSize != Data.size(); 922218893Sdim} 923205218Srdivacky 924235633Sdimbool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout, 925218893Sdim MCDwarfCallFrameFragment &DF) { 926263509Sdim MCContext &Context = Layout.getAssembler().getContext(); 927218893Sdim int64_t AddrDelta = 0; 928218893Sdim uint64_t OldSize = DF.getContents().size(); 929218893Sdim bool IsAbs = DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout); 930218893Sdim (void)IsAbs; 931218893Sdim assert(IsAbs); 932218893Sdim SmallString<8> &Data = DF.getContents(); 933218893Sdim Data.clear(); 934218893Sdim raw_svector_ostream OSE(Data); 935263509Sdim MCDwarfFrameEmitter::EncodeAdvanceLoc(Context, AddrDelta, OSE); 936218893Sdim OSE.flush(); 937218893Sdim return OldSize != Data.size(); 938218893Sdim} 939218893Sdim 940252723Sdimbool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) { 941252723Sdim // Holds the first fragment which needed relaxing during this layout. It will 942252723Sdim // remain NULL if none were relaxed. 943252723Sdim // When a fragment is relaxed, all the fragments following it should get 944252723Sdim // invalidated because their offset is going to change. 945252723Sdim MCFragment *FirstRelaxedFragment = NULL; 946252723Sdim 947252723Sdim // Attempt to relax all the fragments in the section. 948252723Sdim for (MCSectionData::iterator I = SD.begin(), IE = SD.end(); I != IE; ++I) { 949252723Sdim // Check if this is a fragment that needs relaxation. 950252723Sdim bool RelaxedFrag = false; 951252723Sdim switch(I->getKind()) { 952218893Sdim default: 953218893Sdim break; 954252723Sdim case MCFragment::FT_Relaxable: 955252723Sdim assert(!getRelaxAll() && 956252723Sdim "Did not expect a MCRelaxableFragment in RelaxAll mode"); 957252723Sdim RelaxedFrag = relaxInstruction(Layout, *cast<MCRelaxableFragment>(I)); 958252723Sdim break; 959218893Sdim case MCFragment::FT_Dwarf: 960252723Sdim RelaxedFrag = relaxDwarfLineAddr(Layout, 961252723Sdim *cast<MCDwarfLineAddrFragment>(I)); 962218893Sdim break; 963218893Sdim case MCFragment::FT_DwarfFrame: 964252723Sdim RelaxedFrag = 965235633Sdim relaxDwarfCallFrameFragment(Layout, 966252723Sdim *cast<MCDwarfCallFrameFragment>(I)); 967218893Sdim break; 968218893Sdim case MCFragment::FT_LEB: 969252723Sdim RelaxedFrag = relaxLEB(Layout, *cast<MCLEBFragment>(I)); 970218893Sdim break; 971206083Srdivacky } 972252723Sdim if (RelaxedFrag && !FirstRelaxedFragment) 973252723Sdim FirstRelaxedFragment = I; 974206083Srdivacky } 975252723Sdim if (FirstRelaxedFragment) { 976252723Sdim Layout.invalidateFragmentsFrom(FirstRelaxedFragment); 977218893Sdim return true; 978218893Sdim } 979218893Sdim return false; 980206083Srdivacky} 981205218Srdivacky 982235633Sdimbool MCAssembler::layoutOnce(MCAsmLayout &Layout) { 983218893Sdim ++stats::RelaxationSteps; 984218893Sdim 985218893Sdim bool WasRelaxed = false; 986206083Srdivacky for (iterator it = begin(), ie = end(); it != ie; ++it) { 987206083Srdivacky MCSectionData &SD = *it; 988252723Sdim while (layoutSectionOnce(Layout, SD)) 989218893Sdim WasRelaxed = true; 990218893Sdim } 991205218Srdivacky 992218893Sdim return WasRelaxed; 993218893Sdim} 994205218Srdivacky 995235633Sdimvoid MCAssembler::finishLayout(MCAsmLayout &Layout) { 996218893Sdim // The layout is done. Mark every fragment as valid. 997218893Sdim for (unsigned int i = 0, n = Layout.getSectionOrder().size(); i != n; ++i) { 998218893Sdim Layout.getFragmentOffset(&*Layout.getSectionOrder()[i]->rbegin()); 999205218Srdivacky } 1000198090Srdivacky} 1001203954Srdivacky 1002203954Srdivacky// Debugging methods 1003203954Srdivacky 1004203954Srdivackynamespace llvm { 1005203954Srdivacky 1006208599Srdivackyraw_ostream &operator<<(raw_ostream &OS, const MCFixup &AF) { 1007208599Srdivacky OS << "<MCFixup" << " Offset:" << AF.getOffset() 1008208599Srdivacky << " Value:" << *AF.getValue() 1009208599Srdivacky << " Kind:" << AF.getKind() << ">"; 1010203954Srdivacky return OS; 1011203954Srdivacky} 1012203954Srdivacky 1013203954Srdivacky} 1014203954Srdivacky 1015245431Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1016203954Srdivackyvoid MCFragment::dump() { 1017203954Srdivacky raw_ostream &OS = llvm::errs(); 1018203954Srdivacky 1019208599Srdivacky OS << "<"; 1020208599Srdivacky switch (getKind()) { 1021208599Srdivacky case MCFragment::FT_Align: OS << "MCAlignFragment"; break; 1022208599Srdivacky case MCFragment::FT_Data: OS << "MCDataFragment"; break; 1023252723Sdim case MCFragment::FT_CompactEncodedInst: 1024252723Sdim OS << "MCCompactEncodedInstFragment"; break; 1025208599Srdivacky case MCFragment::FT_Fill: OS << "MCFillFragment"; break; 1026252723Sdim case MCFragment::FT_Relaxable: OS << "MCRelaxableFragment"; break; 1027208599Srdivacky case MCFragment::FT_Org: OS << "MCOrgFragment"; break; 1028218893Sdim case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break; 1029218893Sdim case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break; 1030218893Sdim case MCFragment::FT_LEB: OS << "MCLEBFragment"; break; 1031208599Srdivacky } 1032203954Srdivacky 1033208599Srdivacky OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder 1034252723Sdim << " Offset:" << Offset 1035252723Sdim << " HasInstructions:" << hasInstructions() 1036252723Sdim << " BundlePadding:" << static_cast<unsigned>(getBundlePadding()) << ">"; 1037203954Srdivacky 1038208599Srdivacky switch (getKind()) { 1039208599Srdivacky case MCFragment::FT_Align: { 1040208599Srdivacky const MCAlignFragment *AF = cast<MCAlignFragment>(this); 1041208599Srdivacky if (AF->hasEmitNops()) 1042208599Srdivacky OS << " (emit nops)"; 1043208599Srdivacky OS << "\n "; 1044208599Srdivacky OS << " Alignment:" << AF->getAlignment() 1045208599Srdivacky << " Value:" << AF->getValue() << " ValueSize:" << AF->getValueSize() 1046208599Srdivacky << " MaxBytesToEmit:" << AF->getMaxBytesToEmit() << ">"; 1047208599Srdivacky break; 1048203954Srdivacky } 1049208599Srdivacky case MCFragment::FT_Data: { 1050208599Srdivacky const MCDataFragment *DF = cast<MCDataFragment>(this); 1051208599Srdivacky OS << "\n "; 1052208599Srdivacky OS << " Contents:["; 1053208599Srdivacky const SmallVectorImpl<char> &Contents = DF->getContents(); 1054208599Srdivacky for (unsigned i = 0, e = Contents.size(); i != e; ++i) { 1055208599Srdivacky if (i) OS << ","; 1056208599Srdivacky OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF); 1057208599Srdivacky } 1058208599Srdivacky OS << "] (" << Contents.size() << " bytes)"; 1059203954Srdivacky 1060252723Sdim if (DF->fixup_begin() != DF->fixup_end()) { 1061208599Srdivacky OS << ",\n "; 1062208599Srdivacky OS << " Fixups:["; 1063208599Srdivacky for (MCDataFragment::const_fixup_iterator it = DF->fixup_begin(), 1064208599Srdivacky ie = DF->fixup_end(); it != ie; ++it) { 1065208599Srdivacky if (it != DF->fixup_begin()) OS << ",\n "; 1066208599Srdivacky OS << *it; 1067208599Srdivacky } 1068208599Srdivacky OS << "]"; 1069203954Srdivacky } 1070208599Srdivacky break; 1071203954Srdivacky } 1072252723Sdim case MCFragment::FT_CompactEncodedInst: { 1073252723Sdim const MCCompactEncodedInstFragment *CEIF = 1074252723Sdim cast<MCCompactEncodedInstFragment>(this); 1075252723Sdim OS << "\n "; 1076252723Sdim OS << " Contents:["; 1077252723Sdim const SmallVectorImpl<char> &Contents = CEIF->getContents(); 1078252723Sdim for (unsigned i = 0, e = Contents.size(); i != e; ++i) { 1079252723Sdim if (i) OS << ","; 1080252723Sdim OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF); 1081252723Sdim } 1082252723Sdim OS << "] (" << Contents.size() << " bytes)"; 1083252723Sdim break; 1084252723Sdim } 1085208599Srdivacky case MCFragment::FT_Fill: { 1086208599Srdivacky const MCFillFragment *FF = cast<MCFillFragment>(this); 1087208599Srdivacky OS << " Value:" << FF->getValue() << " ValueSize:" << FF->getValueSize() 1088208599Srdivacky << " Size:" << FF->getSize(); 1089208599Srdivacky break; 1090208599Srdivacky } 1091252723Sdim case MCFragment::FT_Relaxable: { 1092252723Sdim const MCRelaxableFragment *F = cast<MCRelaxableFragment>(this); 1093208599Srdivacky OS << "\n "; 1094208599Srdivacky OS << " Inst:"; 1095252723Sdim F->getInst().dump_pretty(OS); 1096208599Srdivacky break; 1097208599Srdivacky } 1098208599Srdivacky case MCFragment::FT_Org: { 1099208599Srdivacky const MCOrgFragment *OF = cast<MCOrgFragment>(this); 1100208599Srdivacky OS << "\n "; 1101208599Srdivacky OS << " Offset:" << OF->getOffset() << " Value:" << OF->getValue(); 1102208599Srdivacky break; 1103208599Srdivacky } 1104218893Sdim case MCFragment::FT_Dwarf: { 1105218893Sdim const MCDwarfLineAddrFragment *OF = cast<MCDwarfLineAddrFragment>(this); 1106218893Sdim OS << "\n "; 1107218893Sdim OS << " AddrDelta:" << OF->getAddrDelta() 1108218893Sdim << " LineDelta:" << OF->getLineDelta(); 1109218893Sdim break; 1110208599Srdivacky } 1111218893Sdim case MCFragment::FT_DwarfFrame: { 1112218893Sdim const MCDwarfCallFrameFragment *CF = cast<MCDwarfCallFrameFragment>(this); 1113218893Sdim OS << "\n "; 1114218893Sdim OS << " AddrDelta:" << CF->getAddrDelta(); 1115218893Sdim break; 1116218893Sdim } 1117218893Sdim case MCFragment::FT_LEB: { 1118218893Sdim const MCLEBFragment *LF = cast<MCLEBFragment>(this); 1119218893Sdim OS << "\n "; 1120218893Sdim OS << " Value:" << LF->getValue() << " Signed:" << LF->isSigned(); 1121218893Sdim break; 1122218893Sdim } 1123218893Sdim } 1124203954Srdivacky OS << ">"; 1125203954Srdivacky} 1126203954Srdivacky 1127203954Srdivackyvoid MCSectionData::dump() { 1128203954Srdivacky raw_ostream &OS = llvm::errs(); 1129203954Srdivacky 1130203954Srdivacky OS << "<MCSectionData"; 1131252723Sdim OS << " Alignment:" << getAlignment() 1132252723Sdim << " Fragments:[\n "; 1133203954Srdivacky for (iterator it = begin(), ie = end(); it != ie; ++it) { 1134203954Srdivacky if (it != begin()) OS << ",\n "; 1135203954Srdivacky it->dump(); 1136203954Srdivacky } 1137203954Srdivacky OS << "]>"; 1138203954Srdivacky} 1139203954Srdivacky 1140203954Srdivackyvoid MCSymbolData::dump() { 1141203954Srdivacky raw_ostream &OS = llvm::errs(); 1142203954Srdivacky 1143203954Srdivacky OS << "<MCSymbolData Symbol:" << getSymbol() 1144203954Srdivacky << " Fragment:" << getFragment() << " Offset:" << getOffset() 1145203954Srdivacky << " Flags:" << getFlags() << " Index:" << getIndex(); 1146203954Srdivacky if (isCommon()) 1147203954Srdivacky OS << " (common, size:" << getCommonSize() 1148203954Srdivacky << " align: " << getCommonAlignment() << ")"; 1149203954Srdivacky if (isExternal()) 1150203954Srdivacky OS << " (external)"; 1151203954Srdivacky if (isPrivateExtern()) 1152203954Srdivacky OS << " (private extern)"; 1153203954Srdivacky OS << ">"; 1154203954Srdivacky} 1155203954Srdivacky 1156203954Srdivackyvoid MCAssembler::dump() { 1157203954Srdivacky raw_ostream &OS = llvm::errs(); 1158203954Srdivacky 1159203954Srdivacky OS << "<MCAssembler\n"; 1160204961Srdivacky OS << " Sections:[\n "; 1161203954Srdivacky for (iterator it = begin(), ie = end(); it != ie; ++it) { 1162203954Srdivacky if (it != begin()) OS << ",\n "; 1163203954Srdivacky it->dump(); 1164203954Srdivacky } 1165203954Srdivacky OS << "],\n"; 1166203954Srdivacky OS << " Symbols:["; 1167203954Srdivacky 1168203954Srdivacky for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) { 1169204961Srdivacky if (it != symbol_begin()) OS << ",\n "; 1170203954Srdivacky it->dump(); 1171203954Srdivacky } 1172203954Srdivacky OS << "]>\n"; 1173203954Srdivacky} 1174245431Sdim#endif 1175235633Sdim 1176235633Sdim// anchors for MC*Fragment vtables 1177252723Sdimvoid MCEncodedFragment::anchor() { } 1178252723Sdimvoid MCEncodedFragmentWithFixups::anchor() { } 1179235633Sdimvoid MCDataFragment::anchor() { } 1180252723Sdimvoid MCCompactEncodedInstFragment::anchor() { } 1181252723Sdimvoid MCRelaxableFragment::anchor() { } 1182235633Sdimvoid MCAlignFragment::anchor() { } 1183235633Sdimvoid MCFillFragment::anchor() { } 1184235633Sdimvoid MCOrgFragment::anchor() { } 1185235633Sdimvoid MCLEBFragment::anchor() { } 1186235633Sdimvoid MCDwarfLineAddrFragment::anchor() { } 1187235633Sdimvoid MCDwarfCallFrameFragment::anchor() { } 1188