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