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