f083d3c814a0816bd814b94654f823f3075d34de
[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/Object/Binary.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Support/DataTypes.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/MemoryBuffer.h"
22 #include <cstring>
23
24 namespace llvm {
25 namespace object {
26
27 class ObjectFile;
28
29 union DataRefImpl {
30   struct {
31     uint32_t a, b;
32   } d;
33   uintptr_t p;
34 };
35
36 static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) {
37   // Check bitwise identical. This is the only legal way to compare a union w/o
38   // knowing which member is in use.
39   return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
40 }
41
42 class RelocationRef {
43   DataRefImpl RelocationPimpl;
44   const ObjectFile *OwningObject;
45
46 public:
47   RelocationRef() : OwningObject(NULL) { std::memset(&RelocationPimpl, 0, sizeof(RelocationPimpl)); }
48   RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
49
50   bool operator==(const RelocationRef &Other) const;
51
52   error_code getNext(RelocationRef &Result);
53 };
54
55 /// SymbolRef - This is a value type class that represents a single symbol in
56 /// the list of symbols in the object file.
57 class SymbolRef {
58   DataRefImpl SymbolPimpl;
59   const ObjectFile *OwningObject;
60
61 public:
62   SymbolRef() : OwningObject(NULL) { std::memset(&SymbolPimpl, 0, sizeof(SymbolPimpl)); }
63   SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
64
65   bool operator==(const SymbolRef &Other) const;
66
67   error_code getNext(SymbolRef &Result) const;
68
69   error_code getName(StringRef &Result) const;
70   error_code getAddress(uint64_t &Result) const;
71   error_code getSize(uint64_t &Result) const;
72
73   /// Returns the ascii char that should be displayed in a symbol table dump via
74   /// nm for this symbol.
75   error_code getNMTypeChar(char &Result) const;
76
77   /// Returns true for symbols that are internal to the object file format such
78   /// as section symbols.
79   error_code isInternal(bool &Result) const;
80 };
81
82 /// SectionRef - This is a value type class that represents a single section in
83 /// the list of sections in the object file.
84 class SectionRef {
85   DataRefImpl SectionPimpl;
86   const ObjectFile *OwningObject;
87
88 public:
89   SectionRef() : OwningObject(NULL) { std::memset(&SectionPimpl, 0, sizeof(SectionPimpl)); }
90   SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
91
92   bool operator==(const SectionRef &Other) const;
93
94   error_code getNext(SectionRef &Result) const;
95
96   error_code getName(StringRef &Result) const;
97   error_code getAddress(uint64_t &Result) const;
98   error_code getSize(uint64_t &Result) const;
99   error_code getContents(StringRef &Result) const;
100
101   // FIXME: Move to the normalization layer when it's created.
102   error_code isText(bool &Result) const;
103 };
104
105 const uint64_t UnknownAddressOrSize = ~0ULL;
106
107 /// ObjectFile - This class is the base class for all object file types.
108 /// Concrete instances of this object are created by createObjectFile, which
109 /// figure out which type to create.
110 class ObjectFile : public Binary {
111 private:
112   ObjectFile(); // = delete
113   ObjectFile(const ObjectFile &other); // = delete
114
115 protected:
116   ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec);
117
118   const uint8_t *base() const {
119     return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
120   }
121
122   // These functions are for SymbolRef to call internally. The main goal of
123   // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
124   // entry in the memory mapped object file. SymbolPimpl cannot contain any
125   // virtual functions because then it could not point into the memory mapped
126   // file.
127   //
128   // Implementations assume that the DataRefImpl is valid and has not been
129   // modified externally. It's UB otherwise.
130   friend class SymbolRef;
131   virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0;
132   virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0;
133   virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const =0;
134   virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
135   virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0;
136   virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const = 0;
137
138   // Same as above for SectionRef.
139   friend class SectionRef;
140   virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const = 0;
141   virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0;
142   virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0;
143   virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0;
144   virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)const=0;
145   virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0;
146
147
148 public:
149   template<class content_type>
150   class content_iterator {
151     content_type Current;
152   public:
153     content_iterator(content_type symb)
154       : Current(symb) {}
155
156     const content_type* operator->() const {
157       return &Current;
158     }
159
160     bool operator==(const content_iterator &other) const {
161       return Current == other.Current;
162     }
163
164     bool operator!=(const content_iterator &other) const {
165       return !(*this == other);
166     }
167
168     content_iterator& increment(error_code &err) {
169       content_type next;
170       if (error_code ec = Current.getNext(next))
171         err = ec;
172       else
173         Current = next;
174       return *this;
175     }
176   };
177
178   typedef content_iterator<SymbolRef> symbol_iterator;
179   typedef content_iterator<SectionRef> section_iterator;
180
181   virtual symbol_iterator begin_symbols() const = 0;
182   virtual symbol_iterator end_symbols() const = 0;
183
184   virtual section_iterator begin_sections() const = 0;
185   virtual section_iterator end_sections() const = 0;
186
187   /// @brief The number of bytes used to represent an address in this object
188   ///        file format.
189   virtual uint8_t getBytesInAddress() const = 0;
190
191   virtual StringRef getFileFormatName() const = 0;
192   virtual /* Triple::ArchType */ unsigned getArch() const = 0;
193
194   /// @returns Pointer to ObjectFile subclass to handle this type of object.
195   /// @param ObjectPath The path to the object file. ObjectPath.isObject must
196   ///        return true.
197   /// @brief Create ObjectFile from path.
198   static ObjectFile *createObjectFile(StringRef ObjectPath);
199   static ObjectFile *createObjectFile(MemoryBuffer *Object);
200
201   static inline bool classof(const Binary *v) {
202     return v->getType() >= isObject &&
203            v->getType() < lastObject;
204   }
205   static inline bool classof(const ObjectFile *v) { return true; }
206
207 public:
208   static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
209   static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
210   static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
211 };
212
213 // Inline function definitions.
214 inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
215   : SymbolPimpl(SymbolP)
216   , OwningObject(Owner) {}
217
218 inline bool SymbolRef::operator==(const SymbolRef &Other) const {
219   return SymbolPimpl == Other.SymbolPimpl;
220 }
221
222 inline error_code SymbolRef::getNext(SymbolRef &Result) const {
223   return OwningObject->getSymbolNext(SymbolPimpl, Result);
224 }
225
226 inline error_code SymbolRef::getName(StringRef &Result) const {
227   return OwningObject->getSymbolName(SymbolPimpl, Result);
228 }
229
230 inline error_code SymbolRef::getAddress(uint64_t &Result) const {
231   return OwningObject->getSymbolAddress(SymbolPimpl, Result);
232 }
233
234 inline error_code SymbolRef::getSize(uint64_t &Result) const {
235   return OwningObject->getSymbolSize(SymbolPimpl, Result);
236 }
237
238 inline error_code SymbolRef::getNMTypeChar(char &Result) const {
239   return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result);
240 }
241
242 inline error_code SymbolRef::isInternal(bool &Result) const {
243   return OwningObject->isSymbolInternal(SymbolPimpl, Result);
244 }
245
246
247 /// SectionRef
248 inline SectionRef::SectionRef(DataRefImpl SectionP,
249                               const ObjectFile *Owner)
250   : SectionPimpl(SectionP)
251   , OwningObject(Owner) {}
252
253 inline bool SectionRef::operator==(const SectionRef &Other) const {
254   return SectionPimpl == Other.SectionPimpl;
255 }
256
257 inline error_code SectionRef::getNext(SectionRef &Result) const {
258   return OwningObject->getSectionNext(SectionPimpl, Result);
259 }
260
261 inline error_code SectionRef::getName(StringRef &Result) const {
262   return OwningObject->getSectionName(SectionPimpl, Result);
263 }
264
265 inline error_code SectionRef::getAddress(uint64_t &Result) const {
266   return OwningObject->getSectionAddress(SectionPimpl, Result);
267 }
268
269 inline error_code SectionRef::getSize(uint64_t &Result) const {
270   return OwningObject->getSectionSize(SectionPimpl, Result);
271 }
272
273 inline error_code SectionRef::getContents(StringRef &Result) const {
274   return OwningObject->getSectionContents(SectionPimpl, Result);
275 }
276
277 inline error_code SectionRef::isText(bool &Result) const {
278   return OwningObject->isSectionText(SectionPimpl, Result);
279 }
280
281 } // end namespace object
282 } // end namespace llvm
283
284 #endif