ELFObjectFile.h revision 6c2dc9e66eeec5d39b2e6e53d18a023a5fa0af54
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_ELF_OBJECT_FILE_H 15#define LLVM_OBJECT_ELF_OBJECT_FILE_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 <limits> 32#include <utility> 33 34namespace llvm { 35namespace object { 36 37template <class ELFT> 38class ELFObjectFile : public ObjectFile { 39public: 40 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 41 42 typedef typename ELFFile<ELFT>::uintX_t uintX_t; 43 44 typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; 45 typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 46 typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel; 47 typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela; 48 typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; 49 50 typedef typename ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter; 51 typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter; 52 typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter; 53 54protected: 55 ELFFile<ELFT> EF; 56 57 virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; 58 virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; 59 virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const; 60 virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; 61 virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const; 62 virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; 63 virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; 64 virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; 65 virtual error_code getSymbolType(DataRefImpl Symb, 66 SymbolRef::Type &Res) const; 67 virtual error_code getSymbolSection(DataRefImpl Symb, 68 section_iterator &Res) const; 69 virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; 70 71 virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const; 72 virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const; 73 74 virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; 75 virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; 76 virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; 77 virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; 78 virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; 79 virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const; 80 virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; 81 virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; 82 virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; 83 virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, 84 bool &Res) const; 85 virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; 86 virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; 87 virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const; 88 virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, 89 bool &Result) const; 90 virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; 91 virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const; 92 virtual section_iterator getRelocatedSection(DataRefImpl Sec) const; 93 94 virtual error_code getRelocationNext(DataRefImpl Rel, 95 RelocationRef &Res) const; 96 virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const; 97 virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const; 98 virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const; 99 virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const; 100 virtual error_code getRelocationTypeName(DataRefImpl Rel, 101 SmallVectorImpl<char> &Result) const; 102 virtual error_code 103 getRelocationValueString(DataRefImpl Rel, 104 SmallVectorImpl<char> &Result) const; 105 106protected: // ELF specific protected members. 107 const Elf_Sym *getSymbol(DataRefImpl Symb) const; 108 uint64_t getROffset(DataRefImpl Rel) const; 109 StringRef getRelocationTypeName(uint32_t Type) const; 110 111 /// \brief Get the relocation section that contains \a Rel. 112 const Elf_Shdr *getRelSection(DataRefImpl Rel) const { 113 return EF.getSection(Rel.d.a); 114 } 115 116 const Elf_Rel *getRel(DataRefImpl Rel) const; 117 const Elf_Rela *getRela(DataRefImpl Rela) const; 118 119 Elf_Sym_Iter toELFSymIter(DataRefImpl Symb) const { 120 bool IsDynamic = Symb.p & 1; 121 if (IsDynamic) 122 return Elf_Sym_Iter( 123 EF.begin_dynamic_symbols().getEntSize(), 124 reinterpret_cast<const char *>(Symb.p & ~uintptr_t(1)), IsDynamic); 125 return Elf_Sym_Iter(EF.begin_symbols().getEntSize(), 126 reinterpret_cast<const char *>(Symb.p), IsDynamic); 127 } 128 129 DataRefImpl toDRI(Elf_Sym_Iter Symb) const { 130 DataRefImpl DRI; 131 DRI.p = reinterpret_cast<uintptr_t>(Symb.get()) | 132 static_cast<uintptr_t>(Symb.isDynamic()); 133 return DRI; 134 } 135 136 Elf_Shdr_Iter toELFShdrIter(DataRefImpl Sec) const { 137 return Elf_Shdr_Iter(EF.getHeader()->e_shentsize, 138 reinterpret_cast<const char *>(Sec.p)); 139 } 140 141 DataRefImpl toDRI(Elf_Shdr_Iter Sec) const { 142 DataRefImpl DRI; 143 DRI.p = reinterpret_cast<uintptr_t>(Sec.get()); 144 return DRI; 145 } 146 147 DataRefImpl toDRI(const Elf_Shdr *Sec) const { 148 DataRefImpl DRI; 149 DRI.p = reinterpret_cast<uintptr_t>(Sec); 150 return DRI; 151 } 152 153 Elf_Dyn_Iter toELFDynIter(DataRefImpl Dyn) const { 154 return Elf_Dyn_Iter(EF.begin_dynamic_table().getEntSize(), 155 reinterpret_cast<const char *>(Dyn.p)); 156 } 157 158 DataRefImpl toDRI(Elf_Dyn_Iter Dyn) const { 159 DataRefImpl DRI; 160 DRI.p = reinterpret_cast<uintptr_t>(Dyn.get()); 161 return DRI; 162 } 163 164 // This flag is used for classof, to distinguish ELFObjectFile from 165 // its subclass. If more subclasses will be created, this flag will 166 // have to become an enum. 167 bool isDyldELFObject; 168 169public: 170 ELFObjectFile(MemoryBuffer *Object, error_code &ec); 171 172 virtual symbol_iterator begin_symbols() const; 173 virtual symbol_iterator end_symbols() const; 174 175 virtual symbol_iterator begin_dynamic_symbols() const; 176 virtual symbol_iterator end_dynamic_symbols() const; 177 178 virtual section_iterator begin_sections() const; 179 virtual section_iterator end_sections() const; 180 181 virtual library_iterator begin_libraries_needed() const; 182 virtual library_iterator end_libraries_needed() const; 183 184 error_code getRelocationAddend(DataRefImpl Rel, int64_t &Res) const; 185 error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, 186 bool &IsDefault) const; 187 188 virtual uint8_t getBytesInAddress() const; 189 virtual StringRef getFileFormatName() const; 190 virtual StringRef getObjectType() const { return "ELF"; } 191 virtual unsigned getArch() const; 192 virtual StringRef getLoadName() const; 193 194 const ELFFile<ELFT> *getELFFile() const { return &EF; } 195 196 bool isDyldType() const { return isDyldELFObject; } 197 static inline bool classof(const Binary *v) { 198 return v->getType() == getELFType(ELFT::TargetEndianness == support::little, 199 ELFT::Is64Bits); 200 } 201}; 202 203// Use an alignment of 2 for the typedefs since that is the worst case for 204// ELF files in archives. 205typedef ELFObjectFile<ELFType<support::little, 2, false> > ELF32LEObjectFile; 206typedef ELFObjectFile<ELFType<support::little, 2, true> > ELF64LEObjectFile; 207typedef ELFObjectFile<ELFType<support::big, 2, false> > ELF32BEObjectFile; 208typedef ELFObjectFile<ELFType<support::big, 2, true> > ELF64BEObjectFile; 209 210template <class ELFT> 211error_code ELFObjectFile<ELFT>::getSymbolNext(DataRefImpl Symb, 212 SymbolRef &Result) const { 213 Result = SymbolRef(toDRI(++toELFSymIter(Symb)), this); 214 return object_error::success; 215} 216 217template <class ELFT> 218error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb, 219 StringRef &Result) const { 220 ErrorOr<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb)); 221 if (!Name) 222 return Name; 223 Result = *Name; 224 return object_error::success; 225} 226 227template <class ELFT> 228error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef, 229 StringRef &Version, 230 bool &IsDefault) const { 231 DataRefImpl Symb = SymRef.getRawDataRefImpl(); 232 const Elf_Sym *symb = getSymbol(Symb); 233 ErrorOr<StringRef> Ver = 234 EF.getSymbolVersion(EF.getSection(Symb.d.b), symb, IsDefault); 235 if (!Ver) 236 return Ver; 237 Version = *Ver; 238 return object_error::success; 239} 240 241template <class ELFT> 242error_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb, 243 uint64_t &Result) const { 244 const Elf_Sym *ESym = getSymbol(Symb); 245 const Elf_Shdr *ESec; 246 switch (EF.getSymbolTableIndex(ESym)) { 247 case ELF::SHN_COMMON: 248 // Unintialized symbols have no offset in the object file 249 case ELF::SHN_UNDEF: 250 Result = UnknownAddressOrSize; 251 return object_error::success; 252 case ELF::SHN_ABS: 253 Result = ESym->st_value; 254 return object_error::success; 255 default: 256 ESec = EF.getSection(ESym); 257 } 258 259 switch (ESym->getType()) { 260 case ELF::STT_SECTION: 261 Result = ESec ? ESec->sh_offset : UnknownAddressOrSize; 262 return object_error::success; 263 case ELF::STT_FUNC: 264 case ELF::STT_OBJECT: 265 case ELF::STT_NOTYPE: 266 Result = ESym->st_value + (ESec ? ESec->sh_offset : 0); 267 return object_error::success; 268 default: 269 Result = UnknownAddressOrSize; 270 return object_error::success; 271 } 272} 273 274template <class ELFT> 275error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, 276 uint64_t &Result) const { 277 const Elf_Sym *ESym = getSymbol(Symb); 278 const Elf_Shdr *ESec; 279 switch (EF.getSymbolTableIndex(ESym)) { 280 case ELF::SHN_COMMON: 281 case ELF::SHN_UNDEF: 282 Result = UnknownAddressOrSize; 283 return object_error::success; 284 case ELF::SHN_ABS: 285 Result = ESym->st_value; 286 return object_error::success; 287 default: 288 ESec = EF.getSection(ESym); 289 } 290 291 switch (ESym->getType()) { 292 case ELF::STT_SECTION: 293 Result = ESec ? ESec->sh_addr : UnknownAddressOrSize; 294 return object_error::success; 295 case ELF::STT_FUNC: 296 case ELF::STT_OBJECT: 297 case ELF::STT_NOTYPE: 298 bool IsRelocatable; 299 switch (EF.getHeader()->e_type) { 300 case ELF::ET_EXEC: 301 case ELF::ET_DYN: 302 IsRelocatable = false; 303 break; 304 default: 305 IsRelocatable = true; 306 } 307 Result = ESym->st_value; 308 309 // Clear the ARM/Thumb indicator flag. 310 if (EF.getHeader()->e_machine == ELF::EM_ARM) 311 Result &= ~1; 312 313 if (IsRelocatable && ESec != 0) 314 Result += ESec->sh_addr; 315 return object_error::success; 316 default: 317 Result = UnknownAddressOrSize; 318 return object_error::success; 319 } 320} 321 322template <class ELFT> 323error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb, 324 uint32_t &Res) const { 325 Elf_Sym_Iter Sym = toELFSymIter(Symb); 326 if (Sym->st_shndx == ELF::SHN_COMMON) 327 Res = Sym->st_value; 328 else 329 Res = 0; 330 return object_error::success; 331} 332 333template <class ELFT> 334error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb, 335 uint64_t &Result) const { 336 Result = toELFSymIter(Symb)->st_size; 337 return object_error::success; 338} 339 340template <class ELFT> 341error_code ELFObjectFile<ELFT>::getSymbolNMTypeChar(DataRefImpl Symb, 342 char &Result) const { 343 const Elf_Sym *ESym = getSymbol(Symb); 344 const Elf_Shdr *ESec = EF.getSection(ESym); 345 346 char ret = '?'; 347 348 if (ESec) { 349 switch (ESec->sh_type) { 350 case ELF::SHT_PROGBITS: 351 case ELF::SHT_DYNAMIC: 352 switch (ESec->sh_flags) { 353 case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): 354 ret = 't'; 355 break; 356 case (ELF::SHF_ALLOC | ELF::SHF_WRITE): 357 ret = 'd'; 358 break; 359 case ELF::SHF_ALLOC: 360 case (ELF::SHF_ALLOC | ELF::SHF_MERGE): 361 case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): 362 ret = 'r'; 363 break; 364 } 365 break; 366 case ELF::SHT_NOBITS: 367 ret = 'b'; 368 } 369 } 370 371 switch (EF.getSymbolTableIndex(ESym)) { 372 case ELF::SHN_UNDEF: 373 if (ret == '?') 374 ret = 'U'; 375 break; 376 case ELF::SHN_ABS: 377 ret = 'a'; 378 break; 379 case ELF::SHN_COMMON: 380 ret = 'c'; 381 break; 382 } 383 384 switch (ESym->getBinding()) { 385 case ELF::STB_GLOBAL: 386 ret = ::toupper(ret); 387 break; 388 case ELF::STB_WEAK: 389 if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF) 390 ret = 'w'; 391 else if (ESym->getType() == ELF::STT_OBJECT) 392 ret = 'V'; 393 else 394 ret = 'W'; 395 } 396 397 if (ret == '?' && ESym->getType() == ELF::STT_SECTION) { 398 ErrorOr<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb)); 399 if (!Name) 400 return Name; 401 Result = StringSwitch<char>(*Name) 402 .StartsWith(".debug", 'N') 403 .StartsWith(".note", 'n') 404 .Default('?'); 405 return object_error::success; 406 } 407 408 Result = ret; 409 return object_error::success; 410} 411 412template <class ELFT> 413error_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb, 414 SymbolRef::Type &Result) const { 415 const Elf_Sym *ESym = getSymbol(Symb); 416 417 switch (ESym->getType()) { 418 case ELF::STT_NOTYPE: 419 Result = SymbolRef::ST_Unknown; 420 break; 421 case ELF::STT_SECTION: 422 Result = SymbolRef::ST_Debug; 423 break; 424 case ELF::STT_FILE: 425 Result = SymbolRef::ST_File; 426 break; 427 case ELF::STT_FUNC: 428 Result = SymbolRef::ST_Function; 429 break; 430 case ELF::STT_OBJECT: 431 case ELF::STT_COMMON: 432 case ELF::STT_TLS: 433 Result = SymbolRef::ST_Data; 434 break; 435 default: 436 Result = SymbolRef::ST_Other; 437 break; 438 } 439 return object_error::success; 440} 441 442template <class ELFT> 443error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb, 444 uint32_t &Result) const { 445 const Elf_Sym *ESym = getSymbol(Symb); 446 447 Result = SymbolRef::SF_None; 448 449 if (ESym->getBinding() != ELF::STB_LOCAL) 450 Result |= SymbolRef::SF_Global; 451 452 if (ESym->getBinding() == ELF::STB_WEAK) 453 Result |= SymbolRef::SF_Weak; 454 455 if (ESym->st_shndx == ELF::SHN_ABS) 456 Result |= SymbolRef::SF_Absolute; 457 458 if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION || 459 ESym == &*EF.begin_symbols()) 460 Result |= SymbolRef::SF_FormatSpecific; 461 462 if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF) 463 Result |= SymbolRef::SF_Undefined; 464 465 if (ESym->getType() == ELF::STT_COMMON || 466 EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON) 467 Result |= SymbolRef::SF_Common; 468 469 if (ESym->getType() == ELF::STT_TLS) 470 Result |= SymbolRef::SF_ThreadLocal; 471 472 return object_error::success; 473} 474 475template <class ELFT> 476error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, 477 section_iterator &Res) const { 478 const Elf_Sym *ESym = getSymbol(Symb); 479 const Elf_Shdr *ESec = EF.getSection(ESym); 480 if (!ESec) 481 Res = end_sections(); 482 else { 483 DataRefImpl Sec; 484 Sec.p = reinterpret_cast<intptr_t>(ESec); 485 Res = section_iterator(SectionRef(Sec, this)); 486 } 487 return object_error::success; 488} 489 490template <class ELFT> 491error_code ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb, 492 uint64_t &Val) const { 493 const Elf_Sym *ESym = getSymbol(Symb); 494 Val = ESym->st_value; 495 return object_error::success; 496} 497 498template <class ELFT> 499error_code ELFObjectFile<ELFT>::getSectionNext(DataRefImpl Sec, 500 SectionRef &Result) const { 501 Result = SectionRef(toDRI(++toELFShdrIter(Sec)), this); 502 return object_error::success; 503} 504 505template <class ELFT> 506error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, 507 StringRef &Result) const { 508 ErrorOr<StringRef> Name = EF.getSectionName(&*toELFShdrIter(Sec)); 509 if (!Name) 510 return Name; 511 Result = *Name; 512 return object_error::success; 513} 514 515template <class ELFT> 516error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec, 517 uint64_t &Result) const { 518 Result = toELFShdrIter(Sec)->sh_addr; 519 return object_error::success; 520} 521 522template <class ELFT> 523error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec, 524 uint64_t &Result) const { 525 Result = toELFShdrIter(Sec)->sh_size; 526 return object_error::success; 527} 528 529template <class ELFT> 530error_code ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec, 531 StringRef &Result) const { 532 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 533 Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size); 534 return object_error::success; 535} 536 537template <class ELFT> 538error_code ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec, 539 uint64_t &Result) const { 540 Result = toELFShdrIter(Sec)->sh_addralign; 541 return object_error::success; 542} 543 544template <class ELFT> 545error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec, 546 bool &Result) const { 547 Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR; 548 return object_error::success; 549} 550 551template <class ELFT> 552error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec, 553 bool &Result) const { 554 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 555 Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && 556 EShdr->sh_type == ELF::SHT_PROGBITS; 557 return object_error::success; 558} 559 560template <class ELFT> 561error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec, 562 bool &Result) const { 563 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 564 Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && 565 EShdr->sh_type == ELF::SHT_NOBITS; 566 return object_error::success; 567} 568 569template <class ELFT> 570error_code 571ELFObjectFile<ELFT>::isSectionRequiredForExecution(DataRefImpl Sec, 572 bool &Result) const { 573 Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_ALLOC; 574 return object_error::success; 575} 576 577template <class ELFT> 578error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec, 579 bool &Result) const { 580 Result = toELFShdrIter(Sec)->sh_type & ELF::SHT_NOBITS; 581 return object_error::success; 582} 583 584template <class ELFT> 585error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec, 586 bool &Result) const { 587 Result = toELFShdrIter(Sec)->sh_type & ELF::SHT_NOBITS; 588 return object_error::success; 589} 590 591template <class ELFT> 592error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec, 593 bool &Result) const { 594 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 595 Result = !(EShdr->sh_flags & (ELF::SHF_WRITE | ELF::SHF_EXECINSTR)); 596 return object_error::success; 597} 598 599template <class ELFT> 600error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec, 601 DataRefImpl Symb, 602 bool &Result) const { 603 Elf_Sym_Iter ESym = toELFSymIter(Symb); 604 605 uintX_t Index = ESym->st_shndx; 606 bool Reserved = Index >= ELF::SHN_LORESERVE && Index <= ELF::SHN_HIRESERVE; 607 608 Result = !Reserved && (&*toELFShdrIter(Sec) == EF.getSection(ESym->st_shndx)); 609 return object_error::success; 610} 611 612template <class ELFT> 613relocation_iterator 614ELFObjectFile<ELFT>::getSectionRelBegin(DataRefImpl Sec) const { 615 DataRefImpl RelData; 616 uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get()); 617 RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize; 618 RelData.d.b = 0; 619 return relocation_iterator(RelocationRef(RelData, this)); 620} 621 622template <class ELFT> 623relocation_iterator 624ELFObjectFile<ELFT>::getSectionRelEnd(DataRefImpl Sec) const { 625 DataRefImpl RelData; 626 uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get()); 627 const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p); 628 RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize; 629 if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL) 630 RelData.d.b = 0; 631 else 632 RelData.d.b = S->sh_size / S->sh_entsize; 633 634 return relocation_iterator(RelocationRef(RelData, this)); 635} 636 637template <class ELFT> 638section_iterator 639ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const { 640 if (EF.getHeader()->e_type != ELF::ET_REL) 641 return end_sections(); 642 643 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 644 uintX_t Type = EShdr->sh_type; 645 if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA) 646 return end_sections(); 647 648 const Elf_Shdr *R = EF.getSection(EShdr->sh_info); 649 return section_iterator(SectionRef(toDRI(R), this)); 650} 651 652// Relocations 653template <class ELFT> 654error_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel, 655 RelocationRef &Result) const { 656 ++Rel.d.b; 657 Result = RelocationRef(Rel, this); 658 return object_error::success; 659} 660 661template <class ELFT> 662symbol_iterator 663ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const { 664 uint32_t symbolIdx; 665 const Elf_Shdr *sec = getRelSection(Rel); 666 switch (sec->sh_type) { 667 default: 668 report_fatal_error("Invalid section type in Rel!"); 669 case ELF::SHT_REL: { 670 symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL()); 671 break; 672 } 673 case ELF::SHT_RELA: { 674 symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL()); 675 break; 676 } 677 } 678 if (!symbolIdx) 679 return end_symbols(); 680 681 const Elf_Shdr *SymSec = EF.getSection(sec->sh_link); 682 683 DataRefImpl SymbolData; 684 switch (SymSec->sh_type) { 685 default: 686 report_fatal_error("Invalid symbol table section type!"); 687 case ELF::SHT_SYMTAB: 688 SymbolData = toDRI(EF.begin_symbols() + symbolIdx); 689 break; 690 case ELF::SHT_DYNSYM: 691 SymbolData = toDRI(EF.begin_dynamic_symbols() + symbolIdx); 692 break; 693 } 694 695 return symbol_iterator(SymbolRef(SymbolData, this)); 696} 697 698template <class ELFT> 699error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, 700 uint64_t &Result) const { 701 Result = getROffset(Rel); 702 return object_error::success; 703} 704 705template <class ELFT> 706error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel, 707 uint64_t &Result) const { 708 Result = getROffset(Rel); 709 return object_error::success; 710} 711 712template <class ELFT> 713uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const { 714 const Elf_Shdr *sec = getRelSection(Rel); 715 switch (sec->sh_type) { 716 default: 717 report_fatal_error("Invalid section type in Rel!"); 718 case ELF::SHT_REL: 719 return getRel(Rel)->r_offset; 720 case ELF::SHT_RELA: 721 return getRela(Rel)->r_offset; 722 } 723} 724 725template <class ELFT> 726error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel, 727 uint64_t &Result) const { 728 const Elf_Shdr *sec = getRelSection(Rel); 729 switch (sec->sh_type) { 730 default: 731 report_fatal_error("Invalid section type in Rel!"); 732 case ELF::SHT_REL: { 733 Result = getRel(Rel)->getType(EF.isMips64EL()); 734 break; 735 } 736 case ELF::SHT_RELA: { 737 Result = getRela(Rel)->getType(EF.isMips64EL()); 738 break; 739 } 740 } 741 return object_error::success; 742} 743 744template <class ELFT> 745StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const { 746 return getELFRelocationTypeName(EF.getHeader()->e_machine, Type); 747} 748 749template <class ELFT> 750error_code ELFObjectFile<ELFT>::getRelocationTypeName( 751 DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 752 const Elf_Shdr *sec = getRelSection(Rel); 753 uint32_t type; 754 switch (sec->sh_type) { 755 default: 756 return object_error::parse_failed; 757 case ELF::SHT_REL: { 758 type = getRel(Rel)->getType(EF.isMips64EL()); 759 break; 760 } 761 case ELF::SHT_RELA: { 762 type = getRela(Rel)->getType(EF.isMips64EL()); 763 break; 764 } 765 } 766 767 EF.getRelocationTypeName(type, Result); 768 return object_error::success; 769} 770 771template <class ELFT> 772error_code ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel, 773 int64_t &Result) const { 774 const Elf_Shdr *sec = getRelSection(Rel); 775 switch (sec->sh_type) { 776 default: 777 report_fatal_error("Invalid section type in Rel!"); 778 case ELF::SHT_REL: { 779 Result = 0; 780 return object_error::success; 781 } 782 case ELF::SHT_RELA: { 783 Result = getRela(Rel)->r_addend; 784 return object_error::success; 785 } 786 } 787} 788 789template <class ELFT> 790error_code ELFObjectFile<ELFT>::getRelocationValueString( 791 DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 792 const Elf_Shdr *sec = getRelSection(Rel); 793 uint8_t type; 794 StringRef res; 795 int64_t addend = 0; 796 uint16_t symbol_index = 0; 797 switch (sec->sh_type) { 798 default: 799 return object_error::parse_failed; 800 case ELF::SHT_REL: { 801 type = getRel(Rel)->getType(EF.isMips64EL()); 802 symbol_index = getRel(Rel)->getSymbol(EF.isMips64EL()); 803 // TODO: Read implicit addend from section data. 804 break; 805 } 806 case ELF::SHT_RELA: { 807 type = getRela(Rel)->getType(EF.isMips64EL()); 808 symbol_index = getRela(Rel)->getSymbol(EF.isMips64EL()); 809 addend = getRela(Rel)->r_addend; 810 break; 811 } 812 } 813 const Elf_Sym *symb = 814 EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index); 815 ErrorOr<StringRef> SymName = 816 EF.getSymbolName(EF.getSection(sec->sh_link), symb); 817 if (!SymName) 818 return SymName; 819 switch (EF.getHeader()->e_machine) { 820 case ELF::EM_X86_64: 821 switch (type) { 822 case ELF::R_X86_64_PC8: 823 case ELF::R_X86_64_PC16: 824 case ELF::R_X86_64_PC32: { 825 std::string fmtbuf; 826 raw_string_ostream fmt(fmtbuf); 827 fmt << *SymName << (addend < 0 ? "" : "+") << addend << "-P"; 828 fmt.flush(); 829 Result.append(fmtbuf.begin(), fmtbuf.end()); 830 } break; 831 case ELF::R_X86_64_8: 832 case ELF::R_X86_64_16: 833 case ELF::R_X86_64_32: 834 case ELF::R_X86_64_32S: 835 case ELF::R_X86_64_64: { 836 std::string fmtbuf; 837 raw_string_ostream fmt(fmtbuf); 838 fmt << *SymName << (addend < 0 ? "" : "+") << addend; 839 fmt.flush(); 840 Result.append(fmtbuf.begin(), fmtbuf.end()); 841 } break; 842 default: 843 res = "Unknown"; 844 } 845 break; 846 case ELF::EM_AARCH64: { 847 std::string fmtbuf; 848 raw_string_ostream fmt(fmtbuf); 849 fmt << *SymName; 850 if (addend != 0) 851 fmt << (addend < 0 ? "" : "+") << addend; 852 fmt.flush(); 853 Result.append(fmtbuf.begin(), fmtbuf.end()); 854 break; 855 } 856 case ELF::EM_ARM: 857 case ELF::EM_HEXAGON: 858 res = *SymName; 859 break; 860 default: 861 res = "Unknown"; 862 } 863 if (Result.empty()) 864 Result.append(res.begin(), res.end()); 865 return object_error::success; 866} 867 868template <class ELFT> 869const typename ELFFile<ELFT>::Elf_Sym * 870ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const { 871 return &*toELFSymIter(Symb); 872} 873 874template <class ELFT> 875const typename ELFObjectFile<ELFT>::Elf_Rel * 876ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const { 877 return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b); 878} 879 880template <class ELFT> 881const typename ELFObjectFile<ELFT>::Elf_Rela * 882ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { 883 return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b); 884} 885 886template <class ELFT> 887ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec) 888 : ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) == 889 support::little, 890 ELFT::Is64Bits), 891 Object), 892 EF(Object, ec) {} 893 894template <class ELFT> 895symbol_iterator ELFObjectFile<ELFT>::begin_symbols() const { 896 return symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this)); 897} 898 899template <class ELFT> 900symbol_iterator ELFObjectFile<ELFT>::end_symbols() const { 901 return symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this)); 902} 903 904template <class ELFT> 905symbol_iterator ELFObjectFile<ELFT>::begin_dynamic_symbols() const { 906 return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this)); 907} 908 909template <class ELFT> 910symbol_iterator ELFObjectFile<ELFT>::end_dynamic_symbols() const { 911 return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this)); 912} 913 914template <class ELFT> 915section_iterator ELFObjectFile<ELFT>::begin_sections() const { 916 return section_iterator(SectionRef(toDRI(EF.begin_sections()), this)); 917} 918 919template <class ELFT> 920section_iterator ELFObjectFile<ELFT>::end_sections() const { 921 return section_iterator(SectionRef(toDRI(EF.end_sections()), this)); 922} 923 924template <class ELFT> 925StringRef ELFObjectFile<ELFT>::getLoadName() const { 926 Elf_Dyn_Iter DI = EF.begin_dynamic_table(); 927 Elf_Dyn_Iter DE = EF.end_dynamic_table(); 928 929 while (DI != DE && DI->getTag() != ELF::DT_SONAME) 930 ++DI; 931 932 if (DI != DE) 933 return EF.getDynamicString(DI->getVal()); 934 return ""; 935} 936 937template <class ELFT> 938library_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const { 939 Elf_Dyn_Iter DI = EF.begin_dynamic_table(); 940 Elf_Dyn_Iter DE = EF.end_dynamic_table(); 941 942 while (DI != DE && DI->getTag() != ELF::DT_SONAME) 943 ++DI; 944 945 return library_iterator(LibraryRef(toDRI(DI), this)); 946} 947 948template <class ELFT> 949error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data, 950 LibraryRef &Result) const { 951 Elf_Dyn_Iter DI = toELFDynIter(Data); 952 Elf_Dyn_Iter DE = EF.end_dynamic_table(); 953 954 // Skip to the next DT_NEEDED entry. 955 do 956 ++DI; 957 while (DI != DE && DI->getTag() != ELF::DT_NEEDED); 958 959 Result = LibraryRef(toDRI(DI), this); 960 return object_error::success; 961} 962 963template <class ELFT> 964error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data, 965 StringRef &Res) const { 966 Res = EF.getDynamicString(toELFDynIter(Data)->getVal()); 967 return object_error::success; 968} 969 970template <class ELFT> 971library_iterator ELFObjectFile<ELFT>::end_libraries_needed() const { 972 return library_iterator(LibraryRef(toDRI(EF.end_dynamic_table()), this)); 973} 974 975template <class ELFT> 976uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const { 977 return ELFT::Is64Bits ? 8 : 4; 978} 979 980template <class ELFT> 981StringRef ELFObjectFile<ELFT>::getFileFormatName() const { 982 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) { 983 case ELF::ELFCLASS32: 984 switch (EF.getHeader()->e_machine) { 985 case ELF::EM_386: 986 return "ELF32-i386"; 987 case ELF::EM_X86_64: 988 return "ELF32-x86-64"; 989 case ELF::EM_ARM: 990 return "ELF32-arm"; 991 case ELF::EM_HEXAGON: 992 return "ELF32-hexagon"; 993 case ELF::EM_MIPS: 994 return "ELF32-mips"; 995 case ELF::EM_PPC: 996 return "ELF32-ppc"; 997 default: 998 return "ELF32-unknown"; 999 } 1000 case ELF::ELFCLASS64: 1001 switch (EF.getHeader()->e_machine) { 1002 case ELF::EM_386: 1003 return "ELF64-i386"; 1004 case ELF::EM_X86_64: 1005 return "ELF64-x86-64"; 1006 case ELF::EM_AARCH64: 1007 return "ELF64-aarch64"; 1008 case ELF::EM_PPC64: 1009 return "ELF64-ppc64"; 1010 case ELF::EM_S390: 1011 return "ELF64-s390"; 1012 default: 1013 return "ELF64-unknown"; 1014 } 1015 default: 1016 // FIXME: Proper error handling. 1017 report_fatal_error("Invalid ELFCLASS!"); 1018 } 1019} 1020 1021template <class ELFT> 1022unsigned ELFObjectFile<ELFT>::getArch() const { 1023 switch (EF.getHeader()->e_machine) { 1024 case ELF::EM_386: 1025 return Triple::x86; 1026 case ELF::EM_X86_64: 1027 return Triple::x86_64; 1028 case ELF::EM_AARCH64: 1029 return Triple::aarch64; 1030 case ELF::EM_ARM: 1031 return Triple::arm; 1032 case ELF::EM_HEXAGON: 1033 return Triple::hexagon; 1034 case ELF::EM_MIPS: 1035 return (ELFT::TargetEndianness == support::little) ? Triple::mipsel 1036 : Triple::mips; 1037 case ELF::EM_PPC64: 1038 return (ELFT::TargetEndianness == support::little) ? Triple::ppc64le 1039 : Triple::ppc64; 1040 case ELF::EM_S390: 1041 return Triple::systemz; 1042 default: 1043 return Triple::UnknownArch; 1044 } 1045} 1046 1047/// FIXME: Maybe we should have a base ElfObjectFile that is not a template 1048/// and make these member functions? 1049static inline error_code getELFRelocationAddend(const RelocationRef R, 1050 int64_t &Addend) { 1051 const ObjectFile *Obj = R.getObjectFile(); 1052 DataRefImpl DRI = R.getRawDataRefImpl(); 1053 // Little-endian 32-bit 1054 if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj)) 1055 return ELFObj->getRelocationAddend(DRI, Addend); 1056 1057 // Big-endian 32-bit 1058 if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj)) 1059 return ELFObj->getRelocationAddend(DRI, Addend); 1060 1061 // Little-endian 64-bit 1062 if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj)) 1063 return ELFObj->getRelocationAddend(DRI, Addend); 1064 1065 // Big-endian 64-bit 1066 if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) 1067 return ELFObj->getRelocationAddend(DRI, Addend); 1068 1069 llvm_unreachable("Object passed to getELFRelocationAddend() is not ELF"); 1070} 1071 1072/// This is a generic interface for retrieving GNU symbol version 1073/// information from an ELFObjectFile. 1074static inline error_code GetELFSymbolVersion(const ObjectFile *Obj, 1075 const SymbolRef &Sym, 1076 StringRef &Version, 1077 bool &IsDefault) { 1078 // Little-endian 32-bit 1079 if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj)) 1080 return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 1081 1082 // Big-endian 32-bit 1083 if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj)) 1084 return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 1085 1086 // Little-endian 64-bit 1087 if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj)) 1088 return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 1089 1090 // Big-endian 64-bit 1091 if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) 1092 return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 1093 1094 llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF"); 1095} 1096} 1097} 1098 1099#endif 1100