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