ELFObjectFile.h revision 263763
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 <cctype> 32#include <limits> 33#include <utility> 34 35namespace llvm { 36namespace object { 37 38template <class ELFT> 39class ELFObjectFile : public ObjectFile { 40public: 41 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 42 43 typedef typename ELFFile<ELFT>::uintX_t uintX_t; 44 45 typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; 46 typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 47 typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel; 48 typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela; 49 typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; 50 51 typedef typename ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter; 52 typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter; 53 typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter; 54 55protected: 56 ELFFile<ELFT> EF; 57 58 virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; 59 virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; 60 virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const; 61 virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; 62 virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const; 63 virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &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 section_rel_begin(DataRefImpl Sec) const; 91 virtual relocation_iterator section_rel_end(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 106 uint64_t getROffset(DataRefImpl Rel) const; 107 StringRef getRelocationTypeName(uint32_t Type) const; 108 109 /// \brief Get the relocation section that contains \a Rel. 110 const Elf_Shdr *getRelSection(DataRefImpl Rel) const { 111 return EF.getSection(Rel.d.a); 112 } 113 114 const Elf_Rel *getRel(DataRefImpl Rel) const; 115 const Elf_Rela *getRela(DataRefImpl Rela) const; 116 117 Elf_Sym_Iter toELFSymIter(DataRefImpl Symb) const { 118 bool IsDynamic = Symb.p & 1; 119 if (IsDynamic) 120 return Elf_Sym_Iter( 121 EF.begin_dynamic_symbols().getEntSize(), 122 reinterpret_cast<const char *>(Symb.p & ~uintptr_t(1)), IsDynamic); 123 return Elf_Sym_Iter(EF.begin_symbols().getEntSize(), 124 reinterpret_cast<const char *>(Symb.p), IsDynamic); 125 } 126 127 DataRefImpl toDRI(Elf_Sym_Iter Symb) const { 128 DataRefImpl DRI; 129 DRI.p = reinterpret_cast<uintptr_t>(Symb.get()) | 130 static_cast<uintptr_t>(Symb.isDynamic()); 131 return DRI; 132 } 133 134 Elf_Shdr_Iter toELFShdrIter(DataRefImpl Sec) const { 135 return Elf_Shdr_Iter(EF.getHeader()->e_shentsize, 136 reinterpret_cast<const char *>(Sec.p)); 137 } 138 139 DataRefImpl toDRI(Elf_Shdr_Iter Sec) const { 140 DataRefImpl DRI; 141 DRI.p = reinterpret_cast<uintptr_t>(Sec.get()); 142 return DRI; 143 } 144 145 DataRefImpl toDRI(const Elf_Shdr *Sec) const { 146 DataRefImpl DRI; 147 DRI.p = reinterpret_cast<uintptr_t>(Sec); 148 return DRI; 149 } 150 151 Elf_Dyn_Iter toELFDynIter(DataRefImpl Dyn) const { 152 return Elf_Dyn_Iter(EF.begin_dynamic_table().getEntSize(), 153 reinterpret_cast<const char *>(Dyn.p)); 154 } 155 156 DataRefImpl toDRI(Elf_Dyn_Iter Dyn) const { 157 DataRefImpl DRI; 158 DRI.p = reinterpret_cast<uintptr_t>(Dyn.get()); 159 return DRI; 160 } 161 162 // This flag is used for classof, to distinguish ELFObjectFile from 163 // its subclass. If more subclasses will be created, this flag will 164 // have to become an enum. 165 bool isDyldELFObject; 166 167public: 168 ELFObjectFile(MemoryBuffer *Object, error_code &ec); 169 170 const Elf_Sym *getSymbol(DataRefImpl Symb) const; 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>::getSymbolType(DataRefImpl Symb, 342 SymbolRef::Type &Result) const { 343 const Elf_Sym *ESym = getSymbol(Symb); 344 345 switch (ESym->getType()) { 346 case ELF::STT_NOTYPE: 347 Result = SymbolRef::ST_Unknown; 348 break; 349 case ELF::STT_SECTION: 350 Result = SymbolRef::ST_Debug; 351 break; 352 case ELF::STT_FILE: 353 Result = SymbolRef::ST_File; 354 break; 355 case ELF::STT_FUNC: 356 Result = SymbolRef::ST_Function; 357 break; 358 case ELF::STT_OBJECT: 359 case ELF::STT_COMMON: 360 case ELF::STT_TLS: 361 Result = SymbolRef::ST_Data; 362 break; 363 default: 364 Result = SymbolRef::ST_Other; 365 break; 366 } 367 return object_error::success; 368} 369 370template <class ELFT> 371error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb, 372 uint32_t &Result) const { 373 const Elf_Sym *ESym = getSymbol(Symb); 374 375 Result = SymbolRef::SF_None; 376 377 if (ESym->getBinding() != ELF::STB_LOCAL) 378 Result |= SymbolRef::SF_Global; 379 380 if (ESym->getBinding() == ELF::STB_WEAK) 381 Result |= SymbolRef::SF_Weak; 382 383 if (ESym->st_shndx == ELF::SHN_ABS) 384 Result |= SymbolRef::SF_Absolute; 385 386 if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION || 387 ESym == &*EF.begin_symbols()) 388 Result |= SymbolRef::SF_FormatSpecific; 389 390 if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF) 391 Result |= SymbolRef::SF_Undefined; 392 393 if (ESym->getType() == ELF::STT_COMMON || 394 EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON) 395 Result |= SymbolRef::SF_Common; 396 397 if (ESym->getType() == ELF::STT_TLS) 398 Result |= SymbolRef::SF_ThreadLocal; 399 400 return object_error::success; 401} 402 403template <class ELFT> 404error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, 405 section_iterator &Res) const { 406 const Elf_Sym *ESym = getSymbol(Symb); 407 const Elf_Shdr *ESec = EF.getSection(ESym); 408 if (!ESec) 409 Res = end_sections(); 410 else { 411 DataRefImpl Sec; 412 Sec.p = reinterpret_cast<intptr_t>(ESec); 413 Res = section_iterator(SectionRef(Sec, this)); 414 } 415 return object_error::success; 416} 417 418template <class ELFT> 419error_code ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb, 420 uint64_t &Val) const { 421 const Elf_Sym *ESym = getSymbol(Symb); 422 Val = ESym->st_value; 423 return object_error::success; 424} 425 426template <class ELFT> 427error_code ELFObjectFile<ELFT>::getSectionNext(DataRefImpl Sec, 428 SectionRef &Result) const { 429 Result = SectionRef(toDRI(++toELFShdrIter(Sec)), this); 430 return object_error::success; 431} 432 433template <class ELFT> 434error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, 435 StringRef &Result) const { 436 ErrorOr<StringRef> Name = EF.getSectionName(&*toELFShdrIter(Sec)); 437 if (!Name) 438 return Name; 439 Result = *Name; 440 return object_error::success; 441} 442 443template <class ELFT> 444error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec, 445 uint64_t &Result) const { 446 Result = toELFShdrIter(Sec)->sh_addr; 447 return object_error::success; 448} 449 450template <class ELFT> 451error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec, 452 uint64_t &Result) const { 453 Result = toELFShdrIter(Sec)->sh_size; 454 return object_error::success; 455} 456 457template <class ELFT> 458error_code ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec, 459 StringRef &Result) const { 460 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 461 Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size); 462 return object_error::success; 463} 464 465template <class ELFT> 466error_code ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec, 467 uint64_t &Result) const { 468 Result = toELFShdrIter(Sec)->sh_addralign; 469 return object_error::success; 470} 471 472template <class ELFT> 473error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec, 474 bool &Result) const { 475 Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR; 476 return object_error::success; 477} 478 479template <class ELFT> 480error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec, 481 bool &Result) const { 482 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 483 Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && 484 EShdr->sh_type == ELF::SHT_PROGBITS; 485 return object_error::success; 486} 487 488template <class ELFT> 489error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec, 490 bool &Result) const { 491 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 492 Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && 493 EShdr->sh_type == ELF::SHT_NOBITS; 494 return object_error::success; 495} 496 497template <class ELFT> 498error_code 499ELFObjectFile<ELFT>::isSectionRequiredForExecution(DataRefImpl Sec, 500 bool &Result) const { 501 Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_ALLOC; 502 return object_error::success; 503} 504 505template <class ELFT> 506error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec, 507 bool &Result) const { 508 Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS; 509 return object_error::success; 510} 511 512template <class ELFT> 513error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec, 514 bool &Result) const { 515 Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS; 516 return object_error::success; 517} 518 519template <class ELFT> 520error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec, 521 bool &Result) const { 522 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 523 Result = !(EShdr->sh_flags & (ELF::SHF_WRITE | ELF::SHF_EXECINSTR)); 524 return object_error::success; 525} 526 527template <class ELFT> 528error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec, 529 DataRefImpl Symb, 530 bool &Result) const { 531 Elf_Sym_Iter ESym = toELFSymIter(Symb); 532 533 uintX_t Index = ESym->st_shndx; 534 bool Reserved = Index >= ELF::SHN_LORESERVE && Index <= ELF::SHN_HIRESERVE; 535 536 Result = !Reserved && (&*toELFShdrIter(Sec) == EF.getSection(ESym->st_shndx)); 537 return object_error::success; 538} 539 540template <class ELFT> 541relocation_iterator 542ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const { 543 DataRefImpl RelData; 544 uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get()); 545 RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize; 546 RelData.d.b = 0; 547 return relocation_iterator(RelocationRef(RelData, this)); 548} 549 550template <class ELFT> 551relocation_iterator 552ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const { 553 DataRefImpl RelData; 554 uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get()); 555 const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p); 556 RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize; 557 if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL) 558 RelData.d.b = 0; 559 else 560 RelData.d.b = S->sh_size / S->sh_entsize; 561 562 return relocation_iterator(RelocationRef(RelData, this)); 563} 564 565template <class ELFT> 566section_iterator 567ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const { 568 if (EF.getHeader()->e_type != ELF::ET_REL) 569 return end_sections(); 570 571 Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 572 uintX_t Type = EShdr->sh_type; 573 if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA) 574 return end_sections(); 575 576 const Elf_Shdr *R = EF.getSection(EShdr->sh_info); 577 return section_iterator(SectionRef(toDRI(R), this)); 578} 579 580// Relocations 581template <class ELFT> 582error_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel, 583 RelocationRef &Result) const { 584 ++Rel.d.b; 585 Result = RelocationRef(Rel, this); 586 return object_error::success; 587} 588 589template <class ELFT> 590symbol_iterator 591ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const { 592 uint32_t symbolIdx; 593 const Elf_Shdr *sec = getRelSection(Rel); 594 switch (sec->sh_type) { 595 default: 596 report_fatal_error("Invalid section type in Rel!"); 597 case ELF::SHT_REL: { 598 symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL()); 599 break; 600 } 601 case ELF::SHT_RELA: { 602 symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL()); 603 break; 604 } 605 } 606 if (!symbolIdx) 607 return end_symbols(); 608 609 const Elf_Shdr *SymSec = EF.getSection(sec->sh_link); 610 611 DataRefImpl SymbolData; 612 switch (SymSec->sh_type) { 613 default: 614 report_fatal_error("Invalid symbol table section type!"); 615 case ELF::SHT_SYMTAB: 616 SymbolData = toDRI(EF.begin_symbols() + symbolIdx); 617 break; 618 case ELF::SHT_DYNSYM: 619 SymbolData = toDRI(EF.begin_dynamic_symbols() + symbolIdx); 620 break; 621 } 622 623 return symbol_iterator(SymbolRef(SymbolData, this)); 624} 625 626template <class ELFT> 627error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, 628 uint64_t &Result) const { 629 Result = getROffset(Rel); 630 return object_error::success; 631} 632 633template <class ELFT> 634error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel, 635 uint64_t &Result) const { 636 Result = getROffset(Rel); 637 return object_error::success; 638} 639 640template <class ELFT> 641uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const { 642 const Elf_Shdr *sec = getRelSection(Rel); 643 switch (sec->sh_type) { 644 default: 645 report_fatal_error("Invalid section type in Rel!"); 646 case ELF::SHT_REL: 647 return getRel(Rel)->r_offset; 648 case ELF::SHT_RELA: 649 return getRela(Rel)->r_offset; 650 } 651} 652 653template <class ELFT> 654error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel, 655 uint64_t &Result) const { 656 const Elf_Shdr *sec = getRelSection(Rel); 657 switch (sec->sh_type) { 658 default: 659 report_fatal_error("Invalid section type in Rel!"); 660 case ELF::SHT_REL: { 661 Result = getRel(Rel)->getType(EF.isMips64EL()); 662 break; 663 } 664 case ELF::SHT_RELA: { 665 Result = getRela(Rel)->getType(EF.isMips64EL()); 666 break; 667 } 668 } 669 return object_error::success; 670} 671 672template <class ELFT> 673StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const { 674 return getELFRelocationTypeName(EF.getHeader()->e_machine, Type); 675} 676 677template <class ELFT> 678error_code ELFObjectFile<ELFT>::getRelocationTypeName( 679 DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 680 const Elf_Shdr *sec = getRelSection(Rel); 681 uint32_t type; 682 switch (sec->sh_type) { 683 default: 684 return object_error::parse_failed; 685 case ELF::SHT_REL: { 686 type = getRel(Rel)->getType(EF.isMips64EL()); 687 break; 688 } 689 case ELF::SHT_RELA: { 690 type = getRela(Rel)->getType(EF.isMips64EL()); 691 break; 692 } 693 } 694 695 EF.getRelocationTypeName(type, Result); 696 return object_error::success; 697} 698 699template <class ELFT> 700error_code ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel, 701 int64_t &Result) const { 702 const Elf_Shdr *sec = getRelSection(Rel); 703 switch (sec->sh_type) { 704 default: 705 report_fatal_error("Invalid section type in Rel!"); 706 case ELF::SHT_REL: { 707 Result = 0; 708 return object_error::success; 709 } 710 case ELF::SHT_RELA: { 711 Result = getRela(Rel)->r_addend; 712 return object_error::success; 713 } 714 } 715} 716 717template <class ELFT> 718error_code ELFObjectFile<ELFT>::getRelocationValueString( 719 DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 720 const Elf_Shdr *sec = getRelSection(Rel); 721 uint8_t type; 722 StringRef res; 723 int64_t addend = 0; 724 uint16_t symbol_index = 0; 725 switch (sec->sh_type) { 726 default: 727 return object_error::parse_failed; 728 case ELF::SHT_REL: { 729 type = getRel(Rel)->getType(EF.isMips64EL()); 730 symbol_index = getRel(Rel)->getSymbol(EF.isMips64EL()); 731 // TODO: Read implicit addend from section data. 732 break; 733 } 734 case ELF::SHT_RELA: { 735 type = getRela(Rel)->getType(EF.isMips64EL()); 736 symbol_index = getRela(Rel)->getSymbol(EF.isMips64EL()); 737 addend = getRela(Rel)->r_addend; 738 break; 739 } 740 } 741 const Elf_Sym *symb = 742 EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index); 743 ErrorOr<StringRef> SymName = 744 EF.getSymbolName(EF.getSection(sec->sh_link), symb); 745 if (!SymName) 746 return SymName; 747 switch (EF.getHeader()->e_machine) { 748 case ELF::EM_X86_64: 749 switch (type) { 750 case ELF::R_X86_64_PC8: 751 case ELF::R_X86_64_PC16: 752 case ELF::R_X86_64_PC32: { 753 std::string fmtbuf; 754 raw_string_ostream fmt(fmtbuf); 755 fmt << *SymName << (addend < 0 ? "" : "+") << addend << "-P"; 756 fmt.flush(); 757 Result.append(fmtbuf.begin(), fmtbuf.end()); 758 } break; 759 case ELF::R_X86_64_8: 760 case ELF::R_X86_64_16: 761 case ELF::R_X86_64_32: 762 case ELF::R_X86_64_32S: 763 case ELF::R_X86_64_64: { 764 std::string fmtbuf; 765 raw_string_ostream fmt(fmtbuf); 766 fmt << *SymName << (addend < 0 ? "" : "+") << addend; 767 fmt.flush(); 768 Result.append(fmtbuf.begin(), fmtbuf.end()); 769 } break; 770 default: 771 res = "Unknown"; 772 } 773 break; 774 case ELF::EM_AARCH64: { 775 std::string fmtbuf; 776 raw_string_ostream fmt(fmtbuf); 777 fmt << *SymName; 778 if (addend != 0) 779 fmt << (addend < 0 ? "" : "+") << addend; 780 fmt.flush(); 781 Result.append(fmtbuf.begin(), fmtbuf.end()); 782 break; 783 } 784 case ELF::EM_ARM: 785 case ELF::EM_HEXAGON: 786 res = *SymName; 787 break; 788 default: 789 res = "Unknown"; 790 } 791 if (Result.empty()) 792 Result.append(res.begin(), res.end()); 793 return object_error::success; 794} 795 796template <class ELFT> 797const typename ELFFile<ELFT>::Elf_Sym * 798ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const { 799 return &*toELFSymIter(Symb); 800} 801 802template <class ELFT> 803const typename ELFObjectFile<ELFT>::Elf_Rel * 804ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const { 805 return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b); 806} 807 808template <class ELFT> 809const typename ELFObjectFile<ELFT>::Elf_Rela * 810ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { 811 return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b); 812} 813 814template <class ELFT> 815ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec) 816 : ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) == 817 support::little, 818 ELFT::Is64Bits), 819 Object), 820 EF(Object, ec) {} 821 822template <class ELFT> 823symbol_iterator ELFObjectFile<ELFT>::begin_symbols() const { 824 return symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this)); 825} 826 827template <class ELFT> 828symbol_iterator ELFObjectFile<ELFT>::end_symbols() const { 829 return symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this)); 830} 831 832template <class ELFT> 833symbol_iterator ELFObjectFile<ELFT>::begin_dynamic_symbols() const { 834 return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this)); 835} 836 837template <class ELFT> 838symbol_iterator ELFObjectFile<ELFT>::end_dynamic_symbols() const { 839 return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this)); 840} 841 842template <class ELFT> 843section_iterator ELFObjectFile<ELFT>::begin_sections() const { 844 return section_iterator(SectionRef(toDRI(EF.begin_sections()), this)); 845} 846 847template <class ELFT> 848section_iterator ELFObjectFile<ELFT>::end_sections() const { 849 return section_iterator(SectionRef(toDRI(EF.end_sections()), this)); 850} 851 852template <class ELFT> 853StringRef ELFObjectFile<ELFT>::getLoadName() const { 854 Elf_Dyn_Iter DI = EF.begin_dynamic_table(); 855 Elf_Dyn_Iter DE = EF.end_dynamic_table(); 856 857 while (DI != DE && DI->getTag() != ELF::DT_SONAME) 858 ++DI; 859 860 if (DI != DE) 861 return EF.getDynamicString(DI->getVal()); 862 return ""; 863} 864 865template <class ELFT> 866library_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const { 867 Elf_Dyn_Iter DI = EF.begin_dynamic_table(); 868 Elf_Dyn_Iter DE = EF.end_dynamic_table(); 869 870 while (DI != DE && DI->getTag() != ELF::DT_SONAME) 871 ++DI; 872 873 return library_iterator(LibraryRef(toDRI(DI), this)); 874} 875 876template <class ELFT> 877error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data, 878 LibraryRef &Result) const { 879 Elf_Dyn_Iter DI = toELFDynIter(Data); 880 Elf_Dyn_Iter DE = EF.end_dynamic_table(); 881 882 // Skip to the next DT_NEEDED entry. 883 do 884 ++DI; 885 while (DI != DE && DI->getTag() != ELF::DT_NEEDED); 886 887 Result = LibraryRef(toDRI(DI), this); 888 return object_error::success; 889} 890 891template <class ELFT> 892error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data, 893 StringRef &Res) const { 894 Res = EF.getDynamicString(toELFDynIter(Data)->getVal()); 895 return object_error::success; 896} 897 898template <class ELFT> 899library_iterator ELFObjectFile<ELFT>::end_libraries_needed() const { 900 return library_iterator(LibraryRef(toDRI(EF.end_dynamic_table()), this)); 901} 902 903template <class ELFT> 904uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const { 905 return ELFT::Is64Bits ? 8 : 4; 906} 907 908template <class ELFT> 909StringRef ELFObjectFile<ELFT>::getFileFormatName() const { 910 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) { 911 case ELF::ELFCLASS32: 912 switch (EF.getHeader()->e_machine) { 913 case ELF::EM_386: 914 return "ELF32-i386"; 915 case ELF::EM_X86_64: 916 return "ELF32-x86-64"; 917 case ELF::EM_ARM: 918 return "ELF32-arm"; 919 case ELF::EM_HEXAGON: 920 return "ELF32-hexagon"; 921 case ELF::EM_MIPS: 922 return "ELF32-mips"; 923 case ELF::EM_PPC: 924 return "ELF32-ppc"; 925 case ELF::EM_SPARC: 926 case ELF::EM_SPARC32PLUS: 927 return "ELF32-sparc"; 928 default: 929 return "ELF32-unknown"; 930 } 931 case ELF::ELFCLASS64: 932 switch (EF.getHeader()->e_machine) { 933 case ELF::EM_386: 934 return "ELF64-i386"; 935 case ELF::EM_X86_64: 936 return "ELF64-x86-64"; 937 case ELF::EM_AARCH64: 938 return "ELF64-aarch64"; 939 case ELF::EM_PPC64: 940 return "ELF64-ppc64"; 941 case ELF::EM_S390: 942 return "ELF64-s390"; 943 case ELF::EM_SPARCV9: 944 return "ELF64-sparc"; 945 default: 946 return "ELF64-unknown"; 947 } 948 default: 949 // FIXME: Proper error handling. 950 report_fatal_error("Invalid ELFCLASS!"); 951 } 952} 953 954template <class ELFT> 955unsigned ELFObjectFile<ELFT>::getArch() const { 956 switch (EF.getHeader()->e_machine) { 957 case ELF::EM_386: 958 return Triple::x86; 959 case ELF::EM_X86_64: 960 return Triple::x86_64; 961 case ELF::EM_AARCH64: 962 return Triple::aarch64; 963 case ELF::EM_ARM: 964 return Triple::arm; 965 case ELF::EM_HEXAGON: 966 return Triple::hexagon; 967 case ELF::EM_MIPS: 968 return (ELFT::TargetEndianness == support::little) ? Triple::mipsel 969 : Triple::mips; 970 case ELF::EM_PPC64: 971 return (ELFT::TargetEndianness == support::little) ? Triple::ppc64le 972 : Triple::ppc64; 973 case ELF::EM_S390: 974 return Triple::systemz; 975 976 case ELF::EM_SPARC: 977 case ELF::EM_SPARC32PLUS: 978 return Triple::sparc; 979 case ELF::EM_SPARCV9: 980 return Triple::sparcv9; 981 982 default: 983 return Triple::UnknownArch; 984 } 985} 986 987/// FIXME: Maybe we should have a base ElfObjectFile that is not a template 988/// and make these member functions? 989static inline error_code getELFRelocationAddend(const RelocationRef R, 990 int64_t &Addend) { 991 const ObjectFile *Obj = R.getObjectFile(); 992 DataRefImpl DRI = R.getRawDataRefImpl(); 993 // Little-endian 32-bit 994 if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj)) 995 return ELFObj->getRelocationAddend(DRI, Addend); 996 997 // Big-endian 32-bit 998 if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj)) 999 return ELFObj->getRelocationAddend(DRI, Addend); 1000 1001 // Little-endian 64-bit 1002 if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj)) 1003 return ELFObj->getRelocationAddend(DRI, Addend); 1004 1005 // Big-endian 64-bit 1006 if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) 1007 return ELFObj->getRelocationAddend(DRI, Addend); 1008 1009 llvm_unreachable("Object passed to getELFRelocationAddend() is not ELF"); 1010} 1011 1012/// This is a generic interface for retrieving GNU symbol version 1013/// information from an ELFObjectFile. 1014static inline error_code GetELFSymbolVersion(const ObjectFile *Obj, 1015 const SymbolRef &Sym, 1016 StringRef &Version, 1017 bool &IsDefault) { 1018 // Little-endian 32-bit 1019 if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj)) 1020 return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 1021 1022 // Big-endian 32-bit 1023 if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj)) 1024 return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 1025 1026 // Little-endian 64-bit 1027 if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj)) 1028 return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 1029 1030 // Big-endian 64-bit 1031 if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) 1032 return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 1033 1034 llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF"); 1035} 1036} 1037} 1038 1039#endif 1040