LLVM API Documentation
00001 //===- MCAssembler.h - Object File Generation -------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #ifndef LLVM_MC_MCASSEMBLER_H 00011 #define LLVM_MC_MCASSEMBLER_H 00012 00013 #include "llvm/ADT/DenseMap.h" 00014 #include "llvm/ADT/SmallPtrSet.h" 00015 #include "llvm/ADT/SmallString.h" 00016 #include "llvm/ADT/ilist.h" 00017 #include "llvm/ADT/ilist_node.h" 00018 #include "llvm/MC/MCDirectives.h" 00019 #include "llvm/MC/MCFixup.h" 00020 #include "llvm/MC/MCInst.h" 00021 #include "llvm/MC/MCLinkerOptimizationHint.h" 00022 #include "llvm/MC/MCSubtargetInfo.h" 00023 #include "llvm/Support/Casting.h" 00024 #include "llvm/Support/DataTypes.h" 00025 #include <algorithm> 00026 #include <vector> // FIXME: Shouldn't be needed. 00027 00028 namespace llvm { 00029 class raw_ostream; 00030 class MCAsmLayout; 00031 class MCAssembler; 00032 class MCContext; 00033 class MCCodeEmitter; 00034 class MCExpr; 00035 class MCFragment; 00036 class MCObjectWriter; 00037 class MCSection; 00038 class MCSectionData; 00039 class MCSubtargetInfo; 00040 class MCSymbol; 00041 class MCSymbolData; 00042 class MCValue; 00043 class MCAsmBackend; 00044 00045 class MCFragment : public ilist_node<MCFragment> { 00046 friend class MCAsmLayout; 00047 00048 MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION; 00049 void operator=(const MCFragment&) LLVM_DELETED_FUNCTION; 00050 00051 public: 00052 enum FragmentType { 00053 FT_Align, 00054 FT_Data, 00055 FT_CompactEncodedInst, 00056 FT_Fill, 00057 FT_Relaxable, 00058 FT_Org, 00059 FT_Dwarf, 00060 FT_DwarfFrame, 00061 FT_LEB 00062 }; 00063 00064 private: 00065 FragmentType Kind; 00066 00067 /// Parent - The data for the section this fragment is in. 00068 MCSectionData *Parent; 00069 00070 /// Atom - The atom this fragment is in, as represented by it's defining 00071 /// symbol. 00072 MCSymbolData *Atom; 00073 00074 /// @name Assembler Backend Data 00075 /// @{ 00076 // 00077 // FIXME: This could all be kept private to the assembler implementation. 00078 00079 /// Offset - The offset of this fragment in its section. This is ~0 until 00080 /// initialized. 00081 uint64_t Offset; 00082 00083 /// LayoutOrder - The layout order of this fragment. 00084 unsigned LayoutOrder; 00085 00086 /// @} 00087 00088 protected: 00089 MCFragment(FragmentType _Kind, MCSectionData *_Parent = nullptr); 00090 00091 public: 00092 // Only for sentinel. 00093 MCFragment(); 00094 virtual ~MCFragment(); 00095 00096 FragmentType getKind() const { return Kind; } 00097 00098 MCSectionData *getParent() const { return Parent; } 00099 void setParent(MCSectionData *Value) { Parent = Value; } 00100 00101 MCSymbolData *getAtom() const { return Atom; } 00102 void setAtom(MCSymbolData *Value) { Atom = Value; } 00103 00104 unsigned getLayoutOrder() const { return LayoutOrder; } 00105 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 00106 00107 /// \brief Does this fragment have instructions emitted into it? By default 00108 /// this is false, but specific fragment types may set it to true. 00109 virtual bool hasInstructions() const { return false; } 00110 00111 /// \brief Should this fragment be placed at the end of an aligned bundle? 00112 virtual bool alignToBundleEnd() const { return false; } 00113 virtual void setAlignToBundleEnd(bool V) { } 00114 00115 /// \brief Get the padding size that must be inserted before this fragment. 00116 /// Used for bundling. By default, no padding is inserted. 00117 /// Note that padding size is restricted to 8 bits. This is an optimization 00118 /// to reduce the amount of space used for each fragment. In practice, larger 00119 /// padding should never be required. 00120 virtual uint8_t getBundlePadding() const { 00121 return 0; 00122 } 00123 00124 /// \brief Set the padding size for this fragment. By default it's a no-op, 00125 /// and only some fragments have a meaningful implementation. 00126 virtual void setBundlePadding(uint8_t N) { 00127 } 00128 00129 void dump(); 00130 }; 00131 00132 /// Interface implemented by fragments that contain encoded instructions and/or 00133 /// data. 00134 /// 00135 class MCEncodedFragment : public MCFragment { 00136 virtual void anchor(); 00137 00138 uint8_t BundlePadding; 00139 public: 00140 MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = nullptr) 00141 : MCFragment(FType, SD), BundlePadding(0) 00142 { 00143 } 00144 virtual ~MCEncodedFragment(); 00145 00146 virtual SmallVectorImpl<char> &getContents() = 0; 00147 virtual const SmallVectorImpl<char> &getContents() const = 0; 00148 00149 uint8_t getBundlePadding() const override { 00150 return BundlePadding; 00151 } 00152 00153 void setBundlePadding(uint8_t N) override { 00154 BundlePadding = N; 00155 } 00156 00157 static bool classof(const MCFragment *F) { 00158 MCFragment::FragmentType Kind = F->getKind(); 00159 switch (Kind) { 00160 default: 00161 return false; 00162 case MCFragment::FT_Relaxable: 00163 case MCFragment::FT_CompactEncodedInst: 00164 case MCFragment::FT_Data: 00165 return true; 00166 } 00167 } 00168 }; 00169 00170 /// Interface implemented by fragments that contain encoded instructions and/or 00171 /// data and also have fixups registered. 00172 /// 00173 class MCEncodedFragmentWithFixups : public MCEncodedFragment { 00174 void anchor() override; 00175 00176 public: 00177 MCEncodedFragmentWithFixups(MCFragment::FragmentType FType, 00178 MCSectionData *SD = nullptr) 00179 : MCEncodedFragment(FType, SD) 00180 { 00181 } 00182 00183 virtual ~MCEncodedFragmentWithFixups(); 00184 00185 typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; 00186 typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; 00187 00188 virtual SmallVectorImpl<MCFixup> &getFixups() = 0; 00189 virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0; 00190 00191 virtual fixup_iterator fixup_begin() = 0; 00192 virtual const_fixup_iterator fixup_begin() const = 0; 00193 virtual fixup_iterator fixup_end() = 0; 00194 virtual const_fixup_iterator fixup_end() const = 0; 00195 00196 static bool classof(const MCFragment *F) { 00197 MCFragment::FragmentType Kind = F->getKind(); 00198 return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data; 00199 } 00200 }; 00201 00202 /// Fragment for data and encoded instructions. 00203 /// 00204 class MCDataFragment : public MCEncodedFragmentWithFixups { 00205 void anchor() override; 00206 00207 /// \brief Does this fragment contain encoded instructions anywhere in it? 00208 bool HasInstructions; 00209 00210 /// \brief Should this fragment be aligned to the end of a bundle? 00211 bool AlignToBundleEnd; 00212 00213 SmallVector<char, 32> Contents; 00214 00215 /// Fixups - The list of fixups in this fragment. 00216 SmallVector<MCFixup, 4> Fixups; 00217 public: 00218 MCDataFragment(MCSectionData *SD = nullptr) 00219 : MCEncodedFragmentWithFixups(FT_Data, SD), 00220 HasInstructions(false), AlignToBundleEnd(false) 00221 { 00222 } 00223 00224 SmallVectorImpl<char> &getContents() override { return Contents; } 00225 const SmallVectorImpl<char> &getContents() const override { 00226 return Contents; 00227 } 00228 00229 SmallVectorImpl<MCFixup> &getFixups() override { 00230 return Fixups; 00231 } 00232 00233 const SmallVectorImpl<MCFixup> &getFixups() const override { 00234 return Fixups; 00235 } 00236 00237 bool hasInstructions() const override { return HasInstructions; } 00238 virtual void setHasInstructions(bool V) { HasInstructions = V; } 00239 00240 bool alignToBundleEnd() const override { return AlignToBundleEnd; } 00241 void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; } 00242 00243 fixup_iterator fixup_begin() override { return Fixups.begin(); } 00244 const_fixup_iterator fixup_begin() const override { return Fixups.begin(); } 00245 00246 fixup_iterator fixup_end() override {return Fixups.end();} 00247 const_fixup_iterator fixup_end() const override {return Fixups.end();} 00248 00249 static bool classof(const MCFragment *F) { 00250 return F->getKind() == MCFragment::FT_Data; 00251 } 00252 }; 00253 00254 /// This is a compact (memory-size-wise) fragment for holding an encoded 00255 /// instruction (non-relaxable) that has no fixups registered. When applicable, 00256 /// it can be used instead of MCDataFragment and lead to lower memory 00257 /// consumption. 00258 /// 00259 class MCCompactEncodedInstFragment : public MCEncodedFragment { 00260 void anchor() override; 00261 00262 /// \brief Should this fragment be aligned to the end of a bundle? 00263 bool AlignToBundleEnd; 00264 00265 SmallVector<char, 4> Contents; 00266 public: 00267 MCCompactEncodedInstFragment(MCSectionData *SD = nullptr) 00268 : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false) 00269 { 00270 } 00271 00272 bool hasInstructions() const override { 00273 return true; 00274 } 00275 00276 SmallVectorImpl<char> &getContents() override { return Contents; } 00277 const SmallVectorImpl<char> &getContents() const override { return Contents; } 00278 00279 bool alignToBundleEnd() const override { return AlignToBundleEnd; } 00280 void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; } 00281 00282 static bool classof(const MCFragment *F) { 00283 return F->getKind() == MCFragment::FT_CompactEncodedInst; 00284 } 00285 }; 00286 00287 /// A relaxable fragment holds on to its MCInst, since it may need to be 00288 /// relaxed during the assembler layout and relaxation stage. 00289 /// 00290 class MCRelaxableFragment : public MCEncodedFragmentWithFixups { 00291 void anchor() override; 00292 00293 /// Inst - The instruction this is a fragment for. 00294 MCInst Inst; 00295 00296 /// STI - The MCSubtargetInfo in effect when the instruction was encoded. 00297 /// Keep a copy instead of a reference to make sure that updates to STI 00298 /// in the assembler are not seen here. 00299 const MCSubtargetInfo STI; 00300 00301 /// Contents - Binary data for the currently encoded instruction. 00302 SmallVector<char, 8> Contents; 00303 00304 /// Fixups - The list of fixups in this fragment. 00305 SmallVector<MCFixup, 1> Fixups; 00306 00307 public: 00308 MCRelaxableFragment(const MCInst &_Inst, 00309 const MCSubtargetInfo &_STI, 00310 MCSectionData *SD = nullptr) 00311 : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) { 00312 } 00313 00314 SmallVectorImpl<char> &getContents() override { return Contents; } 00315 const SmallVectorImpl<char> &getContents() const override { return Contents; } 00316 00317 const MCInst &getInst() const { return Inst; } 00318 void setInst(const MCInst& Value) { Inst = Value; } 00319 00320 const MCSubtargetInfo &getSubtargetInfo() { return STI; } 00321 00322 SmallVectorImpl<MCFixup> &getFixups() override { 00323 return Fixups; 00324 } 00325 00326 const SmallVectorImpl<MCFixup> &getFixups() const override { 00327 return Fixups; 00328 } 00329 00330 bool hasInstructions() const override { return true; } 00331 00332 fixup_iterator fixup_begin() override { return Fixups.begin(); } 00333 const_fixup_iterator fixup_begin() const override { return Fixups.begin(); } 00334 00335 fixup_iterator fixup_end() override {return Fixups.end();} 00336 const_fixup_iterator fixup_end() const override {return Fixups.end();} 00337 00338 static bool classof(const MCFragment *F) { 00339 return F->getKind() == MCFragment::FT_Relaxable; 00340 } 00341 }; 00342 00343 class MCAlignFragment : public MCFragment { 00344 virtual void anchor(); 00345 00346 /// Alignment - The alignment to ensure, in bytes. 00347 unsigned Alignment; 00348 00349 /// Value - Value to use for filling padding bytes. 00350 int64_t Value; 00351 00352 /// ValueSize - The size of the integer (in bytes) of \p Value. 00353 unsigned ValueSize; 00354 00355 /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment 00356 /// cannot be satisfied in this width then this fragment is ignored. 00357 unsigned MaxBytesToEmit; 00358 00359 /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead 00360 /// of using the provided value. The exact interpretation of this flag is 00361 /// target dependent. 00362 bool EmitNops : 1; 00363 00364 public: 00365 MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize, 00366 unsigned _MaxBytesToEmit, MCSectionData *SD = nullptr) 00367 : MCFragment(FT_Align, SD), Alignment(_Alignment), 00368 Value(_Value),ValueSize(_ValueSize), 00369 MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {} 00370 00371 /// @name Accessors 00372 /// @{ 00373 00374 unsigned getAlignment() const { return Alignment; } 00375 00376 int64_t getValue() const { return Value; } 00377 00378 unsigned getValueSize() const { return ValueSize; } 00379 00380 unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; } 00381 00382 bool hasEmitNops() const { return EmitNops; } 00383 void setEmitNops(bool Value) { EmitNops = Value; } 00384 00385 /// @} 00386 00387 static bool classof(const MCFragment *F) { 00388 return F->getKind() == MCFragment::FT_Align; 00389 } 00390 }; 00391 00392 class MCFillFragment : public MCFragment { 00393 virtual void anchor(); 00394 00395 /// Value - Value to use for filling bytes. 00396 int64_t Value; 00397 00398 /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if 00399 /// this is a virtual fill fragment. 00400 unsigned ValueSize; 00401 00402 /// Size - The number of bytes to insert. 00403 uint64_t Size; 00404 00405 public: 00406 MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size, 00407 MCSectionData *SD = nullptr) 00408 : MCFragment(FT_Fill, SD), 00409 Value(_Value), ValueSize(_ValueSize), Size(_Size) { 00410 assert((!ValueSize || (Size % ValueSize) == 0) && 00411 "Fill size must be a multiple of the value size!"); 00412 } 00413 00414 /// @name Accessors 00415 /// @{ 00416 00417 int64_t getValue() const { return Value; } 00418 00419 unsigned getValueSize() const { return ValueSize; } 00420 00421 uint64_t getSize() const { return Size; } 00422 00423 /// @} 00424 00425 static bool classof(const MCFragment *F) { 00426 return F->getKind() == MCFragment::FT_Fill; 00427 } 00428 }; 00429 00430 class MCOrgFragment : public MCFragment { 00431 virtual void anchor(); 00432 00433 /// Offset - The offset this fragment should start at. 00434 const MCExpr *Offset; 00435 00436 /// Value - Value to use for filling bytes. 00437 int8_t Value; 00438 00439 public: 00440 MCOrgFragment(const MCExpr &_Offset, int8_t _Value, 00441 MCSectionData *SD = nullptr) 00442 : MCFragment(FT_Org, SD), 00443 Offset(&_Offset), Value(_Value) {} 00444 00445 /// @name Accessors 00446 /// @{ 00447 00448 const MCExpr &getOffset() const { return *Offset; } 00449 00450 uint8_t getValue() const { return Value; } 00451 00452 /// @} 00453 00454 static bool classof(const MCFragment *F) { 00455 return F->getKind() == MCFragment::FT_Org; 00456 } 00457 }; 00458 00459 class MCLEBFragment : public MCFragment { 00460 virtual void anchor(); 00461 00462 /// Value - The value this fragment should contain. 00463 const MCExpr *Value; 00464 00465 /// IsSigned - True if this is a sleb128, false if uleb128. 00466 bool IsSigned; 00467 00468 SmallString<8> Contents; 00469 public: 00470 MCLEBFragment(const MCExpr &Value_, bool IsSigned_, 00471 MCSectionData *SD = nullptr) 00472 : MCFragment(FT_LEB, SD), 00473 Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); } 00474 00475 /// @name Accessors 00476 /// @{ 00477 00478 const MCExpr &getValue() const { return *Value; } 00479 00480 bool isSigned() const { return IsSigned; } 00481 00482 SmallString<8> &getContents() { return Contents; } 00483 const SmallString<8> &getContents() const { return Contents; } 00484 00485 /// @} 00486 00487 static bool classof(const MCFragment *F) { 00488 return F->getKind() == MCFragment::FT_LEB; 00489 } 00490 }; 00491 00492 class MCDwarfLineAddrFragment : public MCFragment { 00493 virtual void anchor(); 00494 00495 /// LineDelta - the value of the difference between the two line numbers 00496 /// between two .loc dwarf directives. 00497 int64_t LineDelta; 00498 00499 /// AddrDelta - The expression for the difference of the two symbols that 00500 /// make up the address delta between two .loc dwarf directives. 00501 const MCExpr *AddrDelta; 00502 00503 SmallString<8> Contents; 00504 00505 public: 00506 MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta, 00507 MCSectionData *SD = nullptr) 00508 : MCFragment(FT_Dwarf, SD), 00509 LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); } 00510 00511 /// @name Accessors 00512 /// @{ 00513 00514 int64_t getLineDelta() const { return LineDelta; } 00515 00516 const MCExpr &getAddrDelta() const { return *AddrDelta; } 00517 00518 SmallString<8> &getContents() { return Contents; } 00519 const SmallString<8> &getContents() const { return Contents; } 00520 00521 /// @} 00522 00523 static bool classof(const MCFragment *F) { 00524 return F->getKind() == MCFragment::FT_Dwarf; 00525 } 00526 }; 00527 00528 class MCDwarfCallFrameFragment : public MCFragment { 00529 virtual void anchor(); 00530 00531 /// AddrDelta - The expression for the difference of the two symbols that 00532 /// make up the address delta between two .cfi_* dwarf directives. 00533 const MCExpr *AddrDelta; 00534 00535 SmallString<8> Contents; 00536 00537 public: 00538 MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, 00539 MCSectionData *SD = nullptr) 00540 : MCFragment(FT_DwarfFrame, SD), 00541 AddrDelta(&_AddrDelta) { Contents.push_back(0); } 00542 00543 /// @name Accessors 00544 /// @{ 00545 00546 const MCExpr &getAddrDelta() const { return *AddrDelta; } 00547 00548 SmallString<8> &getContents() { return Contents; } 00549 const SmallString<8> &getContents() const { return Contents; } 00550 00551 /// @} 00552 00553 static bool classof(const MCFragment *F) { 00554 return F->getKind() == MCFragment::FT_DwarfFrame; 00555 } 00556 }; 00557 00558 // FIXME: Should this be a separate class, or just merged into MCSection? Since 00559 // we anticipate the fast path being through an MCAssembler, the only reason to 00560 // keep it out is for API abstraction. 00561 class MCSectionData : public ilist_node<MCSectionData> { 00562 friend class MCAsmLayout; 00563 00564 MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION; 00565 void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION; 00566 00567 public: 00568 typedef iplist<MCFragment> FragmentListType; 00569 00570 typedef FragmentListType::const_iterator const_iterator; 00571 typedef FragmentListType::iterator iterator; 00572 00573 typedef FragmentListType::const_reverse_iterator const_reverse_iterator; 00574 typedef FragmentListType::reverse_iterator reverse_iterator; 00575 00576 /// \brief Express the state of bundle locked groups while emitting code. 00577 enum BundleLockStateType { 00578 NotBundleLocked, 00579 BundleLocked, 00580 BundleLockedAlignToEnd 00581 }; 00582 private: 00583 FragmentListType Fragments; 00584 const MCSection *Section; 00585 00586 /// Ordinal - The section index in the assemblers section list. 00587 unsigned Ordinal; 00588 00589 /// LayoutOrder - The index of this section in the layout order. 00590 unsigned LayoutOrder; 00591 00592 /// Alignment - The maximum alignment seen in this section. 00593 unsigned Alignment; 00594 00595 /// \brief Keeping track of bundle-locked state. 00596 BundleLockStateType BundleLockState; 00597 00598 /// \brief We've seen a bundle_lock directive but not its first instruction 00599 /// yet. 00600 bool BundleGroupBeforeFirstInst; 00601 00602 /// @name Assembler Backend Data 00603 /// @{ 00604 // 00605 // FIXME: This could all be kept private to the assembler implementation. 00606 00607 /// HasInstructions - Whether this section has had instructions emitted into 00608 /// it. 00609 unsigned HasInstructions : 1; 00610 00611 /// Mapping from subsection number to insertion point for subsection numbers 00612 /// below that number. 00613 SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap; 00614 00615 /// @} 00616 00617 public: 00618 // Only for use as sentinel. 00619 MCSectionData(); 00620 MCSectionData(const MCSection &Section, MCAssembler *A = nullptr); 00621 00622 const MCSection &getSection() const { return *Section; } 00623 00624 unsigned getAlignment() const { return Alignment; } 00625 void setAlignment(unsigned Value) { Alignment = Value; } 00626 00627 bool hasInstructions() const { return HasInstructions; } 00628 void setHasInstructions(bool Value) { HasInstructions = Value; } 00629 00630 unsigned getOrdinal() const { return Ordinal; } 00631 void setOrdinal(unsigned Value) { Ordinal = Value; } 00632 00633 unsigned getLayoutOrder() const { return LayoutOrder; } 00634 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } 00635 00636 /// @name Fragment Access 00637 /// @{ 00638 00639 const FragmentListType &getFragmentList() const { return Fragments; } 00640 FragmentListType &getFragmentList() { return Fragments; } 00641 00642 iterator begin() { return Fragments.begin(); } 00643 const_iterator begin() const { return Fragments.begin(); } 00644 00645 iterator end() { return Fragments.end(); } 00646 const_iterator end() const { return Fragments.end(); } 00647 00648 reverse_iterator rbegin() { return Fragments.rbegin(); } 00649 const_reverse_iterator rbegin() const { return Fragments.rbegin(); } 00650 00651 reverse_iterator rend() { return Fragments.rend(); } 00652 const_reverse_iterator rend() const { return Fragments.rend(); } 00653 00654 size_t size() const { return Fragments.size(); } 00655 00656 bool empty() const { return Fragments.empty(); } 00657 00658 iterator getSubsectionInsertionPoint(unsigned Subsection); 00659 00660 bool isBundleLocked() const { 00661 return BundleLockState != NotBundleLocked; 00662 } 00663 00664 BundleLockStateType getBundleLockState() const { 00665 return BundleLockState; 00666 } 00667 00668 void setBundleLockState(BundleLockStateType NewState) { 00669 BundleLockState = NewState; 00670 } 00671 00672 bool isBundleGroupBeforeFirstInst() const { 00673 return BundleGroupBeforeFirstInst; 00674 } 00675 00676 void setBundleGroupBeforeFirstInst(bool IsFirst) { 00677 BundleGroupBeforeFirstInst = IsFirst; 00678 } 00679 00680 void dump(); 00681 00682 /// @} 00683 }; 00684 00685 // FIXME: Same concerns as with SectionData. 00686 class MCSymbolData : public ilist_node<MCSymbolData> { 00687 public: 00688 const MCSymbol *Symbol; 00689 00690 /// Fragment - The fragment this symbol's value is relative to, if any. 00691 MCFragment *Fragment; 00692 00693 /// Offset - The offset to apply to the fragment address to form this symbol's 00694 /// value. 00695 uint64_t Offset; 00696 00697 /// IsExternal - True if this symbol is visible outside this translation 00698 /// unit. 00699 unsigned IsExternal : 1; 00700 00701 /// IsPrivateExtern - True if this symbol is private extern. 00702 unsigned IsPrivateExtern : 1; 00703 00704 /// CommonSize - The size of the symbol, if it is 'common', or 0. 00705 // 00706 // FIXME: Pack this in with other fields? We could put it in offset, since a 00707 // common symbol can never get a definition. 00708 uint64_t CommonSize; 00709 00710 /// SymbolSize - An expression describing how to calculate the size of 00711 /// a symbol. If a symbol has no size this field will be NULL. 00712 const MCExpr *SymbolSize; 00713 00714 /// CommonAlign - The alignment of the symbol, if it is 'common'. 00715 // 00716 // FIXME: Pack this in with other fields? 00717 unsigned CommonAlign; 00718 00719 /// Flags - The Flags field is used by object file implementations to store 00720 /// additional per symbol information which is not easily classified. 00721 uint32_t Flags; 00722 00723 /// Index - Index field, for use by the object file implementation. 00724 uint64_t Index; 00725 00726 public: 00727 // Only for use as sentinel. 00728 MCSymbolData(); 00729 MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset, 00730 MCAssembler *A = nullptr); 00731 00732 /// @name Accessors 00733 /// @{ 00734 00735 const MCSymbol &getSymbol() const { return *Symbol; } 00736 00737 MCFragment *getFragment() const { return Fragment; } 00738 void setFragment(MCFragment *Value) { Fragment = Value; } 00739 00740 uint64_t getOffset() const { return Offset; } 00741 void setOffset(uint64_t Value) { Offset = Value; } 00742 00743 /// @} 00744 /// @name Symbol Attributes 00745 /// @{ 00746 00747 bool isExternal() const { return IsExternal; } 00748 void setExternal(bool Value) { IsExternal = Value; } 00749 00750 bool isPrivateExtern() const { return IsPrivateExtern; } 00751 void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } 00752 00753 /// isCommon - Is this a 'common' symbol. 00754 bool isCommon() const { return CommonSize != 0; } 00755 00756 /// setCommon - Mark this symbol as being 'common'. 00757 /// 00758 /// \param Size - The size of the symbol. 00759 /// \param Align - The alignment of the symbol. 00760 void setCommon(uint64_t Size, unsigned Align) { 00761 CommonSize = Size; 00762 CommonAlign = Align; 00763 } 00764 00765 /// getCommonSize - Return the size of a 'common' symbol. 00766 uint64_t getCommonSize() const { 00767 assert(isCommon() && "Not a 'common' symbol!"); 00768 return CommonSize; 00769 } 00770 00771 void setSize(const MCExpr *SS) { 00772 SymbolSize = SS; 00773 } 00774 00775 const MCExpr *getSize() const { 00776 return SymbolSize; 00777 } 00778 00779 00780 /// getCommonAlignment - Return the alignment of a 'common' symbol. 00781 unsigned getCommonAlignment() const { 00782 assert(isCommon() && "Not a 'common' symbol!"); 00783 return CommonAlign; 00784 } 00785 00786 /// getFlags - Get the (implementation defined) symbol flags. 00787 uint32_t getFlags() const { return Flags; } 00788 00789 /// setFlags - Set the (implementation defined) symbol flags. 00790 void setFlags(uint32_t Value) { Flags = Value; } 00791 00792 /// modifyFlags - Modify the flags via a mask 00793 void modifyFlags(uint32_t Value, uint32_t Mask) { 00794 Flags = (Flags & ~Mask) | Value; 00795 } 00796 00797 /// getIndex - Get the (implementation defined) index. 00798 uint64_t getIndex() const { return Index; } 00799 00800 /// setIndex - Set the (implementation defined) index. 00801 void setIndex(uint64_t Value) { Index = Value; } 00802 00803 /// @} 00804 00805 void dump() const; 00806 }; 00807 00808 // FIXME: This really doesn't belong here. See comments below. 00809 struct IndirectSymbolData { 00810 MCSymbol *Symbol; 00811 MCSectionData *SectionData; 00812 }; 00813 00814 // FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk 00815 // to one another. 00816 struct DataRegionData { 00817 // This enum should be kept in sync w/ the mach-o definition in 00818 // llvm/Object/MachOFormat.h. 00819 enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind; 00820 MCSymbol *Start; 00821 MCSymbol *End; 00822 }; 00823 00824 class MCAssembler { 00825 friend class MCAsmLayout; 00826 00827 public: 00828 typedef iplist<MCSectionData> SectionDataListType; 00829 typedef iplist<MCSymbolData> SymbolDataListType; 00830 00831 typedef SectionDataListType::const_iterator const_iterator; 00832 typedef SectionDataListType::iterator iterator; 00833 00834 typedef SymbolDataListType::const_iterator const_symbol_iterator; 00835 typedef SymbolDataListType::iterator symbol_iterator; 00836 00837 typedef iterator_range<symbol_iterator> symbol_range; 00838 typedef iterator_range<const_symbol_iterator> const_symbol_range; 00839 00840 typedef std::vector<std::string> FileNameVectorType; 00841 typedef FileNameVectorType::const_iterator const_file_name_iterator; 00842 00843 typedef std::vector<IndirectSymbolData>::const_iterator 00844 const_indirect_symbol_iterator; 00845 typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator; 00846 00847 typedef std::vector<DataRegionData>::const_iterator 00848 const_data_region_iterator; 00849 typedef std::vector<DataRegionData>::iterator data_region_iterator; 00850 00851 /// MachO specific deployment target version info. 00852 // A Major version of 0 indicates that no version information was supplied 00853 // and so the corresponding load command should not be emitted. 00854 typedef struct { 00855 MCVersionMinType Kind; 00856 unsigned Major; 00857 unsigned Minor; 00858 unsigned Update; 00859 } VersionMinInfoType; 00860 private: 00861 MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION; 00862 void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION; 00863 00864 MCContext &Context; 00865 00866 MCAsmBackend &Backend; 00867 00868 MCCodeEmitter &Emitter; 00869 00870 MCObjectWriter &Writer; 00871 00872 raw_ostream &OS; 00873 00874 iplist<MCSectionData> Sections; 00875 00876 iplist<MCSymbolData> Symbols; 00877 00878 /// The map of sections to their associated assembler backend data. 00879 // 00880 // FIXME: Avoid this indirection? 00881 DenseMap<const MCSection*, MCSectionData*> SectionMap; 00882 00883 /// The map of symbols to their associated assembler backend data. 00884 // 00885 // FIXME: Avoid this indirection? 00886 DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; 00887 00888 std::vector<IndirectSymbolData> IndirectSymbols; 00889 00890 std::vector<DataRegionData> DataRegions; 00891 00892 /// The list of linker options to propagate into the object file. 00893 std::vector<std::vector<std::string> > LinkerOptions; 00894 00895 /// List of declared file names 00896 FileNameVectorType FileNames; 00897 00898 /// The set of function symbols for which a .thumb_func directive has 00899 /// been seen. 00900 // 00901 // FIXME: We really would like this in target specific code rather than 00902 // here. Maybe when the relocation stuff moves to target specific, 00903 // this can go with it? The streamer would need some target specific 00904 // refactoring too. 00905 mutable SmallPtrSet<const MCSymbol*, 64> ThumbFuncs; 00906 00907 /// \brief The bundle alignment size currently set in the assembler. 00908 /// 00909 /// By default it's 0, which means bundling is disabled. 00910 unsigned BundleAlignSize; 00911 00912 unsigned RelaxAll : 1; 00913 unsigned NoExecStack : 1; 00914 unsigned SubsectionsViaSymbols : 1; 00915 00916 /// ELF specific e_header flags 00917 // It would be good if there were an MCELFAssembler class to hold this. 00918 // ELF header flags are used both by the integrated and standalone assemblers. 00919 // Access to the flags is necessary in cases where assembler directives affect 00920 // which flags to be set. 00921 unsigned ELFHeaderEFlags; 00922 00923 /// Used to communicate Linker Optimization Hint information between 00924 /// the Streamer and the .o writer 00925 MCLOHContainer LOHContainer; 00926 00927 VersionMinInfoType VersionMinInfo; 00928 private: 00929 /// Evaluate a fixup to a relocatable expression and the value which should be 00930 /// placed into the fixup. 00931 /// 00932 /// \param Layout The layout to use for evaluation. 00933 /// \param Fixup The fixup to evaluate. 00934 /// \param DF The fragment the fixup is inside. 00935 /// \param Target [out] On return, the relocatable expression the fixup 00936 /// evaluates to. 00937 /// \param Value [out] On return, the value of the fixup as currently laid 00938 /// out. 00939 /// \return Whether the fixup value was fully resolved. This is true if the 00940 /// \p Value result is fixed, otherwise the value may change due to 00941 /// relocation. 00942 bool evaluateFixup(const MCAsmLayout &Layout, 00943 const MCFixup &Fixup, const MCFragment *DF, 00944 MCValue &Target, uint64_t &Value) const; 00945 00946 /// Check whether a fixup can be satisfied, or whether it needs to be relaxed 00947 /// (increased in size, in order to hold its value correctly). 00948 bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF, 00949 const MCAsmLayout &Layout) const; 00950 00951 /// Check whether the given fragment needs relaxation. 00952 bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF, 00953 const MCAsmLayout &Layout) const; 00954 00955 /// \brief Perform one layout iteration and return true if any offsets 00956 /// were adjusted. 00957 bool layoutOnce(MCAsmLayout &Layout); 00958 00959 /// \brief Perform one layout iteration of the given section and return true 00960 /// if any offsets were adjusted. 00961 bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); 00962 00963 bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF); 00964 00965 bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); 00966 00967 bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); 00968 bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout, 00969 MCDwarfCallFrameFragment &DF); 00970 00971 /// finishLayout - Finalize a layout, including fragment lowering. 00972 void finishLayout(MCAsmLayout &Layout); 00973 00974 std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout, 00975 MCFragment &F, const MCFixup &Fixup); 00976 00977 public: 00978 /// Compute the effective fragment size assuming it is laid out at the given 00979 /// \p SectionAddress and \p FragmentOffset. 00980 uint64_t computeFragmentSize(const MCAsmLayout &Layout, 00981 const MCFragment &F) const; 00982 00983 /// Find the symbol which defines the atom containing the given symbol, or 00984 /// null if there is no such symbol. 00985 const MCSymbolData *getAtom(const MCSymbolData *Symbol) const; 00986 00987 /// Check whether a particular symbol is visible to the linker and is required 00988 /// in the symbol table, or whether it can be discarded by the assembler. This 00989 /// also effects whether the assembler treats the label as potentially 00990 /// defining a separate atom. 00991 bool isSymbolLinkerVisible(const MCSymbol &SD) const; 00992 00993 /// Emit the section contents using the given object writer. 00994 void writeSectionData(const MCSectionData *Section, 00995 const MCAsmLayout &Layout) const; 00996 00997 /// Check whether a given symbol has been flagged with .thumb_func. 00998 bool isThumbFunc(const MCSymbol *Func) const; 00999 01000 /// Flag a function symbol as the target of a .thumb_func directive. 01001 void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } 01002 01003 /// ELF e_header flags 01004 unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;} 01005 void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;} 01006 01007 /// MachO deployment target version information. 01008 const VersionMinInfoType &getVersionMinInfo() const { return VersionMinInfo; } 01009 void setVersionMinInfo(MCVersionMinType Kind, unsigned Major, unsigned Minor, 01010 unsigned Update) { 01011 VersionMinInfo.Kind = Kind; 01012 VersionMinInfo.Major = Major; 01013 VersionMinInfo.Minor = Minor; 01014 VersionMinInfo.Update = Update; 01015 } 01016 01017 public: 01018 /// Construct a new assembler instance. 01019 /// 01020 /// \param OS The stream to output to. 01021 // 01022 // FIXME: How are we going to parameterize this? Two obvious options are stay 01023 // concrete and require clients to pass in a target like object. The other 01024 // option is to make this abstract, and have targets provide concrete 01025 // implementations as we do with AsmParser. 01026 MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, 01027 MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, 01028 raw_ostream &OS); 01029 ~MCAssembler(); 01030 01031 /// Reuse an assembler instance 01032 /// 01033 void reset(); 01034 01035 MCContext &getContext() const { return Context; } 01036 01037 MCAsmBackend &getBackend() const { return Backend; } 01038 01039 MCCodeEmitter &getEmitter() const { return Emitter; } 01040 01041 MCObjectWriter &getWriter() const { return Writer; } 01042 01043 /// Finish - Do final processing and write the object to the output stream. 01044 /// \p Writer is used for custom object writer (as the MCJIT does), 01045 /// if not specified it is automatically created from backend. 01046 void Finish(); 01047 01048 // FIXME: This does not belong here. 01049 bool getSubsectionsViaSymbols() const { 01050 return SubsectionsViaSymbols; 01051 } 01052 void setSubsectionsViaSymbols(bool Value) { 01053 SubsectionsViaSymbols = Value; 01054 } 01055 01056 bool getRelaxAll() const { return RelaxAll; } 01057 void setRelaxAll(bool Value) { RelaxAll = Value; } 01058 01059 bool getNoExecStack() const { return NoExecStack; } 01060 void setNoExecStack(bool Value) { NoExecStack = Value; } 01061 01062 bool isBundlingEnabled() const { 01063 return BundleAlignSize != 0; 01064 } 01065 01066 unsigned getBundleAlignSize() const { 01067 return BundleAlignSize; 01068 } 01069 01070 void setBundleAlignSize(unsigned Size) { 01071 assert((Size == 0 || !(Size & (Size - 1))) && 01072 "Expect a power-of-two bundle align size"); 01073 BundleAlignSize = Size; 01074 } 01075 01076 /// @name Section List Access 01077 /// @{ 01078 01079 const SectionDataListType &getSectionList() const { return Sections; } 01080 SectionDataListType &getSectionList() { return Sections; } 01081 01082 iterator begin() { return Sections.begin(); } 01083 const_iterator begin() const { return Sections.begin(); } 01084 01085 iterator end() { return Sections.end(); } 01086 const_iterator end() const { return Sections.end(); } 01087 01088 size_t size() const { return Sections.size(); } 01089 01090 /// @} 01091 /// @name Symbol List Access 01092 /// @{ 01093 01094 const SymbolDataListType &getSymbolList() const { return Symbols; } 01095 SymbolDataListType &getSymbolList() { return Symbols; } 01096 01097 symbol_iterator symbol_begin() { return Symbols.begin(); } 01098 const_symbol_iterator symbol_begin() const { return Symbols.begin(); } 01099 01100 symbol_iterator symbol_end() { return Symbols.end(); } 01101 const_symbol_iterator symbol_end() const { return Symbols.end(); } 01102 01103 symbol_range symbols() { return make_range(symbol_begin(), symbol_end()); } 01104 const_symbol_range symbols() const { return make_range(symbol_begin(), symbol_end()); } 01105 01106 size_t symbol_size() const { return Symbols.size(); } 01107 01108 /// @} 01109 /// @name Indirect Symbol List Access 01110 /// @{ 01111 01112 // FIXME: This is a total hack, this should not be here. Once things are 01113 // factored so that the streamer has direct access to the .o writer, it can 01114 // disappear. 01115 std::vector<IndirectSymbolData> &getIndirectSymbols() { 01116 return IndirectSymbols; 01117 } 01118 01119 indirect_symbol_iterator indirect_symbol_begin() { 01120 return IndirectSymbols.begin(); 01121 } 01122 const_indirect_symbol_iterator indirect_symbol_begin() const { 01123 return IndirectSymbols.begin(); 01124 } 01125 01126 indirect_symbol_iterator indirect_symbol_end() { 01127 return IndirectSymbols.end(); 01128 } 01129 const_indirect_symbol_iterator indirect_symbol_end() const { 01130 return IndirectSymbols.end(); 01131 } 01132 01133 size_t indirect_symbol_size() const { return IndirectSymbols.size(); } 01134 01135 /// @} 01136 /// @name Linker Option List Access 01137 /// @{ 01138 01139 std::vector<std::vector<std::string> > &getLinkerOptions() { 01140 return LinkerOptions; 01141 } 01142 01143 /// @} 01144 /// @name Data Region List Access 01145 /// @{ 01146 01147 // FIXME: This is a total hack, this should not be here. Once things are 01148 // factored so that the streamer has direct access to the .o writer, it can 01149 // disappear. 01150 std::vector<DataRegionData> &getDataRegions() { 01151 return DataRegions; 01152 } 01153 01154 data_region_iterator data_region_begin() { 01155 return DataRegions.begin(); 01156 } 01157 const_data_region_iterator data_region_begin() const { 01158 return DataRegions.begin(); 01159 } 01160 01161 data_region_iterator data_region_end() { 01162 return DataRegions.end(); 01163 } 01164 const_data_region_iterator data_region_end() const { 01165 return DataRegions.end(); 01166 } 01167 01168 size_t data_region_size() const { return DataRegions.size(); } 01169 01170 /// @} 01171 /// @name Data Region List Access 01172 /// @{ 01173 01174 // FIXME: This is a total hack, this should not be here. Once things are 01175 // factored so that the streamer has direct access to the .o writer, it can 01176 // disappear. 01177 MCLOHContainer & getLOHContainer() { 01178 return LOHContainer; 01179 } 01180 const MCLOHContainer & getLOHContainer() const { 01181 return const_cast<MCAssembler *>(this)->getLOHContainer(); 01182 } 01183 /// @} 01184 /// @name Backend Data Access 01185 /// @{ 01186 01187 MCSectionData &getSectionData(const MCSection &Section) const { 01188 MCSectionData *Entry = SectionMap.lookup(&Section); 01189 assert(Entry && "Missing section data!"); 01190 return *Entry; 01191 } 01192 01193 MCSectionData &getOrCreateSectionData(const MCSection &Section, 01194 bool *Created = nullptr) { 01195 MCSectionData *&Entry = SectionMap[&Section]; 01196 01197 if (Created) *Created = !Entry; 01198 if (!Entry) 01199 Entry = new MCSectionData(Section, this); 01200 01201 return *Entry; 01202 } 01203 01204 bool hasSymbolData(const MCSymbol &Symbol) const { 01205 return SymbolMap.lookup(&Symbol) != nullptr; 01206 } 01207 01208 MCSymbolData &getSymbolData(const MCSymbol &Symbol) { 01209 return const_cast<MCSymbolData &>( 01210 static_cast<const MCAssembler &>(*this).getSymbolData(Symbol)); 01211 } 01212 01213 const MCSymbolData &getSymbolData(const MCSymbol &Symbol) const { 01214 MCSymbolData *Entry = SymbolMap.lookup(&Symbol); 01215 assert(Entry && "Missing symbol data!"); 01216 return *Entry; 01217 } 01218 01219 MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol, 01220 bool *Created = nullptr) { 01221 MCSymbolData *&Entry = SymbolMap[&Symbol]; 01222 01223 if (Created) *Created = !Entry; 01224 if (!Entry) 01225 Entry = new MCSymbolData(Symbol, nullptr, 0, this); 01226 01227 return *Entry; 01228 } 01229 01230 const_file_name_iterator file_names_begin() const { 01231 return FileNames.begin(); 01232 } 01233 01234 const_file_name_iterator file_names_end() const { 01235 return FileNames.end(); 01236 } 01237 01238 void addFileName(StringRef FileName) { 01239 if (std::find(file_names_begin(), file_names_end(), FileName) == 01240 file_names_end()) 01241 FileNames.push_back(FileName); 01242 } 01243 01244 /// @} 01245 01246 void dump(); 01247 }; 01248 01249 } // end namespace llvm 01250 01251 #endif