blob: 9d3efa7ee65cae0e02de56a03a80179ab02aab53 [file] [log] [blame]
Daniel Dunbar7760fbe2009-08-21 09:11:24 +00001//===- 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
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +000013#include "llvm/ADT/SmallString.h"
Daniel Dunbar7760fbe2009-08-21 09:11:24 +000014#include "llvm/ADT/ilist.h"
15#include "llvm/ADT/ilist_node.h"
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +000016#include "llvm/Support/Casting.h"
Chandler Carruth1ec7df12009-10-26 01:35:46 +000017#include "llvm/System/DataTypes.h"
Daniel Dunbara0151d02009-08-24 11:56:58 +000018#include <vector> // FIXME: Shouldn't be needed.
Daniel Dunbar7760fbe2009-08-21 09:11:24 +000019
20namespace llvm {
21class raw_ostream;
22class MCAssembler;
Daniel Dunbar29efe7e2009-08-31 08:07:55 +000023class MCContext;
Daniel Dunbar4e5c1b62009-10-16 01:58:03 +000024class MCExpr;
Daniel Dunbar5e65c6f2010-02-11 21:29:29 +000025class MCFragment;
Daniel Dunbar7760fbe2009-08-21 09:11:24 +000026class MCSection;
27class MCSectionData;
Daniel Dunbar4e5c1b62009-10-16 01:58:03 +000028class MCSymbol;
Daniel Dunbar7760fbe2009-08-21 09:11:24 +000029
Daniel Dunbar5e65c6f2010-02-11 21:29:29 +000030/// MCAsmFixup - Represent a fixed size region of bytes inside some fragment
31/// which needs to be rewritten. This region will either be rewritten by the
32/// assembler or cause a relocation entry to be generated.
33struct MCAsmFixup {
34 /// Fragment - The fragment containing the fixup.
35 MCFragment *Fragment;
36
37 /// Offset - The offset inside the fragment which needs to be rewritten.
38 uint64_t Offset;
39
40 /// Value - The expression to eventually write into the fragment.
41 const MCExpr *Value;
42
43 /// Size - The fixup size.
44 unsigned Size;
45
46 /// FixedValue - The value to replace the fix up by.
47 //
48 // FIXME: This should not be here.
49 uint64_t FixedValue;
50
51public:
52 MCAsmFixup(MCFragment &_Fragment, uint64_t _Offset, const MCExpr &_Value,
53 unsigned _Size)
54 : Fragment(&_Fragment), Offset(_Offset), Value(&_Value), Size(_Size),
55 FixedValue(0) {}
56};
57
Daniel Dunbar7760fbe2009-08-21 09:11:24 +000058class MCFragment : public ilist_node<MCFragment> {
59 MCFragment(const MCFragment&); // DO NOT IMPLEMENT
60 void operator=(const MCFragment&); // DO NOT IMPLEMENT
61
62public:
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +000063 enum FragmentType {
64 FT_Data,
65 FT_Align,
66 FT_Fill,
Daniel Dunbardf98a142009-08-28 05:49:21 +000067 FT_Org,
68 FT_ZeroFill
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +000069 };
70
71private:
72 FragmentType Kind;
73
Daniel Dunbarb3730b12009-08-26 02:48:04 +000074 /// Parent - The data for the section this fragment is in.
75 MCSectionData *Parent;
76
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +000077 /// @name Assembler Backend Data
78 /// @{
79 //
80 // FIXME: This could all be kept private to the assembler implementation.
81
Daniel Dunbar1f022e22009-08-22 08:27:54 +000082 /// Offset - The offset of this fragment in its section. This is ~0 until
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +000083 /// initialized.
Daniel Dunbar1f022e22009-08-22 08:27:54 +000084 uint64_t Offset;
85
86 /// FileSize - The file size of this section. This is ~0 until initialized.
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +000087 uint64_t FileSize;
88
89 /// @}
90
91protected:
Daniel Dunbarb3730b12009-08-26 02:48:04 +000092 MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +000093
94public:
95 // Only for sentinel.
96 MCFragment();
97 virtual ~MCFragment();
98
99 FragmentType getKind() const { return Kind; }
100
Daniel Dunbarb3730b12009-08-26 02:48:04 +0000101 MCSectionData *getParent() const { return Parent; }
102 void setParent(MCSectionData *Value) { Parent = Value; }
103
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000104 // FIXME: This should be abstract, fix sentinel.
Daniel Dunbar3d153ff2009-08-21 23:07:38 +0000105 virtual uint64_t getMaxFileSize() const {
Daniel Dunbar197f5632009-08-22 10:13:24 +0000106 assert(0 && "Invalid getMaxFileSize call!");
Daniel Dunbar33bf7c22009-08-21 23:11:36 +0000107 return 0;
Douglas Gregor8cb41382009-12-19 07:05:23 +0000108 }
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000109
110 /// @name Assembler Backend Support
111 /// @{
112 //
113 // FIXME: This could all be kept private to the assembler implementation.
114
Daniel Dunbarb3730b12009-08-26 02:48:04 +0000115 uint64_t getAddress() const;
116
Daniel Dunbar0f56d412009-08-26 04:13:32 +0000117 uint64_t getFileSize() const {
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000118 assert(FileSize != ~UINT64_C(0) && "File size not set!");
119 return FileSize;
120 }
121 void setFileSize(uint64_t Value) {
122 assert(Value <= getMaxFileSize() && "Invalid file size!");
123 FileSize = Value;
124 }
125
Daniel Dunbar1f022e22009-08-22 08:27:54 +0000126 uint64_t getOffset() const {
127 assert(Offset != ~UINT64_C(0) && "File offset not set!");
128 return Offset;
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000129 }
Daniel Dunbar1f022e22009-08-22 08:27:54 +0000130 void setOffset(uint64_t Value) { Offset = Value; }
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000131
132 /// @}
133
134 static bool classof(const MCFragment *O) { return true; }
135};
136
137class MCDataFragment : public MCFragment {
138 SmallString<32> Contents;
139
140public:
141 MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
142
143 /// @name Accessors
144 /// @{
145
Daniel Dunbar3d153ff2009-08-21 23:07:38 +0000146 uint64_t getMaxFileSize() const {
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000147 return Contents.size();
148 }
149
150 SmallString<32> &getContents() { return Contents; }
151 const SmallString<32> &getContents() const { return Contents; }
152
153 /// @}
154
155 static bool classof(const MCFragment *F) {
156 return F->getKind() == MCFragment::FT_Data;
157 }
158 static bool classof(const MCDataFragment *) { return true; }
159};
160
161class MCAlignFragment : public MCFragment {
162 /// Alignment - The alignment to ensure, in bytes.
163 unsigned Alignment;
164
165 /// Value - Value to use for filling padding bytes.
166 int64_t Value;
167
168 /// ValueSize - The size of the integer (in bytes) of \arg Value.
169 unsigned ValueSize;
170
171 /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
172 /// cannot be satisfied in this width then this fragment is ignored.
173 unsigned MaxBytesToEmit;
174
175public:
176 MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
177 unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
178 : MCFragment(FT_Align, SD), Alignment(_Alignment),
179 Value(_Value),ValueSize(_ValueSize),
180 MaxBytesToEmit(_MaxBytesToEmit) {}
181
182 /// @name Accessors
183 /// @{
184
Daniel Dunbar3d153ff2009-08-21 23:07:38 +0000185 uint64_t getMaxFileSize() const {
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000186 return std::max(Alignment - 1, MaxBytesToEmit);
187 }
188
189 unsigned getAlignment() const { return Alignment; }
190
191 int64_t getValue() const { return Value; }
192
193 unsigned getValueSize() const { return ValueSize; }
194
195 unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
196
197 /// @}
198
199 static bool classof(const MCFragment *F) {
200 return F->getKind() == MCFragment::FT_Align;
201 }
202 static bool classof(const MCAlignFragment *) { return true; }
203};
204
205class MCFillFragment : public MCFragment {
206 /// Value - Value to use for filling bytes.
Daniel Dunbar4e5c1b62009-10-16 01:58:03 +0000207 const MCExpr *Value;
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000208
209 /// ValueSize - The size (in bytes) of \arg Value to use when filling.
210 unsigned ValueSize;
211
212 /// Count - The number of copies of \arg Value to insert.
213 uint64_t Count;
214
215public:
Daniel Dunbar4e5c1b62009-10-16 01:58:03 +0000216 MCFillFragment(const MCExpr &_Value, unsigned _ValueSize, uint64_t _Count,
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000217 MCSectionData *SD = 0)
218 : MCFragment(FT_Fill, SD),
Daniel Dunbar4e5c1b62009-10-16 01:58:03 +0000219 Value(&_Value), ValueSize(_ValueSize), Count(_Count) {}
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000220
221 /// @name Accessors
222 /// @{
223
Daniel Dunbar3d153ff2009-08-21 23:07:38 +0000224 uint64_t getMaxFileSize() const {
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000225 return ValueSize * Count;
226 }
227
Daniel Dunbar4e5c1b62009-10-16 01:58:03 +0000228 const MCExpr &getValue() const { return *Value; }
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000229
230 unsigned getValueSize() const { return ValueSize; }
231
232 uint64_t getCount() const { return Count; }
233
234 /// @}
235
236 static bool classof(const MCFragment *F) {
237 return F->getKind() == MCFragment::FT_Fill;
238 }
239 static bool classof(const MCFillFragment *) { return true; }
240};
241
242class MCOrgFragment : public MCFragment {
243 /// Offset - The offset this fragment should start at.
Daniel Dunbar4e5c1b62009-10-16 01:58:03 +0000244 const MCExpr *Offset;
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000245
246 /// Value - Value to use for filling bytes.
Daniel Dunbar3d153ff2009-08-21 23:07:38 +0000247 int8_t Value;
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000248
249public:
Daniel Dunbar4e5c1b62009-10-16 01:58:03 +0000250 MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000251 : MCFragment(FT_Org, SD),
Daniel Dunbar4e5c1b62009-10-16 01:58:03 +0000252 Offset(&_Offset), Value(_Value) {}
Daniel Dunbardf98a142009-08-28 05:49:21 +0000253
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000254 /// @name Accessors
255 /// @{
256
Daniel Dunbar3d153ff2009-08-21 23:07:38 +0000257 uint64_t getMaxFileSize() const {
258 // FIXME: This doesn't make much sense.
259 return ~UINT64_C(0);
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000260 }
261
Daniel Dunbar4e5c1b62009-10-16 01:58:03 +0000262 const MCExpr &getOffset() const { return *Offset; }
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000263
Daniel Dunbar3d153ff2009-08-21 23:07:38 +0000264 uint8_t getValue() const { return Value; }
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000265
266 /// @}
267
268 static bool classof(const MCFragment *F) {
269 return F->getKind() == MCFragment::FT_Org;
270 }
271 static bool classof(const MCOrgFragment *) { return true; }
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000272};
273
Daniel Dunbardf98a142009-08-28 05:49:21 +0000274/// MCZeroFillFragment - Represent data which has a fixed size and alignment,
275/// but requires no physical space in the object file.
276class MCZeroFillFragment : public MCFragment {
277 /// Size - The size of this fragment.
278 uint64_t Size;
279
280 /// Alignment - The alignment for this fragment.
281 unsigned Alignment;
282
283public:
284 MCZeroFillFragment(uint64_t _Size, unsigned _Alignment, MCSectionData *SD = 0)
285 : MCFragment(FT_ZeroFill, SD),
286 Size(_Size), Alignment(_Alignment) {}
287
288 /// @name Accessors
289 /// @{
290
291 uint64_t getMaxFileSize() const {
292 // FIXME: This also doesn't make much sense, this method is misnamed.
293 return ~UINT64_C(0);
294 }
295
296 uint64_t getSize() const { return Size; }
297
298 unsigned getAlignment() const { return Alignment; }
299
300 /// @}
301
302 static bool classof(const MCFragment *F) {
303 return F->getKind() == MCFragment::FT_ZeroFill;
304 }
305 static bool classof(const MCZeroFillFragment *) { return true; }
306};
307
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000308// FIXME: Should this be a separate class, or just merged into MCSection? Since
309// we anticipate the fast path being through an MCAssembler, the only reason to
310// keep it out is for API abstraction.
311class MCSectionData : public ilist_node<MCSectionData> {
312 MCSectionData(const MCSectionData&); // DO NOT IMPLEMENT
313 void operator=(const MCSectionData&); // DO NOT IMPLEMENT
314
315public:
Daniel Dunbar8fa9da22009-08-26 13:58:10 +0000316
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000317 typedef iplist<MCFragment> FragmentListType;
318
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000319 typedef FragmentListType::const_iterator const_iterator;
320 typedef FragmentListType::iterator iterator;
321
Daniel Dunbar5e65c6f2010-02-11 21:29:29 +0000322 typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator;
323 typedef std::vector<MCAsmFixup>::iterator fixup_iterator;
Daniel Dunbar8fa9da22009-08-26 13:58:10 +0000324
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000325private:
326 iplist<MCFragment> Fragments;
Daniel Dunbaradb77e42009-08-27 00:38:04 +0000327 const MCSection *Section;
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000328
329 /// Alignment - The maximum alignment seen in this section.
330 unsigned Alignment;
331
332 /// @name Assembler Backend Data
333 /// @{
334 //
335 // FIXME: This could all be kept private to the assembler implementation.
336
Daniel Dunbarb3730b12009-08-26 02:48:04 +0000337 /// Address - The computed address of this section. This is ~0 until
338 /// initialized.
339 uint64_t Address;
340
Daniel Dunbar0f56d412009-08-26 04:13:32 +0000341 /// Size - The content size of this section. This is ~0 until initialized.
342 uint64_t Size;
343
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000344 /// FileSize - The size of this section in the object file. This is ~0 until
345 /// initialized.
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000346 uint64_t FileSize;
347
Daniel Dunbar8fa9da22009-08-26 13:58:10 +0000348 /// LastFixupLookup - Cache for the last looked up fixup.
349 mutable unsigned LastFixupLookup;
350
351 /// Fixups - The list of fixups in this section.
Daniel Dunbar5e65c6f2010-02-11 21:29:29 +0000352 std::vector<MCAsmFixup> Fixups;
Daniel Dunbar8253f502010-02-02 21:44:01 +0000353
354 /// HasInstructions - Whether this section has had instructions emitted into
355 /// it.
356 unsigned HasInstructions : 1;
357
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000358 /// @}
359
360public:
361 // Only for use as sentinel.
362 MCSectionData();
363 MCSectionData(const MCSection &Section, MCAssembler *A = 0);
364
Daniel Dunbaradb77e42009-08-27 00:38:04 +0000365 const MCSection &getSection() const { return *Section; }
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000366
367 unsigned getAlignment() const { return Alignment; }
368 void setAlignment(unsigned Value) { Alignment = Value; }
369
Daniel Dunbarc3c19922009-08-26 13:57:54 +0000370 /// @name Fragment Access
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000371 /// @{
372
373 const FragmentListType &getFragmentList() const { return Fragments; }
374 FragmentListType &getFragmentList() { return Fragments; }
375
376 iterator begin() { return Fragments.begin(); }
377 const_iterator begin() const { return Fragments.begin(); }
378
379 iterator end() { return Fragments.end(); }
380 const_iterator end() const { return Fragments.end(); }
381
382 size_t size() const { return Fragments.size(); }
383
Daniel Dunbar197f5632009-08-22 10:13:24 +0000384 bool empty() const { return Fragments.empty(); }
385
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000386 /// @}
Daniel Dunbar8fa9da22009-08-26 13:58:10 +0000387 /// @name Fixup Access
388 /// @{
389
Daniel Dunbar5e65c6f2010-02-11 21:29:29 +0000390 std::vector<MCAsmFixup> &getFixups() {
Daniel Dunbar8fa9da22009-08-26 13:58:10 +0000391 return Fixups;
392 }
393
394 fixup_iterator fixup_begin() {
395 return Fixups.begin();
396 }
397
398 fixup_iterator fixup_end() {
399 return Fixups.end();
400 }
401
402 size_t fixup_size() const { return Fixups.size(); }
403
404 /// @}
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000405 /// @name Assembler Backend Support
406 /// @{
407 //
408 // FIXME: This could all be kept private to the assembler implementation.
409
Daniel Dunbar8fa9da22009-08-26 13:58:10 +0000410 /// LookupFixup - Look up the fixup for the given \arg Fragment and \arg
411 /// Offset.
412 ///
413 /// If multiple fixups exist for the same fragment and offset it is undefined
414 /// which one is returned.
415 //
416 // FIXME: This isn't horribly slow in practice, but there are much nicer
417 // solutions to applying the fixups.
Daniel Dunbar5e65c6f2010-02-11 21:29:29 +0000418 const MCAsmFixup *LookupFixup(const MCFragment *Fragment,
419 uint64_t Offset) const;
Daniel Dunbar8fa9da22009-08-26 13:58:10 +0000420
Daniel Dunbar0f56d412009-08-26 04:13:32 +0000421 uint64_t getAddress() const {
Daniel Dunbarb3730b12009-08-26 02:48:04 +0000422 assert(Address != ~UINT64_C(0) && "Address not set!");
423 return Address;
424 }
425 void setAddress(uint64_t Value) { Address = Value; }
426
Daniel Dunbar0f56d412009-08-26 04:13:32 +0000427 uint64_t getSize() const {
428 assert(Size != ~UINT64_C(0) && "File size not set!");
429 return Size;
430 }
431 void setSize(uint64_t Value) { Size = Value; }
432
433 uint64_t getFileSize() const {
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000434 assert(FileSize != ~UINT64_C(0) && "File size not set!");
435 return FileSize;
436 }
Daniel Dunbarc3c19922009-08-26 13:57:54 +0000437 void setFileSize(uint64_t Value) { FileSize = Value; }
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000438
Daniel Dunbar8253f502010-02-02 21:44:01 +0000439 bool hasInstructions() const { return HasInstructions; }
440 void setHasInstructions(bool Value) { HasInstructions = Value; }
441
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000442 /// @}
443};
444
Daniel Dunbar197f5632009-08-22 10:13:24 +0000445// FIXME: Same concerns as with SectionData.
446class MCSymbolData : public ilist_node<MCSymbolData> {
447public:
Daniel Dunbaref0f6372009-09-01 04:09:03 +0000448 const MCSymbol *Symbol;
Daniel Dunbar197f5632009-08-22 10:13:24 +0000449
450 /// Fragment - The fragment this symbol's value is relative to, if any.
451 MCFragment *Fragment;
452
453 /// Offset - The offset to apply to the fragment address to form this symbol's
454 /// value.
455 uint64_t Offset;
Daniel Dunbar6fae16d2009-08-22 11:41:10 +0000456
457 /// IsExternal - True if this symbol is visible outside this translation
458 /// unit.
459 unsigned IsExternal : 1;
Daniel Dunbar197f5632009-08-22 10:13:24 +0000460
Daniel Dunbar30b09422009-08-24 08:40:12 +0000461 /// IsPrivateExtern - True if this symbol is private extern.
462 unsigned IsPrivateExtern : 1;
463
Daniel Dunbar8388a8f2009-08-28 07:08:35 +0000464 /// CommonSize - The size of the symbol, if it is 'common', or 0.
465 //
466 // FIXME: Pack this in with other fields? We could put it in offset, since a
467 // common symbol can never get a definition.
468 uint64_t CommonSize;
469
470 /// CommonAlign - The alignment of the symbol, if it is 'common'.
471 //
472 // FIXME: Pack this in with other fields?
473 unsigned CommonAlign;
474
Daniel Dunbar30b09422009-08-24 08:40:12 +0000475 /// Flags - The Flags field is used by object file implementations to store
476 /// additional per symbol information which is not easily classified.
477 uint32_t Flags;
478
Daniel Dunbarc3c19922009-08-26 13:57:54 +0000479 /// Index - Index field, for use by the object file implementation.
480 uint64_t Index;
481
Daniel Dunbar197f5632009-08-22 10:13:24 +0000482public:
483 // Only for use as sentinel.
484 MCSymbolData();
Daniel Dunbar22ad5f82009-08-31 08:08:06 +0000485 MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
Daniel Dunbar197f5632009-08-22 10:13:24 +0000486 MCAssembler *A = 0);
487
488 /// @name Accessors
489 /// @{
490
Daniel Dunbaref0f6372009-09-01 04:09:03 +0000491 const MCSymbol &getSymbol() const { return *Symbol; }
Daniel Dunbar197f5632009-08-22 10:13:24 +0000492
493 MCFragment *getFragment() const { return Fragment; }
494 void setFragment(MCFragment *Value) { Fragment = Value; }
495
496 uint64_t getOffset() const { return Offset; }
497 void setOffset(uint64_t Value) { Offset = Value; }
498
Daniel Dunbar30b09422009-08-24 08:40:12 +0000499 /// @}
500 /// @name Symbol Attributes
501 /// @{
502
503 bool isExternal() const { return IsExternal; }
504 void setExternal(bool Value) { IsExternal = Value; }
505
506 bool isPrivateExtern() const { return IsPrivateExtern; }
507 void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
Daniel Dunbar8388a8f2009-08-28 07:08:35 +0000508
509 /// isCommon - Is this a 'common' symbol.
510 bool isCommon() const { return CommonSize != 0; }
511
512 /// setCommon - Mark this symbol as being 'common'.
513 ///
514 /// \param Size - The size of the symbol.
515 /// \param Align - The alignment of the symbol.
516 void setCommon(uint64_t Size, unsigned Align) {
517 CommonSize = Size;
518 CommonAlign = Align;
519 }
520
521 /// getCommonSize - Return the size of a 'common' symbol.
522 uint64_t getCommonSize() const {
523 assert(isCommon() && "Not a 'common' symbol!");
524 return CommonSize;
525 }
526
527 /// getCommonAlignment - Return the alignment of a 'common' symbol.
528 unsigned getCommonAlignment() const {
529 assert(isCommon() && "Not a 'common' symbol!");
530 return CommonAlign;
531 }
532
Daniel Dunbar30b09422009-08-24 08:40:12 +0000533 /// getFlags - Get the (implementation defined) symbol flags.
534 uint32_t getFlags() const { return Flags; }
Daniel Dunbar6fae16d2009-08-22 11:41:10 +0000535
Daniel Dunbar30b09422009-08-24 08:40:12 +0000536 /// setFlags - Set the (implementation defined) symbol flags.
537 void setFlags(uint32_t Value) { Flags = Value; }
538
Daniel Dunbarc3c19922009-08-26 13:57:54 +0000539 /// getIndex - Get the (implementation defined) index.
540 uint64_t getIndex() const { return Index; }
541
542 /// setIndex - Set the (implementation defined) index.
543 void setIndex(uint64_t Value) { Index = Value; }
544
Daniel Dunbar197f5632009-08-22 10:13:24 +0000545 /// @}
546};
547
Daniel Dunbara0151d02009-08-24 11:56:58 +0000548// FIXME: This really doesn't belong here. See comments below.
549struct IndirectSymbolData {
550 MCSymbol *Symbol;
551 MCSectionData *SectionData;
552};
553
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000554class MCAssembler {
555public:
556 typedef iplist<MCSectionData> SectionDataListType;
Daniel Dunbar197f5632009-08-22 10:13:24 +0000557 typedef iplist<MCSymbolData> SymbolDataListType;
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000558
559 typedef SectionDataListType::const_iterator const_iterator;
560 typedef SectionDataListType::iterator iterator;
561
Daniel Dunbar197f5632009-08-22 10:13:24 +0000562 typedef SymbolDataListType::const_iterator const_symbol_iterator;
563 typedef SymbolDataListType::iterator symbol_iterator;
564
Daniel Dunbara0151d02009-08-24 11:56:58 +0000565 typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
566
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000567private:
568 MCAssembler(const MCAssembler&); // DO NOT IMPLEMENT
569 void operator=(const MCAssembler&); // DO NOT IMPLEMENT
570
Daniel Dunbar29efe7e2009-08-31 08:07:55 +0000571 MCContext &Context;
572
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000573 raw_ostream &OS;
574
575 iplist<MCSectionData> Sections;
576
Daniel Dunbar197f5632009-08-22 10:13:24 +0000577 iplist<MCSymbolData> Symbols;
578
Daniel Dunbara0151d02009-08-24 11:56:58 +0000579 std::vector<IndirectSymbolData> IndirectSymbols;
580
Daniel Dunbarf8c4bb72009-08-26 21:22:22 +0000581 unsigned SubsectionsViaSymbols : 1;
582
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000583private:
584 /// LayoutSection - Assign offsets and sizes to the fragments in the section
585 /// \arg SD, and update the section size. The section file offset should
586 /// already have been computed.
Daniel Dunbar1c215be2009-08-28 05:49:04 +0000587 void LayoutSection(MCSectionData &SD);
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000588
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000589public:
590 /// Construct a new assembler instance.
591 ///
592 /// \arg OS - The stream to output to.
593 //
594 // FIXME: How are we going to parameterize this? Two obvious options are stay
595 // concrete and require clients to pass in a target like object. The other
596 // option is to make this abstract, and have targets provide concrete
597 // implementations as we do with AsmParser.
Daniel Dunbar29efe7e2009-08-31 08:07:55 +0000598 MCAssembler(MCContext &_Context, raw_ostream &OS);
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000599 ~MCAssembler();
600
Daniel Dunbar29efe7e2009-08-31 08:07:55 +0000601 MCContext &getContext() const { return Context; }
602
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000603 /// Finish - Do final processing and write the object to the output stream.
604 void Finish();
605
Daniel Dunbarf8c4bb72009-08-26 21:22:22 +0000606 // FIXME: This does not belong here.
607 bool getSubsectionsViaSymbols() const {
608 return SubsectionsViaSymbols;
609 }
610 void setSubsectionsViaSymbols(bool Value) {
611 SubsectionsViaSymbols = Value;
612 }
613
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000614 /// @name Section List Access
615 /// @{
616
617 const SectionDataListType &getSectionList() const { return Sections; }
618 SectionDataListType &getSectionList() { return Sections; }
619
620 iterator begin() { return Sections.begin(); }
621 const_iterator begin() const { return Sections.begin(); }
622
623 iterator end() { return Sections.end(); }
624 const_iterator end() const { return Sections.end(); }
625
626 size_t size() const { return Sections.size(); }
627
628 /// @}
Daniel Dunbar197f5632009-08-22 10:13:24 +0000629 /// @name Symbol List Access
630 /// @{
631
632 const SymbolDataListType &getSymbolList() const { return Symbols; }
633 SymbolDataListType &getSymbolList() { return Symbols; }
634
635 symbol_iterator symbol_begin() { return Symbols.begin(); }
636 const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
637
638 symbol_iterator symbol_end() { return Symbols.end(); }
639 const_symbol_iterator symbol_end() const { return Symbols.end(); }
640
641 size_t symbol_size() const { return Symbols.size(); }
642
643 /// @}
Daniel Dunbara0151d02009-08-24 11:56:58 +0000644 /// @name Indirect Symbol List Access
645 /// @{
646
647 // FIXME: This is a total hack, this should not be here. Once things are
648 // factored so that the streamer has direct access to the .o writer, it can
649 // disappear.
650 std::vector<IndirectSymbolData> &getIndirectSymbols() {
651 return IndirectSymbols;
652 }
653
654 indirect_symbol_iterator indirect_symbol_begin() {
655 return IndirectSymbols.begin();
656 }
657
658 indirect_symbol_iterator indirect_symbol_end() {
659 return IndirectSymbols.end();
660 }
661
662 size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
663
664 /// @}
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000665};
666
667} // end namespace llvm
668
669#endif