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