4527f3c28d36269a02713c10a8256db71d9b328e
[oota-llvm.git] / include / llvm / MC / MCAssembler.h
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
10 #ifndef LLVM_MC_MCASSEMBLER_H
11 #define LLVM_MC_MCASSEMBLER_H
12
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/ilist.h"
15 #include "llvm/ADT/ilist_node.h"
16 #include "llvm/Support/Casting.h"
17 #include "llvm/MC/MCFixup.h"
18 #include "llvm/System/DataTypes.h"
19 #include <vector> // FIXME: Shouldn't be needed.
20
21 namespace llvm {
22 class raw_ostream;
23 class MCAssembler;
24 class MCContext;
25 class MCExpr;
26 class MCFragment;
27 class MCSection;
28 class MCSectionData;
29 class MCSymbol;
30
31 /// MCAsmFixup - Represent a fixed size region of bytes inside some fragment
32 /// which needs to be rewritten. This region will either be rewritten by the
33 /// assembler or cause a relocation entry to be generated.
34 struct MCAsmFixup {
35   /// Offset - The offset inside the fragment which needs to be rewritten.
36   uint64_t Offset;
37
38   /// Value - The expression to eventually write into the fragment.
39   const MCExpr *Value;
40
41   /// Kind - The fixup kind.
42   MCFixupKind Kind;
43
44   /// FixedValue - The value to replace the fix up by.
45   //
46   // FIXME: This should not be here.
47   uint64_t FixedValue;
48
49 public:
50   MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind)
51     : Offset(_Offset), Value(&_Value), Kind(_Kind), FixedValue(0) {}
52 };
53
54 class MCFragment : public ilist_node<MCFragment> {
55   MCFragment(const MCFragment&);     // DO NOT IMPLEMENT
56   void operator=(const MCFragment&); // DO NOT IMPLEMENT
57
58 public:
59   enum FragmentType {
60     FT_Data,
61     FT_Align,
62     FT_Fill,
63     FT_Org,
64     FT_ZeroFill
65   };
66
67 private:
68   FragmentType Kind;
69
70   /// Parent - The data for the section this fragment is in.
71   MCSectionData *Parent;
72
73   /// @name Assembler Backend Data
74   /// @{
75   //
76   // FIXME: This could all be kept private to the assembler implementation.
77
78   /// Offset - The offset of this fragment in its section. This is ~0 until
79   /// initialized.
80   uint64_t Offset;
81
82   /// FileSize - The file size of this section. This is ~0 until initialized.
83   uint64_t FileSize;
84
85   /// @}
86
87 protected:
88   MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
89
90 public:
91   // Only for sentinel.
92   MCFragment();
93   virtual ~MCFragment();
94
95   FragmentType getKind() const { return Kind; }
96
97   MCSectionData *getParent() const { return Parent; }
98   void setParent(MCSectionData *Value) { Parent = Value; }
99
100   // FIXME: This should be abstract, fix sentinel.
101   virtual uint64_t getMaxFileSize() const {
102     assert(0 && "Invalid getMaxFileSize call!");
103     return 0;
104   }
105
106   /// @name Assembler Backend Support
107   /// @{
108   //
109   // FIXME: This could all be kept private to the assembler implementation.
110
111   uint64_t getAddress() const;
112
113   uint64_t getFileSize() const {
114     assert(FileSize != ~UINT64_C(0) && "File size not set!");
115     return FileSize;
116   }
117   void setFileSize(uint64_t Value) {
118     assert(Value <= getMaxFileSize() && "Invalid file size!");
119     FileSize = Value;
120   }
121
122   uint64_t getOffset() const {
123     assert(Offset != ~UINT64_C(0) && "File offset not set!");
124     return Offset;
125   }
126   void setOffset(uint64_t Value) { Offset = Value; }
127
128   /// @}
129
130   static bool classof(const MCFragment *O) { return true; }
131
132   virtual void dump();
133 };
134
135 class MCDataFragment : public MCFragment {
136   SmallString<32> Contents;
137
138   /// Fixups - The list of fixups in this fragment.
139   std::vector<MCAsmFixup> Fixups;
140
141 public:
142   typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator;
143   typedef std::vector<MCAsmFixup>::iterator fixup_iterator;
144
145 public:
146   MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
147
148   /// @name Accessors
149   /// @{
150
151   uint64_t getMaxFileSize() const {
152     return Contents.size();
153   }
154
155   SmallString<32> &getContents() { return Contents; }
156   const SmallString<32> &getContents() const { return Contents; }
157
158   /// @}
159
160   /// @name Fixup Access
161   /// @{
162
163   std::vector<MCAsmFixup> &getFixups() { return Fixups; }
164   const std::vector<MCAsmFixup> &getFixups() const { return Fixups; }
165
166   fixup_iterator fixup_begin() { return Fixups.begin(); }
167   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
168
169   fixup_iterator fixup_end() {return Fixups.end();}
170   const_fixup_iterator fixup_end() const {return Fixups.end();}
171
172   size_t fixup_size() const { return Fixups.size(); }
173
174   /// @}
175
176   static bool classof(const MCFragment *F) {
177     return F->getKind() == MCFragment::FT_Data;
178   }
179   static bool classof(const MCDataFragment *) { return true; }
180
181   virtual void dump();
182 };
183
184 class MCAlignFragment : public MCFragment {
185   /// Alignment - The alignment to ensure, in bytes.
186   unsigned Alignment;
187
188   /// Value - Value to use for filling padding bytes.
189   int64_t Value;
190
191   /// ValueSize - The size of the integer (in bytes) of \arg Value.
192   unsigned ValueSize;
193
194   /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
195   /// cannot be satisfied in this width then this fragment is ignored.
196   unsigned MaxBytesToEmit;
197
198 public:
199   MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
200                   unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
201     : MCFragment(FT_Align, SD), Alignment(_Alignment),
202       Value(_Value),ValueSize(_ValueSize),
203       MaxBytesToEmit(_MaxBytesToEmit) {}
204
205   /// @name Accessors
206   /// @{
207
208   uint64_t getMaxFileSize() const {
209     return std::max(Alignment - 1, MaxBytesToEmit);
210   }
211
212   unsigned getAlignment() const { return Alignment; }
213
214   int64_t getValue() const { return Value; }
215
216   unsigned getValueSize() const { return ValueSize; }
217
218   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
219
220   /// @}
221
222   static bool classof(const MCFragment *F) {
223     return F->getKind() == MCFragment::FT_Align;
224   }
225   static bool classof(const MCAlignFragment *) { return true; }
226
227   virtual void dump();
228 };
229
230 class MCFillFragment : public MCFragment {
231   /// Value - Value to use for filling bytes.
232   int64_t Value;
233
234   /// ValueSize - The size (in bytes) of \arg Value to use when filling.
235   unsigned ValueSize;
236
237   /// Count - The number of copies of \arg Value to insert.
238   uint64_t Count;
239
240 public:
241   MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Count,
242                  MCSectionData *SD = 0)
243     : MCFragment(FT_Fill, SD),
244       Value(_Value), ValueSize(_ValueSize), Count(_Count) {}
245
246   /// @name Accessors
247   /// @{
248
249   uint64_t getMaxFileSize() const {
250     return ValueSize * Count;
251   }
252
253   int64_t getValue() const { return Value; }
254
255   unsigned getValueSize() const { return ValueSize; }
256
257   uint64_t getCount() const { return Count; }
258
259   /// @}
260
261   static bool classof(const MCFragment *F) {
262     return F->getKind() == MCFragment::FT_Fill;
263   }
264   static bool classof(const MCFillFragment *) { return true; }
265
266   virtual void dump();
267 };
268
269 class MCOrgFragment : public MCFragment {
270   /// Offset - The offset this fragment should start at.
271   const MCExpr *Offset;
272
273   /// Value - Value to use for filling bytes.
274   int8_t Value;
275
276 public:
277   MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
278     : MCFragment(FT_Org, SD),
279       Offset(&_Offset), Value(_Value) {}
280
281   /// @name Accessors
282   /// @{
283
284   uint64_t getMaxFileSize() const {
285     // FIXME: This doesn't make much sense.
286     return ~UINT64_C(0);
287   }
288
289   const MCExpr &getOffset() const { return *Offset; }
290
291   uint8_t getValue() const { return Value; }
292
293   /// @}
294
295   static bool classof(const MCFragment *F) {
296     return F->getKind() == MCFragment::FT_Org;
297   }
298   static bool classof(const MCOrgFragment *) { return true; }
299
300   virtual void dump();
301 };
302
303 /// MCZeroFillFragment - Represent data which has a fixed size and alignment,
304 /// but requires no physical space in the object file.
305 class MCZeroFillFragment : public MCFragment {
306   /// Size - The size of this fragment.
307   uint64_t Size;
308
309   /// Alignment - The alignment for this fragment.
310   unsigned Alignment;
311
312 public:
313   MCZeroFillFragment(uint64_t _Size, unsigned _Alignment, MCSectionData *SD = 0)
314     : MCFragment(FT_ZeroFill, SD),
315       Size(_Size), Alignment(_Alignment) {}
316
317   /// @name Accessors
318   /// @{
319
320   uint64_t getMaxFileSize() const {
321     // FIXME: This also doesn't make much sense, this method is misnamed.
322     return ~UINT64_C(0);
323   }
324
325   uint64_t getSize() const { return Size; }
326
327   unsigned getAlignment() const { return Alignment; }
328
329   /// @}
330
331   static bool classof(const MCFragment *F) {
332     return F->getKind() == MCFragment::FT_ZeroFill;
333   }
334   static bool classof(const MCZeroFillFragment *) { return true; }
335
336   virtual void dump();
337 };
338
339 // FIXME: Should this be a separate class, or just merged into MCSection? Since
340 // we anticipate the fast path being through an MCAssembler, the only reason to
341 // keep it out is for API abstraction.
342 class MCSectionData : public ilist_node<MCSectionData> {
343   MCSectionData(const MCSectionData&);  // DO NOT IMPLEMENT
344   void operator=(const MCSectionData&); // DO NOT IMPLEMENT
345
346 public:
347   typedef iplist<MCFragment> FragmentListType;
348
349   typedef FragmentListType::const_iterator const_iterator;
350   typedef FragmentListType::iterator iterator;
351
352   typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
353   typedef FragmentListType::reverse_iterator reverse_iterator;
354
355 private:
356   iplist<MCFragment> Fragments;
357   const MCSection *Section;
358
359   /// Alignment - The maximum alignment seen in this section.
360   unsigned Alignment;
361
362   /// @name Assembler Backend Data
363   /// @{
364   //
365   // FIXME: This could all be kept private to the assembler implementation.
366
367   /// Address - The computed address of this section. This is ~0 until
368   /// initialized.
369   uint64_t Address;
370
371   /// Size - The content size of this section. This is ~0 until initialized.
372   uint64_t Size;
373
374   /// FileSize - The size of this section in the object file. This is ~0 until
375   /// initialized.
376   uint64_t FileSize;
377
378   /// HasInstructions - Whether this section has had instructions emitted into
379   /// it.
380   unsigned HasInstructions : 1;
381
382   /// @}
383
384 public:
385   // Only for use as sentinel.
386   MCSectionData();
387   MCSectionData(const MCSection &Section, MCAssembler *A = 0);
388
389   const MCSection &getSection() const { return *Section; }
390
391   unsigned getAlignment() const { return Alignment; }
392   void setAlignment(unsigned Value) { Alignment = Value; }
393
394   /// @name Fragment Access
395   /// @{
396
397   const FragmentListType &getFragmentList() const { return Fragments; }
398   FragmentListType &getFragmentList() { return Fragments; }
399
400   iterator begin() { return Fragments.begin(); }
401   const_iterator begin() const { return Fragments.begin(); }
402
403   iterator end() { return Fragments.end(); }
404   const_iterator end() const { return Fragments.end(); }
405
406   reverse_iterator rbegin() { return Fragments.rbegin(); }
407   const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
408
409   reverse_iterator rend() { return Fragments.rend(); }
410   const_reverse_iterator rend() const { return Fragments.rend(); }
411
412   size_t size() const { return Fragments.size(); }
413
414   bool empty() const { return Fragments.empty(); }
415
416   /// @}
417   /// @name Assembler Backend Support
418   /// @{
419   //
420   // FIXME: This could all be kept private to the assembler implementation.
421
422   uint64_t getAddress() const {
423     assert(Address != ~UINT64_C(0) && "Address not set!");
424     return Address;
425   }
426   void setAddress(uint64_t Value) { Address = Value; }
427
428   uint64_t getSize() const {
429     assert(Size != ~UINT64_C(0) && "File size not set!");
430     return Size;
431   }
432   void setSize(uint64_t Value) { Size = Value; }
433
434   uint64_t getFileSize() const {
435     assert(FileSize != ~UINT64_C(0) && "File size not set!");
436     return FileSize;
437   }
438   void setFileSize(uint64_t Value) { FileSize = Value; }
439
440   bool hasInstructions() const { return HasInstructions; }
441   void setHasInstructions(bool Value) { HasInstructions = Value; }
442
443   /// @}
444
445   void dump();
446 };
447
448 // FIXME: Same concerns as with SectionData.
449 class MCSymbolData : public ilist_node<MCSymbolData> {
450 public:
451   const MCSymbol *Symbol;
452
453   /// Fragment - The fragment this symbol's value is relative to, if any.
454   MCFragment *Fragment;
455
456   /// Offset - The offset to apply to the fragment address to form this symbol's
457   /// value.
458   uint64_t Offset;
459
460   /// IsExternal - True if this symbol is visible outside this translation
461   /// unit.
462   unsigned IsExternal : 1;
463
464   /// IsPrivateExtern - True if this symbol is private extern.
465   unsigned IsPrivateExtern : 1;
466
467   /// CommonSize - The size of the symbol, if it is 'common', or 0.
468   //
469   // FIXME: Pack this in with other fields? We could put it in offset, since a
470   // common symbol can never get a definition.
471   uint64_t CommonSize;
472
473   /// CommonAlign - The alignment of the symbol, if it is 'common'.
474   //
475   // FIXME: Pack this in with other fields?
476   unsigned CommonAlign;
477
478   /// Flags - The Flags field is used by object file implementations to store
479   /// additional per symbol information which is not easily classified.
480   uint32_t Flags;
481
482   /// Index - Index field, for use by the object file implementation.
483   uint64_t Index;
484
485 public:
486   // Only for use as sentinel.
487   MCSymbolData();
488   MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
489                MCAssembler *A = 0);
490
491   /// @name Accessors
492   /// @{
493
494   const MCSymbol &getSymbol() const { return *Symbol; }
495
496   MCFragment *getFragment() const { return Fragment; }
497   void setFragment(MCFragment *Value) { Fragment = Value; }
498
499   uint64_t getOffset() const { return Offset; }
500   void setOffset(uint64_t Value) { Offset = Value; }
501
502   /// @}
503   /// @name Symbol Attributes
504   /// @{
505
506   bool isExternal() const { return IsExternal; }
507   void setExternal(bool Value) { IsExternal = Value; }
508
509   bool isPrivateExtern() const { return IsPrivateExtern; }
510   void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
511
512   /// isCommon - Is this a 'common' symbol.
513   bool isCommon() const { return CommonSize != 0; }
514
515   /// setCommon - Mark this symbol as being 'common'.
516   ///
517   /// \param Size - The size of the symbol.
518   /// \param Align - The alignment of the symbol.
519   void setCommon(uint64_t Size, unsigned Align) {
520     CommonSize = Size;
521     CommonAlign = Align;
522   }
523
524   /// getCommonSize - Return the size of a 'common' symbol.
525   uint64_t getCommonSize() const {
526     assert(isCommon() && "Not a 'common' symbol!");
527     return CommonSize;
528   }
529
530   /// getCommonAlignment - Return the alignment of a 'common' symbol.
531   unsigned getCommonAlignment() const {
532     assert(isCommon() && "Not a 'common' symbol!");
533     return CommonAlign;
534   }
535
536   /// getFlags - Get the (implementation defined) symbol flags.
537   uint32_t getFlags() const { return Flags; }
538
539   /// setFlags - Set the (implementation defined) symbol flags.
540   void setFlags(uint32_t Value) { Flags = Value; }
541
542   /// getIndex - Get the (implementation defined) index.
543   uint64_t getIndex() const { return Index; }
544
545   /// setIndex - Set the (implementation defined) index.
546   void setIndex(uint64_t Value) { Index = Value; }
547
548   /// @}
549
550   void dump();
551 };
552
553 // FIXME: This really doesn't belong here. See comments below.
554 struct IndirectSymbolData {
555   MCSymbol *Symbol;
556   MCSectionData *SectionData;
557 };
558
559 class MCAssembler {
560 public:
561   typedef iplist<MCSectionData> SectionDataListType;
562   typedef iplist<MCSymbolData> SymbolDataListType;
563
564   typedef SectionDataListType::const_iterator const_iterator;
565   typedef SectionDataListType::iterator iterator;
566
567   typedef SymbolDataListType::const_iterator const_symbol_iterator;
568   typedef SymbolDataListType::iterator symbol_iterator;
569
570   typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
571
572 private:
573   MCAssembler(const MCAssembler&);    // DO NOT IMPLEMENT
574   void operator=(const MCAssembler&); // DO NOT IMPLEMENT
575
576   MCContext &Context;
577
578   raw_ostream &OS;
579
580   iplist<MCSectionData> Sections;
581
582   iplist<MCSymbolData> Symbols;
583
584   std::vector<IndirectSymbolData> IndirectSymbols;
585
586   unsigned SubsectionsViaSymbols : 1;
587
588 private:
589   /// LayoutSection - Assign offsets and sizes to the fragments in the section
590   /// \arg SD, and update the section size. The section file offset should
591   /// already have been computed.
592   void LayoutSection(MCSectionData &SD);
593
594 public:
595   /// Construct a new assembler instance.
596   ///
597   /// \arg OS - The stream to output to.
598   //
599   // FIXME: How are we going to parameterize this? Two obvious options are stay
600   // concrete and require clients to pass in a target like object. The other
601   // option is to make this abstract, and have targets provide concrete
602   // implementations as we do with AsmParser.
603   MCAssembler(MCContext &_Context, raw_ostream &OS);
604   ~MCAssembler();
605
606   MCContext &getContext() const { return Context; }
607
608   /// Finish - Do final processing and write the object to the output stream.
609   void Finish();
610
611   // FIXME: This does not belong here.
612   bool getSubsectionsViaSymbols() const {
613     return SubsectionsViaSymbols;
614   }
615   void setSubsectionsViaSymbols(bool Value) {
616     SubsectionsViaSymbols = Value;
617   }
618
619   /// @name Section List Access
620   /// @{
621
622   const SectionDataListType &getSectionList() const { return Sections; }
623   SectionDataListType &getSectionList() { return Sections; }
624
625   iterator begin() { return Sections.begin(); }
626   const_iterator begin() const { return Sections.begin(); }
627
628   iterator end() { return Sections.end(); }
629   const_iterator end() const { return Sections.end(); }
630
631   size_t size() const { return Sections.size(); }
632
633   /// @}
634   /// @name Symbol List Access
635   /// @{
636
637   const SymbolDataListType &getSymbolList() const { return Symbols; }
638   SymbolDataListType &getSymbolList() { return Symbols; }
639
640   symbol_iterator symbol_begin() { return Symbols.begin(); }
641   const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
642
643   symbol_iterator symbol_end() { return Symbols.end(); }
644   const_symbol_iterator symbol_end() const { return Symbols.end(); }
645
646   size_t symbol_size() const { return Symbols.size(); }
647
648   /// @}
649   /// @name Indirect Symbol List Access
650   /// @{
651
652   // FIXME: This is a total hack, this should not be here. Once things are
653   // factored so that the streamer has direct access to the .o writer, it can
654   // disappear.
655   std::vector<IndirectSymbolData> &getIndirectSymbols() {
656     return IndirectSymbols;
657   }
658
659   indirect_symbol_iterator indirect_symbol_begin() {
660     return IndirectSymbols.begin();
661   }
662
663   indirect_symbol_iterator indirect_symbol_end() {
664     return IndirectSymbols.end();
665   }
666
667   size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
668
669   /// @}
670
671   void dump();
672 };
673
674 } // end namespace llvm
675
676 #endif