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