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 26 namespace llvm { 27 namespace object { 28 29 class ObjectFile; 30 class COFFObjectFile; 31 class MachOObjectFile; 32 33 class SymbolRef; 34 class symbol_iterator; 35 class SectionRef; 36 typedef 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. 40 class RelocationRef { 41 DataRefImpl RelocationPimpl; 42 const ObjectFile *OwningObject; 43 44 public: 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 }; 65 typedef 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. 69 class SectionRef { 70 friend class SymbolRef; 71 DataRefImpl SectionPimpl; 72 const ObjectFile *OwningObject; 73 74 public: 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. 115 class SymbolRef : public BasicSymbolRef { 116 friend class SectionRef; 117 118 public: 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 156 class symbol_iterator : public basic_symbol_iterator { 157 public: 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. 177 class ObjectFile : public SymbolicFile { 178 virtual void anchor(); 179 ObjectFile() = delete; 180 ObjectFile(const ObjectFile &other) = delete; 181 182 protected: 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 241 public: 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. 308 inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner) 309 : BasicSymbolRef(SymbolP, Owner) {} 310 311 inline Expected<StringRef> SymbolRef::getName() const { 312 return getObject()->getSymbolName(getRawDataRefImpl()); 313 } 314 315 inline Expected<uint64_t> SymbolRef::getAddress() const { 316 return getObject()->getSymbolAddress(getRawDataRefImpl()); 317 } 318 319 inline uint64_t SymbolRef::getValue() const { 320 return getObject()->getSymbolValue(getRawDataRefImpl()); 321 } 322 323 inline uint32_t SymbolRef::getAlignment() const { 324 return getObject()->getSymbolAlignment(getRawDataRefImpl()); 325 } 326 327 inline uint64_t SymbolRef::getCommonSize() const { 328 return getObject()->getCommonSymbolSize(getRawDataRefImpl()); 329 } 330 331 inline Expected<section_iterator> SymbolRef::getSection() const { 332 return getObject()->getSymbolSection(getRawDataRefImpl()); 333 } 334 335 inline Expected<SymbolRef::Type> SymbolRef::getType() const { 336 return getObject()->getSymbolType(getRawDataRefImpl()); 337 } 338 339 inline const ObjectFile *SymbolRef::getObject() const { 340 const SymbolicFile *O = BasicSymbolRef::getObject(); 341 return cast<ObjectFile>(O); 342 } 343 344 345 /// SectionRef 346 inline SectionRef::SectionRef(DataRefImpl SectionP, 347 const ObjectFile *Owner) 348 : SectionPimpl(SectionP) 349 , OwningObject(Owner) {} 350 351 inline bool SectionRef::operator==(const SectionRef &Other) const { 352 return SectionPimpl == Other.SectionPimpl; 353 } 354 355 inline bool SectionRef::operator!=(const SectionRef &Other) const { 356 return SectionPimpl != Other.SectionPimpl; 357 } 358 359 inline bool SectionRef::operator<(const SectionRef &Other) const { 360 return SectionPimpl < Other.SectionPimpl; 361 } 362 363 inline void SectionRef::moveNext() { 364 return OwningObject->moveSectionNext(SectionPimpl); 365 } 366 367 inline std::error_code SectionRef::getName(StringRef &Result) const { 368 return OwningObject->getSectionName(SectionPimpl, Result); 369 } 370 371 inline uint64_t SectionRef::getAddress() const { 372 return OwningObject->getSectionAddress(SectionPimpl); 373 } 374 375 inline uint64_t SectionRef::getSize() const { 376 return OwningObject->getSectionSize(SectionPimpl); 377 } 378 379 inline std::error_code SectionRef::getContents(StringRef &Result) const { 380 return OwningObject->getSectionContents(SectionPimpl, Result); 381 } 382 383 inline uint64_t SectionRef::getAlignment() const { 384 return OwningObject->getSectionAlignment(SectionPimpl); 385 } 386 387 inline bool SectionRef::isCompressed() const { 388 return OwningObject->isSectionCompressed(SectionPimpl); 389 } 390 391 inline bool SectionRef::isText() const { 392 return OwningObject->isSectionText(SectionPimpl); 393 } 394 395 inline bool SectionRef::isData() const { 396 return OwningObject->isSectionData(SectionPimpl); 397 } 398 399 inline bool SectionRef::isBSS() const { 400 return OwningObject->isSectionBSS(SectionPimpl); 401 } 402 403 inline bool SectionRef::isVirtual() const { 404 return OwningObject->isSectionVirtual(SectionPimpl); 405 } 406 407 inline bool SectionRef::isBitcode() const { 408 return OwningObject->isSectionBitcode(SectionPimpl); 409 } 410 411 inline relocation_iterator SectionRef::relocation_begin() const { 412 return OwningObject->section_rel_begin(SectionPimpl); 413 } 414 415 inline relocation_iterator SectionRef::relocation_end() const { 416 return OwningObject->section_rel_end(SectionPimpl); 417 } 418 419 inline section_iterator SectionRef::getRelocatedSection() const { 420 return OwningObject->getRelocatedSection(SectionPimpl); 421 } 422 423 inline DataRefImpl SectionRef::getRawDataRefImpl() const { 424 return SectionPimpl; 425 } 426 427 inline const ObjectFile *SectionRef::getObject() const { 428 return OwningObject; 429 } 430 431 /// RelocationRef 432 inline RelocationRef::RelocationRef(DataRefImpl RelocationP, 433 const ObjectFile *Owner) 434 : RelocationPimpl(RelocationP) 435 , OwningObject(Owner) {} 436 437 inline bool RelocationRef::operator==(const RelocationRef &Other) const { 438 return RelocationPimpl == Other.RelocationPimpl; 439 } 440 441 inline void RelocationRef::moveNext() { 442 return OwningObject->moveRelocationNext(RelocationPimpl); 443 } 444 445 inline uint64_t RelocationRef::getOffset() const { 446 return OwningObject->getRelocationOffset(RelocationPimpl); 447 } 448 449 inline symbol_iterator RelocationRef::getSymbol() const { 450 return OwningObject->getRelocationSymbol(RelocationPimpl); 451 } 452 453 inline uint64_t RelocationRef::getType() const { 454 return OwningObject->getRelocationType(RelocationPimpl); 455 } 456 457 inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const { 458 return OwningObject->getRelocationTypeName(RelocationPimpl, Result); 459 } 460 461 inline DataRefImpl RelocationRef::getRawDataRefImpl() const { 462 return RelocationPimpl; 463 } 464 465 inline const ObjectFile *RelocationRef::getObject() const { 466 return OwningObject; 467 } 468 469 470 } // end namespace object 471 } // end namespace llvm 472 473 #endif 474