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_OBJECTFILE_H 15#define LLVM_OBJECT_OBJECTFILE_H 16 17#include "llvm/ADT/StringRef.h" 18#include "llvm/MC/SubtargetFeature.h" 19#include "llvm/Object/SymbolicFile.h" 20#include "llvm/Support/DataTypes.h" 21#include "llvm/Support/ErrorHandling.h" 22#include "llvm/Support/FileSystem.h" 23#include "llvm/Support/MemoryBuffer.h" 24#include <cstring> 25 26namespace llvm { 27namespace object { 28 29class ObjectFile; 30class COFFObjectFile; 31class MachOObjectFile; 32 33class SymbolRef; 34class symbol_iterator; 35class SectionRef; 36typedef content_iterator<SectionRef> section_iterator; 37 38/// This is a value type class that represents a single relocation in the list 39/// of relocations in the object file. 40class RelocationRef { 41 DataRefImpl RelocationPimpl; 42 const ObjectFile *OwningObject; 43 44public: 45 RelocationRef() : OwningObject(nullptr) { } 46 47 RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner); 48 49 bool operator==(const RelocationRef &Other) const; 50 51 void moveNext(); 52 53 uint64_t getOffset() const; 54 symbol_iterator getSymbol() const; 55 uint64_t getType() const; 56 57 /// @brief Get a string that represents the type of this relocation. 58 /// 59 /// This is for display purposes only. 60 void getTypeName(SmallVectorImpl<char> &Result) const; 61 62 DataRefImpl getRawDataRefImpl() const; 63 const ObjectFile *getObject() const; 64}; 65typedef content_iterator<RelocationRef> relocation_iterator; 66 67/// This is a value type class that represents a single section in the list of 68/// sections in the object file. 69class SectionRef { 70 friend class SymbolRef; 71 DataRefImpl SectionPimpl; 72 const ObjectFile *OwningObject; 73 74public: 75 SectionRef() : OwningObject(nullptr) { } 76 77 SectionRef(DataRefImpl SectionP, const ObjectFile *Owner); 78 79 bool operator==(const SectionRef &Other) const; 80 bool operator!=(const SectionRef &Other) const; 81 bool operator<(const SectionRef &Other) const; 82 83 void moveNext(); 84 85 std::error_code getName(StringRef &Result) const; 86 uint64_t getAddress() const; 87 uint64_t getSize() const; 88 std::error_code getContents(StringRef &Result) const; 89 90 /// @brief Get the alignment of this section as the actual value (not log 2). 91 uint64_t getAlignment() const; 92 93 bool isCompressed() const; 94 bool isText() const; 95 bool isData() const; 96 bool isBSS() const; 97 bool isVirtual() const; 98 bool isBitcode() const; 99 100 bool containsSymbol(SymbolRef S) const; 101 102 relocation_iterator relocation_begin() const; 103 relocation_iterator relocation_end() const; 104 iterator_range<relocation_iterator> relocations() const { 105 return make_range(relocation_begin(), relocation_end()); 106 } 107 section_iterator getRelocatedSection() const; 108 109 DataRefImpl getRawDataRefImpl() const; 110 const ObjectFile *getObject() const; 111}; 112 113/// This is a value type class that represents a single symbol in the list of 114/// symbols in the object file. 115class SymbolRef : public BasicSymbolRef { 116 friend class SectionRef; 117 118public: 119 SymbolRef() : BasicSymbolRef() {} 120 121 enum Type { 122 ST_Unknown, // Type not specified 123 ST_Data, 124 ST_Debug, 125 ST_File, 126 ST_Function, 127 ST_Other 128 }; 129 130 SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); 131 SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) { 132 assert(isa<ObjectFile>(BasicSymbolRef::getObject())); 133 } 134 135 Expected<StringRef> getName() const; 136 /// Returns the symbol virtual address (i.e. address at which it will be 137 /// mapped). 138 Expected<uint64_t> getAddress() const; 139 140 /// Return the value of the symbol depending on the object this can be an 141 /// offset or a virtual address. 142 uint64_t getValue() const; 143 144 /// @brief Get the alignment of this symbol as the actual value (not log 2). 145 uint32_t getAlignment() const; 146 uint64_t getCommonSize() const; 147 Expected<SymbolRef::Type> getType() const; 148 149 /// @brief Get section this symbol is defined in reference to. Result is 150 /// end_sections() if it is undefined or is an absolute symbol. 151 Expected<section_iterator> getSection() const; 152 153 const ObjectFile *getObject() const; 154}; 155 156class symbol_iterator : public basic_symbol_iterator { 157public: 158 symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {} 159 symbol_iterator(const basic_symbol_iterator &B) 160 : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(), 161 cast<ObjectFile>(B->getObject()))) {} 162 163 const SymbolRef *operator->() const { 164 const BasicSymbolRef &P = basic_symbol_iterator::operator *(); 165 return static_cast<const SymbolRef*>(&P); 166 } 167 168 const SymbolRef &operator*() const { 169 const BasicSymbolRef &P = basic_symbol_iterator::operator *(); 170 return static_cast<const SymbolRef&>(P); 171 } 172}; 173 174/// This class is the base class for all object file types. Concrete instances 175/// of this object are created by createObjectFile, which figures out which type 176/// to create. 177class ObjectFile : public SymbolicFile { 178 virtual void anchor(); 179 ObjectFile() = delete; 180 ObjectFile(const ObjectFile &other) = delete; 181 182protected: 183 ObjectFile(unsigned int Type, MemoryBufferRef Source); 184 185 const uint8_t *base() const { 186 return reinterpret_cast<const uint8_t *>(Data.getBufferStart()); 187 } 188 189 // These functions are for SymbolRef to call internally. The main goal of 190 // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol 191 // entry in the memory mapped object file. SymbolPimpl cannot contain any 192 // virtual functions because then it could not point into the memory mapped 193 // file. 194 // 195 // Implementations assume that the DataRefImpl is valid and has not been 196 // modified externally. It's UB otherwise. 197 friend class SymbolRef; 198 virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0; 199 std::error_code printSymbolName(raw_ostream &OS, 200 DataRefImpl Symb) const override; 201 virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0; 202 virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0; 203 virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const; 204 virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0; 205 virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0; 206 virtual Expected<section_iterator> 207 getSymbolSection(DataRefImpl Symb) const = 0; 208 209 // Same as above for SectionRef. 210 friend class SectionRef; 211 virtual void moveSectionNext(DataRefImpl &Sec) const = 0; 212 virtual std::error_code getSectionName(DataRefImpl Sec, 213 StringRef &Res) const = 0; 214 virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0; 215 virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0; 216 virtual std::error_code getSectionContents(DataRefImpl Sec, 217 StringRef &Res) const = 0; 218 virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0; 219 virtual bool isSectionCompressed(DataRefImpl Sec) const = 0; 220 virtual bool isSectionText(DataRefImpl Sec) const = 0; 221 virtual bool isSectionData(DataRefImpl Sec) const = 0; 222 virtual bool isSectionBSS(DataRefImpl Sec) const = 0; 223 // A section is 'virtual' if its contents aren't present in the object image. 224 virtual bool isSectionVirtual(DataRefImpl Sec) const = 0; 225 virtual bool isSectionBitcode(DataRefImpl Sec) const; 226 virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0; 227 virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0; 228 virtual section_iterator getRelocatedSection(DataRefImpl Sec) const; 229 230 // Same as above for RelocationRef. 231 friend class RelocationRef; 232 virtual void moveRelocationNext(DataRefImpl &Rel) const = 0; 233 virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0; 234 virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0; 235 virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0; 236 virtual void getRelocationTypeName(DataRefImpl Rel, 237 SmallVectorImpl<char> &Result) const = 0; 238 239 uint64_t getSymbolValue(DataRefImpl Symb) const; 240 241public: 242 uint64_t getCommonSymbolSize(DataRefImpl Symb) const { 243 assert(getSymbolFlags(Symb) & SymbolRef::SF_Common); 244 return getCommonSymbolSizeImpl(Symb); 245 } 246 247 typedef iterator_range<symbol_iterator> symbol_iterator_range; 248 symbol_iterator_range symbols() const { 249 return symbol_iterator_range(symbol_begin(), symbol_end()); 250 } 251 252 virtual section_iterator section_begin() const = 0; 253 virtual section_iterator section_end() const = 0; 254 255 typedef iterator_range<section_iterator> section_iterator_range; 256 section_iterator_range sections() const { 257 return section_iterator_range(section_begin(), section_end()); 258 } 259 260 /// @brief The number of bytes used to represent an address in this object 261 /// file format. 262 virtual uint8_t getBytesInAddress() const = 0; 263 264 virtual StringRef getFileFormatName() const = 0; 265 virtual /* Triple::ArchType */ unsigned getArch() const = 0; 266 virtual SubtargetFeatures getFeatures() const = 0; 267 268 /// Returns platform-specific object flags, if any. 269 virtual std::error_code getPlatformFlags(unsigned &Result) const { 270 Result = 0; 271 return object_error::invalid_file_type; 272 } 273 274 /// True if this is a relocatable object (.o/.obj). 275 virtual bool isRelocatableObject() const = 0; 276 277 /// @returns Pointer to ObjectFile subclass to handle this type of object. 278 /// @param ObjectPath The path to the object file. ObjectPath.isObject must 279 /// return true. 280 /// @brief Create ObjectFile from path. 281 static Expected<OwningBinary<ObjectFile>> 282 createObjectFile(StringRef ObjectPath); 283 284 static Expected<std::unique_ptr<ObjectFile>> 285 createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type); 286 static Expected<std::unique_ptr<ObjectFile>> 287 createObjectFile(MemoryBufferRef Object) { 288 return createObjectFile(Object, sys::fs::file_magic::unknown); 289 } 290 291 292 static inline bool classof(const Binary *v) { 293 return v->isObject(); 294 } 295 296 static ErrorOr<std::unique_ptr<COFFObjectFile>> 297 createCOFFObjectFile(MemoryBufferRef Object); 298 299 static ErrorOr<std::unique_ptr<ObjectFile>> 300 createELFObjectFile(MemoryBufferRef Object); 301 302 static Expected<std::unique_ptr<MachOObjectFile>> 303 createMachOObjectFile(MemoryBufferRef Object); 304 305}; 306 307// Inline function definitions. 308inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner) 309 : BasicSymbolRef(SymbolP, Owner) {} 310 311inline Expected<StringRef> SymbolRef::getName() const { 312 return getObject()->getSymbolName(getRawDataRefImpl()); 313} 314 315inline Expected<uint64_t> SymbolRef::getAddress() const { 316 return getObject()->getSymbolAddress(getRawDataRefImpl()); 317} 318 319inline uint64_t SymbolRef::getValue() const { 320 return getObject()->getSymbolValue(getRawDataRefImpl()); 321} 322 323inline uint32_t SymbolRef::getAlignment() const { 324 return getObject()->getSymbolAlignment(getRawDataRefImpl()); 325} 326 327inline uint64_t SymbolRef::getCommonSize() const { 328 return getObject()->getCommonSymbolSize(getRawDataRefImpl()); 329} 330 331inline Expected<section_iterator> SymbolRef::getSection() const { 332 return getObject()->getSymbolSection(getRawDataRefImpl()); 333} 334 335inline Expected<SymbolRef::Type> SymbolRef::getType() const { 336 return getObject()->getSymbolType(getRawDataRefImpl()); 337} 338 339inline const ObjectFile *SymbolRef::getObject() const { 340 const SymbolicFile *O = BasicSymbolRef::getObject(); 341 return cast<ObjectFile>(O); 342} 343 344 345/// SectionRef 346inline SectionRef::SectionRef(DataRefImpl SectionP, 347 const ObjectFile *Owner) 348 : SectionPimpl(SectionP) 349 , OwningObject(Owner) {} 350 351inline bool SectionRef::operator==(const SectionRef &Other) const { 352 return SectionPimpl == Other.SectionPimpl; 353} 354 355inline bool SectionRef::operator!=(const SectionRef &Other) const { 356 return SectionPimpl != Other.SectionPimpl; 357} 358 359inline bool SectionRef::operator<(const SectionRef &Other) const { 360 return SectionPimpl < Other.SectionPimpl; 361} 362 363inline void SectionRef::moveNext() { 364 return OwningObject->moveSectionNext(SectionPimpl); 365} 366 367inline std::error_code SectionRef::getName(StringRef &Result) const { 368 return OwningObject->getSectionName(SectionPimpl, Result); 369} 370 371inline uint64_t SectionRef::getAddress() const { 372 return OwningObject->getSectionAddress(SectionPimpl); 373} 374 375inline uint64_t SectionRef::getSize() const { 376 return OwningObject->getSectionSize(SectionPimpl); 377} 378 379inline std::error_code SectionRef::getContents(StringRef &Result) const { 380 return OwningObject->getSectionContents(SectionPimpl, Result); 381} 382 383inline uint64_t SectionRef::getAlignment() const { 384 return OwningObject->getSectionAlignment(SectionPimpl); 385} 386 387inline bool SectionRef::isCompressed() const { 388 return OwningObject->isSectionCompressed(SectionPimpl); 389} 390 391inline bool SectionRef::isText() const { 392 return OwningObject->isSectionText(SectionPimpl); 393} 394 395inline bool SectionRef::isData() const { 396 return OwningObject->isSectionData(SectionPimpl); 397} 398 399inline bool SectionRef::isBSS() const { 400 return OwningObject->isSectionBSS(SectionPimpl); 401} 402 403inline bool SectionRef::isVirtual() const { 404 return OwningObject->isSectionVirtual(SectionPimpl); 405} 406 407inline bool SectionRef::isBitcode() const { 408 return OwningObject->isSectionBitcode(SectionPimpl); 409} 410 411inline relocation_iterator SectionRef::relocation_begin() const { 412 return OwningObject->section_rel_begin(SectionPimpl); 413} 414 415inline relocation_iterator SectionRef::relocation_end() const { 416 return OwningObject->section_rel_end(SectionPimpl); 417} 418 419inline section_iterator SectionRef::getRelocatedSection() const { 420 return OwningObject->getRelocatedSection(SectionPimpl); 421} 422 423inline DataRefImpl SectionRef::getRawDataRefImpl() const { 424 return SectionPimpl; 425} 426 427inline const ObjectFile *SectionRef::getObject() const { 428 return OwningObject; 429} 430 431/// RelocationRef 432inline RelocationRef::RelocationRef(DataRefImpl RelocationP, 433 const ObjectFile *Owner) 434 : RelocationPimpl(RelocationP) 435 , OwningObject(Owner) {} 436 437inline bool RelocationRef::operator==(const RelocationRef &Other) const { 438 return RelocationPimpl == Other.RelocationPimpl; 439} 440 441inline void RelocationRef::moveNext() { 442 return OwningObject->moveRelocationNext(RelocationPimpl); 443} 444 445inline uint64_t RelocationRef::getOffset() const { 446 return OwningObject->getRelocationOffset(RelocationPimpl); 447} 448 449inline symbol_iterator RelocationRef::getSymbol() const { 450 return OwningObject->getRelocationSymbol(RelocationPimpl); 451} 452 453inline uint64_t RelocationRef::getType() const { 454 return OwningObject->getRelocationType(RelocationPimpl); 455} 456 457inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const { 458 return OwningObject->getRelocationTypeName(RelocationPimpl, Result); 459} 460 461inline DataRefImpl RelocationRef::getRawDataRefImpl() const { 462 return RelocationPimpl; 463} 464 465inline const ObjectFile *RelocationRef::getObject() const { 466 return OwningObject; 467} 468 469 470} // end namespace object 471} // end namespace llvm 472 473#endif 474