split SROA into two passes: one that uses DomFrontiers (-scalarrepl)
[oota-llvm.git] / include / llvm / Object / ObjectFile.h
1 //===- ObjectFile.h - File format independent object file -------*- 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 // This file declares a file format independent ObjectFile class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_OBJECT_OBJECT_FILE_H
15 #define LLVM_OBJECT_OBJECT_FILE_H
16
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/DataTypes.h"
19
20 namespace llvm {
21
22 class MemoryBuffer;
23 class StringRef;
24
25 namespace object {
26
27 class ObjectFile;
28 typedef uint64_t DataRefImpl;
29
30 /// SymbolRef - This is a value type class that represents a single symbol in
31 /// the list of symbols in the object file.
32 class SymbolRef {
33   DataRefImpl SymbolPimpl;
34   const ObjectFile *OwningObject;
35
36 public:
37   SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
38
39   bool operator==(const SymbolRef &Other) const;
40
41   SymbolRef getNext() const;
42
43   StringRef getName() const;
44   uint64_t  getAddress() const;
45   uint64_t  getSize() const;
46
47   /// Returns the ascii char that should be displayed in a symbol table dump via
48   /// nm for this symbol.
49   char      getNMTypeChar() const;
50
51   /// Returns true for symbols that are internal to the object file format such
52   /// as section symbols.
53   bool      isInternal() const;
54 };
55
56 /// SectionRef - This is a value type class that represents a single section in
57 /// the list of sections in the object file.
58 class SectionRef {
59   DataRefImpl SectionPimpl;
60   const ObjectFile *OwningObject;
61
62 public:
63   SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
64
65   bool operator==(const SectionRef &Other) const;
66
67   SectionRef getNext() const;
68
69   StringRef getName() const;
70   uint64_t  getAddress() const;
71   uint64_t  getSize() const;
72   StringRef getContents() const;
73
74   // FIXME: Move to the normalization layer when it's created.
75   bool      isText() const;
76 };
77
78 const uint64_t UnknownAddressOrSize = ~0ULL;
79
80 /// ObjectFile - This class is the base class for all object file types.
81 /// Concrete instances of this object are created by createObjectFile, which
82 /// figure out which type to create.
83 class ObjectFile {
84 private:
85   ObjectFile(); // = delete
86   ObjectFile(const ObjectFile &other); // = delete
87
88 protected:
89   MemoryBuffer *MapFile;
90   const uint8_t *base;
91
92   ObjectFile(MemoryBuffer *Object);
93
94   // These functions are for SymbolRef to call internally. The main goal of
95   // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
96   // entry in the memory mapped object file. SymbolPimpl cannot contain any
97   // virtual functions because then it could not point into the memory mapped
98   // file.
99   friend class SymbolRef;
100   virtual SymbolRef getSymbolNext(DataRefImpl Symb) const = 0;
101   virtual StringRef getSymbolName(DataRefImpl Symb) const = 0;
102   virtual uint64_t  getSymbolAddress(DataRefImpl Symb) const = 0;
103   virtual uint64_t  getSymbolSize(DataRefImpl Symb) const = 0;
104   virtual char      getSymbolNMTypeChar(DataRefImpl Symb) const = 0;
105   virtual bool      isSymbolInternal(DataRefImpl Symb) const = 0;
106
107   // Same as above for SectionRef.
108   friend class SectionRef;
109   virtual SectionRef getSectionNext(DataRefImpl Sec) const = 0;
110   virtual StringRef  getSectionName(DataRefImpl Sec) const = 0;
111   virtual uint64_t   getSectionAddress(DataRefImpl Sec) const = 0;
112   virtual uint64_t   getSectionSize(DataRefImpl Sec) const = 0;
113   virtual StringRef  getSectionContents(DataRefImpl Sec) const = 0;
114   virtual bool       isSectionText(DataRefImpl Sec) const = 0;
115
116
117 public:
118   template<class content_type>
119   class content_iterator {
120     content_type Current;
121   public:
122     content_iterator(content_type symb)
123       : Current(symb) {}
124
125     const content_type* operator->() const {
126       return &Current;
127     }
128
129     bool operator==(const content_iterator &other) const {
130       return Current == other.Current;
131     }
132
133     bool operator!=(const content_iterator &other) const {
134       return !(*this == other);
135     }
136
137     content_iterator& operator++() {  // Preincrement
138       Current = Current.getNext();
139       return *this;
140     }
141   };
142
143   typedef content_iterator<SymbolRef> symbol_iterator;
144   typedef content_iterator<SectionRef> section_iterator;
145
146   virtual ~ObjectFile();
147
148   virtual symbol_iterator begin_symbols() const = 0;
149   virtual symbol_iterator end_symbols() const = 0;
150
151   virtual section_iterator begin_sections() const = 0;
152   virtual section_iterator end_sections() const = 0;
153
154   /// @brief The number of bytes used to represent an address in this object
155   ///        file format.
156   virtual uint8_t getBytesInAddress() const = 0;
157
158   virtual StringRef getFileFormatName() const = 0;
159   virtual /* Triple::ArchType */ unsigned getArch() const = 0;
160
161   StringRef getFilename() const;
162
163   /// @returns Pointer to ObjectFile subclass to handle this type of object.
164   /// @param ObjectPath The path to the object file. ObjectPath.isObject must
165   ///        return true.
166   /// @brief Create ObjectFile from path.
167   static ObjectFile *createObjectFile(StringRef ObjectPath);
168   static ObjectFile *createObjectFile(MemoryBuffer *Object);
169
170 private:
171   static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
172   static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
173   static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
174   static ObjectFile *createArchiveObjectFile(MemoryBuffer *Object);
175   static ObjectFile *createLibObjectFile(MemoryBuffer *Object);
176 };
177
178 // Inline function definitions.
179 inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
180   : SymbolPimpl(SymbolP)
181   , OwningObject(Owner) {}
182
183 inline bool SymbolRef::operator==(const SymbolRef &Other) const {
184   return SymbolPimpl == Other.SymbolPimpl;
185 }
186
187 inline SymbolRef SymbolRef::getNext() const {
188   return OwningObject->getSymbolNext(SymbolPimpl);
189 }
190
191 inline StringRef SymbolRef::getName() const {
192   return OwningObject->getSymbolName(SymbolPimpl);
193 }
194
195 inline uint64_t SymbolRef::getAddress() const {
196   return OwningObject->getSymbolAddress(SymbolPimpl);
197 }
198
199 inline uint64_t SymbolRef::getSize() const {
200   return OwningObject->getSymbolSize(SymbolPimpl);
201 }
202
203 inline char SymbolRef::getNMTypeChar() const {
204   return OwningObject->getSymbolNMTypeChar(SymbolPimpl);
205 }
206
207 inline bool SymbolRef::isInternal() const {
208   return OwningObject->isSymbolInternal(SymbolPimpl);
209 }
210
211
212 /// SectionRef
213 inline SectionRef::SectionRef(DataRefImpl SectionP,
214                               const ObjectFile *Owner)
215   : SectionPimpl(SectionP)
216   , OwningObject(Owner) {}
217
218 inline bool SectionRef::operator==(const SectionRef &Other) const {
219   return SectionPimpl == Other.SectionPimpl;
220 }
221
222 inline SectionRef SectionRef::getNext() const {
223   return OwningObject->getSectionNext(SectionPimpl);
224 }
225
226 inline StringRef SectionRef::getName() const {
227   return OwningObject->getSectionName(SectionPimpl);
228 }
229
230 inline uint64_t SectionRef::getAddress() const {
231   return OwningObject->getSectionAddress(SectionPimpl);
232 }
233
234 inline uint64_t SectionRef::getSize() const {
235   return OwningObject->getSectionSize(SectionPimpl);
236 }
237
238 inline StringRef SectionRef::getContents() const {
239   return OwningObject->getSectionContents(SectionPimpl);
240 }
241
242 inline bool SectionRef::isText() const {
243   return OwningObject->isSectionText(SectionPimpl);
244 }
245
246 } // end namespace object
247 } // end namespace llvm
248
249 #endif