10 #define DEBUG_TYPE "assembler"
36 STATISTIC(EmittedFragments,
"Number of emitted assembler fragments - total");
38 "Number of emitted assembler fragments - relaxable");
40 "Number of emitted assembler fragments - data");
41 STATISTIC(EmittedCompactEncodedInstFragments,
42 "Number of emitted assembler fragments - compact encoded inst");
44 "Number of emitted assembler fragments - align");
46 "Number of emitted assembler fragments - fill");
48 "Number of emitted assembler fragments - org");
49 STATISTIC(evaluateFixup,
"Number of evaluated fixups");
50 STATISTIC(FragmentLayouts,
"Number of fragment layouts");
51 STATISTIC(ObjectBytes,
"Number of emitted object file bytes");
52 STATISTIC(RelaxationSteps,
"Number of assembler layout and relaxation steps");
53 STATISTIC(RelaxedInstructions,
"Number of relaxed instructions");
65 : Assembler(Asm), LastValidFragment()
69 if (!it->getSection().isVirtualSection())
70 SectionOrder.push_back(&*it);
72 if (it->getSection().isVirtualSection())
73 SectionOrder.push_back(&*it);
76 bool MCAsmLayout::isFragmentValid(
const MCFragment *
F)
const {
78 const MCFragment *LastValid = LastValidFragment.lookup(&SD);
87 if (!isFragmentValid(F))
96 void MCAsmLayout::ensureValid(
const MCFragment *F)
const {
106 while (!isFragmentValid(F)) {
107 assert(Cur &&
"Layout bookkeeping error");
115 assert(F->Offset != ~UINT64_C(0) &&
"Address not set!");
147 assert(SD->
getFragment() &&
"Invalid getOffset() on undefined symbol!");
166 uint64_t MCAsmLayout::computeBundlePadding(
const MCFragment *F,
167 uint64_t FOffset, uint64_t FSize) {
169 assert(BundleSize > 0 &&
170 "computeBundlePadding should only be called if bundling is enabled");
171 uint64_t BundleMask = BundleSize - 1;
172 uint64_t OffsetInBundle = FOffset & BundleMask;
173 uint64_t EndOfFragment = OffsetInBundle + FSize;
193 if (EndOfFragment == BundleSize)
195 else if (EndOfFragment < BundleSize)
196 return BundleSize - EndOfFragment;
198 return 2 * BundleSize - EndOfFragment;
200 }
else if (EndOfFragment > BundleSize)
201 return BundleSize - OffsetInBundle;
215 :
Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0))
237 Ordinal(~UINT32_C(0)),
239 BundleLockState(NotBundleLocked), BundleGroupBeforeFirstInst(
false),
240 HasInstructions(
false)
248 if (Subsection == 0 && SubsectionFragmentMap.empty())
252 std::lower_bound(SubsectionFragmentMap.begin(), SubsectionFragmentMap.end(),
254 bool ExactMatch =
false;
255 if (MI != SubsectionFragmentMap.end()) {
256 ExactMatch = MI->first == Subsection;
261 if (MI == SubsectionFragmentMap.end())
265 if (!ExactMatch && Subsection != 0) {
269 SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F));
282 :
Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset),
296 : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
298 SubsectionsViaSymbols(
false), ELFHeaderEFlags(0) {
309 IndirectSymbols.clear();
314 SubsectionsViaSymbols =
false;
355 bool MCAssembler::evaluateFixup(
const MCAsmLayout &Layout,
358 ++stats::evaluateFixup;
370 }
else if (!Target.
getSymA()) {
405 assert((ShouldAlignPC ? IsPCRel :
true) &&
406 "FKF_IsAlignedDownTo32Bits is only allowed on PC-relative fixups!");
413 if (ShouldAlignPC) Offset &= ~0x3;
431 return cast<MCEncodedFragment>(
F).getContents().size();
433 return cast<MCFillFragment>(
F).getSize();
436 return cast<MCLEBFragment>(
F).getContents().size();
455 int64_t TargetLocation;
456 if (!OF.
getOffset().EvaluateAsAbsolute(TargetLocation, Layout))
461 int64_t Size = TargetLocation - FragmentOffset;
462 if (Size < 0 || Size >= 0x40000000)
464 "' (at offset '" +
Twine(FragmentOffset) +
"')");
469 return cast<MCDwarfLineAddrFragment>(
F).getContents().size();
471 return cast<MCDwarfCallFrameFragment>(
F).getContents().size();
481 assert(!isFragmentValid(F) &&
"Attempt to recompute a valid fragment!");
484 assert((!Prev || isFragmentValid(Prev)) &&
485 "Attempt to compute fragment before its predecessor!");
487 ++stats::FragmentLayouts;
513 assert(isa<MCEncodedFragment>(F) &&
514 "Only MCEncodedFragment implementations have instructions");
520 uint64_t RequiredBundlePadding = computeBundlePadding(F, F->Offset, FSize);
521 if (RequiredBundlePadding > UINT8_MAX)
524 F->Offset += RequiredBundlePadding;
545 if (BundlePadding > 0) {
547 "Writing bundle padding with disabled bundling");
549 "Writing bundle padding for a fragment without instructions");
551 unsigned TotalLength = BundlePadding +
static_cast<unsigned>(FragmentSize);
564 Twine(DistanceToBoundary) +
" bytes");
565 BundlePadding -= DistanceToBoundary;
569 Twine(BundlePadding) +
" bytes");
577 ++stats::EmittedFragments;
581 ++stats::EmittedAlignFragments;
583 assert(AF.
getValueSize() &&
"Invalid virtual align in concrete fragment!");
593 "' is not a divisor of padding size '" +
594 Twine(FragmentSize) +
"'");
603 Twine(Count) +
" bytes");
608 for (uint64_t i = 0; i != Count; ++i) {
621 ++stats::EmittedDataFragments;
626 ++stats::EmittedRelaxableFragments;
631 ++stats::EmittedCompactEncodedInstFragments;
636 ++stats::EmittedFillFragments;
639 assert(FF.
getValueSize() &&
"Invalid virtual align in concrete fragment!");
660 ++stats::EmittedOrgFragments;
663 for (uint64_t i = 0, e = FragmentSize; i != e; ++i)
682 "The stream should advance by fragment size");
693 ie = SD->
end(); it != ie; ++it) {
694 switch (it->getKind()) {
702 "Cannot have fixups in virtual section!");
705 "Invalid data value for virtual section!");
711 assert((cast<MCAlignFragment>(it)->getValueSize() == 0 ||
712 cast<MCAlignFragment>(it)->getValue() == 0) &&
713 "Invalid align in virtual section!");
716 assert((cast<MCFillFragment>(it)->getValueSize() == 0 ||
717 cast<MCFillFragment>(it)->getValue() == 0) &&
718 "Invalid fill in virtual section!");
733 assert(
getWriter().getStream().tell() - Start ==
738 uint64_t MCAssembler::handleFixup(
const MCAsmLayout &Layout,
744 if (!evaluateFixup(Layout, Fixup, &F, Target, FixedValue)) {
755 llvm::errs() <<
"assembler backend - pre-layout\n--\n";
762 unsigned SectionIndex = 0;
766 if (it->getFragmentList().empty())
769 it->setOrdinal(SectionIndex++);
773 for (
unsigned i = 0, e = Layout.getSectionOrder().size(); i != e; ++i) {
777 unsigned FragmentIndex = 0;
779 iFrag != iFragEnd; ++iFrag)
780 iFrag->setLayoutOrder(FragmentIndex++);
784 while (layoutOnce(Layout))
788 llvm::errs() <<
"assembler backend - post-relaxation\n--\n";
792 finishLayout(Layout);
795 llvm::errs() <<
"assembler backend - final-layout\n--\n";
798 uint64_t StartOffset = OS.
tell();
807 ie2 = it->end(); it2 != ie2; ++it2) {
812 ie3 = F->
fixup_end(); it3 != ie3; ++it3) {
814 uint64_t FixedValue = handleFixup(Layout, *F, Fixup);
825 stats::ObjectBytes += OS.
tell() - StartOffset;
828 bool MCAssembler::fixupNeedsRelaxation(
const MCFixup &Fixup,
834 if (!evaluateFixup(Layout, Fixup, DF, Target, Value))
850 if (fixupNeedsRelaxation(*it, F, Layout))
856 bool MCAssembler::relaxInstruction(
MCAsmLayout &Layout,
858 if (!fragmentNeedsRelaxation(&F, Layout))
861 ++stats::RelaxedInstructions;
892 bool IsAbs = LF.
getValue().EvaluateAsAbsolute(Value, Layout);
906 bool MCAssembler::relaxDwarfLineAddr(
MCAsmLayout &Layout,
909 int64_t AddrDelta = 0;
911 bool IsAbs = DF.
getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout);
921 return OldSize != Data.
size();
924 bool MCAssembler::relaxDwarfCallFrameFragment(
MCAsmLayout &Layout,
927 int64_t AddrDelta = 0;
929 bool IsAbs = DF.
getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout);
937 return OldSize != Data.
size();
950 bool RelaxedFrag =
false;
951 switch(
I->getKind()) {
956 "Did not expect a MCRelaxableFragment in RelaxAll mode");
957 RelaxedFrag = relaxInstruction(Layout, *cast<MCRelaxableFragment>(
I));
960 RelaxedFrag = relaxDwarfLineAddr(Layout,
961 *cast<MCDwarfLineAddrFragment>(
I));
965 relaxDwarfCallFrameFragment(Layout,
966 *cast<MCDwarfCallFrameFragment>(
I));
969 RelaxedFrag = relaxLEB(Layout, *cast<MCLEBFragment>(
I));
972 if (RelaxedFrag && !FirstRelaxedFragment)
973 FirstRelaxedFragment =
I;
975 if (FirstRelaxedFragment) {
982 bool MCAssembler::layoutOnce(
MCAsmLayout &Layout) {
983 ++stats::RelaxationSteps;
985 bool WasRelaxed =
false;
988 while (layoutSectionOnce(Layout, SD))
995 void MCAssembler::finishLayout(
MCAsmLayout &Layout) {
997 for (
unsigned int i = 0, n = Layout.
getSectionOrder().size(); i != n; ++i) {
1007 OS <<
"<MCFixup" <<
" Offset:" << AF.
getOffset()
1009 <<
" Kind:" << AF.
getKind() <<
">";
1015 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1024 OS <<
"MCCompactEncodedInstFragment";
break;
1033 OS <<
"<MCFragment " << (
void*)
this <<
" LayoutOrder:" << LayoutOrder
1034 <<
" Offset:" << Offset
1042 OS <<
" (emit nops)";
1052 OS <<
" Contents:[";
1054 for (
unsigned i = 0, e = Contents.
size(); i != e; ++i) {
1056 OS << hexdigit((Contents[i] >> 4) & 0xF) <<
hexdigit(Contents[i] & 0xF);
1058 OS <<
"] (" << Contents.
size() <<
" bytes)";
1074 cast<MCCompactEncodedInstFragment>(
this);
1076 OS <<
" Contents:[";
1078 for (
unsigned i = 0, e = Contents.
size(); i != e; ++i) {
1080 OS << hexdigit((Contents[i] >> 4) & 0xF) <<
hexdigit(Contents[i] & 0xF);
1082 OS <<
"] (" << Contents.
size() <<
" bytes)";
1130 OS <<
"<MCSectionData";
1132 <<
" Fragments:[\n ";
1134 if (it !=
begin()) OS <<
",\n ";
1143 OS <<
"<MCSymbolData Symbol:" <<
getSymbol()
1150 OS <<
" (external)";
1152 OS <<
" (private extern)";
1159 OS <<
"<MCAssembler\n";
1160 OS <<
" Sections:[\n ";
1162 if (it !=
begin()) OS <<
",\n ";
1177 void MCEncodedFragment::anchor() { }
1178 void MCEncodedFragmentWithFixups::anchor() { }
1179 void MCDataFragment::anchor() { }
1180 void MCCompactEncodedInstFragment::anchor() { }
1181 void MCRelaxableFragment::anchor() { }
1182 void MCAlignFragment::anchor() { }
1183 void MCFillFragment::anchor() { }
1184 void MCOrgFragment::anchor() { }
1185 void MCLEBFragment::anchor() { }
1186 void MCDwarfLineAddrFragment::anchor() { }
1187 void MCDwarfCallFrameFragment::anchor() { }
void setParent(MCSectionData *Value)
static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW)
Write the contents of a fragment to the given object writer. Expects a MCEncodedFragment.
fixup_iterator fixup_end()
unsigned getValueSize() const
virtual ~MCEncodedFragment()
raw_ostream & getStream()
const MCSymbol & getSymbol() const
unsigned getAlignment() const
const MCExpr & getAddrDelta() const
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
MCAsmLayout(MCAssembler &_Assembler)
unsigned getBundleAlignSize() const
SmallVectorImpl< MCFixup >::const_iterator const_fixup_iterator
MCCodeEmitter & getEmitter() const
void Write32(uint32_t Value)
virtual SmallVectorImpl< char > & getContents()
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const =0
MCContext & getContext() const
virtual bool alignToBundleEnd() const
Should this fragment be placed at the end of an aligned bundle?
const MCSymbol & getSymbol() const
virtual bool doesSectionRequireSymbols(const MCSection &Section) const
const FragmentListType & getFragmentList() const
const MCExpr & getOffset() const
void WriteBytes(const SmallVectorImpl< char > &ByteVec, unsigned ZeroFillSize=0)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
symbol_iterator symbol_begin()
const MCInst & getInst() const
#define DEBUG_WITH_TYPE(TYPE, X)
static void Encode(MCContext &Context, int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS)
Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
virtual unsigned getMinimumNopSize() const
virtual SmallVectorImpl< char > & getContents()=0
uint64_t getIndex() const
getIndex - Get the (implementation defined) index.
void push_back(NodeTy *val)
virtual uint8_t getBundlePadding() const
Get the padding size that must be inserted before this fragment. Used for bundling. By default, no padding is inserted. Note that padding size is restricted to 8 bits. This is an optimization to reduce the amount of space used for each fragment. In practice, larger padding should never be required.
const MCSection & getSection() const
NodeTy * getNextNode()
Get the next node, or 0 for the list tail.
const MCSymbolData * getAtom(const MCSymbolData *Symbol) const
#define llvm_unreachable(msg)
virtual bool hasInstructions() const
Does this fragment have instructions emitted into it? By default this is false, but specific fragment...
virtual fixup_iterator fixup_end()=0
const MCExpr * getVariableValue() const
getVariableValue() - Get the value for variable symbols.
virtual bool isSectionAtomizable(const MCSection &Section) const
NodeTy * getPrevNode()
Get the previous node, or 0 for the list head.
unsigned getMaxBytesToEmit() const
virtual fixup_iterator fixup_begin()=0
#define STATISTIC(VARNAME, DESC)
uint64_t getCommonSize() const
getCommonSize - Return the size of a 'common' symbol.
const SymbolDataListType & getSymbolList() const
int64_t getLineDelta() const
uint64_t tell() const
tell - Return the current offset with the file.
virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB, bool InSet, bool IsPCRel) const
MCObjectWriter & getWriter() const
virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups) const =0
bool isAbsolute() const
isAbsolute - Is this an absolute (as opposed to relocatable) value.
MCFragment * getFragment() const
void layoutFragment(MCFragment *Fragment)
Perform layout for a single fragment, assuming that the previous fragment has already been laid out c...
const MCSection & getSection() const
uint32_t getOffset() const
const MCExpr & getAddrDelta() const
virtual void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, MCValue &Target, uint64_t &Value, bool &IsResolved)
virtual bool writeNopData(uint64_t Count, MCObjectWriter *OW) const =0
virtual ~MCEncodedFragmentWithFixups()
virtual void setBundlePadding(uint8_t N)
Set the padding size for this fragment. By default it's a no-op, and only some fragments have a meani...
const MCExpr * getValue() const
virtual void reset()
Lifetime management.
MCSectionData * getParent() const
void Write8(uint8_t Value)
virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)=0
Record a relocation entry.
void setLayoutOrder(unsigned Value)
uint64_t computeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const
uint32_t getFlags() const
getFlags - Get the (implementation defined) symbol flags.
virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const =0
FragmentType getKind() const
void invalidateFragmentsFrom(MCFragment *F)
Invalidate the fragments starting with F because it has been resized. The fragment's size should have...
MCCodeEmitter - Generic instruction encoding interface.
virtual void reset()
lifetime management
virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout)=0
Write the object file.
virtual void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout)=0
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
MCSymbolData * getAtom() const
void Write64(uint64_t Value)
iterator insert(iterator where, NodeTy *New)
Should this fixup kind force a 4-byte aligned effective PC value?
uint64_t getOffset() const
virtual SmallVectorImpl< char > & getContents()
llvm::SmallVectorImpl< MCSectionData * > & getSectionOrder()
uint64_t getSectionFileSize(const MCSectionData *SD) const
Get the data size of the given section, as emitted to the object file. This may include additional pa...
MCFixupKind getKind() const
const MCSymbolRefExpr * getSymB() const
bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout &Layout) const
bool isSymbolLinkerVisible(const MCSymbol &SD) const
LLVM_ATTRIBUTE_NORETURN void FatalError(SMLoc L, const Twine &Msg)
MCSymbolData & getSymbolData(const MCSymbol &Symbol) const
virtual SmallVectorImpl< char > & getContents()
void Write16(uint16_t Value)
const MCSymbolRefExpr * getSymA() const
unsigned getCommonAlignment() const
getCommonAlignment - Return the alignment of a 'common' symbol.
virtual bool isVirtualSection() const =0
bool isBundlingEnabled() const
unsigned getAlignment() const
bool isCommon() const
isCommon - Is this a 'common' symbol.
static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment &F)
Write the fragment F to the output file.
static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, raw_ostream &OS)
uint64_t getSymbolOffset(const MCSymbolData *SD) const
Get the offset of the given symbol, as computed in the current layout.
virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, uint64_t Value) const =0
uint64_t getSectionAddressSize(const MCSectionData *SD) const
Get the address space size of the given section, as it effects layout. This may differ from the size ...
void encodeSLEB128(int64_t Value, raw_ostream &OS)
Utility function to encode a SLEB128 value to an output stream.
StringRef str() const
Explicit conversion to StringRef.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
SmallString< 8 > & getContents()
static char hexdigit(unsigned X, bool LowerCase=false)
const SectionDataListType & getSectionList() const
void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI=0, const MCInstPrinter *Printer=0, StringRef Separator=" ") const
Dump the MCInst as prettily as possible using the additional MC structures, if given. Operators are separated by the Separator string.
StringRef getName() const
getName - Get the symbol name.
pointer data()
data - Return a pointer to the vector's buffer, even if empty().
const MCSymbol & AliasedSymbol() const
MCAsmBackend & getBackend() const
fixup_iterator fixup_end()
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
SmallString< 8 > & getContents()
fixup_iterator fixup_begin()
SectionDataListType::iterator iterator
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
unsigned getValueSize() const
bool isVariable() const
isVariable - Check if this is a variable symbol.
VariantKind getKind() const
fixup_iterator fixup_begin()
int64_t getConstant() const
LLVM Value Representation.
MCAsmBackend - Generic interface to target specific assembler backends.
bool isPrivateExtern() const
cl::opt< bool > RelaxAll("mc-relax-all", cl::desc("When used with filetype=obj, ""relax all fixups in the emitted object file"))
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
void writeSectionData(const MCSectionData *Section, const MCAsmLayout &Layout) const
Emit the section contents using the given object writer.
const MCExpr & getValue() const
void encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned Padding=0)
Utility function to encode a ULEB128 value to an output stream.
unsigned getLayoutOrder() const
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
SmallString< 8 > & getContents()
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
getFixupKindInfo - Get information on a fixup kind.
virtual void reset()
lifetime management
iterator getSubsectionInsertionPoint(unsigned Subsection)
void setInst(const MCInst &Value)
SmallVectorImpl< MCFixup > & getFixups()
symbol_iterator symbol_end()