LLVM API Documentation
00001 //===- ObjectFile.h - File format independent object file -------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file declares a file format independent ObjectFile class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_OBJECT_OBJECTFILE_H 00015 #define LLVM_OBJECT_OBJECTFILE_H 00016 00017 #include "llvm/ADT/StringRef.h" 00018 #include "llvm/Object/SymbolicFile.h" 00019 #include "llvm/Support/DataTypes.h" 00020 #include "llvm/Support/ErrorHandling.h" 00021 #include "llvm/Support/FileSystem.h" 00022 #include "llvm/Support/MemoryBuffer.h" 00023 #include <cstring> 00024 #include <vector> 00025 00026 namespace llvm { 00027 namespace object { 00028 00029 class ObjectFile; 00030 class COFFObjectFile; 00031 class MachOObjectFile; 00032 00033 class SymbolRef; 00034 class symbol_iterator; 00035 00036 /// RelocationRef - This is a value type class that represents a single 00037 /// relocation in the list of relocations in the object file. 00038 class RelocationRef { 00039 DataRefImpl RelocationPimpl; 00040 const ObjectFile *OwningObject; 00041 00042 public: 00043 RelocationRef() : OwningObject(nullptr) { } 00044 00045 RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner); 00046 00047 bool operator==(const RelocationRef &Other) const; 00048 00049 void moveNext(); 00050 00051 std::error_code getAddress(uint64_t &Result) const; 00052 std::error_code getOffset(uint64_t &Result) const; 00053 symbol_iterator getSymbol() const; 00054 std::error_code getType(uint64_t &Result) const; 00055 00056 /// @brief Indicates whether this relocation should hidden when listing 00057 /// relocations, usually because it is the trailing part of a multipart 00058 /// relocation that will be printed as part of the leading relocation. 00059 std::error_code getHidden(bool &Result) const; 00060 00061 /// @brief Get a string that represents the type of this relocation. 00062 /// 00063 /// This is for display purposes only. 00064 std::error_code getTypeName(SmallVectorImpl<char> &Result) const; 00065 00066 /// @brief Get a string that represents the calculation of the value of this 00067 /// relocation. 00068 /// 00069 /// This is for display purposes only. 00070 std::error_code getValueString(SmallVectorImpl<char> &Result) const; 00071 00072 DataRefImpl getRawDataRefImpl() const; 00073 const ObjectFile *getObjectFile() const; 00074 }; 00075 typedef content_iterator<RelocationRef> relocation_iterator; 00076 00077 /// SectionRef - This is a value type class that represents a single section in 00078 /// the list of sections in the object file. 00079 class SectionRef; 00080 typedef content_iterator<SectionRef> section_iterator; 00081 class SectionRef { 00082 friend class SymbolRef; 00083 DataRefImpl SectionPimpl; 00084 const ObjectFile *OwningObject; 00085 00086 public: 00087 SectionRef() : OwningObject(nullptr) { } 00088 00089 SectionRef(DataRefImpl SectionP, const ObjectFile *Owner); 00090 00091 bool operator==(const SectionRef &Other) const; 00092 bool operator!=(const SectionRef &Other) const; 00093 bool operator<(const SectionRef &Other) const; 00094 00095 void moveNext(); 00096 00097 std::error_code getName(StringRef &Result) const; 00098 std::error_code getAddress(uint64_t &Result) const; 00099 std::error_code getSize(uint64_t &Result) const; 00100 std::error_code getContents(StringRef &Result) const; 00101 00102 /// @brief Get the alignment of this section as the actual value (not log 2). 00103 std::error_code getAlignment(uint64_t &Result) const; 00104 00105 // FIXME: Move to the normalization layer when it's created. 00106 std::error_code isText(bool &Result) const; 00107 std::error_code isData(bool &Result) const; 00108 std::error_code isBSS(bool &Result) const; 00109 std::error_code isRequiredForExecution(bool &Result) const; 00110 std::error_code isVirtual(bool &Result) const; 00111 std::error_code isZeroInit(bool &Result) const; 00112 std::error_code isReadOnlyData(bool &Result) const; 00113 00114 std::error_code containsSymbol(SymbolRef S, bool &Result) const; 00115 00116 relocation_iterator relocation_begin() const; 00117 relocation_iterator relocation_end() const; 00118 iterator_range<relocation_iterator> relocations() const { 00119 return iterator_range<relocation_iterator>(relocation_begin(), 00120 relocation_end()); 00121 } 00122 section_iterator getRelocatedSection() const; 00123 00124 DataRefImpl getRawDataRefImpl() const; 00125 }; 00126 00127 /// SymbolRef - This is a value type class that represents a single symbol in 00128 /// the list of symbols in the object file. 00129 class SymbolRef : public BasicSymbolRef { 00130 friend class SectionRef; 00131 00132 public: 00133 SymbolRef() : BasicSymbolRef() {} 00134 00135 enum Type { 00136 ST_Unknown, // Type not specified 00137 ST_Data, 00138 ST_Debug, 00139 ST_File, 00140 ST_Function, 00141 ST_Other 00142 }; 00143 00144 SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); 00145 00146 std::error_code getName(StringRef &Result) const; 00147 /// Returns the symbol virtual address (i.e. address at which it will be 00148 /// mapped). 00149 std::error_code getAddress(uint64_t &Result) const; 00150 /// @brief Get the alignment of this symbol as the actual value (not log 2). 00151 std::error_code getAlignment(uint32_t &Result) const; 00152 std::error_code getSize(uint64_t &Result) const; 00153 std::error_code getType(SymbolRef::Type &Result) const; 00154 std::error_code getOther(uint8_t &Result) const; 00155 00156 /// @brief Get section this symbol is defined in reference to. Result is 00157 /// end_sections() if it is undefined or is an absolute symbol. 00158 std::error_code getSection(section_iterator &Result) const; 00159 00160 const ObjectFile *getObject() const; 00161 }; 00162 00163 class symbol_iterator : public basic_symbol_iterator { 00164 public: 00165 symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {} 00166 symbol_iterator(const basic_symbol_iterator &B) 00167 : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(), 00168 cast<ObjectFile>(B->getObject()))) {} 00169 00170 const SymbolRef *operator->() const { 00171 const BasicSymbolRef &P = basic_symbol_iterator::operator *(); 00172 return static_cast<const SymbolRef*>(&P); 00173 } 00174 00175 const SymbolRef &operator*() const { 00176 const BasicSymbolRef &P = basic_symbol_iterator::operator *(); 00177 return static_cast<const SymbolRef&>(P); 00178 } 00179 }; 00180 00181 /// ObjectFile - This class is the base class for all object file types. 00182 /// Concrete instances of this object are created by createObjectFile, which 00183 /// figures out which type to create. 00184 class ObjectFile : public SymbolicFile { 00185 virtual void anchor(); 00186 ObjectFile() LLVM_DELETED_FUNCTION; 00187 ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION; 00188 00189 protected: 00190 ObjectFile(unsigned int Type, MemoryBufferRef Source); 00191 00192 const uint8_t *base() const { 00193 return reinterpret_cast<const uint8_t *>(Data.getBufferStart()); 00194 } 00195 00196 // These functions are for SymbolRef to call internally. The main goal of 00197 // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol 00198 // entry in the memory mapped object file. SymbolPimpl cannot contain any 00199 // virtual functions because then it could not point into the memory mapped 00200 // file. 00201 // 00202 // Implementations assume that the DataRefImpl is valid and has not been 00203 // modified externally. It's UB otherwise. 00204 friend class SymbolRef; 00205 virtual std::error_code getSymbolName(DataRefImpl Symb, 00206 StringRef &Res) const = 0; 00207 std::error_code printSymbolName(raw_ostream &OS, 00208 DataRefImpl Symb) const override; 00209 virtual std::error_code getSymbolAddress(DataRefImpl Symb, 00210 uint64_t &Res) const = 0; 00211 virtual std::error_code getSymbolAlignment(DataRefImpl Symb, 00212 uint32_t &Res) const; 00213 virtual std::error_code getSymbolSize(DataRefImpl Symb, 00214 uint64_t &Res) const = 0; 00215 virtual std::error_code getSymbolType(DataRefImpl Symb, 00216 SymbolRef::Type &Res) const = 0; 00217 virtual std::error_code getSymbolSection(DataRefImpl Symb, 00218 section_iterator &Res) const = 0; 00219 virtual std::error_code getSymbolOther(DataRefImpl Symb, 00220 uint8_t &Res) const { 00221 return object_error::invalid_file_type; 00222 } 00223 00224 // Same as above for SectionRef. 00225 friend class SectionRef; 00226 virtual void moveSectionNext(DataRefImpl &Sec) const = 0; 00227 virtual std::error_code getSectionName(DataRefImpl Sec, 00228 StringRef &Res) const = 0; 00229 virtual std::error_code getSectionAddress(DataRefImpl Sec, 00230 uint64_t &Res) const = 0; 00231 virtual std::error_code getSectionSize(DataRefImpl Sec, 00232 uint64_t &Res) const = 0; 00233 virtual std::error_code getSectionContents(DataRefImpl Sec, 00234 StringRef &Res) const = 0; 00235 virtual std::error_code getSectionAlignment(DataRefImpl Sec, 00236 uint64_t &Res) const = 0; 00237 virtual std::error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0; 00238 virtual std::error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0; 00239 virtual std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0; 00240 virtual std::error_code isSectionRequiredForExecution(DataRefImpl Sec, 00241 bool &Res) const = 0; 00242 // A section is 'virtual' if its contents aren't present in the object image. 00243 virtual std::error_code isSectionVirtual(DataRefImpl Sec, 00244 bool &Res) const = 0; 00245 virtual std::error_code isSectionZeroInit(DataRefImpl Sec, 00246 bool &Res) const = 0; 00247 virtual std::error_code isSectionReadOnlyData(DataRefImpl Sec, 00248 bool &Res) const = 0; 00249 virtual std::error_code sectionContainsSymbol(DataRefImpl Sec, 00250 DataRefImpl Symb, 00251 bool &Result) const = 0; 00252 virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0; 00253 virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0; 00254 virtual section_iterator getRelocatedSection(DataRefImpl Sec) const; 00255 00256 // Same as above for RelocationRef. 00257 friend class RelocationRef; 00258 virtual void moveRelocationNext(DataRefImpl &Rel) const = 0; 00259 virtual std::error_code getRelocationAddress(DataRefImpl Rel, 00260 uint64_t &Res) const = 0; 00261 virtual std::error_code getRelocationOffset(DataRefImpl Rel, 00262 uint64_t &Res) const = 0; 00263 virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0; 00264 virtual std::error_code getRelocationType(DataRefImpl Rel, 00265 uint64_t &Res) const = 0; 00266 virtual std::error_code 00267 getRelocationTypeName(DataRefImpl Rel, 00268 SmallVectorImpl<char> &Result) const = 0; 00269 virtual std::error_code 00270 getRelocationValueString(DataRefImpl Rel, 00271 SmallVectorImpl<char> &Result) const = 0; 00272 virtual std::error_code getRelocationHidden(DataRefImpl Rel, 00273 bool &Result) const { 00274 Result = false; 00275 return object_error::success; 00276 } 00277 00278 public: 00279 typedef iterator_range<symbol_iterator> symbol_iterator_range; 00280 symbol_iterator_range symbols() const { 00281 return symbol_iterator_range(symbol_begin(), symbol_end()); 00282 } 00283 00284 virtual section_iterator section_begin() const = 0; 00285 virtual section_iterator section_end() const = 0; 00286 00287 typedef iterator_range<section_iterator> section_iterator_range; 00288 section_iterator_range sections() const { 00289 return section_iterator_range(section_begin(), section_end()); 00290 } 00291 00292 /// @brief The number of bytes used to represent an address in this object 00293 /// file format. 00294 virtual uint8_t getBytesInAddress() const = 0; 00295 00296 virtual StringRef getFileFormatName() const = 0; 00297 virtual /* Triple::ArchType */ unsigned getArch() const = 0; 00298 00299 /// Returns platform-specific object flags, if any. 00300 virtual std::error_code getPlatformFlags(unsigned &Result) const { 00301 Result = 0; 00302 return object_error::invalid_file_type; 00303 } 00304 00305 /// True if this is a relocatable object (.o/.obj). 00306 virtual bool isRelocatableObject() const = 0; 00307 00308 /// @returns Pointer to ObjectFile subclass to handle this type of object. 00309 /// @param ObjectPath The path to the object file. ObjectPath.isObject must 00310 /// return true. 00311 /// @brief Create ObjectFile from path. 00312 static ErrorOr<OwningBinary<ObjectFile>> 00313 createObjectFile(StringRef ObjectPath); 00314 00315 static ErrorOr<std::unique_ptr<ObjectFile>> 00316 createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type); 00317 static ErrorOr<std::unique_ptr<ObjectFile>> 00318 createObjectFile(MemoryBufferRef Object) { 00319 return createObjectFile(Object, sys::fs::file_magic::unknown); 00320 } 00321 00322 00323 static inline bool classof(const Binary *v) { 00324 return v->isObject(); 00325 } 00326 00327 static ErrorOr<std::unique_ptr<COFFObjectFile>> 00328 createCOFFObjectFile(MemoryBufferRef Object); 00329 00330 static ErrorOr<std::unique_ptr<ObjectFile>> 00331 createELFObjectFile(MemoryBufferRef Object); 00332 00333 static ErrorOr<std::unique_ptr<MachOObjectFile>> 00334 createMachOObjectFile(MemoryBufferRef Object); 00335 }; 00336 00337 // Inline function definitions. 00338 inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner) 00339 : BasicSymbolRef(SymbolP, Owner) {} 00340 00341 inline std::error_code SymbolRef::getName(StringRef &Result) const { 00342 return getObject()->getSymbolName(getRawDataRefImpl(), Result); 00343 } 00344 00345 inline std::error_code SymbolRef::getAddress(uint64_t &Result) const { 00346 return getObject()->getSymbolAddress(getRawDataRefImpl(), Result); 00347 } 00348 00349 inline std::error_code SymbolRef::getAlignment(uint32_t &Result) const { 00350 return getObject()->getSymbolAlignment(getRawDataRefImpl(), Result); 00351 } 00352 00353 inline std::error_code SymbolRef::getSize(uint64_t &Result) const { 00354 return getObject()->getSymbolSize(getRawDataRefImpl(), Result); 00355 } 00356 00357 inline std::error_code SymbolRef::getSection(section_iterator &Result) const { 00358 return getObject()->getSymbolSection(getRawDataRefImpl(), Result); 00359 } 00360 00361 inline std::error_code SymbolRef::getType(SymbolRef::Type &Result) const { 00362 return getObject()->getSymbolType(getRawDataRefImpl(), Result); 00363 } 00364 00365 inline std::error_code SymbolRef::getOther(uint8_t &Result) const { 00366 return getObject()->getSymbolOther(getRawDataRefImpl(), Result); 00367 } 00368 00369 inline const ObjectFile *SymbolRef::getObject() const { 00370 const SymbolicFile *O = BasicSymbolRef::getObject(); 00371 return cast<ObjectFile>(O); 00372 } 00373 00374 00375 /// SectionRef 00376 inline SectionRef::SectionRef(DataRefImpl SectionP, 00377 const ObjectFile *Owner) 00378 : SectionPimpl(SectionP) 00379 , OwningObject(Owner) {} 00380 00381 inline bool SectionRef::operator==(const SectionRef &Other) const { 00382 return SectionPimpl == Other.SectionPimpl; 00383 } 00384 00385 inline bool SectionRef::operator!=(const SectionRef &Other) const { 00386 return SectionPimpl != Other.SectionPimpl; 00387 } 00388 00389 inline bool SectionRef::operator<(const SectionRef &Other) const { 00390 return SectionPimpl < Other.SectionPimpl; 00391 } 00392 00393 inline void SectionRef::moveNext() { 00394 return OwningObject->moveSectionNext(SectionPimpl); 00395 } 00396 00397 inline std::error_code SectionRef::getName(StringRef &Result) const { 00398 return OwningObject->getSectionName(SectionPimpl, Result); 00399 } 00400 00401 inline std::error_code SectionRef::getAddress(uint64_t &Result) const { 00402 return OwningObject->getSectionAddress(SectionPimpl, Result); 00403 } 00404 00405 inline std::error_code SectionRef::getSize(uint64_t &Result) const { 00406 return OwningObject->getSectionSize(SectionPimpl, Result); 00407 } 00408 00409 inline std::error_code SectionRef::getContents(StringRef &Result) const { 00410 return OwningObject->getSectionContents(SectionPimpl, Result); 00411 } 00412 00413 inline std::error_code SectionRef::getAlignment(uint64_t &Result) const { 00414 return OwningObject->getSectionAlignment(SectionPimpl, Result); 00415 } 00416 00417 inline std::error_code SectionRef::isText(bool &Result) const { 00418 return OwningObject->isSectionText(SectionPimpl, Result); 00419 } 00420 00421 inline std::error_code SectionRef::isData(bool &Result) const { 00422 return OwningObject->isSectionData(SectionPimpl, Result); 00423 } 00424 00425 inline std::error_code SectionRef::isBSS(bool &Result) const { 00426 return OwningObject->isSectionBSS(SectionPimpl, Result); 00427 } 00428 00429 inline std::error_code SectionRef::isRequiredForExecution(bool &Result) const { 00430 return OwningObject->isSectionRequiredForExecution(SectionPimpl, Result); 00431 } 00432 00433 inline std::error_code SectionRef::isVirtual(bool &Result) const { 00434 return OwningObject->isSectionVirtual(SectionPimpl, Result); 00435 } 00436 00437 inline std::error_code SectionRef::isZeroInit(bool &Result) const { 00438 return OwningObject->isSectionZeroInit(SectionPimpl, Result); 00439 } 00440 00441 inline std::error_code SectionRef::isReadOnlyData(bool &Result) const { 00442 return OwningObject->isSectionReadOnlyData(SectionPimpl, Result); 00443 } 00444 00445 inline std::error_code SectionRef::containsSymbol(SymbolRef S, 00446 bool &Result) const { 00447 return OwningObject->sectionContainsSymbol(SectionPimpl, 00448 S.getRawDataRefImpl(), Result); 00449 } 00450 00451 inline relocation_iterator SectionRef::relocation_begin() const { 00452 return OwningObject->section_rel_begin(SectionPimpl); 00453 } 00454 00455 inline relocation_iterator SectionRef::relocation_end() const { 00456 return OwningObject->section_rel_end(SectionPimpl); 00457 } 00458 00459 inline section_iterator SectionRef::getRelocatedSection() const { 00460 return OwningObject->getRelocatedSection(SectionPimpl); 00461 } 00462 00463 inline DataRefImpl SectionRef::getRawDataRefImpl() const { 00464 return SectionPimpl; 00465 } 00466 00467 /// RelocationRef 00468 inline RelocationRef::RelocationRef(DataRefImpl RelocationP, 00469 const ObjectFile *Owner) 00470 : RelocationPimpl(RelocationP) 00471 , OwningObject(Owner) {} 00472 00473 inline bool RelocationRef::operator==(const RelocationRef &Other) const { 00474 return RelocationPimpl == Other.RelocationPimpl; 00475 } 00476 00477 inline void RelocationRef::moveNext() { 00478 return OwningObject->moveRelocationNext(RelocationPimpl); 00479 } 00480 00481 inline std::error_code RelocationRef::getAddress(uint64_t &Result) const { 00482 return OwningObject->getRelocationAddress(RelocationPimpl, Result); 00483 } 00484 00485 inline std::error_code RelocationRef::getOffset(uint64_t &Result) const { 00486 return OwningObject->getRelocationOffset(RelocationPimpl, Result); 00487 } 00488 00489 inline symbol_iterator RelocationRef::getSymbol() const { 00490 return OwningObject->getRelocationSymbol(RelocationPimpl); 00491 } 00492 00493 inline std::error_code RelocationRef::getType(uint64_t &Result) const { 00494 return OwningObject->getRelocationType(RelocationPimpl, Result); 00495 } 00496 00497 inline std::error_code 00498 RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const { 00499 return OwningObject->getRelocationTypeName(RelocationPimpl, Result); 00500 } 00501 00502 inline std::error_code 00503 RelocationRef::getValueString(SmallVectorImpl<char> &Result) const { 00504 return OwningObject->getRelocationValueString(RelocationPimpl, Result); 00505 } 00506 00507 inline std::error_code RelocationRef::getHidden(bool &Result) const { 00508 return OwningObject->getRelocationHidden(RelocationPimpl, Result); 00509 } 00510 00511 inline DataRefImpl RelocationRef::getRawDataRefImpl() const { 00512 return RelocationPimpl; 00513 } 00514 00515 inline const ObjectFile *RelocationRef::getObjectFile() const { 00516 return OwningObject; 00517 } 00518 00519 00520 } // end namespace object 00521 } // end namespace llvm 00522 00523 #endif