MCAssembler.h revision 6009db486e7fba448ccb28dff676c012efade8f0
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//===- MCAssembler.h - Object File Generation -------------------*- C++ -*-===//
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//                     The LLVM Compiler Infrastructure
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// License. See LICENSE.TXT for details.
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//===----------------------------------------------------------------------===//
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef LLVM_MC_MCASSEMBLER_H
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define LLVM_MC_MCASSEMBLER_H
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "llvm/ADT/SmallString.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "llvm/ADT/ilist.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "llvm/ADT/ilist_node.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "llvm/MC/MCValue.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "llvm/Support/Casting.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "llvm/Support/DataTypes.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <vector> // FIXME: Shouldn't be needed.
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace llvm {
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass raw_ostream;
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass MCAssembler;
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass MCSection;
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass MCSectionData;
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MCFragment : public ilist_node<MCFragment> {
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MCFragment(const MCFragment&);     // DO NOT IMPLEMENT
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void operator=(const MCFragment&); // DO NOT IMPLEMENT
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)public:
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  enum FragmentType {
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FT_Data,
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FT_Align,
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FT_Fill,
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FT_Org
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  };
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)private:
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FragmentType Kind;
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /// Parent - The data for the section this fragment is in.
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MCSectionData *Parent;
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  /// @name Assembler Backend Data
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// @{
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  //
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // FIXME: This could all be kept private to the assembler implementation.
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  /// Offset - The offset of this fragment in its section. This is ~0 until
51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  /// initialized.
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  uint64_t Offset;
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
54e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  /// FileSize - The file size of this section. This is ~0 until initialized.
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  uint64_t FileSize;
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  /// @}
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochprotected:
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)public:
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Only for sentinel.
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MCFragment();
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~MCFragment();
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FragmentType getKind() const { return Kind; }
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MCSectionData *getParent() const { return Parent; }
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void setParent(MCSectionData *Value) { Parent = Value; }
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // FIXME: This should be abstract, fix sentinel.
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual uint64_t getMaxFileSize() const {
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    assert(0 && "Invalid getMaxFileSize call!");
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return 0;
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  /// @name Assembler Backend Support
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  /// @{
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // FIXME: This could all be kept private to the assembler implementation.
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint64_t getAddress() const;
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  uint64_t getFileSize() const {
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    assert(FileSize != ~UINT64_C(0) && "File size not set!");
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return FileSize;
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void setFileSize(uint64_t Value) {
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    assert(Value <= getMaxFileSize() && "Invalid file size!");
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    FileSize = Value;
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  uint64_t getOffset() const {
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    assert(Offset != ~UINT64_C(0) && "File offset not set!");
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return Offset;
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void setOffset(uint64_t Value) { Offset = Value; }
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  /// @}
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static bool classof(const MCFragment *O) { return true; }
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass MCDataFragment : public MCFragment {
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SmallString<32> Contents;
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdochpublic:
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /// @name Accessors
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /// @{
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint64_t getMaxFileSize() const {
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return Contents.size();
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SmallString<32> &getContents() { return Contents; }
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const SmallString<32> &getContents() const { return Contents; }
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /// @}
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static bool classof(const MCFragment *F) {
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return F->getKind() == MCFragment::FT_Data;
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static bool classof(const MCDataFragment *) { return true; }
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class MCAlignFragment : public MCFragment {
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// Alignment - The alignment to ensure, in bytes.
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned Alignment;
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// Value - Value to use for filling padding bytes.
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int64_t Value;
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// ValueSize - The size of the integer (in bytes) of \arg Value.
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  unsigned ValueSize;
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// cannot be satisfied in this width then this fragment is ignored.
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned MaxBytesToEmit;
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)public:
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : MCFragment(FT_Align, SD), Alignment(_Alignment),
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Value(_Value),ValueSize(_ValueSize),
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      MaxBytesToEmit(_MaxBytesToEmit) {}
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// @name Accessors
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /// @{
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  uint64_t getMaxFileSize() const {
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return std::max(Alignment - 1, MaxBytesToEmit);
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
157ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  unsigned getAlignment() const { return Alignment; }
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int64_t getValue() const { return Value; }
160ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  unsigned getValueSize() const { return ValueSize; }
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// @}
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static bool classof(const MCFragment *F) {
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return F->getKind() == MCFragment::FT_Align;
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static bool classof(const MCAlignFragment *) { return true; }
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class MCFillFragment : public MCFragment {
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /// Value - Value to use for filling bytes.
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MCValue Value;
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  /// ValueSize - The size (in bytes) of \arg Value to use when filling.
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned ValueSize;
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /// Count - The number of copies of \arg Value to insert.
181ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  uint64_t Count;
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)public:
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MCFillFragment(MCValue _Value, unsigned _ValueSize, uint64_t _Count,
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 MCSectionData *SD = 0)
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : MCFragment(FT_Fill, SD),
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      Value(_Value), ValueSize(_ValueSize), Count(_Count) {}
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// @name Accessors
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// @{
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  uint64_t getMaxFileSize() const {
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return ValueSize * Count;
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  MCValue getValue() const { return Value; }
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned getValueSize() const { return ValueSize; }
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint64_t getCount() const { return Count; }
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /// @}
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static bool classof(const MCFragment *F) {
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return F->getKind() == MCFragment::FT_Fill;
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static bool classof(const MCFillFragment *) { return true; }
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class MCOrgFragment : public MCFragment {
21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  /// Offset - The offset this fragment should start at.
21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MCValue Offset;
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  /// Value - Value to use for filling bytes.
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int8_t Value;
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)public:
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MCOrgFragment(MCValue _Offset, int8_t _Value, MCSectionData *SD = 0)
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : MCFragment(FT_Org, SD),
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Offset(_Offset), Value(_Value) {}
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// @name Accessors
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// @{
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint64_t getMaxFileSize() const {
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // FIXME: This doesn't make much sense.
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ~UINT64_C(0);
22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MCValue getOffset() const { return Offset; }
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint8_t getValue() const { return Value; }
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /// @}
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static bool classof(const MCFragment *F) {
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return F->getKind() == MCFragment::FT_Org;
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static bool classof(const MCOrgFragment *) { return true; }
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// FIXME: Should this be a separate class, or just merged into MCSection? Since
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// we anticipate the fast path being through an MCAssembler, the only reason to
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// keep it out is for API abstraction.
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MCSectionData : public ilist_node<MCSectionData> {
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  MCSectionData(const MCSectionData&);  // DO NOT IMPLEMENT
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void operator=(const MCSectionData&); // DO NOT IMPLEMENT
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)public:
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  /// Fixup - Represent a fixed size region of bytes inside some fragment which
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  /// needs to be rewritten. This region will either be rewritten by the
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  /// assembler or cause a relocation entry to be generated.
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  struct Fixup {
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    /// Fragment - The fragment containing the fixup.
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MCFragment *Fragment;
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    /// Offset - The offset inside the fragment which needs to be rewritten.
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint64_t Offset;
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    /// Value - The expression to eventually write into the fragment.
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    //
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // FIXME: We could probably get away with requiring the client to pass in an
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // owned reference whose lifetime extends past that of the fixup.
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MCValue Value;
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    /// Size - The fixup size.
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    unsigned Size;
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /// FixedValue - The value to replace the fix up by.
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    //
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // FIXME: This should not be here.
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint64_t FixedValue;
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
273  public:
274    Fixup(MCFragment &_Fragment, uint64_t _Offset, const MCValue &_Value,
275          unsigned _Size)
276      : Fragment(&_Fragment), Offset(_Offset), Value(_Value), Size(_Size),
277        FixedValue(0) {}
278  };
279
280  typedef iplist<MCFragment> FragmentListType;
281
282  typedef FragmentListType::const_iterator const_iterator;
283  typedef FragmentListType::iterator iterator;
284
285  typedef std::vector<Fixup>::const_iterator const_fixup_iterator;
286  typedef std::vector<Fixup>::iterator fixup_iterator;
287
288private:
289  iplist<MCFragment> Fragments;
290  const MCSection &Section;
291
292  /// Alignment - The maximum alignment seen in this section.
293  unsigned Alignment;
294
295  /// @name Assembler Backend Data
296  /// @{
297  //
298  // FIXME: This could all be kept private to the assembler implementation.
299
300  /// Address - The computed address of this section. This is ~0 until
301  /// initialized.
302  uint64_t Address;
303
304  /// Size - The content size of this section. This is ~0 until initialized.
305  uint64_t Size;
306
307  /// FileSize - The size of this section in the object file. This is ~0 until
308  /// initialized.
309  uint64_t FileSize;
310
311  /// LastFixupLookup - Cache for the last looked up fixup.
312  mutable unsigned LastFixupLookup;
313
314  /// Fixups - The list of fixups in this section.
315  std::vector<Fixup> Fixups;
316
317  /// @}
318
319public:
320  // Only for use as sentinel.
321  MCSectionData();
322  MCSectionData(const MCSection &Section, MCAssembler *A = 0);
323
324  const MCSection &getSection() const { return Section; }
325
326  unsigned getAlignment() const { return Alignment; }
327  void setAlignment(unsigned Value) { Alignment = Value; }
328
329  /// @name Fragment Access
330  /// @{
331
332  const FragmentListType &getFragmentList() const { return Fragments; }
333  FragmentListType &getFragmentList() { return Fragments; }
334
335  iterator begin() { return Fragments.begin(); }
336  const_iterator begin() const { return Fragments.begin(); }
337
338  iterator end() { return Fragments.end(); }
339  const_iterator end() const { return Fragments.end(); }
340
341  size_t size() const { return Fragments.size(); }
342
343  bool empty() const { return Fragments.empty(); }
344
345  /// @}
346  /// @name Fixup Access
347  /// @{
348
349  std::vector<Fixup> &getFixups() {
350    return Fixups;
351  }
352
353  fixup_iterator fixup_begin() {
354    return Fixups.begin();
355  }
356
357  fixup_iterator fixup_end() {
358    return Fixups.end();
359  }
360
361  size_t fixup_size() const { return Fixups.size(); }
362
363  /// @}
364  /// @name Assembler Backend Support
365  /// @{
366  //
367  // FIXME: This could all be kept private to the assembler implementation.
368
369  /// LookupFixup - Look up the fixup for the given \arg Fragment and \arg
370  /// Offset.
371  ///
372  /// If multiple fixups exist for the same fragment and offset it is undefined
373  /// which one is returned.
374  //
375  // FIXME: This isn't horribly slow in practice, but there are much nicer
376  // solutions to applying the fixups.
377  const Fixup *LookupFixup(const MCFragment *Fragment, uint64_t Offset) const;
378
379  uint64_t getAddress() const {
380    assert(Address != ~UINT64_C(0) && "Address not set!");
381    return Address;
382  }
383  void setAddress(uint64_t Value) { Address = Value; }
384
385  uint64_t getSize() const {
386    assert(Size != ~UINT64_C(0) && "File size not set!");
387    return Size;
388  }
389  void setSize(uint64_t Value) { Size = Value; }
390
391  uint64_t getFileSize() const {
392    assert(FileSize != ~UINT64_C(0) && "File size not set!");
393    return FileSize;
394  }
395  void setFileSize(uint64_t Value) { FileSize = Value; }
396
397  /// @}
398};
399
400// FIXME: Same concerns as with SectionData.
401class MCSymbolData : public ilist_node<MCSymbolData> {
402public:
403  MCSymbol &Symbol;
404
405  /// Fragment - The fragment this symbol's value is relative to, if any.
406  MCFragment *Fragment;
407
408  /// Offset - The offset to apply to the fragment address to form this symbol's
409  /// value.
410  uint64_t Offset;
411
412  /// IsExternal - True if this symbol is visible outside this translation
413  /// unit.
414  unsigned IsExternal : 1;
415
416  /// IsPrivateExtern - True if this symbol is private extern.
417  unsigned IsPrivateExtern : 1;
418
419  /// Flags - The Flags field is used by object file implementations to store
420  /// additional per symbol information which is not easily classified.
421  uint32_t Flags;
422
423  /// Index - Index field, for use by the object file implementation.
424  uint64_t Index;
425
426public:
427  // Only for use as sentinel.
428  MCSymbolData();
429  MCSymbolData(MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
430               MCAssembler *A = 0);
431
432  /// @name Accessors
433  /// @{
434
435  MCSymbol &getSymbol() const { return Symbol; }
436
437  MCFragment *getFragment() const { return Fragment; }
438  void setFragment(MCFragment *Value) { Fragment = Value; }
439
440  uint64_t getOffset() const { return Offset; }
441  void setOffset(uint64_t Value) { Offset = Value; }
442
443  /// @}
444  /// @name Symbol Attributes
445  /// @{
446
447  bool isExternal() const { return IsExternal; }
448  void setExternal(bool Value) { IsExternal = Value; }
449
450  bool isPrivateExtern() const { return IsPrivateExtern; }
451  void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
452
453  /// getFlags - Get the (implementation defined) symbol flags.
454  uint32_t getFlags() const { return Flags; }
455
456  /// setFlags - Set the (implementation defined) symbol flags.
457  void setFlags(uint32_t Value) { Flags = Value; }
458
459  /// getIndex - Get the (implementation defined) index.
460  uint64_t getIndex() const { return Index; }
461
462  /// setIndex - Set the (implementation defined) index.
463  void setIndex(uint64_t Value) { Index = Value; }
464
465  /// @}
466};
467
468// FIXME: This really doesn't belong here. See comments below.
469struct IndirectSymbolData {
470  MCSymbol *Symbol;
471  MCSectionData *SectionData;
472};
473
474class MCAssembler {
475public:
476  typedef iplist<MCSectionData> SectionDataListType;
477  typedef iplist<MCSymbolData> SymbolDataListType;
478
479  typedef SectionDataListType::const_iterator const_iterator;
480  typedef SectionDataListType::iterator iterator;
481
482  typedef SymbolDataListType::const_iterator const_symbol_iterator;
483  typedef SymbolDataListType::iterator symbol_iterator;
484
485  typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
486
487private:
488  MCAssembler(const MCAssembler&);    // DO NOT IMPLEMENT
489  void operator=(const MCAssembler&); // DO NOT IMPLEMENT
490
491  raw_ostream &OS;
492
493  iplist<MCSectionData> Sections;
494
495  iplist<MCSymbolData> Symbols;
496
497  std::vector<IndirectSymbolData> IndirectSymbols;
498
499  unsigned SubsectionsViaSymbols : 1;
500
501private:
502  /// LayoutSection - Assign offsets and sizes to the fragments in the section
503  /// \arg SD, and update the section size. The section file offset should
504  /// already have been computed.
505  ///
506  /// \param NextAlign - The alignment for the section end address, which may
507  /// add padding bytes to the section (these are included in the section "file"
508  /// size, but not its regular size).
509  void LayoutSection(MCSectionData &SD, unsigned NextAlign);
510
511public:
512  /// Construct a new assembler instance.
513  ///
514  /// \arg OS - The stream to output to.
515  //
516  // FIXME: How are we going to parameterize this? Two obvious options are stay
517  // concrete and require clients to pass in a target like object. The other
518  // option is to make this abstract, and have targets provide concrete
519  // implementations as we do with AsmParser.
520  MCAssembler(raw_ostream &OS);
521  ~MCAssembler();
522
523  /// Finish - Do final processing and write the object to the output stream.
524  void Finish();
525
526  // FIXME: This does not belong here.
527  bool getSubsectionsViaSymbols() const {
528    return SubsectionsViaSymbols;
529  }
530  void setSubsectionsViaSymbols(bool Value) {
531    SubsectionsViaSymbols = Value;
532  }
533
534  /// @name Section List Access
535  /// @{
536
537  const SectionDataListType &getSectionList() const { return Sections; }
538  SectionDataListType &getSectionList() { return Sections; }
539
540  iterator begin() { return Sections.begin(); }
541  const_iterator begin() const { return Sections.begin(); }
542
543  iterator end() { return Sections.end(); }
544  const_iterator end() const { return Sections.end(); }
545
546  size_t size() const { return Sections.size(); }
547
548  /// @}
549  /// @name Symbol List Access
550  /// @{
551
552  const SymbolDataListType &getSymbolList() const { return Symbols; }
553  SymbolDataListType &getSymbolList() { return Symbols; }
554
555  symbol_iterator symbol_begin() { return Symbols.begin(); }
556  const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
557
558  symbol_iterator symbol_end() { return Symbols.end(); }
559  const_symbol_iterator symbol_end() const { return Symbols.end(); }
560
561  size_t symbol_size() const { return Symbols.size(); }
562
563  /// @}
564  /// @name Indirect Symbol List Access
565  /// @{
566
567  // FIXME: This is a total hack, this should not be here. Once things are
568  // factored so that the streamer has direct access to the .o writer, it can
569  // disappear.
570  std::vector<IndirectSymbolData> &getIndirectSymbols() {
571    return IndirectSymbols;
572  }
573
574  indirect_symbol_iterator indirect_symbol_begin() {
575    return IndirectSymbols.begin();
576  }
577
578  indirect_symbol_iterator indirect_symbol_end() {
579    return IndirectSymbols.end();
580  }
581
582  size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
583
584  /// @}
585};
586
587} // end namespace llvm
588
589#endif
590