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