1 //===- ELFObjectFile.h - ELF object file implementation ---------*- 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 the ELFObjectFile template class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_OBJECT_ELFOBJECTFILE_H 15 #define LLVM_OBJECT_ELFOBJECTFILE_H 16 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/ADT/Triple.h" 21 #include "llvm/ADT/iterator_range.h" 22 #include "llvm/MC/SubtargetFeature.h" 23 #include "llvm/Object/Binary.h" 24 #include "llvm/Object/ELF.h" 25 #include "llvm/Object/ELFTypes.h" 26 #include "llvm/Object/Error.h" 27 #include "llvm/Object/ObjectFile.h" 28 #include "llvm/Object/SymbolicFile.h" 29 #include "llvm/Support/Casting.h" 30 #include "llvm/Support/ELF.h" 31 #include "llvm/Support/Endian.h" 32 #include "llvm/Support/Error.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include "llvm/Support/ErrorOr.h" 35 #include "llvm/Support/MemoryBuffer.h" 36 #include <cassert> 37 #include <cstdint> 38 #include <system_error> 39 40 namespace llvm { 41 namespace object { 42 43 class elf_symbol_iterator; 44 class ELFSymbolRef; 45 class ELFRelocationRef; 46 47 class ELFObjectFileBase : public ObjectFile { 48 friend class ELFSymbolRef; 49 friend class ELFSectionRef; 50 friend class ELFRelocationRef; 51 52 protected: 53 ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source); 54 55 virtual uint16_t getEMachine() const = 0; 56 virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; 57 virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0; 58 virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0; 59 60 virtual uint32_t getSectionType(DataRefImpl Sec) const = 0; 61 virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0; 62 63 virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0; 64 65 public: 66 typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range; 67 virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0; 68 69 elf_symbol_iterator_range symbols() const; 70 71 static inline bool classof(const Binary *v) { return v->isELF(); } 72 73 SubtargetFeatures getFeatures() const override; 74 }; 75 76 class ELFSectionRef : public SectionRef { 77 public: 78 ELFSectionRef(const SectionRef &B) : SectionRef(B) { 79 assert(isa<ELFObjectFileBase>(SectionRef::getObject())); 80 } 81 82 const ELFObjectFileBase *getObject() const { 83 return cast<ELFObjectFileBase>(SectionRef::getObject()); 84 } 85 86 uint32_t getType() const { 87 return getObject()->getSectionType(getRawDataRefImpl()); 88 } 89 90 uint64_t getFlags() const { 91 return getObject()->getSectionFlags(getRawDataRefImpl()); 92 } 93 }; 94 95 class elf_section_iterator : public section_iterator { 96 public: 97 elf_section_iterator(const section_iterator &B) : section_iterator(B) { 98 assert(isa<ELFObjectFileBase>(B->getObject())); 99 } 100 101 const ELFSectionRef *operator->() const { 102 return static_cast<const ELFSectionRef *>(section_iterator::operator->()); 103 } 104 105 const ELFSectionRef &operator*() const { 106 return static_cast<const ELFSectionRef &>(section_iterator::operator*()); 107 } 108 }; 109 110 class ELFSymbolRef : public SymbolRef { 111 public: 112 ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) { 113 assert(isa<ELFObjectFileBase>(SymbolRef::getObject())); 114 } 115 116 const ELFObjectFileBase *getObject() const { 117 return cast<ELFObjectFileBase>(BasicSymbolRef::getObject()); 118 } 119 120 uint64_t getSize() const { 121 return getObject()->getSymbolSize(getRawDataRefImpl()); 122 } 123 124 uint8_t getOther() const { 125 return getObject()->getSymbolOther(getRawDataRefImpl()); 126 } 127 128 uint8_t getELFType() const { 129 return getObject()->getSymbolELFType(getRawDataRefImpl()); 130 } 131 }; 132 133 class elf_symbol_iterator : public symbol_iterator { 134 public: 135 elf_symbol_iterator(const basic_symbol_iterator &B) 136 : symbol_iterator(SymbolRef(B->getRawDataRefImpl(), 137 cast<ELFObjectFileBase>(B->getObject()))) {} 138 139 const ELFSymbolRef *operator->() const { 140 return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->()); 141 } 142 143 const ELFSymbolRef &operator*() const { 144 return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*()); 145 } 146 }; 147 148 class ELFRelocationRef : public RelocationRef { 149 public: 150 ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) { 151 assert(isa<ELFObjectFileBase>(RelocationRef::getObject())); 152 } 153 154 const ELFObjectFileBase *getObject() const { 155 return cast<ELFObjectFileBase>(RelocationRef::getObject()); 156 } 157 158 ErrorOr<int64_t> getAddend() const { 159 return getObject()->getRelocationAddend(getRawDataRefImpl()); 160 } 161 }; 162 163 class elf_relocation_iterator : public relocation_iterator { 164 public: 165 elf_relocation_iterator(const relocation_iterator &B) 166 : relocation_iterator(RelocationRef( 167 B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {} 168 169 const ELFRelocationRef *operator->() const { 170 return static_cast<const ELFRelocationRef *>( 171 relocation_iterator::operator->()); 172 } 173 174 const ELFRelocationRef &operator*() const { 175 return static_cast<const ELFRelocationRef &>( 176 relocation_iterator::operator*()); 177 } 178 }; 179 180 inline ELFObjectFileBase::elf_symbol_iterator_range 181 ELFObjectFileBase::symbols() const { 182 return elf_symbol_iterator_range(symbol_begin(), symbol_end()); 183 } 184 185 template <class ELFT> class ELFObjectFile : public ELFObjectFileBase { 186 uint16_t getEMachine() const override; 187 uint64_t getSymbolSize(DataRefImpl Sym) const override; 188 189 public: 190 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 191 192 typedef typename ELFFile<ELFT>::uintX_t uintX_t; 193 194 typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; 195 typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 196 typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr; 197 typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel; 198 typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela; 199 typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; 200 201 protected: 202 ELFFile<ELFT> EF; 203 204 const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section. 205 const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section. 206 ArrayRef<Elf_Word> ShndxTable; 207 208 void moveSymbolNext(DataRefImpl &Symb) const override; 209 Expected<StringRef> getSymbolName(DataRefImpl Symb) const override; 210 Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override; 211 uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; 212 uint32_t getSymbolAlignment(DataRefImpl Symb) const override; 213 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; 214 uint32_t getSymbolFlags(DataRefImpl Symb) const override; 215 uint8_t getSymbolOther(DataRefImpl Symb) const override; 216 uint8_t getSymbolELFType(DataRefImpl Symb) const override; 217 Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override; 218 Expected<section_iterator> getSymbolSection(const Elf_Sym *Symb, 219 const Elf_Shdr *SymTab) const; 220 Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override; 221 222 void moveSectionNext(DataRefImpl &Sec) const override; 223 std::error_code getSectionName(DataRefImpl Sec, 224 StringRef &Res) const override; 225 uint64_t getSectionAddress(DataRefImpl Sec) const override; 226 uint64_t getSectionSize(DataRefImpl Sec) const override; 227 std::error_code getSectionContents(DataRefImpl Sec, 228 StringRef &Res) const override; 229 uint64_t getSectionAlignment(DataRefImpl Sec) const override; 230 bool isSectionCompressed(DataRefImpl Sec) const override; 231 bool isSectionText(DataRefImpl Sec) const override; 232 bool isSectionData(DataRefImpl Sec) const override; 233 bool isSectionBSS(DataRefImpl Sec) const override; 234 bool isSectionVirtual(DataRefImpl Sec) const override; 235 relocation_iterator section_rel_begin(DataRefImpl Sec) const override; 236 relocation_iterator section_rel_end(DataRefImpl Sec) const override; 237 section_iterator getRelocatedSection(DataRefImpl Sec) const override; 238 239 void moveRelocationNext(DataRefImpl &Rel) const override; 240 uint64_t getRelocationOffset(DataRefImpl Rel) const override; 241 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; 242 uint64_t getRelocationType(DataRefImpl Rel) const override; 243 void getRelocationTypeName(DataRefImpl Rel, 244 SmallVectorImpl<char> &Result) const override; 245 246 uint32_t getSectionType(DataRefImpl Sec) const override; 247 uint64_t getSectionFlags(DataRefImpl Sec) const override; 248 StringRef getRelocationTypeName(uint32_t Type) const; 249 250 /// \brief Get the relocation section that contains \a Rel. 251 const Elf_Shdr *getRelSection(DataRefImpl Rel) const { 252 return *EF.getSection(Rel.d.a); 253 } 254 255 DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const { 256 DataRefImpl DRI; 257 if (!SymTable) { 258 DRI.d.a = 0; 259 DRI.d.b = 0; 260 return DRI; 261 } 262 assert(SymTable->sh_type == ELF::SHT_SYMTAB || 263 SymTable->sh_type == ELF::SHT_DYNSYM); 264 265 uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin()); 266 unsigned SymTableIndex = 267 (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr); 268 269 DRI.d.a = SymTableIndex; 270 DRI.d.b = SymbolNum; 271 return DRI; 272 } 273 274 const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const { 275 return reinterpret_cast<const Elf_Shdr *>(Sec.p); 276 } 277 278 DataRefImpl toDRI(const Elf_Shdr *Sec) const { 279 DataRefImpl DRI; 280 DRI.p = reinterpret_cast<uintptr_t>(Sec); 281 return DRI; 282 } 283 284 DataRefImpl toDRI(const Elf_Dyn *Dyn) const { 285 DataRefImpl DRI; 286 DRI.p = reinterpret_cast<uintptr_t>(Dyn); 287 return DRI; 288 } 289 290 bool isExportedToOtherDSO(const Elf_Sym *ESym) const { 291 unsigned char Binding = ESym->getBinding(); 292 unsigned char Visibility = ESym->getVisibility(); 293 294 // A symbol is exported if its binding is either GLOBAL or WEAK, and its 295 // visibility is either DEFAULT or PROTECTED. All other symbols are not 296 // exported. 297 return ((Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK) && 298 (Visibility == ELF::STV_DEFAULT || 299 Visibility == ELF::STV_PROTECTED)); 300 } 301 302 // This flag is used for classof, to distinguish ELFObjectFile from 303 // its subclass. If more subclasses will be created, this flag will 304 // have to become an enum. 305 bool isDyldELFObject; 306 307 public: 308 ELFObjectFile(MemoryBufferRef Object, std::error_code &EC); 309 310 const Elf_Rel *getRel(DataRefImpl Rel) const; 311 const Elf_Rela *getRela(DataRefImpl Rela) const; 312 313 const Elf_Sym *getSymbol(DataRefImpl Sym) const { 314 return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b); 315 } 316 317 const Elf_Shdr *getSection(DataRefImpl Sec) const { 318 return reinterpret_cast<const Elf_Shdr *>(Sec.p); 319 } 320 321 basic_symbol_iterator symbol_begin_impl() const override; 322 basic_symbol_iterator symbol_end_impl() const override; 323 324 elf_symbol_iterator dynamic_symbol_begin() const; 325 elf_symbol_iterator dynamic_symbol_end() const; 326 327 section_iterator section_begin() const override; 328 section_iterator section_end() const override; 329 330 ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const override; 331 332 uint8_t getBytesInAddress() const override; 333 StringRef getFileFormatName() const override; 334 unsigned getArch() const override; 335 336 std::error_code getPlatformFlags(unsigned &Result) const override { 337 Result = EF.getHeader()->e_flags; 338 return std::error_code(); 339 } 340 341 const ELFFile<ELFT> *getELFFile() const { return &EF; } 342 343 bool isDyldType() const { return isDyldELFObject; } 344 static inline bool classof(const Binary *v) { 345 return v->getType() == getELFType(ELFT::TargetEndianness == support::little, 346 ELFT::Is64Bits); 347 } 348 349 elf_symbol_iterator_range getDynamicSymbolIterators() const override; 350 351 bool isRelocatableObject() const override; 352 }; 353 354 typedef ELFObjectFile<ELFType<support::little, false>> ELF32LEObjectFile; 355 typedef ELFObjectFile<ELFType<support::little, true>> ELF64LEObjectFile; 356 typedef ELFObjectFile<ELFType<support::big, false>> ELF32BEObjectFile; 357 typedef ELFObjectFile<ELFType<support::big, true>> ELF64BEObjectFile; 358 359 template <class ELFT> 360 void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const { 361 ++Sym.d.b; 362 } 363 364 template <class ELFT> 365 Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const { 366 const Elf_Sym *ESym = getSymbol(Sym); 367 const Elf_Shdr *SymTableSec = *EF.getSection(Sym.d.a); 368 const Elf_Shdr *StringTableSec = *EF.getSection(SymTableSec->sh_link); 369 StringRef SymTable = *EF.getStringTable(StringTableSec); 370 return ESym->getName(SymTable); 371 } 372 373 template <class ELFT> 374 uint64_t ELFObjectFile<ELFT>::getSectionFlags(DataRefImpl Sec) const { 375 return getSection(Sec)->sh_flags; 376 } 377 378 template <class ELFT> 379 uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const { 380 return getSection(Sec)->sh_type; 381 } 382 383 template <class ELFT> 384 uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const { 385 const Elf_Sym *ESym = getSymbol(Symb); 386 uint64_t Ret = ESym->st_value; 387 if (ESym->st_shndx == ELF::SHN_ABS) 388 return Ret; 389 390 const Elf_Ehdr *Header = EF.getHeader(); 391 // Clear the ARM/Thumb or microMIPS indicator flag. 392 if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) && 393 ESym->getType() == ELF::STT_FUNC) 394 Ret &= ~1; 395 396 return Ret; 397 } 398 399 template <class ELFT> 400 Expected<uint64_t> 401 ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const { 402 uint64_t Result = getSymbolValue(Symb); 403 const Elf_Sym *ESym = getSymbol(Symb); 404 switch (ESym->st_shndx) { 405 case ELF::SHN_COMMON: 406 case ELF::SHN_UNDEF: 407 case ELF::SHN_ABS: 408 return Result; 409 } 410 411 const Elf_Ehdr *Header = EF.getHeader(); 412 const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a); 413 414 if (Header->e_type == ELF::ET_REL) { 415 ErrorOr<const Elf_Shdr *> SectionOrErr = 416 EF.getSection(ESym, SymTab, ShndxTable); 417 if (std::error_code EC = SectionOrErr.getError()) 418 return errorCodeToError(EC); 419 const Elf_Shdr *Section = *SectionOrErr; 420 if (Section) 421 Result += Section->sh_addr; 422 } 423 424 return Result; 425 } 426 427 template <class ELFT> 428 uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const { 429 const Elf_Sym *Sym = getSymbol(Symb); 430 if (Sym->st_shndx == ELF::SHN_COMMON) 431 return Sym->st_value; 432 return 0; 433 } 434 435 template <class ELFT> 436 uint16_t ELFObjectFile<ELFT>::getEMachine() const { 437 return EF.getHeader()->e_machine; 438 } 439 440 template <class ELFT> 441 uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const { 442 return getSymbol(Sym)->st_size; 443 } 444 445 template <class ELFT> 446 uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const { 447 return getSymbol(Symb)->st_size; 448 } 449 450 template <class ELFT> 451 uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const { 452 return getSymbol(Symb)->st_other; 453 } 454 455 template <class ELFT> 456 uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const { 457 return getSymbol(Symb)->getType(); 458 } 459 460 template <class ELFT> 461 Expected<SymbolRef::Type> 462 ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const { 463 const Elf_Sym *ESym = getSymbol(Symb); 464 465 switch (ESym->getType()) { 466 case ELF::STT_NOTYPE: 467 return SymbolRef::ST_Unknown; 468 case ELF::STT_SECTION: 469 return SymbolRef::ST_Debug; 470 case ELF::STT_FILE: 471 return SymbolRef::ST_File; 472 case ELF::STT_FUNC: 473 return SymbolRef::ST_Function; 474 case ELF::STT_OBJECT: 475 case ELF::STT_COMMON: 476 case ELF::STT_TLS: 477 return SymbolRef::ST_Data; 478 default: 479 return SymbolRef::ST_Other; 480 } 481 } 482 483 template <class ELFT> 484 uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const { 485 const Elf_Sym *ESym = getSymbol(Sym); 486 487 uint32_t Result = SymbolRef::SF_None; 488 489 if (ESym->getBinding() != ELF::STB_LOCAL) 490 Result |= SymbolRef::SF_Global; 491 492 if (ESym->getBinding() == ELF::STB_WEAK) 493 Result |= SymbolRef::SF_Weak; 494 495 if (ESym->st_shndx == ELF::SHN_ABS) 496 Result |= SymbolRef::SF_Absolute; 497 498 if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION || 499 ESym == EF.symbol_begin(DotSymtabSec) || 500 ESym == EF.symbol_begin(DotDynSymSec)) 501 Result |= SymbolRef::SF_FormatSpecific; 502 503 if (EF.getHeader()->e_machine == ELF::EM_ARM) { 504 if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) { 505 StringRef Name = *NameOrErr; 506 if (Name.startswith("$d") || Name.startswith("$t") || 507 Name.startswith("$a")) 508 Result |= SymbolRef::SF_FormatSpecific; 509 } else { 510 // TODO: Actually report errors helpfully. 511 consumeError(NameOrErr.takeError()); 512 } 513 if (ESym->getType() == ELF::STT_FUNC && (ESym->st_value & 1) == 1) 514 Result |= SymbolRef::SF_Thumb; 515 } 516 517 if (ESym->st_shndx == ELF::SHN_UNDEF) 518 Result |= SymbolRef::SF_Undefined; 519 520 if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON) 521 Result |= SymbolRef::SF_Common; 522 523 if (isExportedToOtherDSO(ESym)) 524 Result |= SymbolRef::SF_Exported; 525 526 if (ESym->getVisibility() == ELF::STV_HIDDEN) 527 Result |= SymbolRef::SF_Hidden; 528 529 return Result; 530 } 531 532 template <class ELFT> 533 Expected<section_iterator> 534 ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym, 535 const Elf_Shdr *SymTab) const { 536 ErrorOr<const Elf_Shdr *> ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable); 537 if (std::error_code EC = ESecOrErr.getError()) 538 return errorCodeToError(EC); 539 540 const Elf_Shdr *ESec = *ESecOrErr; 541 if (!ESec) 542 return section_end(); 543 544 DataRefImpl Sec; 545 Sec.p = reinterpret_cast<intptr_t>(ESec); 546 return section_iterator(SectionRef(Sec, this)); 547 } 548 549 template <class ELFT> 550 Expected<section_iterator> 551 ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const { 552 const Elf_Sym *Sym = getSymbol(Symb); 553 const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a); 554 return getSymbolSection(Sym, SymTab); 555 } 556 557 template <class ELFT> 558 void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const { 559 const Elf_Shdr *ESec = getSection(Sec); 560 Sec = toDRI(++ESec); 561 } 562 563 template <class ELFT> 564 std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, 565 StringRef &Result) const { 566 ErrorOr<StringRef> Name = EF.getSectionName(&*getSection(Sec)); 567 if (!Name) 568 return Name.getError(); 569 Result = *Name; 570 return std::error_code(); 571 } 572 573 template <class ELFT> 574 uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const { 575 return getSection(Sec)->sh_addr; 576 } 577 578 template <class ELFT> 579 uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const { 580 return getSection(Sec)->sh_size; 581 } 582 583 template <class ELFT> 584 std::error_code 585 ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec, 586 StringRef &Result) const { 587 const Elf_Shdr *EShdr = getSection(Sec); 588 Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size); 589 return std::error_code(); 590 } 591 592 template <class ELFT> 593 uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const { 594 return getSection(Sec)->sh_addralign; 595 } 596 597 template <class ELFT> 598 bool ELFObjectFile<ELFT>::isSectionCompressed(DataRefImpl Sec) const { 599 return getSection(Sec)->sh_flags & ELF::SHF_COMPRESSED; 600 } 601 602 template <class ELFT> 603 bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const { 604 return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR; 605 } 606 607 template <class ELFT> 608 bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const { 609 const Elf_Shdr *EShdr = getSection(Sec); 610 return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && 611 EShdr->sh_type == ELF::SHT_PROGBITS; 612 } 613 614 template <class ELFT> 615 bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const { 616 const Elf_Shdr *EShdr = getSection(Sec); 617 return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && 618 EShdr->sh_type == ELF::SHT_NOBITS; 619 } 620 621 template <class ELFT> 622 bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const { 623 return getSection(Sec)->sh_type == ELF::SHT_NOBITS; 624 } 625 626 template <class ELFT> 627 relocation_iterator 628 ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const { 629 DataRefImpl RelData; 630 uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin()); 631 RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize; 632 RelData.d.b = 0; 633 return relocation_iterator(RelocationRef(RelData, this)); 634 } 635 636 template <class ELFT> 637 relocation_iterator 638 ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const { 639 const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p); 640 relocation_iterator Begin = section_rel_begin(Sec); 641 if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL) 642 return Begin; 643 DataRefImpl RelData = Begin->getRawDataRefImpl(); 644 const Elf_Shdr *RelSec = getRelSection(RelData); 645 646 // Error check sh_link here so that getRelocationSymbol can just use it. 647 ErrorOr<const Elf_Shdr *> SymSecOrErr = EF.getSection(RelSec->sh_link); 648 if (std::error_code EC = SymSecOrErr.getError()) 649 report_fatal_error(EC.message()); 650 651 RelData.d.b += S->sh_size / S->sh_entsize; 652 return relocation_iterator(RelocationRef(RelData, this)); 653 } 654 655 template <class ELFT> 656 section_iterator 657 ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const { 658 if (EF.getHeader()->e_type != ELF::ET_REL) 659 return section_end(); 660 661 const Elf_Shdr *EShdr = getSection(Sec); 662 uintX_t Type = EShdr->sh_type; 663 if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA) 664 return section_end(); 665 666 ErrorOr<const Elf_Shdr *> R = EF.getSection(EShdr->sh_info); 667 if (std::error_code EC = R.getError()) 668 report_fatal_error(EC.message()); 669 return section_iterator(SectionRef(toDRI(*R), this)); 670 } 671 672 // Relocations 673 template <class ELFT> 674 void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const { 675 ++Rel.d.b; 676 } 677 678 template <class ELFT> 679 symbol_iterator 680 ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const { 681 uint32_t symbolIdx; 682 const Elf_Shdr *sec = getRelSection(Rel); 683 if (sec->sh_type == ELF::SHT_REL) 684 symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL()); 685 else 686 symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL()); 687 if (!symbolIdx) 688 return symbol_end(); 689 690 // FIXME: error check symbolIdx 691 DataRefImpl SymbolData; 692 SymbolData.d.a = sec->sh_link; 693 SymbolData.d.b = symbolIdx; 694 return symbol_iterator(SymbolRef(SymbolData, this)); 695 } 696 697 template <class ELFT> 698 uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const { 699 assert(EF.getHeader()->e_type == ELF::ET_REL && 700 "Only relocatable object files have relocation offsets"); 701 const Elf_Shdr *sec = getRelSection(Rel); 702 if (sec->sh_type == ELF::SHT_REL) 703 return getRel(Rel)->r_offset; 704 705 return getRela(Rel)->r_offset; 706 } 707 708 template <class ELFT> 709 uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const { 710 const Elf_Shdr *sec = getRelSection(Rel); 711 if (sec->sh_type == ELF::SHT_REL) 712 return getRel(Rel)->getType(EF.isMips64EL()); 713 else 714 return getRela(Rel)->getType(EF.isMips64EL()); 715 } 716 717 template <class ELFT> 718 StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const { 719 return getELFRelocationTypeName(EF.getHeader()->e_machine, Type); 720 } 721 722 template <class ELFT> 723 void ELFObjectFile<ELFT>::getRelocationTypeName( 724 DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 725 uint32_t type = getRelocationType(Rel); 726 EF.getRelocationTypeName(type, Result); 727 } 728 729 template <class ELFT> 730 ErrorOr<int64_t> 731 ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const { 732 if (getRelSection(Rel)->sh_type != ELF::SHT_RELA) 733 return object_error::parse_failed; 734 return (int64_t)getRela(Rel)->r_addend; 735 } 736 737 template <class ELFT> 738 const typename ELFObjectFile<ELFT>::Elf_Rel * 739 ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const { 740 assert(getRelSection(Rel)->sh_type == ELF::SHT_REL); 741 return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b); 742 } 743 744 template <class ELFT> 745 const typename ELFObjectFile<ELFT>::Elf_Rela * 746 ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { 747 assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA); 748 return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b); 749 } 750 751 template <class ELFT> 752 ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC) 753 : ELFObjectFileBase( 754 getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits), 755 Object), 756 EF(Data.getBuffer(), EC) { 757 if (EC) 758 return; 759 for (const Elf_Shdr &Sec : EF.sections()) { 760 switch (Sec.sh_type) { 761 case ELF::SHT_DYNSYM: { 762 if (DotDynSymSec) { 763 // More than one .dynsym! 764 EC = object_error::parse_failed; 765 return; 766 } 767 DotDynSymSec = &Sec; 768 break; 769 } 770 case ELF::SHT_SYMTAB: { 771 if (DotSymtabSec) { 772 // More than one .dynsym! 773 EC = object_error::parse_failed; 774 return; 775 } 776 DotSymtabSec = &Sec; 777 break; 778 } 779 case ELF::SHT_SYMTAB_SHNDX: { 780 ErrorOr<ArrayRef<Elf_Word>> TableOrErr = EF.getSHNDXTable(Sec); 781 if ((EC = TableOrErr.getError())) 782 return; 783 ShndxTable = *TableOrErr; 784 break; 785 } 786 } 787 } 788 } 789 790 template <class ELFT> 791 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const { 792 DataRefImpl Sym = toDRI(DotSymtabSec, 0); 793 return basic_symbol_iterator(SymbolRef(Sym, this)); 794 } 795 796 template <class ELFT> 797 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const { 798 const Elf_Shdr *SymTab = DotSymtabSec; 799 if (!SymTab) 800 return symbol_begin_impl(); 801 DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym)); 802 return basic_symbol_iterator(SymbolRef(Sym, this)); 803 } 804 805 template <class ELFT> 806 elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const { 807 DataRefImpl Sym = toDRI(DotDynSymSec, 0); 808 return symbol_iterator(SymbolRef(Sym, this)); 809 } 810 811 template <class ELFT> 812 elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const { 813 const Elf_Shdr *SymTab = DotDynSymSec; 814 DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym)); 815 return basic_symbol_iterator(SymbolRef(Sym, this)); 816 } 817 818 template <class ELFT> 819 section_iterator ELFObjectFile<ELFT>::section_begin() const { 820 return section_iterator(SectionRef(toDRI(EF.section_begin()), this)); 821 } 822 823 template <class ELFT> 824 section_iterator ELFObjectFile<ELFT>::section_end() const { 825 return section_iterator(SectionRef(toDRI(EF.section_end()), this)); 826 } 827 828 template <class ELFT> 829 uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const { 830 return ELFT::Is64Bits ? 8 : 4; 831 } 832 833 template <class ELFT> 834 StringRef ELFObjectFile<ELFT>::getFileFormatName() const { 835 bool IsLittleEndian = ELFT::TargetEndianness == support::little; 836 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) { 837 case ELF::ELFCLASS32: 838 switch (EF.getHeader()->e_machine) { 839 case ELF::EM_386: 840 return "ELF32-i386"; 841 case ELF::EM_IAMCU: 842 return "ELF32-iamcu"; 843 case ELF::EM_X86_64: 844 return "ELF32-x86-64"; 845 case ELF::EM_ARM: 846 return (IsLittleEndian ? "ELF32-arm-little" : "ELF32-arm-big"); 847 case ELF::EM_AVR: 848 return "ELF32-avr"; 849 case ELF::EM_HEXAGON: 850 return "ELF32-hexagon"; 851 case ELF::EM_LANAI: 852 return "ELF32-lanai"; 853 case ELF::EM_MIPS: 854 return "ELF32-mips"; 855 case ELF::EM_PPC: 856 return "ELF32-ppc"; 857 case ELF::EM_SPARC: 858 case ELF::EM_SPARC32PLUS: 859 return "ELF32-sparc"; 860 case ELF::EM_WEBASSEMBLY: 861 return "ELF32-wasm"; 862 case ELF::EM_AMDGPU: 863 return "ELF32-amdgpu"; 864 default: 865 return "ELF32-unknown"; 866 } 867 case ELF::ELFCLASS64: 868 switch (EF.getHeader()->e_machine) { 869 case ELF::EM_386: 870 return "ELF64-i386"; 871 case ELF::EM_X86_64: 872 return "ELF64-x86-64"; 873 case ELF::EM_AARCH64: 874 return (IsLittleEndian ? "ELF64-aarch64-little" : "ELF64-aarch64-big"); 875 case ELF::EM_PPC64: 876 return "ELF64-ppc64"; 877 case ELF::EM_S390: 878 return "ELF64-s390"; 879 case ELF::EM_SPARCV9: 880 return "ELF64-sparc"; 881 case ELF::EM_MIPS: 882 return "ELF64-mips"; 883 case ELF::EM_WEBASSEMBLY: 884 return "ELF64-wasm"; 885 case ELF::EM_AMDGPU: 886 return (EF.getHeader()->e_ident[ELF::EI_OSABI] == ELF::ELFOSABI_AMDGPU_HSA 887 && IsLittleEndian) ? 888 "ELF64-amdgpu-hsacobj" : "ELF64-amdgpu"; 889 default: 890 return "ELF64-unknown"; 891 } 892 default: 893 // FIXME: Proper error handling. 894 report_fatal_error("Invalid ELFCLASS!"); 895 } 896 } 897 898 template <class ELFT> 899 unsigned ELFObjectFile<ELFT>::getArch() const { 900 bool IsLittleEndian = ELFT::TargetEndianness == support::little; 901 switch (EF.getHeader()->e_machine) { 902 case ELF::EM_386: 903 case ELF::EM_IAMCU: 904 return Triple::x86; 905 case ELF::EM_X86_64: 906 return Triple::x86_64; 907 case ELF::EM_AARCH64: 908 return Triple::aarch64; 909 case ELF::EM_ARM: 910 return Triple::arm; 911 case ELF::EM_AVR: 912 return Triple::avr; 913 case ELF::EM_HEXAGON: 914 return Triple::hexagon; 915 case ELF::EM_LANAI: 916 return Triple::lanai; 917 case ELF::EM_MIPS: 918 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) { 919 case ELF::ELFCLASS32: 920 return IsLittleEndian ? Triple::mipsel : Triple::mips; 921 case ELF::ELFCLASS64: 922 return IsLittleEndian ? Triple::mips64el : Triple::mips64; 923 default: 924 report_fatal_error("Invalid ELFCLASS!"); 925 } 926 case ELF::EM_PPC: 927 return Triple::ppc; 928 case ELF::EM_PPC64: 929 return IsLittleEndian ? Triple::ppc64le : Triple::ppc64; 930 case ELF::EM_S390: 931 return Triple::systemz; 932 933 case ELF::EM_SPARC: 934 case ELF::EM_SPARC32PLUS: 935 return IsLittleEndian ? Triple::sparcel : Triple::sparc; 936 case ELF::EM_SPARCV9: 937 return Triple::sparcv9; 938 case ELF::EM_WEBASSEMBLY: 939 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) { 940 case ELF::ELFCLASS32: return Triple::wasm32; 941 case ELF::ELFCLASS64: return Triple::wasm64; 942 default: return Triple::UnknownArch; 943 } 944 945 case ELF::EM_AMDGPU: 946 return (EF.getHeader()->e_ident[ELF::EI_CLASS] == ELF::ELFCLASS64 947 && EF.getHeader()->e_ident[ELF::EI_OSABI] == ELF::ELFOSABI_AMDGPU_HSA 948 && IsLittleEndian) ? 949 Triple::amdgcn : Triple::UnknownArch; 950 951 default: 952 return Triple::UnknownArch; 953 } 954 } 955 956 template <class ELFT> 957 ELFObjectFileBase::elf_symbol_iterator_range 958 ELFObjectFile<ELFT>::getDynamicSymbolIterators() const { 959 return make_range(dynamic_symbol_begin(), dynamic_symbol_end()); 960 } 961 962 template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const { 963 return EF.getHeader()->e_type == ELF::ET_REL; 964 } 965 966 } // end namespace object 967 } // end namespace llvm 968 969 #endif // LLVM_OBJECT_ELFOBJECTFILE_H 970