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