Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1162 lines
34 KiB

  1. //===- MCAssembler.h - Object File Generation -------------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef LLVM_MC_MCASSEMBLER_H
  10. #define LLVM_MC_MCASSEMBLER_H
  11. #include "llvm/ADT/DenseMap.h"
  12. #include "llvm/ADT/SmallPtrSet.h"
  13. #include "llvm/ADT/SmallString.h"
  14. #include "llvm/ADT/ilist.h"
  15. #include "llvm/ADT/ilist_node.h"
  16. #include "llvm/MC/MCFixup.h"
  17. #include "llvm/MC/MCInst.h"
  18. #include "llvm/Support/Casting.h"
  19. #include "llvm/Support/DataTypes.h"
  20. #include <vector> // FIXME: Shouldn't be needed.
  21. namespace llvm {
  22. class raw_ostream;
  23. class MCAsmLayout;
  24. class MCAssembler;
  25. class MCContext;
  26. class MCCodeEmitter;
  27. class MCExpr;
  28. class MCFragment;
  29. class MCObjectWriter;
  30. class MCSection;
  31. class MCSectionData;
  32. class MCSymbol;
  33. class MCSymbolData;
  34. class MCValue;
  35. class MCAsmBackend;
  36. class MCFragment : public ilist_node<MCFragment> {
  37. friend class MCAsmLayout;
  38. MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION;
  39. void operator=(const MCFragment&) LLVM_DELETED_FUNCTION;
  40. public:
  41. enum FragmentType {
  42. FT_Align,
  43. FT_Data,
  44. FT_CompactEncodedInst,
  45. FT_Fill,
  46. FT_Relaxable,
  47. FT_Org,
  48. FT_Dwarf,
  49. FT_DwarfFrame,
  50. FT_LEB
  51. };
  52. private:
  53. FragmentType Kind;
  54. /// Parent - The data for the section this fragment is in.
  55. MCSectionData *Parent;
  56. /// Atom - The atom this fragment is in, as represented by it's defining
  57. /// symbol. Atom's are only used by backends which set
  58. /// \see MCAsmBackend::hasReliableSymbolDifference().
  59. MCSymbolData *Atom;
  60. /// @name Assembler Backend Data
  61. /// @{
  62. //
  63. // FIXME: This could all be kept private to the assembler implementation.
  64. /// Offset - The offset of this fragment in its section. This is ~0 until
  65. /// initialized.
  66. uint64_t Offset;
  67. /// LayoutOrder - The layout order of this fragment.
  68. unsigned LayoutOrder;
  69. /// @}
  70. protected:
  71. MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
  72. public:
  73. // Only for sentinel.
  74. MCFragment();
  75. virtual ~MCFragment();
  76. FragmentType getKind() const { return Kind; }
  77. MCSectionData *getParent() const { return Parent; }
  78. void setParent(MCSectionData *Value) { Parent = Value; }
  79. MCSymbolData *getAtom() const { return Atom; }
  80. void setAtom(MCSymbolData *Value) { Atom = Value; }
  81. unsigned getLayoutOrder() const { return LayoutOrder; }
  82. void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
  83. /// \brief Does this fragment have instructions emitted into it? By default
  84. /// this is false, but specific fragment types may set it to true.
  85. virtual bool hasInstructions() const { return false; }
  86. /// \brief Should this fragment be placed at the end of an aligned bundle?
  87. virtual bool alignToBundleEnd() const { return false; }
  88. virtual void setAlignToBundleEnd(bool V) { }
  89. /// \brief Get the padding size that must be inserted before this fragment.
  90. /// Used for bundling. By default, no padding is inserted.
  91. /// Note that padding size is restricted to 8 bits. This is an optimization
  92. /// to reduce the amount of space used for each fragment. In practice, larger
  93. /// padding should never be required.
  94. virtual uint8_t getBundlePadding() const {
  95. return 0;
  96. }
  97. /// \brief Set the padding size for this fragment. By default it's a no-op,
  98. /// and only some fragments have a meaningful implementation.
  99. virtual void setBundlePadding(uint8_t N) {
  100. }
  101. void dump();
  102. };
  103. /// Interface implemented by fragments that contain encoded instructions and/or
  104. /// data.
  105. ///
  106. class MCEncodedFragment : public MCFragment {
  107. virtual void anchor();
  108. uint8_t BundlePadding;
  109. public:
  110. MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
  111. : MCFragment(FType, SD), BundlePadding(0)
  112. {
  113. }
  114. virtual ~MCEncodedFragment();
  115. virtual SmallVectorImpl<char> &getContents() = 0;
  116. virtual const SmallVectorImpl<char> &getContents() const = 0;
  117. virtual uint8_t getBundlePadding() const {
  118. return BundlePadding;
  119. }
  120. virtual void setBundlePadding(uint8_t N) {
  121. BundlePadding = N;
  122. }
  123. static bool classof(const MCFragment *F) {
  124. MCFragment::FragmentType Kind = F->getKind();
  125. switch (Kind) {
  126. default:
  127. return false;
  128. case MCFragment::FT_Relaxable:
  129. case MCFragment::FT_CompactEncodedInst:
  130. case MCFragment::FT_Data:
  131. return true;
  132. }
  133. }
  134. };
  135. /// Interface implemented by fragments that contain encoded instructions and/or
  136. /// data and also have fixups registered.
  137. ///
  138. class MCEncodedFragmentWithFixups : public MCEncodedFragment {
  139. virtual void anchor();
  140. public:
  141. MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
  142. MCSectionData *SD = 0)
  143. : MCEncodedFragment(FType, SD)
  144. {
  145. }
  146. virtual ~MCEncodedFragmentWithFixups();
  147. typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
  148. typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
  149. virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
  150. virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
  151. virtual fixup_iterator fixup_begin() = 0;
  152. virtual const_fixup_iterator fixup_begin() const = 0;
  153. virtual fixup_iterator fixup_end() = 0;
  154. virtual const_fixup_iterator fixup_end() const = 0;
  155. static bool classof(const MCFragment *F) {
  156. MCFragment::FragmentType Kind = F->getKind();
  157. return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data;
  158. }
  159. };
  160. /// Fragment for data and encoded instructions.
  161. ///
  162. class MCDataFragment : public MCEncodedFragmentWithFixups {
  163. virtual void anchor();
  164. /// \brief Does this fragment contain encoded instructions anywhere in it?
  165. bool HasInstructions;
  166. /// \brief Should this fragment be aligned to the end of a bundle?
  167. bool AlignToBundleEnd;
  168. SmallVector<char, 32> Contents;
  169. /// Fixups - The list of fixups in this fragment.
  170. SmallVector<MCFixup, 4> Fixups;
  171. public:
  172. MCDataFragment(MCSectionData *SD = 0)
  173. : MCEncodedFragmentWithFixups(FT_Data, SD),
  174. HasInstructions(false), AlignToBundleEnd(false)
  175. {
  176. }
  177. virtual SmallVectorImpl<char> &getContents() { return Contents; }
  178. virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
  179. SmallVectorImpl<MCFixup> &getFixups() {
  180. return Fixups;
  181. }
  182. const SmallVectorImpl<MCFixup> &getFixups() const {
  183. return Fixups;
  184. }
  185. virtual bool hasInstructions() const { return HasInstructions; }
  186. virtual void setHasInstructions(bool V) { HasInstructions = V; }
  187. virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
  188. virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
  189. fixup_iterator fixup_begin() { return Fixups.begin(); }
  190. const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
  191. fixup_iterator fixup_end() {return Fixups.end();}
  192. const_fixup_iterator fixup_end() const {return Fixups.end();}
  193. static bool classof(const MCFragment *F) {
  194. return F->getKind() == MCFragment::FT_Data;
  195. }
  196. };
  197. /// This is a compact (memory-size-wise) fragment for holding an encoded
  198. /// instruction (non-relaxable) that has no fixups registered. When applicable,
  199. /// it can be used instead of MCDataFragment and lead to lower memory
  200. /// consumption.
  201. ///
  202. class MCCompactEncodedInstFragment : public MCEncodedFragment {
  203. virtual void anchor();
  204. /// \brief Should this fragment be aligned to the end of a bundle?
  205. bool AlignToBundleEnd;
  206. SmallVector<char, 4> Contents;
  207. public:
  208. MCCompactEncodedInstFragment(MCSectionData *SD = 0)
  209. : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false)
  210. {
  211. }
  212. virtual bool hasInstructions() const {
  213. return true;
  214. }
  215. virtual SmallVectorImpl<char> &getContents() { return Contents; }
  216. virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
  217. virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
  218. virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
  219. static bool classof(const MCFragment *F) {
  220. return F->getKind() == MCFragment::FT_CompactEncodedInst;
  221. }
  222. };
  223. /// A relaxable fragment holds on to its MCInst, since it may need to be
  224. /// relaxed during the assembler layout and relaxation stage.
  225. ///
  226. class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
  227. virtual void anchor();
  228. /// Inst - The instruction this is a fragment for.
  229. MCInst Inst;
  230. /// Contents - Binary data for the currently encoded instruction.
  231. SmallVector<char, 8> Contents;
  232. /// Fixups - The list of fixups in this fragment.
  233. SmallVector<MCFixup, 1> Fixups;
  234. public:
  235. MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0)
  236. : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) {
  237. }
  238. virtual SmallVectorImpl<char> &getContents() { return Contents; }
  239. virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
  240. const MCInst &getInst() const { return Inst; }
  241. void setInst(const MCInst& Value) { Inst = Value; }
  242. SmallVectorImpl<MCFixup> &getFixups() {
  243. return Fixups;
  244. }
  245. const SmallVectorImpl<MCFixup> &getFixups() const {
  246. return Fixups;
  247. }
  248. virtual bool hasInstructions() const { return true; }
  249. fixup_iterator fixup_begin() { return Fixups.begin(); }
  250. const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
  251. fixup_iterator fixup_end() {return Fixups.end();}
  252. const_fixup_iterator fixup_end() const {return Fixups.end();}
  253. static bool classof(const MCFragment *F) {
  254. return F->getKind() == MCFragment::FT_Relaxable;
  255. }
  256. };
  257. class MCAlignFragment : public MCFragment {
  258. virtual void anchor();
  259. /// Alignment - The alignment to ensure, in bytes.
  260. unsigned Alignment;
  261. /// Value - Value to use for filling padding bytes.
  262. int64_t Value;
  263. /// ValueSize - The size of the integer (in bytes) of \p Value.
  264. unsigned ValueSize;
  265. /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
  266. /// cannot be satisfied in this width then this fragment is ignored.
  267. unsigned MaxBytesToEmit;
  268. /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
  269. /// of using the provided value. The exact interpretation of this flag is
  270. /// target dependent.
  271. bool EmitNops : 1;
  272. public:
  273. MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
  274. unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
  275. : MCFragment(FT_Align, SD), Alignment(_Alignment),
  276. Value(_Value),ValueSize(_ValueSize),
  277. MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
  278. /// @name Accessors
  279. /// @{
  280. unsigned getAlignment() const { return Alignment; }
  281. int64_t getValue() const { return Value; }
  282. unsigned getValueSize() const { return ValueSize; }
  283. unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
  284. bool hasEmitNops() const { return EmitNops; }
  285. void setEmitNops(bool Value) { EmitNops = Value; }
  286. /// @}
  287. static bool classof(const MCFragment *F) {
  288. return F->getKind() == MCFragment::FT_Align;
  289. }
  290. };
  291. class MCFillFragment : public MCFragment {
  292. virtual void anchor();
  293. /// Value - Value to use for filling bytes.
  294. int64_t Value;
  295. /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if
  296. /// this is a virtual fill fragment.
  297. unsigned ValueSize;
  298. /// Size - The number of bytes to insert.
  299. uint64_t Size;
  300. public:
  301. MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
  302. MCSectionData *SD = 0)
  303. : MCFragment(FT_Fill, SD),
  304. Value(_Value), ValueSize(_ValueSize), Size(_Size) {
  305. assert((!ValueSize || (Size % ValueSize) == 0) &&
  306. "Fill size must be a multiple of the value size!");
  307. }
  308. /// @name Accessors
  309. /// @{
  310. int64_t getValue() const { return Value; }
  311. unsigned getValueSize() const { return ValueSize; }
  312. uint64_t getSize() const { return Size; }
  313. /// @}
  314. static bool classof(const MCFragment *F) {
  315. return F->getKind() == MCFragment::FT_Fill;
  316. }
  317. };
  318. class MCOrgFragment : public MCFragment {
  319. virtual void anchor();
  320. /// Offset - The offset this fragment should start at.
  321. const MCExpr *Offset;
  322. /// Value - Value to use for filling bytes.
  323. int8_t Value;
  324. public:
  325. MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
  326. : MCFragment(FT_Org, SD),
  327. Offset(&_Offset), Value(_Value) {}
  328. /// @name Accessors
  329. /// @{
  330. const MCExpr &getOffset() const { return *Offset; }
  331. uint8_t getValue() const { return Value; }
  332. /// @}
  333. static bool classof(const MCFragment *F) {
  334. return F->getKind() == MCFragment::FT_Org;
  335. }
  336. };
  337. class MCLEBFragment : public MCFragment {
  338. virtual void anchor();
  339. /// Value - The value this fragment should contain.
  340. const MCExpr *Value;
  341. /// IsSigned - True if this is a sleb128, false if uleb128.
  342. bool IsSigned;
  343. SmallString<8> Contents;
  344. public:
  345. MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD = 0)
  346. : MCFragment(FT_LEB, SD),
  347. Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
  348. /// @name Accessors
  349. /// @{
  350. const MCExpr &getValue() const { return *Value; }
  351. bool isSigned() const { return IsSigned; }
  352. SmallString<8> &getContents() { return Contents; }
  353. const SmallString<8> &getContents() const { return Contents; }
  354. /// @}
  355. static bool classof(const MCFragment *F) {
  356. return F->getKind() == MCFragment::FT_LEB;
  357. }
  358. };
  359. class MCDwarfLineAddrFragment : public MCFragment {
  360. virtual void anchor();
  361. /// LineDelta - the value of the difference between the two line numbers
  362. /// between two .loc dwarf directives.
  363. int64_t LineDelta;
  364. /// AddrDelta - The expression for the difference of the two symbols that
  365. /// make up the address delta between two .loc dwarf directives.
  366. const MCExpr *AddrDelta;
  367. SmallString<8> Contents;
  368. public:
  369. MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
  370. MCSectionData *SD = 0)
  371. : MCFragment(FT_Dwarf, SD),
  372. LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
  373. /// @name Accessors
  374. /// @{
  375. int64_t getLineDelta() const { return LineDelta; }
  376. const MCExpr &getAddrDelta() const { return *AddrDelta; }
  377. SmallString<8> &getContents() { return Contents; }
  378. const SmallString<8> &getContents() const { return Contents; }
  379. /// @}
  380. static bool classof(const MCFragment *F) {
  381. return F->getKind() == MCFragment::FT_Dwarf;
  382. }
  383. };
  384. class MCDwarfCallFrameFragment : public MCFragment {
  385. virtual void anchor();
  386. /// AddrDelta - The expression for the difference of the two symbols that
  387. /// make up the address delta between two .cfi_* dwarf directives.
  388. const MCExpr *AddrDelta;
  389. SmallString<8> Contents;
  390. public:
  391. MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD = 0)
  392. : MCFragment(FT_DwarfFrame, SD),
  393. AddrDelta(&_AddrDelta) { Contents.push_back(0); }
  394. /// @name Accessors
  395. /// @{
  396. const MCExpr &getAddrDelta() const { return *AddrDelta; }
  397. SmallString<8> &getContents() { return Contents; }
  398. const SmallString<8> &getContents() const { return Contents; }
  399. /// @}
  400. static bool classof(const MCFragment *F) {
  401. return F->getKind() == MCFragment::FT_DwarfFrame;
  402. }
  403. };
  404. // FIXME: Should this be a separate class, or just merged into MCSection? Since
  405. // we anticipate the fast path being through an MCAssembler, the only reason to
  406. // keep it out is for API abstraction.
  407. class MCSectionData : public ilist_node<MCSectionData> {
  408. friend class MCAsmLayout;
  409. MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION;
  410. void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION;
  411. public:
  412. typedef iplist<MCFragment> FragmentListType;
  413. typedef FragmentListType::const_iterator const_iterator;
  414. typedef FragmentListType::iterator iterator;
  415. typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
  416. typedef FragmentListType::reverse_iterator reverse_iterator;
  417. /// \brief Express the state of bundle locked groups while emitting code.
  418. enum BundleLockStateType {
  419. NotBundleLocked,
  420. BundleLocked,
  421. BundleLockedAlignToEnd
  422. };
  423. private:
  424. FragmentListType Fragments;
  425. const MCSection *Section;
  426. /// Ordinal - The section index in the assemblers section list.
  427. unsigned Ordinal;
  428. /// LayoutOrder - The index of this section in the layout order.
  429. unsigned LayoutOrder;
  430. /// Alignment - The maximum alignment seen in this section.
  431. unsigned Alignment;
  432. /// \brief Keeping track of bundle-locked state.
  433. BundleLockStateType BundleLockState;
  434. /// \brief We've seen a bundle_lock directive but not its first instruction
  435. /// yet.
  436. bool BundleGroupBeforeFirstInst;
  437. /// @name Assembler Backend Data
  438. /// @{
  439. //
  440. // FIXME: This could all be kept private to the assembler implementation.
  441. /// HasInstructions - Whether this section has had instructions emitted into
  442. /// it.
  443. unsigned HasInstructions : 1;
  444. /// Mapping from subsection number to insertion point for subsection numbers
  445. /// below that number.
  446. SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap;
  447. /// @}
  448. public:
  449. // Only for use as sentinel.
  450. MCSectionData();
  451. MCSectionData(const MCSection &Section, MCAssembler *A = 0);
  452. const MCSection &getSection() const { return *Section; }
  453. unsigned getAlignment() const { return Alignment; }
  454. void setAlignment(unsigned Value) { Alignment = Value; }
  455. bool hasInstructions() const { return HasInstructions; }
  456. void setHasInstructions(bool Value) { HasInstructions = Value; }
  457. unsigned getOrdinal() const { return Ordinal; }
  458. void setOrdinal(unsigned Value) { Ordinal = Value; }
  459. unsigned getLayoutOrder() const { return LayoutOrder; }
  460. void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
  461. /// @name Fragment Access
  462. /// @{
  463. const FragmentListType &getFragmentList() const { return Fragments; }
  464. FragmentListType &getFragmentList() { return Fragments; }
  465. iterator begin() { return Fragments.begin(); }
  466. const_iterator begin() const { return Fragments.begin(); }
  467. iterator end() { return Fragments.end(); }
  468. const_iterator end() const { return Fragments.end(); }
  469. reverse_iterator rbegin() { return Fragments.rbegin(); }
  470. const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
  471. reverse_iterator rend() { return Fragments.rend(); }
  472. const_reverse_iterator rend() const { return Fragments.rend(); }
  473. size_t size() const { return Fragments.size(); }
  474. bool empty() const { return Fragments.empty(); }
  475. iterator getSubsectionInsertionPoint(unsigned Subsection);
  476. bool isBundleLocked() const {
  477. return BundleLockState != NotBundleLocked;
  478. }
  479. BundleLockStateType getBundleLockState() const {
  480. return BundleLockState;
  481. }
  482. void setBundleLockState(BundleLockStateType NewState) {
  483. BundleLockState = NewState;
  484. }
  485. bool isBundleGroupBeforeFirstInst() const {
  486. return BundleGroupBeforeFirstInst;
  487. }
  488. void setBundleGroupBeforeFirstInst(bool IsFirst) {
  489. BundleGroupBeforeFirstInst = IsFirst;
  490. }
  491. void dump();
  492. /// @}
  493. };
  494. // FIXME: Same concerns as with SectionData.
  495. class MCSymbolData : public ilist_node<MCSymbolData> {
  496. public:
  497. const MCSymbol *Symbol;
  498. /// Fragment - The fragment this symbol's value is relative to, if any.
  499. MCFragment *Fragment;
  500. /// Offset - The offset to apply to the fragment address to form this symbol's
  501. /// value.
  502. uint64_t Offset;
  503. /// IsExternal - True if this symbol is visible outside this translation
  504. /// unit.
  505. unsigned IsExternal : 1;
  506. /// IsPrivateExtern - True if this symbol is private extern.
  507. unsigned IsPrivateExtern : 1;
  508. /// CommonSize - The size of the symbol, if it is 'common', or 0.
  509. //
  510. // FIXME: Pack this in with other fields? We could put it in offset, since a
  511. // common symbol can never get a definition.
  512. uint64_t CommonSize;
  513. /// SymbolSize - An expression describing how to calculate the size of
  514. /// a symbol. If a symbol has no size this field will be NULL.
  515. const MCExpr *SymbolSize;
  516. /// CommonAlign - The alignment of the symbol, if it is 'common'.
  517. //
  518. // FIXME: Pack this in with other fields?
  519. unsigned CommonAlign;
  520. /// Flags - The Flags field is used by object file implementations to store
  521. /// additional per symbol information which is not easily classified.
  522. uint32_t Flags;
  523. /// Index - Index field, for use by the object file implementation.
  524. uint64_t Index;
  525. public:
  526. // Only for use as sentinel.
  527. MCSymbolData();
  528. MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
  529. MCAssembler *A = 0);
  530. /// @name Accessors
  531. /// @{
  532. const MCSymbol &getSymbol() const { return *Symbol; }
  533. MCFragment *getFragment() const { return Fragment; }
  534. void setFragment(MCFragment *Value) { Fragment = Value; }
  535. uint64_t getOffset() const { return Offset; }
  536. void setOffset(uint64_t Value) { Offset = Value; }
  537. /// @}
  538. /// @name Symbol Attributes
  539. /// @{
  540. bool isExternal() const { return IsExternal; }
  541. void setExternal(bool Value) { IsExternal = Value; }
  542. bool isPrivateExtern() const { return IsPrivateExtern; }
  543. void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
  544. /// isCommon - Is this a 'common' symbol.
  545. bool isCommon() const { return CommonSize != 0; }
  546. /// setCommon - Mark this symbol as being 'common'.
  547. ///
  548. /// \param Size - The size of the symbol.
  549. /// \param Align - The alignment of the symbol.
  550. void setCommon(uint64_t Size, unsigned Align) {
  551. CommonSize = Size;
  552. CommonAlign = Align;
  553. }
  554. /// getCommonSize - Return the size of a 'common' symbol.
  555. uint64_t getCommonSize() const {
  556. assert(isCommon() && "Not a 'common' symbol!");
  557. return CommonSize;
  558. }
  559. void setSize(const MCExpr *SS) {
  560. SymbolSize = SS;
  561. }
  562. const MCExpr *getSize() const {
  563. return SymbolSize;
  564. }
  565. /// getCommonAlignment - Return the alignment of a 'common' symbol.
  566. unsigned getCommonAlignment() const {
  567. assert(isCommon() && "Not a 'common' symbol!");
  568. return CommonAlign;
  569. }
  570. /// getFlags - Get the (implementation defined) symbol flags.
  571. uint32_t getFlags() const { return Flags; }
  572. /// setFlags - Set the (implementation defined) symbol flags.
  573. void setFlags(uint32_t Value) { Flags = Value; }
  574. /// modifyFlags - Modify the flags via a mask
  575. void modifyFlags(uint32_t Value, uint32_t Mask) {
  576. Flags = (Flags & ~Mask) | Value;
  577. }
  578. /// getIndex - Get the (implementation defined) index.
  579. uint64_t getIndex() const { return Index; }
  580. /// setIndex - Set the (implementation defined) index.
  581. void setIndex(uint64_t Value) { Index = Value; }
  582. /// @}
  583. void dump();
  584. };
  585. // FIXME: This really doesn't belong here. See comments below.
  586. struct IndirectSymbolData {
  587. MCSymbol *Symbol;
  588. MCSectionData *SectionData;
  589. };
  590. // FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk
  591. // to one another.
  592. struct DataRegionData {
  593. // This enum should be kept in sync w/ the mach-o definition in
  594. // llvm/Object/MachOFormat.h.
  595. enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind;
  596. MCSymbol *Start;
  597. MCSymbol *End;
  598. };
  599. class MCAssembler {
  600. friend class MCAsmLayout;
  601. public:
  602. typedef iplist<MCSectionData> SectionDataListType;
  603. typedef iplist<MCSymbolData> SymbolDataListType;
  604. typedef SectionDataListType::const_iterator const_iterator;
  605. typedef SectionDataListType::iterator iterator;
  606. typedef SymbolDataListType::const_iterator const_symbol_iterator;
  607. typedef SymbolDataListType::iterator symbol_iterator;
  608. typedef std::vector<IndirectSymbolData>::const_iterator
  609. const_indirect_symbol_iterator;
  610. typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
  611. typedef std::vector<DataRegionData>::const_iterator
  612. const_data_region_iterator;
  613. typedef std::vector<DataRegionData>::iterator data_region_iterator;
  614. private:
  615. MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
  616. void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
  617. MCContext &Context;
  618. MCAsmBackend &Backend;
  619. MCCodeEmitter &Emitter;
  620. MCObjectWriter &Writer;
  621. raw_ostream &OS;
  622. iplist<MCSectionData> Sections;
  623. iplist<MCSymbolData> Symbols;
  624. /// The map of sections to their associated assembler backend data.
  625. //
  626. // FIXME: Avoid this indirection?
  627. DenseMap<const MCSection*, MCSectionData*> SectionMap;
  628. /// The map of symbols to their associated assembler backend data.
  629. //
  630. // FIXME: Avoid this indirection?
  631. DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
  632. std::vector<IndirectSymbolData> IndirectSymbols;
  633. std::vector<DataRegionData> DataRegions;
  634. /// The list of linker options to propagate into the object file.
  635. std::vector<std::vector<std::string> > LinkerOptions;
  636. /// The set of function symbols for which a .thumb_func directive has
  637. /// been seen.
  638. //
  639. // FIXME: We really would like this in target specific code rather than
  640. // here. Maybe when the relocation stuff moves to target specific,
  641. // this can go with it? The streamer would need some target specific
  642. // refactoring too.
  643. SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
  644. /// \brief The bundle alignment size currently set in the assembler.
  645. ///
  646. /// By default it's 0, which means bundling is disabled.
  647. unsigned BundleAlignSize;
  648. unsigned RelaxAll : 1;
  649. unsigned NoExecStack : 1;
  650. unsigned SubsectionsViaSymbols : 1;
  651. /// ELF specific e_header flags
  652. // It would be good if there were an MCELFAssembler class to hold this.
  653. // ELF header flags are used both by the integrated and standalone assemblers.
  654. // Access to the flags is necessary in cases where assembler directives affect
  655. // which flags to be set.
  656. unsigned ELFHeaderEFlags;
  657. private:
  658. /// Evaluate a fixup to a relocatable expression and the value which should be
  659. /// placed into the fixup.
  660. ///
  661. /// \param Layout The layout to use for evaluation.
  662. /// \param Fixup The fixup to evaluate.
  663. /// \param DF The fragment the fixup is inside.
  664. /// \param Target [out] On return, the relocatable expression the fixup
  665. /// evaluates to.
  666. /// \param Value [out] On return, the value of the fixup as currently laid
  667. /// out.
  668. /// \return Whether the fixup value was fully resolved. This is true if the
  669. /// \p Value result is fixed, otherwise the value may change due to
  670. /// relocation.
  671. bool evaluateFixup(const MCAsmLayout &Layout,
  672. const MCFixup &Fixup, const MCFragment *DF,
  673. MCValue &Target, uint64_t &Value) const;
  674. /// Check whether a fixup can be satisfied, or whether it needs to be relaxed
  675. /// (increased in size, in order to hold its value correctly).
  676. bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF,
  677. const MCAsmLayout &Layout) const;
  678. /// Check whether the given fragment needs relaxation.
  679. bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF,
  680. const MCAsmLayout &Layout) const;
  681. /// \brief Perform one layout iteration and return true if any offsets
  682. /// were adjusted.
  683. bool layoutOnce(MCAsmLayout &Layout);
  684. /// \brief Perform one layout iteration of the given section and return true
  685. /// if any offsets were adjusted.
  686. bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
  687. bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF);
  688. bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
  689. bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
  690. bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
  691. MCDwarfCallFrameFragment &DF);
  692. /// finishLayout - Finalize a layout, including fragment lowering.
  693. void finishLayout(MCAsmLayout &Layout);
  694. uint64_t handleFixup(const MCAsmLayout &Layout,
  695. MCFragment &F, const MCFixup &Fixup);
  696. public:
  697. /// Compute the effective fragment size assuming it is laid out at the given
  698. /// \p SectionAddress and \p FragmentOffset.
  699. uint64_t computeFragmentSize(const MCAsmLayout &Layout,
  700. const MCFragment &F) const;
  701. /// Find the symbol which defines the atom containing the given symbol, or
  702. /// null if there is no such symbol.
  703. const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;
  704. /// Check whether a particular symbol is visible to the linker and is required
  705. /// in the symbol table, or whether it can be discarded by the assembler. This
  706. /// also effects whether the assembler treats the label as potentially
  707. /// defining a separate atom.
  708. bool isSymbolLinkerVisible(const MCSymbol &SD) const;
  709. /// Emit the section contents using the given object writer.
  710. void writeSectionData(const MCSectionData *Section,
  711. const MCAsmLayout &Layout) const;
  712. /// Check whether a given symbol has been flagged with .thumb_func.
  713. bool isThumbFunc(const MCSymbol *Func) const {
  714. return ThumbFuncs.count(Func);
  715. }
  716. /// Flag a function symbol as the target of a .thumb_func directive.
  717. void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
  718. /// ELF e_header flags
  719. unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;}
  720. void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;}
  721. public:
  722. /// Construct a new assembler instance.
  723. ///
  724. /// \param OS The stream to output to.
  725. //
  726. // FIXME: How are we going to parameterize this? Two obvious options are stay
  727. // concrete and require clients to pass in a target like object. The other
  728. // option is to make this abstract, and have targets provide concrete
  729. // implementations as we do with AsmParser.
  730. MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
  731. MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
  732. raw_ostream &OS);
  733. ~MCAssembler();
  734. /// Reuse an assembler instance
  735. ///
  736. void reset();
  737. MCContext &getContext() const { return Context; }
  738. MCAsmBackend &getBackend() const { return Backend; }
  739. MCCodeEmitter &getEmitter() const { return Emitter; }
  740. MCObjectWriter &getWriter() const { return Writer; }
  741. /// Finish - Do final processing and write the object to the output stream.
  742. /// \p Writer is used for custom object writer (as the MCJIT does),
  743. /// if not specified it is automatically created from backend.
  744. void Finish();
  745. // FIXME: This does not belong here.
  746. bool getSubsectionsViaSymbols() const {
  747. return SubsectionsViaSymbols;
  748. }
  749. void setSubsectionsViaSymbols(bool Value) {
  750. SubsectionsViaSymbols = Value;
  751. }
  752. bool getRelaxAll() const { return RelaxAll; }
  753. void setRelaxAll(bool Value) { RelaxAll = Value; }
  754. bool getNoExecStack() const { return NoExecStack; }
  755. void setNoExecStack(bool Value) { NoExecStack = Value; }
  756. bool isBundlingEnabled() const {
  757. return BundleAlignSize != 0;
  758. }
  759. unsigned getBundleAlignSize() const {
  760. return BundleAlignSize;
  761. }
  762. void setBundleAlignSize(unsigned Size) {
  763. assert((Size == 0 || !(Size & (Size - 1))) &&
  764. "Expect a power-of-two bundle align size");
  765. BundleAlignSize = Size;
  766. }
  767. /// @name Section List Access
  768. /// @{
  769. const SectionDataListType &getSectionList() const { return Sections; }
  770. SectionDataListType &getSectionList() { return Sections; }
  771. iterator begin() { return Sections.begin(); }
  772. const_iterator begin() const { return Sections.begin(); }
  773. iterator end() { return Sections.end(); }
  774. const_iterator end() const { return Sections.end(); }
  775. size_t size() const { return Sections.size(); }
  776. /// @}
  777. /// @name Symbol List Access
  778. /// @{
  779. const SymbolDataListType &getSymbolList() const { return Symbols; }
  780. SymbolDataListType &getSymbolList() { return Symbols; }
  781. symbol_iterator symbol_begin() { return Symbols.begin(); }
  782. const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
  783. symbol_iterator symbol_end() { return Symbols.end(); }
  784. const_symbol_iterator symbol_end() const { return Symbols.end(); }
  785. size_t symbol_size() const { return Symbols.size(); }
  786. /// @}
  787. /// @name Indirect Symbol List Access
  788. /// @{
  789. // FIXME: This is a total hack, this should not be here. Once things are
  790. // factored so that the streamer has direct access to the .o writer, it can
  791. // disappear.
  792. std::vector<IndirectSymbolData> &getIndirectSymbols() {
  793. return IndirectSymbols;
  794. }
  795. indirect_symbol_iterator indirect_symbol_begin() {
  796. return IndirectSymbols.begin();
  797. }
  798. const_indirect_symbol_iterator indirect_symbol_begin() const {
  799. return IndirectSymbols.begin();
  800. }
  801. indirect_symbol_iterator indirect_symbol_end() {
  802. return IndirectSymbols.end();
  803. }
  804. const_indirect_symbol_iterator indirect_symbol_end() const {
  805. return IndirectSymbols.end();
  806. }
  807. size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
  808. /// @}
  809. /// @name Linker Option List Access
  810. /// @{
  811. std::vector<std::vector<std::string> > &getLinkerOptions() {
  812. return LinkerOptions;
  813. }
  814. /// @}
  815. /// @name Data Region List Access
  816. /// @{
  817. // FIXME: This is a total hack, this should not be here. Once things are
  818. // factored so that the streamer has direct access to the .o writer, it can
  819. // disappear.
  820. std::vector<DataRegionData> &getDataRegions() {
  821. return DataRegions;
  822. }
  823. data_region_iterator data_region_begin() {
  824. return DataRegions.begin();
  825. }
  826. const_data_region_iterator data_region_begin() const {
  827. return DataRegions.begin();
  828. }
  829. data_region_iterator data_region_end() {
  830. return DataRegions.end();
  831. }
  832. const_data_region_iterator data_region_end() const {
  833. return DataRegions.end();
  834. }
  835. size_t data_region_size() const { return DataRegions.size(); }
  836. /// @}
  837. /// @name Backend Data Access
  838. /// @{
  839. MCSectionData &getSectionData(const MCSection &Section) const {
  840. MCSectionData *Entry = SectionMap.lookup(&Section);
  841. assert(Entry && "Missing section data!");
  842. return *Entry;
  843. }
  844. MCSectionData &getOrCreateSectionData(const MCSection &Section,
  845. bool *Created = 0) {
  846. MCSectionData *&Entry = SectionMap[&Section];
  847. if (Created) *Created = !Entry;
  848. if (!Entry)
  849. Entry = new MCSectionData(Section, this);
  850. return *Entry;
  851. }
  852. MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
  853. MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
  854. assert(Entry && "Missing symbol data!");
  855. return *Entry;
  856. }
  857. MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
  858. bool *Created = 0) {
  859. MCSymbolData *&Entry = SymbolMap[&Symbol];
  860. if (Created) *Created = !Entry;
  861. if (!Entry)
  862. Entry = new MCSymbolData(Symbol, 0, 0, this);
  863. return *Entry;
  864. }
  865. /// @}
  866. void dump();
  867. };
  868. } // end namespace llvm
  869. #endif