LLVM API Documentation
00001 //===- ELF.h - ELF object file implementation -------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file declares the ELFFile template class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_OBJECT_ELF_H 00015 #define LLVM_OBJECT_ELF_H 00016 00017 #include "llvm/ADT/ArrayRef.h" 00018 #include "llvm/ADT/DenseMap.h" 00019 #include "llvm/ADT/PointerIntPair.h" 00020 #include "llvm/ADT/SmallVector.h" 00021 #include "llvm/ADT/StringSwitch.h" 00022 #include "llvm/ADT/Triple.h" 00023 #include "llvm/Object/ELFTypes.h" 00024 #include "llvm/Object/Error.h" 00025 #include "llvm/Support/Casting.h" 00026 #include "llvm/Support/ELF.h" 00027 #include "llvm/Support/Endian.h" 00028 #include "llvm/Support/ErrorHandling.h" 00029 #include "llvm/Support/ErrorOr.h" 00030 #include "llvm/Support/MemoryBuffer.h" 00031 #include "llvm/Support/raw_ostream.h" 00032 #include <algorithm> 00033 #include <limits> 00034 #include <utility> 00035 00036 namespace llvm { 00037 namespace object { 00038 00039 StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type); 00040 00041 // Subclasses of ELFFile may need this for template instantiation 00042 inline std::pair<unsigned char, unsigned char> 00043 getElfArchType(StringRef Object) { 00044 if (Object.size() < ELF::EI_NIDENT) 00045 return std::make_pair((uint8_t)ELF::ELFCLASSNONE, 00046 (uint8_t)ELF::ELFDATANONE); 00047 return std::make_pair((uint8_t)Object[ELF::EI_CLASS], 00048 (uint8_t)Object[ELF::EI_DATA]); 00049 } 00050 00051 template <class ELFT> 00052 class ELFFile { 00053 public: 00054 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 00055 typedef typename std::conditional<ELFT::Is64Bits, 00056 uint64_t, uint32_t>::type uintX_t; 00057 00058 /// \brief Iterate over constant sized entities. 00059 template <class EntT> 00060 class ELFEntityIterator { 00061 public: 00062 typedef ptrdiff_t difference_type; 00063 typedef EntT value_type; 00064 typedef std::forward_iterator_tag iterator_category; 00065 typedef value_type &reference; 00066 typedef value_type *pointer; 00067 00068 /// \brief Default construct iterator. 00069 ELFEntityIterator() : EntitySize(0), Current(nullptr) {} 00070 ELFEntityIterator(uintX_t EntSize, const char *Start) 00071 : EntitySize(EntSize), Current(Start) {} 00072 00073 reference operator *() { 00074 assert(Current && "Attempted to dereference an invalid iterator!"); 00075 return *reinterpret_cast<pointer>(Current); 00076 } 00077 00078 pointer operator ->() { 00079 assert(Current && "Attempted to dereference an invalid iterator!"); 00080 return reinterpret_cast<pointer>(Current); 00081 } 00082 00083 bool operator ==(const ELFEntityIterator &Other) { 00084 return Current == Other.Current; 00085 } 00086 00087 bool operator !=(const ELFEntityIterator &Other) { 00088 return !(*this == Other); 00089 } 00090 00091 ELFEntityIterator &operator ++() { 00092 assert(Current && "Attempted to increment an invalid iterator!"); 00093 Current += EntitySize; 00094 return *this; 00095 } 00096 00097 ELFEntityIterator operator ++(int) { 00098 ELFEntityIterator Tmp = *this; 00099 ++*this; 00100 return Tmp; 00101 } 00102 00103 ELFEntityIterator &operator =(const ELFEntityIterator &Other) { 00104 EntitySize = Other.EntitySize; 00105 Current = Other.Current; 00106 return *this; 00107 } 00108 00109 difference_type operator -(const ELFEntityIterator &Other) const { 00110 assert(EntitySize == Other.EntitySize && 00111 "Subtracting iterators of different EntitySize!"); 00112 return (Current - Other.Current) / EntitySize; 00113 } 00114 00115 const char *get() const { return Current; } 00116 00117 uintX_t getEntSize() const { return EntitySize; } 00118 00119 private: 00120 uintX_t EntitySize; 00121 const char *Current; 00122 }; 00123 00124 typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr; 00125 typedef Elf_Shdr_Impl<ELFT> Elf_Shdr; 00126 typedef Elf_Sym_Impl<ELFT> Elf_Sym; 00127 typedef Elf_Dyn_Impl<ELFT> Elf_Dyn; 00128 typedef Elf_Phdr_Impl<ELFT> Elf_Phdr; 00129 typedef Elf_Rel_Impl<ELFT, false> Elf_Rel; 00130 typedef Elf_Rel_Impl<ELFT, true> Elf_Rela; 00131 typedef Elf_Verdef_Impl<ELFT> Elf_Verdef; 00132 typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux; 00133 typedef Elf_Verneed_Impl<ELFT> Elf_Verneed; 00134 typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux; 00135 typedef Elf_Versym_Impl<ELFT> Elf_Versym; 00136 typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_Iter; 00137 typedef iterator_range<Elf_Dyn_Iter> Elf_Dyn_Range; 00138 typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter; 00139 typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter; 00140 typedef ELFEntityIterator<const Elf_Shdr> Elf_Shdr_Iter; 00141 typedef iterator_range<Elf_Shdr_Iter> Elf_Shdr_Range; 00142 00143 /// \brief Archive files are 2 byte aligned, so we need this for 00144 /// PointerIntPair to work. 00145 template <typename T> 00146 class ArchivePointerTypeTraits { 00147 public: 00148 static inline const void *getAsVoidPointer(T *P) { return P; } 00149 static inline T *getFromVoidPointer(const void *P) { 00150 return static_cast<T *>(P); 00151 } 00152 enum { NumLowBitsAvailable = 1 }; 00153 }; 00154 00155 class Elf_Sym_Iter { 00156 public: 00157 typedef ptrdiff_t difference_type; 00158 typedef const Elf_Sym value_type; 00159 typedef std::random_access_iterator_tag iterator_category; 00160 typedef value_type &reference; 00161 typedef value_type *pointer; 00162 00163 /// \brief Default construct iterator. 00164 Elf_Sym_Iter() : EntitySize(0), Current(0, false) {} 00165 Elf_Sym_Iter(uintX_t EntSize, const char *Start, bool IsDynamic) 00166 : EntitySize(EntSize), Current(Start, IsDynamic) {} 00167 00168 reference operator*() { 00169 assert(Current.getPointer() && 00170 "Attempted to dereference an invalid iterator!"); 00171 return *reinterpret_cast<pointer>(Current.getPointer()); 00172 } 00173 00174 pointer operator->() { 00175 assert(Current.getPointer() && 00176 "Attempted to dereference an invalid iterator!"); 00177 return reinterpret_cast<pointer>(Current.getPointer()); 00178 } 00179 00180 bool operator==(const Elf_Sym_Iter &Other) { 00181 return Current == Other.Current; 00182 } 00183 00184 bool operator!=(const Elf_Sym_Iter &Other) { return !(*this == Other); } 00185 00186 Elf_Sym_Iter &operator++() { 00187 assert(Current.getPointer() && 00188 "Attempted to increment an invalid iterator!"); 00189 Current.setPointer(Current.getPointer() + EntitySize); 00190 return *this; 00191 } 00192 00193 Elf_Sym_Iter operator++(int) { 00194 Elf_Sym_Iter Tmp = *this; 00195 ++*this; 00196 return Tmp; 00197 } 00198 00199 Elf_Sym_Iter operator+(difference_type Dist) { 00200 assert(Current.getPointer() && 00201 "Attempted to increment an invalid iterator!"); 00202 Current.setPointer(Current.getPointer() + EntitySize * Dist); 00203 return *this; 00204 } 00205 00206 Elf_Sym_Iter &operator=(const Elf_Sym_Iter &Other) { 00207 EntitySize = Other.EntitySize; 00208 Current = Other.Current; 00209 return *this; 00210 } 00211 00212 difference_type operator-(const Elf_Sym_Iter &Other) const { 00213 assert(EntitySize == Other.EntitySize && 00214 "Subtracting iterators of different EntitySize!"); 00215 return (Current.getPointer() - Other.Current.getPointer()) / EntitySize; 00216 } 00217 00218 const char *get() const { return Current.getPointer(); } 00219 00220 bool isDynamic() const { return Current.getInt(); } 00221 00222 uintX_t getEntSize() const { return EntitySize; } 00223 00224 private: 00225 uintX_t EntitySize; 00226 PointerIntPair<const char *, 1, bool, 00227 ArchivePointerTypeTraits<const char> > Current; 00228 }; 00229 00230 private: 00231 typedef SmallVector<const Elf_Shdr *, 2> Sections_t; 00232 typedef DenseMap<unsigned, unsigned> IndexMap_t; 00233 00234 StringRef Buf; 00235 00236 const uint8_t *base() const { 00237 return reinterpret_cast<const uint8_t *>(Buf.data()); 00238 } 00239 00240 const Elf_Ehdr *Header; 00241 const Elf_Shdr *SectionHeaderTable; 00242 const Elf_Shdr *dot_shstrtab_sec; // Section header string table. 00243 const Elf_Shdr *dot_strtab_sec; // Symbol header string table. 00244 const Elf_Shdr *dot_symtab_sec; // Symbol table section. 00245 00246 const Elf_Shdr *SymbolTableSectionHeaderIndex; 00247 DenseMap<const Elf_Sym *, ELF::Elf64_Word> ExtendedSymbolTable; 00248 00249 const Elf_Shdr *dot_gnu_version_sec; // .gnu.version 00250 const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r 00251 const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d 00252 00253 /// \brief Represents a region described by entries in the .dynamic table. 00254 struct DynRegionInfo { 00255 DynRegionInfo() : Addr(nullptr), Size(0), EntSize(0) {} 00256 /// \brief Address in current address space. 00257 const void *Addr; 00258 /// \brief Size in bytes of the region. 00259 uintX_t Size; 00260 /// \brief Size of each entity in the region. 00261 uintX_t EntSize; 00262 }; 00263 00264 DynRegionInfo DynamicRegion; 00265 DynRegionInfo DynHashRegion; 00266 DynRegionInfo DynStrRegion; 00267 DynRegionInfo DynSymRegion; 00268 00269 // Pointer to SONAME entry in dynamic string table 00270 // This is set the first time getLoadName is called. 00271 mutable const char *dt_soname; 00272 00273 // Records for each version index the corresponding Verdef or Vernaux entry. 00274 // This is filled the first time LoadVersionMap() is called. 00275 class VersionMapEntry : public PointerIntPair<const void*, 1> { 00276 public: 00277 // If the integer is 0, this is an Elf_Verdef*. 00278 // If the integer is 1, this is an Elf_Vernaux*. 00279 VersionMapEntry() : PointerIntPair<const void*, 1>(nullptr, 0) { } 00280 VersionMapEntry(const Elf_Verdef *verdef) 00281 : PointerIntPair<const void*, 1>(verdef, 0) { } 00282 VersionMapEntry(const Elf_Vernaux *vernaux) 00283 : PointerIntPair<const void*, 1>(vernaux, 1) { } 00284 bool isNull() const { return getPointer() == nullptr; } 00285 bool isVerdef() const { return !isNull() && getInt() == 0; } 00286 bool isVernaux() const { return !isNull() && getInt() == 1; } 00287 const Elf_Verdef *getVerdef() const { 00288 return isVerdef() ? (const Elf_Verdef*)getPointer() : nullptr; 00289 } 00290 const Elf_Vernaux *getVernaux() const { 00291 return isVernaux() ? (const Elf_Vernaux*)getPointer() : nullptr; 00292 } 00293 }; 00294 mutable SmallVector<VersionMapEntry, 16> VersionMap; 00295 void LoadVersionDefs(const Elf_Shdr *sec) const; 00296 void LoadVersionNeeds(const Elf_Shdr *ec) const; 00297 void LoadVersionMap() const; 00298 00299 public: 00300 template<typename T> 00301 const T *getEntry(uint32_t Section, uint32_t Entry) const; 00302 template <typename T> 00303 const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const; 00304 const char *getString(uint32_t section, uint32_t offset) const; 00305 const char *getString(const Elf_Shdr *section, uint32_t offset) const; 00306 const char *getDynamicString(uintX_t Offset) const; 00307 ErrorOr<StringRef> getSymbolVersion(const Elf_Shdr *section, 00308 const Elf_Sym *Symb, 00309 bool &IsDefault) const; 00310 void VerifyStrTab(const Elf_Shdr *sh) const; 00311 00312 StringRef getRelocationTypeName(uint32_t Type) const; 00313 void getRelocationTypeName(uint32_t Type, 00314 SmallVectorImpl<char> &Result) const; 00315 00316 /// \brief Get the symbol table section and symbol for a given relocation. 00317 template <class RelT> 00318 std::pair<const Elf_Shdr *, const Elf_Sym *> 00319 getRelocationSymbol(const Elf_Shdr *RelSec, const RelT *Rel) const; 00320 00321 ELFFile(StringRef Object, std::error_code &ec); 00322 00323 bool isMipsELF64() const { 00324 return Header->e_machine == ELF::EM_MIPS && 00325 Header->getFileClass() == ELF::ELFCLASS64; 00326 } 00327 00328 bool isMips64EL() const { 00329 return Header->e_machine == ELF::EM_MIPS && 00330 Header->getFileClass() == ELF::ELFCLASS64 && 00331 Header->getDataEncoding() == ELF::ELFDATA2LSB; 00332 } 00333 00334 Elf_Shdr_Iter begin_sections() const; 00335 Elf_Shdr_Iter end_sections() const; 00336 Elf_Shdr_Range sections() const { 00337 return make_range(begin_sections(), end_sections()); 00338 } 00339 00340 Elf_Sym_Iter begin_symbols() const; 00341 Elf_Sym_Iter end_symbols() const; 00342 00343 Elf_Dyn_Iter begin_dynamic_table() const; 00344 /// \param NULLEnd use one past the first DT_NULL entry as the end instead of 00345 /// the section size. 00346 Elf_Dyn_Iter end_dynamic_table(bool NULLEnd = false) const; 00347 Elf_Dyn_Range dynamic_table(bool NULLEnd = false) const { 00348 return make_range(begin_dynamic_table(), end_dynamic_table(NULLEnd)); 00349 } 00350 00351 Elf_Sym_Iter begin_dynamic_symbols() const { 00352 if (DynSymRegion.Addr) 00353 return Elf_Sym_Iter(DynSymRegion.EntSize, (const char *)DynSymRegion.Addr, 00354 true); 00355 return Elf_Sym_Iter(0, nullptr, true); 00356 } 00357 00358 Elf_Sym_Iter end_dynamic_symbols() const { 00359 if (DynSymRegion.Addr) 00360 return Elf_Sym_Iter(DynSymRegion.EntSize, 00361 (const char *)DynSymRegion.Addr + DynSymRegion.Size, 00362 true); 00363 return Elf_Sym_Iter(0, nullptr, true); 00364 } 00365 00366 Elf_Rela_Iter begin_rela(const Elf_Shdr *sec) const { 00367 return Elf_Rela_Iter(sec->sh_entsize, 00368 (const char *)(base() + sec->sh_offset)); 00369 } 00370 00371 Elf_Rela_Iter end_rela(const Elf_Shdr *sec) const { 00372 return Elf_Rela_Iter( 00373 sec->sh_entsize, 00374 (const char *)(base() + sec->sh_offset + sec->sh_size)); 00375 } 00376 00377 Elf_Rel_Iter begin_rel(const Elf_Shdr *sec) const { 00378 return Elf_Rel_Iter(sec->sh_entsize, 00379 (const char *)(base() + sec->sh_offset)); 00380 } 00381 00382 Elf_Rel_Iter end_rel(const Elf_Shdr *sec) const { 00383 return Elf_Rel_Iter(sec->sh_entsize, 00384 (const char *)(base() + sec->sh_offset + sec->sh_size)); 00385 } 00386 00387 /// \brief Iterate over program header table. 00388 typedef ELFEntityIterator<const Elf_Phdr> Elf_Phdr_Iter; 00389 00390 Elf_Phdr_Iter begin_program_headers() const { 00391 return Elf_Phdr_Iter(Header->e_phentsize, 00392 (const char*)base() + Header->e_phoff); 00393 } 00394 00395 Elf_Phdr_Iter end_program_headers() const { 00396 return Elf_Phdr_Iter(Header->e_phentsize, 00397 (const char*)base() + 00398 Header->e_phoff + 00399 (Header->e_phnum * Header->e_phentsize)); 00400 } 00401 00402 uint64_t getNumSections() const; 00403 uintX_t getStringTableIndex() const; 00404 ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const; 00405 const Elf_Ehdr *getHeader() const { return Header; } 00406 const Elf_Shdr *getSection(const Elf_Sym *symb) const; 00407 const Elf_Shdr *getSection(uint32_t Index) const; 00408 const Elf_Sym *getSymbol(uint32_t index) const; 00409 00410 ErrorOr<StringRef> getSymbolName(Elf_Sym_Iter Sym) const; 00411 00412 /// \brief Get the name of \p Symb. 00413 /// \param SymTab The symbol table section \p Symb is contained in. 00414 /// \param Symb The symbol to get the name of. 00415 /// 00416 /// \p SymTab is used to lookup the string table to use to get the symbol's 00417 /// name. 00418 ErrorOr<StringRef> getSymbolName(const Elf_Shdr *SymTab, 00419 const Elf_Sym *Symb) const; 00420 ErrorOr<StringRef> getSectionName(const Elf_Shdr *Section) const; 00421 uint64_t getSymbolIndex(const Elf_Sym *sym) const; 00422 ErrorOr<ArrayRef<uint8_t> > getSectionContents(const Elf_Shdr *Sec) const; 00423 StringRef getLoadName() const; 00424 }; 00425 00426 // Use an alignment of 2 for the typedefs since that is the worst case for 00427 // ELF files in archives. 00428 typedef ELFFile<ELFType<support::little, 2, false> > ELF32LEFile; 00429 typedef ELFFile<ELFType<support::little, 2, true> > ELF64LEFile; 00430 typedef ELFFile<ELFType<support::big, 2, false> > ELF32BEFile; 00431 typedef ELFFile<ELFType<support::big, 2, true> > ELF64BEFile; 00432 00433 // Iterate through the version definitions, and place each Elf_Verdef 00434 // in the VersionMap according to its index. 00435 template <class ELFT> 00436 void ELFFile<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const { 00437 unsigned vd_size = sec->sh_size; // Size of section in bytes 00438 unsigned vd_count = sec->sh_info; // Number of Verdef entries 00439 const char *sec_start = (const char*)base() + sec->sh_offset; 00440 const char *sec_end = sec_start + vd_size; 00441 // The first Verdef entry is at the start of the section. 00442 const char *p = sec_start; 00443 for (unsigned i = 0; i < vd_count; i++) { 00444 if (p + sizeof(Elf_Verdef) > sec_end) 00445 report_fatal_error("Section ended unexpectedly while scanning " 00446 "version definitions."); 00447 const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p); 00448 if (vd->vd_version != ELF::VER_DEF_CURRENT) 00449 report_fatal_error("Unexpected verdef version"); 00450 size_t index = vd->vd_ndx & ELF::VERSYM_VERSION; 00451 if (index >= VersionMap.size()) 00452 VersionMap.resize(index + 1); 00453 VersionMap[index] = VersionMapEntry(vd); 00454 p += vd->vd_next; 00455 } 00456 } 00457 00458 // Iterate through the versions needed section, and place each Elf_Vernaux 00459 // in the VersionMap according to its index. 00460 template <class ELFT> 00461 void ELFFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const { 00462 unsigned vn_size = sec->sh_size; // Size of section in bytes 00463 unsigned vn_count = sec->sh_info; // Number of Verneed entries 00464 const char *sec_start = (const char *)base() + sec->sh_offset; 00465 const char *sec_end = sec_start + vn_size; 00466 // The first Verneed entry is at the start of the section. 00467 const char *p = sec_start; 00468 for (unsigned i = 0; i < vn_count; i++) { 00469 if (p + sizeof(Elf_Verneed) > sec_end) 00470 report_fatal_error("Section ended unexpectedly while scanning " 00471 "version needed records."); 00472 const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p); 00473 if (vn->vn_version != ELF::VER_NEED_CURRENT) 00474 report_fatal_error("Unexpected verneed version"); 00475 // Iterate through the Vernaux entries 00476 const char *paux = p + vn->vn_aux; 00477 for (unsigned j = 0; j < vn->vn_cnt; j++) { 00478 if (paux + sizeof(Elf_Vernaux) > sec_end) 00479 report_fatal_error("Section ended unexpected while scanning auxiliary " 00480 "version needed records."); 00481 const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux); 00482 size_t index = vna->vna_other & ELF::VERSYM_VERSION; 00483 if (index >= VersionMap.size()) 00484 VersionMap.resize(index + 1); 00485 VersionMap[index] = VersionMapEntry(vna); 00486 paux += vna->vna_next; 00487 } 00488 p += vn->vn_next; 00489 } 00490 } 00491 00492 template <class ELFT> 00493 void ELFFile<ELFT>::LoadVersionMap() const { 00494 // If there is no dynamic symtab or version table, there is nothing to do. 00495 if (!DynSymRegion.Addr || !dot_gnu_version_sec) 00496 return; 00497 00498 // Has the VersionMap already been loaded? 00499 if (VersionMap.size() > 0) 00500 return; 00501 00502 // The first two version indexes are reserved. 00503 // Index 0 is LOCAL, index 1 is GLOBAL. 00504 VersionMap.push_back(VersionMapEntry()); 00505 VersionMap.push_back(VersionMapEntry()); 00506 00507 if (dot_gnu_version_d_sec) 00508 LoadVersionDefs(dot_gnu_version_d_sec); 00509 00510 if (dot_gnu_version_r_sec) 00511 LoadVersionNeeds(dot_gnu_version_r_sec); 00512 } 00513 00514 template <class ELFT> 00515 ELF::Elf64_Word ELFFile<ELFT>::getSymbolTableIndex(const Elf_Sym *symb) const { 00516 if (symb->st_shndx == ELF::SHN_XINDEX) 00517 return ExtendedSymbolTable.lookup(symb); 00518 return symb->st_shndx; 00519 } 00520 00521 template <class ELFT> 00522 const typename ELFFile<ELFT>::Elf_Shdr * 00523 ELFFile<ELFT>::getSection(const Elf_Sym *symb) const { 00524 if (symb->st_shndx == ELF::SHN_XINDEX) 00525 return getSection(ExtendedSymbolTable.lookup(symb)); 00526 if (symb->st_shndx >= ELF::SHN_LORESERVE) 00527 return nullptr; 00528 return getSection(symb->st_shndx); 00529 } 00530 00531 template <class ELFT> 00532 const typename ELFFile<ELFT>::Elf_Sym * 00533 ELFFile<ELFT>::getSymbol(uint32_t Index) const { 00534 return &*(begin_symbols() + Index); 00535 } 00536 00537 template <class ELFT> 00538 ErrorOr<ArrayRef<uint8_t> > 00539 ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const { 00540 if (Sec->sh_offset + Sec->sh_size > Buf.size()) 00541 return object_error::parse_failed; 00542 const uint8_t *Start = base() + Sec->sh_offset; 00543 return makeArrayRef(Start, Sec->sh_size); 00544 } 00545 00546 template <class ELFT> 00547 StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const { 00548 return getELFRelocationTypeName(Header->e_machine, Type); 00549 } 00550 00551 template <class ELFT> 00552 void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type, 00553 SmallVectorImpl<char> &Result) const { 00554 if (!isMipsELF64()) { 00555 StringRef Name = getRelocationTypeName(Type); 00556 Result.append(Name.begin(), Name.end()); 00557 } else { 00558 // The Mips N64 ABI allows up to three operations to be specified per 00559 // relocation record. Unfortunately there's no easy way to test for the 00560 // presence of N64 ELFs as they have no special flag that identifies them 00561 // as being N64. We can safely assume at the moment that all Mips 00562 // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough 00563 // information to disambiguate between old vs new ABIs. 00564 uint8_t Type1 = (Type >> 0) & 0xFF; 00565 uint8_t Type2 = (Type >> 8) & 0xFF; 00566 uint8_t Type3 = (Type >> 16) & 0xFF; 00567 00568 // Concat all three relocation type names. 00569 StringRef Name = getRelocationTypeName(Type1); 00570 Result.append(Name.begin(), Name.end()); 00571 00572 Name = getRelocationTypeName(Type2); 00573 Result.append(1, '/'); 00574 Result.append(Name.begin(), Name.end()); 00575 00576 Name = getRelocationTypeName(Type3); 00577 Result.append(1, '/'); 00578 Result.append(Name.begin(), Name.end()); 00579 } 00580 } 00581 00582 template <class ELFT> 00583 template <class RelT> 00584 std::pair<const typename ELFFile<ELFT>::Elf_Shdr *, 00585 const typename ELFFile<ELFT>::Elf_Sym *> 00586 ELFFile<ELFT>::getRelocationSymbol(const Elf_Shdr *Sec, const RelT *Rel) const { 00587 if (!Sec->sh_link) 00588 return std::make_pair(nullptr, nullptr); 00589 const Elf_Shdr *SymTable = getSection(Sec->sh_link); 00590 return std::make_pair( 00591 SymTable, getEntry<Elf_Sym>(SymTable, Rel->getSymbol(isMips64EL()))); 00592 } 00593 00594 // Verify that the last byte in the string table in a null. 00595 template <class ELFT> 00596 void ELFFile<ELFT>::VerifyStrTab(const Elf_Shdr *sh) const { 00597 const char *strtab = (const char *)base() + sh->sh_offset; 00598 if (strtab[sh->sh_size - 1] != 0) 00599 // FIXME: Proper error handling. 00600 report_fatal_error("String table must end with a null terminator!"); 00601 } 00602 00603 template <class ELFT> 00604 uint64_t ELFFile<ELFT>::getNumSections() const { 00605 assert(Header && "Header not initialized!"); 00606 if (Header->e_shnum == ELF::SHN_UNDEF && Header->e_shoff > 0) { 00607 assert(SectionHeaderTable && "SectionHeaderTable not initialized!"); 00608 return SectionHeaderTable->sh_size; 00609 } 00610 return Header->e_shnum; 00611 } 00612 00613 template <class ELFT> 00614 typename ELFFile<ELFT>::uintX_t ELFFile<ELFT>::getStringTableIndex() const { 00615 if (Header->e_shnum == ELF::SHN_UNDEF) { 00616 if (Header->e_shstrndx == ELF::SHN_HIRESERVE) 00617 return SectionHeaderTable->sh_link; 00618 if (Header->e_shstrndx >= getNumSections()) 00619 return 0; 00620 } 00621 return Header->e_shstrndx; 00622 } 00623 00624 template <class ELFT> 00625 ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec) 00626 : Buf(Object), SectionHeaderTable(nullptr), dot_shstrtab_sec(nullptr), 00627 dot_strtab_sec(nullptr), dot_symtab_sec(nullptr), 00628 SymbolTableSectionHeaderIndex(nullptr), dot_gnu_version_sec(nullptr), 00629 dot_gnu_version_r_sec(nullptr), dot_gnu_version_d_sec(nullptr), 00630 dt_soname(nullptr) { 00631 const uint64_t FileSize = Buf.size(); 00632 00633 if (sizeof(Elf_Ehdr) > FileSize) 00634 // FIXME: Proper error handling. 00635 report_fatal_error("File too short!"); 00636 00637 Header = reinterpret_cast<const Elf_Ehdr *>(base()); 00638 00639 if (Header->e_shoff == 0) 00640 return; 00641 00642 const uint64_t SectionTableOffset = Header->e_shoff; 00643 00644 if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) 00645 // FIXME: Proper error handling. 00646 report_fatal_error("Section header table goes past end of file!"); 00647 00648 // The getNumSections() call below depends on SectionHeaderTable being set. 00649 SectionHeaderTable = 00650 reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset); 00651 const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize; 00652 00653 if (SectionTableOffset + SectionTableSize > FileSize) 00654 // FIXME: Proper error handling. 00655 report_fatal_error("Section table goes past end of file!"); 00656 00657 // Scan sections for special sections. 00658 00659 for (const Elf_Shdr &Sec : sections()) { 00660 switch (Sec.sh_type) { 00661 case ELF::SHT_SYMTAB_SHNDX: 00662 if (SymbolTableSectionHeaderIndex) 00663 // FIXME: Proper error handling. 00664 report_fatal_error("More than one .symtab_shndx!"); 00665 SymbolTableSectionHeaderIndex = &Sec; 00666 break; 00667 case ELF::SHT_SYMTAB: 00668 if (dot_symtab_sec) 00669 // FIXME: Proper error handling. 00670 report_fatal_error("More than one .symtab!"); 00671 dot_symtab_sec = &Sec; 00672 dot_strtab_sec = getSection(Sec.sh_link); 00673 break; 00674 case ELF::SHT_DYNSYM: { 00675 if (DynSymRegion.Addr) 00676 // FIXME: Proper error handling. 00677 report_fatal_error("More than one .dynsym!"); 00678 DynSymRegion.Addr = base() + Sec.sh_offset; 00679 DynSymRegion.Size = Sec.sh_size; 00680 DynSymRegion.EntSize = Sec.sh_entsize; 00681 const Elf_Shdr *DynStr = getSection(Sec.sh_link); 00682 DynStrRegion.Addr = base() + DynStr->sh_offset; 00683 DynStrRegion.Size = DynStr->sh_size; 00684 DynStrRegion.EntSize = DynStr->sh_entsize; 00685 break; 00686 } 00687 case ELF::SHT_DYNAMIC: 00688 if (DynamicRegion.Addr) 00689 // FIXME: Proper error handling. 00690 report_fatal_error("More than one .dynamic!"); 00691 DynamicRegion.Addr = base() + Sec.sh_offset; 00692 DynamicRegion.Size = Sec.sh_size; 00693 DynamicRegion.EntSize = Sec.sh_entsize; 00694 break; 00695 case ELF::SHT_GNU_versym: 00696 if (dot_gnu_version_sec != nullptr) 00697 // FIXME: Proper error handling. 00698 report_fatal_error("More than one .gnu.version section!"); 00699 dot_gnu_version_sec = &Sec; 00700 break; 00701 case ELF::SHT_GNU_verdef: 00702 if (dot_gnu_version_d_sec != nullptr) 00703 // FIXME: Proper error handling. 00704 report_fatal_error("More than one .gnu.version_d section!"); 00705 dot_gnu_version_d_sec = &Sec; 00706 break; 00707 case ELF::SHT_GNU_verneed: 00708 if (dot_gnu_version_r_sec != nullptr) 00709 // FIXME: Proper error handling. 00710 report_fatal_error("More than one .gnu.version_r section!"); 00711 dot_gnu_version_r_sec = &Sec; 00712 break; 00713 } 00714 } 00715 00716 // Get string table sections. 00717 dot_shstrtab_sec = getSection(getStringTableIndex()); 00718 if (dot_shstrtab_sec) { 00719 // Verify that the last byte in the string table in a null. 00720 VerifyStrTab(dot_shstrtab_sec); 00721 } 00722 00723 // Build symbol name side-mapping if there is one. 00724 if (SymbolTableSectionHeaderIndex) { 00725 const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() + 00726 SymbolTableSectionHeaderIndex->sh_offset); 00727 for (Elf_Sym_Iter SI = begin_symbols(), SE = end_symbols(); SI != SE; 00728 ++SI) { 00729 if (*ShndxTable != ELF::SHN_UNDEF) 00730 ExtendedSymbolTable[&*SI] = *ShndxTable; 00731 ++ShndxTable; 00732 } 00733 } 00734 00735 // Scan program headers. 00736 for (Elf_Phdr_Iter PhdrI = begin_program_headers(), 00737 PhdrE = end_program_headers(); 00738 PhdrI != PhdrE; ++PhdrI) { 00739 if (PhdrI->p_type == ELF::PT_DYNAMIC) { 00740 DynamicRegion.Addr = base() + PhdrI->p_offset; 00741 DynamicRegion.Size = PhdrI->p_filesz; 00742 DynamicRegion.EntSize = sizeof(Elf_Dyn); 00743 break; 00744 } 00745 } 00746 00747 ec = std::error_code(); 00748 } 00749 00750 // Get the symbol table index in the symtab section given a symbol 00751 template <class ELFT> 00752 uint64_t ELFFile<ELFT>::getSymbolIndex(const Elf_Sym *Sym) const { 00753 uintptr_t SymLoc = uintptr_t(Sym); 00754 uintptr_t SymTabLoc = uintptr_t(base() + dot_symtab_sec->sh_offset); 00755 assert(SymLoc > SymTabLoc && "Symbol not in symbol table!"); 00756 uint64_t SymOffset = SymLoc - SymTabLoc; 00757 assert(SymOffset % dot_symtab_sec->sh_entsize == 0 && 00758 "Symbol not multiple of symbol size!"); 00759 return SymOffset / dot_symtab_sec->sh_entsize; 00760 } 00761 00762 template <class ELFT> 00763 typename ELFFile<ELFT>::Elf_Shdr_Iter ELFFile<ELFT>::begin_sections() const { 00764 return Elf_Shdr_Iter(Header->e_shentsize, 00765 (const char *)base() + Header->e_shoff); 00766 } 00767 00768 template <class ELFT> 00769 typename ELFFile<ELFT>::Elf_Shdr_Iter ELFFile<ELFT>::end_sections() const { 00770 return Elf_Shdr_Iter(Header->e_shentsize, 00771 (const char *)base() + Header->e_shoff + 00772 (getNumSections() * Header->e_shentsize)); 00773 } 00774 00775 template <class ELFT> 00776 typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::begin_symbols() const { 00777 if (!dot_symtab_sec) 00778 return Elf_Sym_Iter(0, nullptr, false); 00779 return Elf_Sym_Iter(dot_symtab_sec->sh_entsize, 00780 (const char *)base() + dot_symtab_sec->sh_offset, false); 00781 } 00782 00783 template <class ELFT> 00784 typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::end_symbols() const { 00785 if (!dot_symtab_sec) 00786 return Elf_Sym_Iter(0, nullptr, false); 00787 return Elf_Sym_Iter(dot_symtab_sec->sh_entsize, 00788 (const char *)base() + dot_symtab_sec->sh_offset + 00789 dot_symtab_sec->sh_size, 00790 false); 00791 } 00792 00793 template <class ELFT> 00794 typename ELFFile<ELFT>::Elf_Dyn_Iter 00795 ELFFile<ELFT>::begin_dynamic_table() const { 00796 if (DynamicRegion.Addr) 00797 return Elf_Dyn_Iter(DynamicRegion.EntSize, 00798 (const char *)DynamicRegion.Addr); 00799 return Elf_Dyn_Iter(0, nullptr); 00800 } 00801 00802 template <class ELFT> 00803 typename ELFFile<ELFT>::Elf_Dyn_Iter 00804 ELFFile<ELFT>::end_dynamic_table(bool NULLEnd) const { 00805 if (!DynamicRegion.Addr) 00806 return Elf_Dyn_Iter(0, nullptr); 00807 Elf_Dyn_Iter Ret(DynamicRegion.EntSize, 00808 (const char *)DynamicRegion.Addr + DynamicRegion.Size); 00809 00810 if (NULLEnd) { 00811 Elf_Dyn_Iter Start = begin_dynamic_table(); 00812 while (Start != Ret && Start->getTag() != ELF::DT_NULL) 00813 ++Start; 00814 00815 // Include the DT_NULL. 00816 if (Start != Ret) 00817 ++Start; 00818 Ret = Start; 00819 } 00820 return Ret; 00821 } 00822 00823 template <class ELFT> 00824 StringRef ELFFile<ELFT>::getLoadName() const { 00825 if (!dt_soname) { 00826 dt_soname = ""; 00827 // Find the DT_SONAME entry 00828 for (const auto &Entry : dynamic_table()) 00829 if (Entry.getTag() == ELF::DT_SONAME) { 00830 dt_soname = getDynamicString(Entry.getVal()); 00831 break; 00832 } 00833 } 00834 return dt_soname; 00835 } 00836 00837 template <class ELFT> 00838 template <typename T> 00839 const T *ELFFile<ELFT>::getEntry(uint32_t Section, uint32_t Entry) const { 00840 return getEntry<T>(getSection(Section), Entry); 00841 } 00842 00843 template <class ELFT> 00844 template <typename T> 00845 const T *ELFFile<ELFT>::getEntry(const Elf_Shdr *Section, 00846 uint32_t Entry) const { 00847 return reinterpret_cast<const T *>(base() + Section->sh_offset + 00848 (Entry * Section->sh_entsize)); 00849 } 00850 00851 template <class ELFT> 00852 const typename ELFFile<ELFT>::Elf_Shdr * 00853 ELFFile<ELFT>::getSection(uint32_t index) const { 00854 if (index == 0) 00855 return nullptr; 00856 if (!SectionHeaderTable || index >= getNumSections()) 00857 // FIXME: Proper error handling. 00858 report_fatal_error("Invalid section index!"); 00859 00860 return reinterpret_cast<const Elf_Shdr *>( 00861 reinterpret_cast<const char *>(SectionHeaderTable) 00862 + (index * Header->e_shentsize)); 00863 } 00864 00865 template <class ELFT> 00866 const char *ELFFile<ELFT>::getString(uint32_t section, 00867 ELF::Elf32_Word offset) const { 00868 return getString(getSection(section), offset); 00869 } 00870 00871 template <class ELFT> 00872 const char *ELFFile<ELFT>::getString(const Elf_Shdr *section, 00873 ELF::Elf32_Word offset) const { 00874 assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!"); 00875 if (offset >= section->sh_size) 00876 // FIXME: Proper error handling. 00877 report_fatal_error("Symbol name offset outside of string table!"); 00878 return (const char *)base() + section->sh_offset + offset; 00879 } 00880 00881 template <class ELFT> 00882 const char *ELFFile<ELFT>::getDynamicString(uintX_t Offset) const { 00883 if (!DynStrRegion.Addr || Offset >= DynStrRegion.Size) 00884 return nullptr; 00885 return (const char *)DynStrRegion.Addr + Offset; 00886 } 00887 00888 template <class ELFT> 00889 ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(Elf_Sym_Iter Sym) const { 00890 if (!Sym.isDynamic()) 00891 return getSymbolName(dot_symtab_sec, &*Sym); 00892 00893 if (!DynStrRegion.Addr || Sym->st_name >= DynStrRegion.Size) 00894 return object_error::parse_failed; 00895 return StringRef(getDynamicString(Sym->st_name)); 00896 } 00897 00898 template <class ELFT> 00899 ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(const Elf_Shdr *Section, 00900 const Elf_Sym *Symb) const { 00901 if (Symb->st_name == 0) { 00902 const Elf_Shdr *ContainingSec = getSection(Symb); 00903 if (ContainingSec) 00904 return getSectionName(ContainingSec); 00905 } 00906 00907 const Elf_Shdr *StrTab = getSection(Section->sh_link); 00908 if (Symb->st_name >= StrTab->sh_size) 00909 return object_error::parse_failed; 00910 return StringRef(getString(StrTab, Symb->st_name)); 00911 } 00912 00913 template <class ELFT> 00914 ErrorOr<StringRef> 00915 ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section) const { 00916 if (Section->sh_name >= dot_shstrtab_sec->sh_size) 00917 return object_error::parse_failed; 00918 return StringRef(getString(dot_shstrtab_sec, Section->sh_name)); 00919 } 00920 00921 template <class ELFT> 00922 ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section, 00923 const Elf_Sym *symb, 00924 bool &IsDefault) const { 00925 // Handle non-dynamic symbols. 00926 if (section != DynSymRegion.Addr && section != nullptr) { 00927 // Non-dynamic symbols can have versions in their names 00928 // A name of the form 'foo@V1' indicates version 'V1', non-default. 00929 // A name of the form 'foo@@V2' indicates version 'V2', default version. 00930 ErrorOr<StringRef> SymName = getSymbolName(section, symb); 00931 if (!SymName) 00932 return SymName; 00933 StringRef Name = *SymName; 00934 size_t atpos = Name.find('@'); 00935 if (atpos == StringRef::npos) { 00936 IsDefault = false; 00937 return StringRef(""); 00938 } 00939 ++atpos; 00940 if (atpos < Name.size() && Name[atpos] == '@') { 00941 IsDefault = true; 00942 ++atpos; 00943 } else { 00944 IsDefault = false; 00945 } 00946 return Name.substr(atpos); 00947 } 00948 00949 // This is a dynamic symbol. Look in the GNU symbol version table. 00950 if (!dot_gnu_version_sec) { 00951 // No version table. 00952 IsDefault = false; 00953 return StringRef(""); 00954 } 00955 00956 // Determine the position in the symbol table of this entry. 00957 size_t entry_index = ((const char *)symb - (const char *)DynSymRegion.Addr) / 00958 DynSymRegion.EntSize; 00959 00960 // Get the corresponding version index entry 00961 const Elf_Versym *vs = getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index); 00962 size_t version_index = vs->vs_index & ELF::VERSYM_VERSION; 00963 00964 // Special markers for unversioned symbols. 00965 if (version_index == ELF::VER_NDX_LOCAL || 00966 version_index == ELF::VER_NDX_GLOBAL) { 00967 IsDefault = false; 00968 return StringRef(""); 00969 } 00970 00971 // Lookup this symbol in the version table 00972 LoadVersionMap(); 00973 if (version_index >= VersionMap.size() || VersionMap[version_index].isNull()) 00974 return object_error::parse_failed; 00975 const VersionMapEntry &entry = VersionMap[version_index]; 00976 00977 // Get the version name string 00978 size_t name_offset; 00979 if (entry.isVerdef()) { 00980 // The first Verdaux entry holds the name. 00981 name_offset = entry.getVerdef()->getAux()->vda_name; 00982 } else { 00983 name_offset = entry.getVernaux()->vna_name; 00984 } 00985 00986 // Set IsDefault 00987 if (entry.isVerdef()) { 00988 IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN); 00989 } else { 00990 IsDefault = false; 00991 } 00992 00993 if (name_offset >= DynStrRegion.Size) 00994 return object_error::parse_failed; 00995 return StringRef(getDynamicString(name_offset)); 00996 } 00997 00998 /// This function returns the hash value for a symbol in the .dynsym section 00999 /// Name of the API remains consistent as specified in the libelf 01000 /// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash 01001 static inline unsigned elf_hash(StringRef &symbolName) { 01002 unsigned h = 0, g; 01003 for (unsigned i = 0, j = symbolName.size(); i < j; i++) { 01004 h = (h << 4) + symbolName[i]; 01005 g = h & 0xf0000000L; 01006 if (g != 0) 01007 h ^= g >> 24; 01008 h &= ~g; 01009 } 01010 return h; 01011 } 01012 } // end namespace object 01013 } // end namespace llvm 01014 01015 #endif