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/Object/Binary.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/Support/DataTypes.h" 20 #include "llvm/Support/ErrorHandling.h" 21 #include "llvm/Support/MemoryBuffer.h" 22 #include <cstring> 23 24 namespace llvm { 25 namespace object { 26 27 class ObjectFile; 28 29 union DataRefImpl { 30 struct { 31 // ELF needs this for relocations. This entire union should probably be a 32 // char[max(8, sizeof(uintptr_t))] and require the impl to cast. 33 uint16_t a, b; 34 uint32_t c; 35 } w; 36 struct { 37 uint32_t a, b; 38 } d; 39 uintptr_t p; 40 }; 41 42 template<class content_type> 43 class content_iterator { 44 content_type Current; 45 public: 46 content_iterator(content_type symb) 47 : Current(symb) {} 48 49 const content_type* operator->() const { 50 return &Current; 51 } 52 53 const content_type &operator*() const { 54 return Current; 55 } 56 57 bool operator==(const content_iterator &other) const { 58 return Current == other.Current; 59 } 60 61 bool operator!=(const content_iterator &other) const { 62 return !(*this == other); 63 } 64 65 content_iterator& increment(error_code &err) { 66 content_type next; 67 if (error_code ec = Current.getNext(next)) 68 err = ec; 69 else 70 Current = next; 71 return *this; 72 } 73 }; 74 75 static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) { 76 // Check bitwise identical. This is the only legal way to compare a union w/o 77 // knowing which member is in use. 78 return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0; 79 } 80 81 class SymbolRef; 82 83 /// RelocationRef - This is a value type class that represents a single 84 /// relocation in the list of relocations in the object file. 85 class RelocationRef { 86 DataRefImpl RelocationPimpl; 87 const ObjectFile *OwningObject; 88 89 public: 90 RelocationRef() : OwningObject(NULL) { 91 std::memset(&RelocationPimpl, 0, sizeof(RelocationPimpl)); 92 } 93 94 RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner); 95 96 bool operator==(const RelocationRef &Other) const; 97 98 error_code getNext(RelocationRef &Result) const; 99 100 error_code getAddress(uint64_t &Result) const; 101 error_code getSymbol(SymbolRef &Result) const; 102 error_code getType(uint32_t &Result) const; 103 104 /// @brief Get a string that represents the type of this relocation. 105 /// 106 /// This is for display purposes only. 107 error_code getTypeName(SmallVectorImpl<char> &Result) const; 108 error_code getAdditionalInfo(int64_t &Result) const; 109 110 /// @brief Get a string that represents the calculation of the value of this 111 /// relocation. 112 /// 113 /// This is for display purposes only. 114 error_code getValueString(SmallVectorImpl<char> &Result) const; 115 }; 116 typedef content_iterator<RelocationRef> relocation_iterator; 117 118 /// SectionRef - This is a value type class that represents a single section in 119 /// the list of sections in the object file. 120 class SectionRef { 121 friend class SymbolRef; 122 DataRefImpl SectionPimpl; 123 const ObjectFile *OwningObject; 124 125 public: 126 SectionRef() : OwningObject(NULL) { 127 std::memset(&SectionPimpl, 0, sizeof(SectionPimpl)); 128 } 129 130 SectionRef(DataRefImpl SectionP, const ObjectFile *Owner); 131 132 bool operator==(const SectionRef &Other) const; 133 134 error_code getNext(SectionRef &Result) const; 135 136 error_code getName(StringRef &Result) const; 137 error_code getAddress(uint64_t &Result) const; 138 error_code getSize(uint64_t &Result) const; 139 error_code getContents(StringRef &Result) const; 140 141 /// @brief Get the alignment of this section as the actual value (not log 2). 142 error_code getAlignment(uint64_t &Result) const; 143 144 // FIXME: Move to the normalization layer when it's created. 145 error_code isText(bool &Result) const; 146 error_code isData(bool &Result) const; 147 error_code isBSS(bool &Result) const; 148 149 error_code containsSymbol(SymbolRef S, bool &Result) const; 150 151 relocation_iterator begin_relocations() const; 152 relocation_iterator end_relocations() const; 153 }; 154 typedef content_iterator<SectionRef> section_iterator; 155 156 /// SymbolRef - This is a value type class that represents a single symbol in 157 /// the list of symbols in the object file. 158 class SymbolRef { 159 friend class SectionRef; 160 DataRefImpl SymbolPimpl; 161 const ObjectFile *OwningObject; 162 163 public: 164 SymbolRef() : OwningObject(NULL) { 165 std::memset(&SymbolPimpl, 0, sizeof(SymbolPimpl)); 166 } 167 168 enum Type { 169 ST_Data, 170 ST_Debug, 171 ST_External, // Defined in another object file 172 ST_File, 173 ST_Function, 174 ST_Other 175 }; 176 177 SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); 178 179 bool operator==(const SymbolRef &Other) const; 180 181 error_code getNext(SymbolRef &Result) const; 182 183 error_code getName(StringRef &Result) const; 184 error_code getAddress(uint64_t &Result) const; 185 error_code getOffset(uint64_t &Result) const; 186 error_code getSize(uint64_t &Result) const; 187 error_code getType(SymbolRef::Type &Result) const; 188 189 /// Returns the ascii char that should be displayed in a symbol table dump via 190 /// nm for this symbol. 191 error_code getNMTypeChar(char &Result) const; 192 193 /// Returns true for symbols that are internal to the object file format such 194 /// as section symbols. 195 error_code isInternal(bool &Result) const; 196 197 /// Returns true for symbols that can be used in another objects, 198 /// such as library functions 199 error_code isGlobal(bool &Result) const; 200 201 /// Returns true for weak symbols. 202 error_code isWeak(bool &Result) const; 203 204 /// @brief Return true for absolute symbols. 205 error_code isAbsolute(bool &Result) const; 206 207 /// @brief Get section this symbol is defined in reference to. Result is 208 /// end_sections() if it is undefined or is an absolute symbol. 209 error_code getSection(section_iterator &Result) const; 210 211 DataRefImpl getRawDataRefImpl() const; 212 }; 213 typedef content_iterator<SymbolRef> symbol_iterator; 214 215 const uint64_t UnknownAddressOrSize = ~0ULL; 216 217 /// ObjectFile - This class is the base class for all object file types. 218 /// Concrete instances of this object are created by createObjectFile, which 219 /// figure out which type to create. 220 class ObjectFile : public Binary { 221 private: 222 ObjectFile(); // = delete 223 ObjectFile(const ObjectFile &other); // = delete 224 225 protected: 226 ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec); 227 228 const uint8_t *base() const { 229 return reinterpret_cast<const uint8_t *>(Data->getBufferStart()); 230 } 231 232 // These functions are for SymbolRef to call internally. The main goal of 233 // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol 234 // entry in the memory mapped object file. SymbolPimpl cannot contain any 235 // virtual functions because then it could not point into the memory mapped 236 // file. 237 // 238 // Implementations assume that the DataRefImpl is valid and has not been 239 // modified externally. It's UB otherwise. 240 friend class SymbolRef; 241 virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0; 242 virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0; 243 virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const =0; 244 virtual error_code getSymbolOffset(DataRefImpl Symb, uint64_t &Res) const =0; 245 virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0; 246 virtual error_code getSymbolType(DataRefImpl Symb, 247 SymbolRef::Type &Res) const = 0; 248 virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0; 249 virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const = 0; 250 virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const = 0; 251 virtual error_code isSymbolWeak(DataRefImpl Symb, bool &Res) const = 0; 252 virtual error_code isSymbolAbsolute(DataRefImpl Symb, bool &Res) const = 0; 253 virtual error_code getSymbolSection(DataRefImpl Symb, 254 section_iterator &Res) const = 0; 255 256 // Same as above for SectionRef. 257 friend class SectionRef; 258 virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const = 0; 259 virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0; 260 virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0; 261 virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0; 262 virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)const=0; 263 virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res)const=0; 264 virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0; 265 virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0; 266 virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0; 267 virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, 268 bool &Result) const = 0; 269 virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const = 0; 270 virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const = 0; 271 272 273 // Same as above for RelocationRef. 274 friend class RelocationRef; 275 virtual error_code getRelocationNext(DataRefImpl Rel, 276 RelocationRef &Res) const = 0; 277 virtual error_code getRelocationAddress(DataRefImpl Rel, 278 uint64_t &Res) const =0; 279 virtual error_code getRelocationSymbol(DataRefImpl Rel, 280 SymbolRef &Res) const = 0; 281 virtual error_code getRelocationType(DataRefImpl Rel, 282 uint32_t &Res) const = 0; 283 virtual error_code getRelocationTypeName(DataRefImpl Rel, 284 SmallVectorImpl<char> &Result) const = 0; 285 virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, 286 int64_t &Res) const = 0; 287 virtual error_code getRelocationValueString(DataRefImpl Rel, 288 SmallVectorImpl<char> &Result) const = 0; 289 290 public: 291 292 virtual symbol_iterator begin_symbols() const = 0; 293 virtual symbol_iterator end_symbols() const = 0; 294 295 virtual section_iterator begin_sections() const = 0; 296 virtual section_iterator end_sections() const = 0; 297 298 /// @brief The number of bytes used to represent an address in this object 299 /// file format. 300 virtual uint8_t getBytesInAddress() const = 0; 301 302 virtual StringRef getFileFormatName() const = 0; 303 virtual /* Triple::ArchType */ unsigned getArch() const = 0; 304 305 /// @returns Pointer to ObjectFile subclass to handle this type of object. 306 /// @param ObjectPath The path to the object file. ObjectPath.isObject must 307 /// return true. 308 /// @brief Create ObjectFile from path. 309 static ObjectFile *createObjectFile(StringRef ObjectPath); 310 static ObjectFile *createObjectFile(MemoryBuffer *Object); 311 312 static inline bool classof(const Binary *v) { 313 return v->getType() >= isObject && 314 v->getType() < lastObject; 315 } 316 static inline bool classof(const ObjectFile *v) { return true; } 317 318 public: 319 static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object); 320 static ObjectFile *createELFObjectFile(MemoryBuffer *Object); 321 static ObjectFile *createMachOObjectFile(MemoryBuffer *Object); 322 }; 323 324 // Inline function definitions. 325 inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner) 326 : SymbolPimpl(SymbolP) 327 , OwningObject(Owner) {} 328 329 inline bool SymbolRef::operator==(const SymbolRef &Other) const { 330 return SymbolPimpl == Other.SymbolPimpl; 331 } 332 333 inline error_code SymbolRef::getNext(SymbolRef &Result) const { 334 return OwningObject->getSymbolNext(SymbolPimpl, Result); 335 } 336 337 inline error_code SymbolRef::getName(StringRef &Result) const { 338 return OwningObject->getSymbolName(SymbolPimpl, Result); 339 } 340 341 inline error_code SymbolRef::getAddress(uint64_t &Result) const { 342 return OwningObject->getSymbolAddress(SymbolPimpl, Result); 343 } 344 345 inline error_code SymbolRef::getOffset(uint64_t &Result) const { 346 return OwningObject->getSymbolOffset(SymbolPimpl, Result); 347 } 348 349 inline error_code SymbolRef::getSize(uint64_t &Result) const { 350 return OwningObject->getSymbolSize(SymbolPimpl, Result); 351 } 352 353 inline error_code SymbolRef::getNMTypeChar(char &Result) const { 354 return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result); 355 } 356 357 inline error_code SymbolRef::isInternal(bool &Result) const { 358 return OwningObject->isSymbolInternal(SymbolPimpl, Result); 359 } 360 361 inline error_code SymbolRef::isGlobal(bool &Result) const { 362 return OwningObject->isSymbolGlobal(SymbolPimpl, Result); 363 } 364 365 inline error_code SymbolRef::isWeak(bool &Result) const { 366 return OwningObject->isSymbolWeak(SymbolPimpl, Result); 367 } 368 369 inline error_code SymbolRef::isAbsolute(bool &Result) const { 370 return OwningObject->isSymbolAbsolute(SymbolPimpl, Result); 371 } 372 373 inline error_code SymbolRef::getSection(section_iterator &Result) const { 374 return OwningObject->getSymbolSection(SymbolPimpl, Result); 375 } 376 377 inline error_code SymbolRef::getType(SymbolRef::Type &Result) const { 378 return OwningObject->getSymbolType(SymbolPimpl, Result); 379 } 380 381 inline DataRefImpl SymbolRef::getRawDataRefImpl() const { 382 return SymbolPimpl; 383 } 384 385 386 /// SectionRef 387 inline SectionRef::SectionRef(DataRefImpl SectionP, 388 const ObjectFile *Owner) 389 : SectionPimpl(SectionP) 390 , OwningObject(Owner) {} 391 392 inline bool SectionRef::operator==(const SectionRef &Other) const { 393 return SectionPimpl == Other.SectionPimpl; 394 } 395 396 inline error_code SectionRef::getNext(SectionRef &Result) const { 397 return OwningObject->getSectionNext(SectionPimpl, Result); 398 } 399 400 inline error_code SectionRef::getName(StringRef &Result) const { 401 return OwningObject->getSectionName(SectionPimpl, Result); 402 } 403 404 inline error_code SectionRef::getAddress(uint64_t &Result) const { 405 return OwningObject->getSectionAddress(SectionPimpl, Result); 406 } 407 408 inline error_code SectionRef::getSize(uint64_t &Result) const { 409 return OwningObject->getSectionSize(SectionPimpl, Result); 410 } 411 412 inline error_code SectionRef::getContents(StringRef &Result) const { 413 return OwningObject->getSectionContents(SectionPimpl, Result); 414 } 415 416 inline error_code SectionRef::getAlignment(uint64_t &Result) const { 417 return OwningObject->getSectionAlignment(SectionPimpl, Result); 418 } 419 420 inline error_code SectionRef::isText(bool &Result) const { 421 return OwningObject->isSectionText(SectionPimpl, Result); 422 } 423 424 inline error_code SectionRef::isData(bool &Result) const { 425 return OwningObject->isSectionData(SectionPimpl, Result); 426 } 427 428 inline error_code SectionRef::isBSS(bool &Result) const { 429 return OwningObject->isSectionBSS(SectionPimpl, Result); 430 } 431 432 inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const { 433 return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl, 434 Result); 435 } 436 437 inline relocation_iterator SectionRef::begin_relocations() const { 438 return OwningObject->getSectionRelBegin(SectionPimpl); 439 } 440 441 inline relocation_iterator SectionRef::end_relocations() const { 442 return OwningObject->getSectionRelEnd(SectionPimpl); 443 } 444 445 446 /// RelocationRef 447 inline RelocationRef::RelocationRef(DataRefImpl RelocationP, 448 const ObjectFile *Owner) 449 : RelocationPimpl(RelocationP) 450 , OwningObject(Owner) {} 451 452 inline bool RelocationRef::operator==(const RelocationRef &Other) const { 453 return RelocationPimpl == Other.RelocationPimpl; 454 } 455 456 inline error_code RelocationRef::getNext(RelocationRef &Result) const { 457 return OwningObject->getRelocationNext(RelocationPimpl, Result); 458 } 459 460 inline error_code RelocationRef::getAddress(uint64_t &Result) const { 461 return OwningObject->getRelocationAddress(RelocationPimpl, Result); 462 } 463 464 inline error_code RelocationRef::getSymbol(SymbolRef &Result) const { 465 return OwningObject->getRelocationSymbol(RelocationPimpl, Result); 466 } 467 468 inline error_code RelocationRef::getType(uint32_t &Result) const { 469 return OwningObject->getRelocationType(RelocationPimpl, Result); 470 } 471 472 inline error_code RelocationRef::getTypeName(SmallVectorImpl<char> &Result) 473 const { 474 return OwningObject->getRelocationTypeName(RelocationPimpl, Result); 475 } 476 477 inline error_code RelocationRef::getAdditionalInfo(int64_t &Result) const { 478 return OwningObject->getRelocationAdditionalInfo(RelocationPimpl, Result); 479 } 480 481 inline error_code RelocationRef::getValueString(SmallVectorImpl<char> &Result) 482 const { 483 return OwningObject->getRelocationValueString(RelocationPimpl, Result); 484 } 485 486 } // end namespace object 487 } // end namespace llvm 488 489 #endif 490