1234285Sdim//===- ELF.h - ELF object file implementation -------------------*- C++ -*-===// 2234285Sdim// 3234285Sdim// The LLVM Compiler Infrastructure 4234285Sdim// 5234285Sdim// This file is distributed under the University of Illinois Open Source 6234285Sdim// License. See LICENSE.TXT for details. 7234285Sdim// 8234285Sdim//===----------------------------------------------------------------------===// 9234285Sdim// 10234285Sdim// This file declares the ELFObjectFile template class. 11234285Sdim// 12234285Sdim//===----------------------------------------------------------------------===// 13234285Sdim 14234285Sdim#ifndef LLVM_OBJECT_ELF_H 15234285Sdim#define LLVM_OBJECT_ELF_H 16234285Sdim 17249423Sdim#include "llvm/ADT/DenseMap.h" 18249423Sdim#include "llvm/ADT/PointerIntPair.h" 19234285Sdim#include "llvm/ADT/SmallVector.h" 20234285Sdim#include "llvm/ADT/StringSwitch.h" 21234285Sdim#include "llvm/ADT/Triple.h" 22234285Sdim#include "llvm/Object/ObjectFile.h" 23234285Sdim#include "llvm/Support/Casting.h" 24234285Sdim#include "llvm/Support/ELF.h" 25234285Sdim#include "llvm/Support/Endian.h" 26234285Sdim#include "llvm/Support/ErrorHandling.h" 27234285Sdim#include "llvm/Support/MemoryBuffer.h" 28234285Sdim#include "llvm/Support/raw_ostream.h" 29234285Sdim#include <algorithm> 30234285Sdim#include <limits> 31234285Sdim#include <utility> 32234285Sdim 33234285Sdimnamespace llvm { 34234285Sdimnamespace object { 35234285Sdim 36249423Sdimusing support::endianness; 37249423Sdim 38249423Sdimtemplate<endianness target_endianness, std::size_t max_alignment, bool is64Bits> 39249423Sdimstruct ELFType { 40249423Sdim static const endianness TargetEndianness = target_endianness; 41249423Sdim static const std::size_t MaxAlignment = max_alignment; 42249423Sdim static const bool Is64Bits = is64Bits; 43249423Sdim}; 44249423Sdim 45249423Sdimtemplate<typename T, int max_align> 46249423Sdimstruct MaximumAlignment { 47249423Sdim enum {value = AlignOf<T>::Alignment > max_align ? max_align 48249423Sdim : AlignOf<T>::Alignment}; 49249423Sdim}; 50249423Sdim 51234982Sdim// Subclasses of ELFObjectFile may need this for template instantiation 52234982Sdiminline std::pair<unsigned char, unsigned char> 53234982SdimgetElfArchType(MemoryBuffer *Object) { 54234982Sdim if (Object->getBufferSize() < ELF::EI_NIDENT) 55234982Sdim return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE); 56234982Sdim return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS] 57234982Sdim , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]); 58234982Sdim} 59234982Sdim 60234285Sdim// Templates to choose Elf_Addr and Elf_Off depending on is64Bits. 61249423Sdimtemplate<endianness target_endianness, std::size_t max_alignment> 62234285Sdimstruct ELFDataTypeTypedefHelperCommon { 63234285Sdim typedef support::detail::packed_endian_specific_integral 64249423Sdim <uint16_t, target_endianness, 65249423Sdim MaximumAlignment<uint16_t, max_alignment>::value> Elf_Half; 66234285Sdim typedef support::detail::packed_endian_specific_integral 67249423Sdim <uint32_t, target_endianness, 68249423Sdim MaximumAlignment<uint32_t, max_alignment>::value> Elf_Word; 69234285Sdim typedef support::detail::packed_endian_specific_integral 70249423Sdim <int32_t, target_endianness, 71249423Sdim MaximumAlignment<int32_t, max_alignment>::value> Elf_Sword; 72234285Sdim typedef support::detail::packed_endian_specific_integral 73249423Sdim <uint64_t, target_endianness, 74249423Sdim MaximumAlignment<uint64_t, max_alignment>::value> Elf_Xword; 75234285Sdim typedef support::detail::packed_endian_specific_integral 76249423Sdim <int64_t, target_endianness, 77249423Sdim MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword; 78234285Sdim}; 79234285Sdim 80249423Sdimtemplate<class ELFT> 81234285Sdimstruct ELFDataTypeTypedefHelper; 82234285Sdim 83234285Sdim/// ELF 32bit types. 84251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 85251662Sdimstruct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, false> > 86249423Sdim : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { 87234285Sdim typedef uint32_t value_type; 88234285Sdim typedef support::detail::packed_endian_specific_integral 89249423Sdim <value_type, TargetEndianness, 90249423Sdim MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; 91234285Sdim typedef support::detail::packed_endian_specific_integral 92249423Sdim <value_type, TargetEndianness, 93249423Sdim MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; 94234285Sdim}; 95234285Sdim 96234285Sdim/// ELF 64bit types. 97251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 98251662Sdimstruct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, true> > 99249423Sdim : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { 100234285Sdim typedef uint64_t value_type; 101234285Sdim typedef support::detail::packed_endian_specific_integral 102249423Sdim <value_type, TargetEndianness, 103249423Sdim MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; 104234285Sdim typedef support::detail::packed_endian_specific_integral 105249423Sdim <value_type, TargetEndianness, 106249423Sdim MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; 107234285Sdim}; 108234285Sdim 109234285Sdim// I really don't like doing this, but the alternative is copypasta. 110251662Sdim#define LLVM_ELF_IMPORT_TYPES(E, M, W) \ 111251662Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Addr Elf_Addr; \ 112251662Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Off Elf_Off; \ 113251662Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Half Elf_Half; \ 114251662Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Word Elf_Word; \ 115251662Sdimtypedef typename \ 116251662Sdim ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Sword Elf_Sword; \ 117251662Sdimtypedef typename \ 118251662Sdim ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Xword Elf_Xword; \ 119251662Sdimtypedef typename \ 120251662Sdim ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Sxword Elf_Sxword; 121234285Sdim 122251662Sdim#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \ 123251662Sdim LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment, \ 124251662Sdim ELFT::Is64Bits) 125249423Sdim 126251662Sdim// Section header. 127249423Sdimtemplate<class ELFT> 128234285Sdimstruct Elf_Shdr_Base; 129234285Sdim 130251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 131251662Sdimstruct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > { 132251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 133234285Sdim Elf_Word sh_name; // Section name (index into string table) 134234285Sdim Elf_Word sh_type; // Section type (SHT_*) 135234285Sdim Elf_Word sh_flags; // Section flags (SHF_*) 136234285Sdim Elf_Addr sh_addr; // Address where section is to be loaded 137234285Sdim Elf_Off sh_offset; // File offset of section data, in bytes 138234285Sdim Elf_Word sh_size; // Size of section, in bytes 139234285Sdim Elf_Word sh_link; // Section type-specific header table index link 140234285Sdim Elf_Word sh_info; // Section type-specific extra information 141234285Sdim Elf_Word sh_addralign;// Section address alignment 142234285Sdim Elf_Word sh_entsize; // Size of records contained within the section 143234285Sdim}; 144234285Sdim 145251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 146251662Sdimstruct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, true> > { 147251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 148234285Sdim Elf_Word sh_name; // Section name (index into string table) 149234285Sdim Elf_Word sh_type; // Section type (SHT_*) 150234285Sdim Elf_Xword sh_flags; // Section flags (SHF_*) 151234285Sdim Elf_Addr sh_addr; // Address where section is to be loaded 152234285Sdim Elf_Off sh_offset; // File offset of section data, in bytes 153234285Sdim Elf_Xword sh_size; // Size of section, in bytes 154234285Sdim Elf_Word sh_link; // Section type-specific header table index link 155234285Sdim Elf_Word sh_info; // Section type-specific extra information 156234285Sdim Elf_Xword sh_addralign;// Section address alignment 157234285Sdim Elf_Xword sh_entsize; // Size of records contained within the section 158234285Sdim}; 159234285Sdim 160249423Sdimtemplate<class ELFT> 161249423Sdimstruct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> { 162249423Sdim using Elf_Shdr_Base<ELFT>::sh_entsize; 163249423Sdim using Elf_Shdr_Base<ELFT>::sh_size; 164234285Sdim 165234285Sdim /// @brief Get the number of entities this section contains if it has any. 166234285Sdim unsigned getEntityCount() const { 167234285Sdim if (sh_entsize == 0) 168234285Sdim return 0; 169234285Sdim return sh_size / sh_entsize; 170234285Sdim } 171234285Sdim}; 172234285Sdim 173249423Sdimtemplate<class ELFT> 174234285Sdimstruct Elf_Sym_Base; 175234285Sdim 176251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 177251662Sdimstruct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > { 178251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 179234285Sdim Elf_Word st_name; // Symbol name (index into string table) 180234285Sdim Elf_Addr st_value; // Value or address associated with the symbol 181234285Sdim Elf_Word st_size; // Size of the symbol 182234285Sdim unsigned char st_info; // Symbol's type and binding attributes 183234285Sdim unsigned char st_other; // Must be zero; reserved 184234285Sdim Elf_Half st_shndx; // Which section (header table index) it's defined in 185234285Sdim}; 186234285Sdim 187251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 188251662Sdimstruct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > { 189251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 190234285Sdim Elf_Word st_name; // Symbol name (index into string table) 191234285Sdim unsigned char st_info; // Symbol's type and binding attributes 192234285Sdim unsigned char st_other; // Must be zero; reserved 193234285Sdim Elf_Half st_shndx; // Which section (header table index) it's defined in 194234285Sdim Elf_Addr st_value; // Value or address associated with the symbol 195234285Sdim Elf_Xword st_size; // Size of the symbol 196234285Sdim}; 197234285Sdim 198249423Sdimtemplate<class ELFT> 199249423Sdimstruct Elf_Sym_Impl : Elf_Sym_Base<ELFT> { 200249423Sdim using Elf_Sym_Base<ELFT>::st_info; 201234285Sdim 202234285Sdim // These accessors and mutators correspond to the ELF32_ST_BIND, 203234285Sdim // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification: 204234285Sdim unsigned char getBinding() const { return st_info >> 4; } 205234285Sdim unsigned char getType() const { return st_info & 0x0f; } 206234285Sdim void setBinding(unsigned char b) { setBindingAndType(b, getType()); } 207234285Sdim void setType(unsigned char t) { setBindingAndType(getBinding(), t); } 208234285Sdim void setBindingAndType(unsigned char b, unsigned char t) { 209234285Sdim st_info = (b << 4) + (t & 0x0f); 210234285Sdim } 211234285Sdim}; 212234285Sdim 213234285Sdim/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section 214234285Sdim/// (.gnu.version). This structure is identical for ELF32 and ELF64. 215249423Sdimtemplate<class ELFT> 216234285Sdimstruct Elf_Versym_Impl { 217251662Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 218234285Sdim Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN) 219234285Sdim}; 220234285Sdim 221249423Sdimtemplate<class ELFT> 222234285Sdimstruct Elf_Verdaux_Impl; 223234285Sdim 224234285Sdim/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section 225234285Sdim/// (.gnu.version_d). This structure is identical for ELF32 and ELF64. 226249423Sdimtemplate<class ELFT> 227234285Sdimstruct Elf_Verdef_Impl { 228251662Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 229249423Sdim typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux; 230234285Sdim Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT) 231234285Sdim Elf_Half vd_flags; // Bitwise flags (VER_DEF_*) 232234285Sdim Elf_Half vd_ndx; // Version index, used in .gnu.version entries 233234285Sdim Elf_Half vd_cnt; // Number of Verdaux entries 234234285Sdim Elf_Word vd_hash; // Hash of name 235234285Sdim Elf_Word vd_aux; // Offset to the first Verdaux entry (in bytes) 236234285Sdim Elf_Word vd_next; // Offset to the next Verdef entry (in bytes) 237234285Sdim 238234285Sdim /// Get the first Verdaux entry for this Verdef. 239234285Sdim const Elf_Verdaux *getAux() const { 240234285Sdim return reinterpret_cast<const Elf_Verdaux*>((const char*)this + vd_aux); 241234285Sdim } 242234285Sdim}; 243234285Sdim 244239462Sdim/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef 245234285Sdim/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64. 246249423Sdimtemplate<class ELFT> 247234285Sdimstruct Elf_Verdaux_Impl { 248251662Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 249234285Sdim Elf_Word vda_name; // Version name (offset in string table) 250234285Sdim Elf_Word vda_next; // Offset to next Verdaux entry (in bytes) 251234285Sdim}; 252234285Sdim 253234285Sdim/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed 254234285Sdim/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64. 255249423Sdimtemplate<class ELFT> 256234285Sdimstruct Elf_Verneed_Impl { 257251662Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 258234285Sdim Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT) 259234285Sdim Elf_Half vn_cnt; // Number of associated Vernaux entries 260234285Sdim Elf_Word vn_file; // Library name (string table offset) 261234285Sdim Elf_Word vn_aux; // Offset to first Vernaux entry (in bytes) 262234285Sdim Elf_Word vn_next; // Offset to next Verneed entry (in bytes) 263234285Sdim}; 264234285Sdim 265234285Sdim/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed 266234285Sdim/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64. 267249423Sdimtemplate<class ELFT> 268234285Sdimstruct Elf_Vernaux_Impl { 269251662Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 270234285Sdim Elf_Word vna_hash; // Hash of dependency name 271234285Sdim Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*) 272234285Sdim Elf_Half vna_other; // Version index, used in .gnu.version entries 273234285Sdim Elf_Word vna_name; // Dependency name 274234285Sdim Elf_Word vna_next; // Offset to next Vernaux entry (in bytes) 275234285Sdim}; 276234285Sdim 277234285Sdim/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic 278234285Sdim/// table section (.dynamic) look like. 279249423Sdimtemplate<class ELFT> 280234285Sdimstruct Elf_Dyn_Base; 281234285Sdim 282251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 283251662Sdimstruct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > { 284251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 285234285Sdim Elf_Sword d_tag; 286234285Sdim union { 287234285Sdim Elf_Word d_val; 288234285Sdim Elf_Addr d_ptr; 289234285Sdim } d_un; 290234285Sdim}; 291234285Sdim 292251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 293251662Sdimstruct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, true> > { 294251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 295234285Sdim Elf_Sxword d_tag; 296234285Sdim union { 297234285Sdim Elf_Xword d_val; 298234285Sdim Elf_Addr d_ptr; 299234285Sdim } d_un; 300234285Sdim}; 301234285Sdim 302234285Sdim/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and setters. 303249423Sdimtemplate<class ELFT> 304249423Sdimstruct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> { 305249423Sdim using Elf_Dyn_Base<ELFT>::d_tag; 306249423Sdim using Elf_Dyn_Base<ELFT>::d_un; 307234285Sdim int64_t getTag() const { return d_tag; } 308234285Sdim uint64_t getVal() const { return d_un.d_val; } 309234285Sdim uint64_t getPtr() const { return d_un.ptr; } 310234285Sdim}; 311234285Sdim 312234285Sdim// Elf_Rel: Elf Relocation 313249423Sdimtemplate<class ELFT, bool isRela> 314234285Sdimstruct Elf_Rel_Base; 315234285Sdim 316251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 317251662Sdimstruct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> { 318251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 319234285Sdim Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 320234285Sdim Elf_Word r_info; // Symbol table index and type of relocation to apply 321249423Sdim 322249423Sdim uint32_t getRInfo(bool isMips64EL) const { 323249423Sdim assert(!isMips64EL); 324249423Sdim return r_info; 325249423Sdim } 326249423Sdim void setRInfo(uint32_t R) { 327249423Sdim r_info = R; 328249423Sdim } 329234285Sdim}; 330234285Sdim 331251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 332251662Sdimstruct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> { 333251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 334234285Sdim Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 335234285Sdim Elf_Xword r_info; // Symbol table index and type of relocation to apply 336249423Sdim 337249423Sdim uint64_t getRInfo(bool isMips64EL) const { 338249423Sdim uint64_t t = r_info; 339249423Sdim if (!isMips64EL) 340249423Sdim return t; 341249423Sdim // Mip64 little endian has a "special" encoding of r_info. Instead of one 342249423Sdim // 64 bit little endian number, it is a little ending 32 bit number followed 343249423Sdim // by a 32 bit big endian number. 344249423Sdim return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | 345249423Sdim ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); 346249423Sdim return r_info; 347249423Sdim } 348249423Sdim void setRInfo(uint64_t R) { 349249423Sdim // FIXME: Add mips64el support. 350249423Sdim r_info = R; 351249423Sdim } 352234285Sdim}; 353234285Sdim 354251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 355251662Sdimstruct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> { 356251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 357234285Sdim Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 358234285Sdim Elf_Word r_info; // Symbol table index and type of relocation to apply 359234285Sdim Elf_Sword r_addend; // Compute value for relocatable field by adding this 360249423Sdim 361249423Sdim uint32_t getRInfo(bool isMips64EL) const { 362249423Sdim assert(!isMips64EL); 363249423Sdim return r_info; 364249423Sdim } 365249423Sdim void setRInfo(uint32_t R) { 366249423Sdim r_info = R; 367249423Sdim } 368234285Sdim}; 369234285Sdim 370251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 371251662Sdimstruct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> { 372251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 373234285Sdim Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 374234285Sdim Elf_Xword r_info; // Symbol table index and type of relocation to apply 375234285Sdim Elf_Sxword r_addend; // Compute value for relocatable field by adding this. 376249423Sdim 377249423Sdim uint64_t getRInfo(bool isMips64EL) const { 378249423Sdim // Mip64 little endian has a "special" encoding of r_info. Instead of one 379249423Sdim // 64 bit little endian number, it is a little ending 32 bit number followed 380249423Sdim // by a 32 bit big endian number. 381249423Sdim uint64_t t = r_info; 382249423Sdim if (!isMips64EL) 383249423Sdim return t; 384249423Sdim return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | 385249423Sdim ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); 386249423Sdim } 387249423Sdim void setRInfo(uint64_t R) { 388249423Sdim // FIXME: Add mips64el support. 389249423Sdim r_info = R; 390249423Sdim } 391234285Sdim}; 392234285Sdim 393249423Sdimtemplate<class ELFT, bool isRela> 394234285Sdimstruct Elf_Rel_Impl; 395234285Sdim 396251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign, bool isRela> 397251662Sdimstruct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>, isRela> 398251662Sdim : Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, isRela> { 399251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 400234285Sdim 401234285Sdim // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, 402234285Sdim // and ELF64_R_INFO macros defined in the ELF specification: 403249423Sdim uint32_t getSymbol(bool isMips64EL) const { 404249423Sdim return (uint32_t) (this->getRInfo(isMips64EL) >> 32); 405234285Sdim } 406249423Sdim uint32_t getType(bool isMips64EL) const { 407249423Sdim return (uint32_t) (this->getRInfo(isMips64EL) & 0xffffffffL); 408234285Sdim } 409249423Sdim void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } 410249423Sdim void setType(uint32_t t) { setSymbolAndType(getSymbol(), t); } 411249423Sdim void setSymbolAndType(uint32_t s, uint32_t t) { 412249423Sdim this->setRInfo(((uint64_t)s << 32) + (t&0xffffffffL)); 413249423Sdim } 414234285Sdim}; 415234285Sdim 416251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign, bool isRela> 417251662Sdimstruct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, false>, isRela> 418251662Sdim : Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, isRela> { 419251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 420234285Sdim 421234285Sdim // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, 422234285Sdim // and ELF32_R_INFO macros defined in the ELF specification: 423249423Sdim uint32_t getSymbol(bool isMips64EL) const { 424249423Sdim return this->getRInfo(isMips64EL) >> 8; 425249423Sdim } 426249423Sdim unsigned char getType(bool isMips64EL) const { 427249423Sdim return (unsigned char) (this->getRInfo(isMips64EL) & 0x0ff); 428249423Sdim } 429234285Sdim void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } 430234285Sdim void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } 431234285Sdim void setSymbolAndType(uint32_t s, unsigned char t) { 432249423Sdim this->setRInfo((s << 8) + t); 433234285Sdim } 434234285Sdim}; 435234285Sdim 436249423Sdimtemplate<class ELFT> 437243830Sdimstruct Elf_Ehdr_Impl { 438251662Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 439243830Sdim unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes 440243830Sdim Elf_Half e_type; // Type of file (see ET_*) 441243830Sdim Elf_Half e_machine; // Required architecture for this file (see EM_*) 442243830Sdim Elf_Word e_version; // Must be equal to 1 443243830Sdim Elf_Addr e_entry; // Address to jump to in order to start program 444243830Sdim Elf_Off e_phoff; // Program header table's file offset, in bytes 445243830Sdim Elf_Off e_shoff; // Section header table's file offset, in bytes 446243830Sdim Elf_Word e_flags; // Processor-specific flags 447243830Sdim Elf_Half e_ehsize; // Size of ELF header, in bytes 448243830Sdim Elf_Half e_phentsize;// Size of an entry in the program header table 449243830Sdim Elf_Half e_phnum; // Number of entries in the program header table 450243830Sdim Elf_Half e_shentsize;// Size of an entry in the section header table 451243830Sdim Elf_Half e_shnum; // Number of entries in the section header table 452243830Sdim Elf_Half e_shstrndx; // Section header table index of section name 453243830Sdim // string table 454243830Sdim bool checkMagic() const { 455243830Sdim return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; 456243830Sdim } 457243830Sdim unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; } 458243830Sdim unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } 459243830Sdim}; 460234285Sdim 461249423Sdimtemplate<class ELFT> 462249423Sdimstruct Elf_Phdr_Impl; 463243830Sdim 464251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 465251662Sdimstruct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > { 466251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 467243830Sdim Elf_Word p_type; // Type of segment 468243830Sdim Elf_Off p_offset; // FileOffset where segment is located, in bytes 469249423Sdim Elf_Addr p_vaddr; // Virtual Address of beginning of segment 470243830Sdim Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific) 471243830Sdim Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero) 472243830Sdim Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero) 473243830Sdim Elf_Word p_flags; // Segment flags 474243830Sdim Elf_Word p_align; // Segment alignment constraint 475243830Sdim}; 476243830Sdim 477251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign> 478251662Sdimstruct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > { 479251662Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 480243830Sdim Elf_Word p_type; // Type of segment 481243830Sdim Elf_Word p_flags; // Segment flags 482243830Sdim Elf_Off p_offset; // FileOffset where segment is located, in bytes 483249423Sdim Elf_Addr p_vaddr; // Virtual Address of beginning of segment 484243830Sdim Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific) 485249423Sdim Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero) 486249423Sdim Elf_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero) 487249423Sdim Elf_Xword p_align; // Segment alignment constraint 488243830Sdim}; 489243830Sdim 490249423Sdimtemplate<class ELFT> 491234285Sdimclass ELFObjectFile : public ObjectFile { 492251662Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 493234285Sdim 494243830Sdimpublic: 495249423Sdim /// \brief Iterate over constant sized entities. 496249423Sdim template<class EntT> 497249423Sdim class ELFEntityIterator { 498243830Sdim public: 499249423Sdim typedef ptrdiff_t difference_type; 500249423Sdim typedef EntT value_type; 501249423Sdim typedef std::random_access_iterator_tag iterator_category; 502243830Sdim typedef value_type &reference; 503243830Sdim typedef value_type *pointer; 504243830Sdim 505243830Sdim /// \brief Default construct iterator. 506249423Sdim ELFEntityIterator() : EntitySize(0), Current(0) {} 507249423Sdim ELFEntityIterator(uint64_t EntSize, const char *Start) 508249423Sdim : EntitySize(EntSize) 509243830Sdim , Current(Start) {} 510243830Sdim 511243830Sdim reference operator *() { 512243830Sdim assert(Current && "Attempted to dereference an invalid iterator!"); 513249423Sdim return *reinterpret_cast<pointer>(Current); 514243830Sdim } 515243830Sdim 516243830Sdim pointer operator ->() { 517243830Sdim assert(Current && "Attempted to dereference an invalid iterator!"); 518249423Sdim return reinterpret_cast<pointer>(Current); 519243830Sdim } 520243830Sdim 521249423Sdim bool operator ==(const ELFEntityIterator &Other) { 522249423Sdim return Current == Other.Current; 523243830Sdim } 524243830Sdim 525249423Sdim bool operator !=(const ELFEntityIterator &Other) { 526243830Sdim return !(*this == Other); 527243830Sdim } 528243830Sdim 529249423Sdim ELFEntityIterator &operator ++() { 530243830Sdim assert(Current && "Attempted to increment an invalid iterator!"); 531249423Sdim Current += EntitySize; 532243830Sdim return *this; 533243830Sdim } 534243830Sdim 535249423Sdim ELFEntityIterator operator ++(int) { 536249423Sdim ELFEntityIterator Tmp = *this; 537243830Sdim ++*this; 538243830Sdim return Tmp; 539243830Sdim } 540243830Sdim 541249423Sdim ELFEntityIterator &operator =(const ELFEntityIterator &Other) { 542249423Sdim EntitySize = Other.EntitySize; 543249423Sdim Current = Other.Current; 544249423Sdim return *this; 545249423Sdim } 546249423Sdim 547249423Sdim difference_type operator -(const ELFEntityIterator &Other) const { 548249423Sdim assert(EntitySize == Other.EntitySize && 549249423Sdim "Subtracting iterators of different EntitiySize!"); 550249423Sdim return (Current - Other.Current) / EntitySize; 551249423Sdim } 552249423Sdim 553249423Sdim const char *get() const { return Current; } 554249423Sdim 555243830Sdim private: 556249423Sdim uint64_t EntitySize; 557243830Sdim const char *Current; 558243830Sdim }; 559243830Sdim 560249423Sdim typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr; 561249423Sdim typedef Elf_Shdr_Impl<ELFT> Elf_Shdr; 562249423Sdim typedef Elf_Sym_Impl<ELFT> Elf_Sym; 563249423Sdim typedef Elf_Dyn_Impl<ELFT> Elf_Dyn; 564249423Sdim typedef Elf_Phdr_Impl<ELFT> Elf_Phdr; 565249423Sdim typedef Elf_Rel_Impl<ELFT, false> Elf_Rel; 566249423Sdim typedef Elf_Rel_Impl<ELFT, true> Elf_Rela; 567249423Sdim typedef Elf_Verdef_Impl<ELFT> Elf_Verdef; 568249423Sdim typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux; 569249423Sdim typedef Elf_Verneed_Impl<ELFT> Elf_Verneed; 570249423Sdim typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux; 571249423Sdim typedef Elf_Versym_Impl<ELFT> Elf_Versym; 572249423Sdim typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_iterator; 573249423Sdim typedef ELFEntityIterator<const Elf_Sym> Elf_Sym_iterator; 574249423Sdim typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter; 575249423Sdim typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter; 576249423Sdim 577249423Sdimprotected: 578249423Sdim // This flag is used for classof, to distinguish ELFObjectFile from 579249423Sdim // its subclass. If more subclasses will be created, this flag will 580249423Sdim // have to become an enum. 581249423Sdim bool isDyldELFObject; 582249423Sdim 583243830Sdimprivate: 584249423Sdim typedef SmallVector<const Elf_Shdr *, 2> Sections_t; 585249423Sdim typedef DenseMap<unsigned, unsigned> IndexMap_t; 586249423Sdim typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t; 587249423Sdim 588249423Sdim const Elf_Ehdr *Header; 589249423Sdim const Elf_Shdr *SectionHeaderTable; 590249423Sdim const Elf_Shdr *dot_shstrtab_sec; // Section header string table. 591249423Sdim const Elf_Shdr *dot_strtab_sec; // Symbol header string table. 592249423Sdim const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table. 593249423Sdim 594249423Sdim // SymbolTableSections[0] always points to the dynamic string table section 595249423Sdim // header, or NULL if there is no dynamic string table. 596249423Sdim Sections_t SymbolTableSections; 597249423Sdim IndexMap_t SymbolTableSectionsIndexMap; 598249423Sdim DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable; 599249423Sdim 600249423Sdim const Elf_Shdr *dot_dynamic_sec; // .dynamic 601249423Sdim const Elf_Shdr *dot_gnu_version_sec; // .gnu.version 602249423Sdim const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r 603249423Sdim const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d 604249423Sdim 605249423Sdim // Pointer to SONAME entry in dynamic string table 606249423Sdim // This is set the first time getLoadName is called. 607249423Sdim mutable const char *dt_soname; 608249423Sdim 609249423Sdimprivate: 610251662Sdim uint64_t getROffset(DataRefImpl Rel) const; 611251662Sdim 612234285Sdim // Records for each version index the corresponding Verdef or Vernaux entry. 613234285Sdim // This is filled the first time LoadVersionMap() is called. 614234285Sdim class VersionMapEntry : public PointerIntPair<const void*, 1> { 615234285Sdim public: 616234285Sdim // If the integer is 0, this is an Elf_Verdef*. 617234285Sdim // If the integer is 1, this is an Elf_Vernaux*. 618234285Sdim VersionMapEntry() : PointerIntPair<const void*, 1>(NULL, 0) { } 619234285Sdim VersionMapEntry(const Elf_Verdef *verdef) 620234285Sdim : PointerIntPair<const void*, 1>(verdef, 0) { } 621234285Sdim VersionMapEntry(const Elf_Vernaux *vernaux) 622234285Sdim : PointerIntPair<const void*, 1>(vernaux, 1) { } 623234285Sdim bool isNull() const { return getPointer() == NULL; } 624234285Sdim bool isVerdef() const { return !isNull() && getInt() == 0; } 625234285Sdim bool isVernaux() const { return !isNull() && getInt() == 1; } 626234285Sdim const Elf_Verdef *getVerdef() const { 627234285Sdim return isVerdef() ? (const Elf_Verdef*)getPointer() : NULL; 628234285Sdim } 629234285Sdim const Elf_Vernaux *getVernaux() const { 630234285Sdim return isVernaux() ? (const Elf_Vernaux*)getPointer() : NULL; 631234285Sdim } 632234285Sdim }; 633234285Sdim mutable SmallVector<VersionMapEntry, 16> VersionMap; 634234285Sdim void LoadVersionDefs(const Elf_Shdr *sec) const; 635234285Sdim void LoadVersionNeeds(const Elf_Shdr *ec) const; 636234285Sdim void LoadVersionMap() const; 637234285Sdim 638234285Sdim /// @brief Map sections to an array of relocation sections that reference 639234285Sdim /// them sorted by section index. 640234285Sdim RelocMap_t SectionRelocMap; 641234285Sdim 642234285Sdim /// @brief Get the relocation section that contains \a Rel. 643234285Sdim const Elf_Shdr *getRelSection(DataRefImpl Rel) const { 644234285Sdim return getSection(Rel.w.b); 645234285Sdim } 646234285Sdim 647249423Sdimpublic: 648234285Sdim bool isRelocationHasAddend(DataRefImpl Rel) const; 649234285Sdim template<typename T> 650234285Sdim const T *getEntry(uint16_t Section, uint32_t Entry) const; 651234285Sdim template<typename T> 652234285Sdim const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const; 653234285Sdim const Elf_Shdr *getSection(DataRefImpl index) const; 654234285Sdim const Elf_Shdr *getSection(uint32_t index) const; 655234285Sdim const Elf_Rel *getRel(DataRefImpl Rel) const; 656234285Sdim const Elf_Rela *getRela(DataRefImpl Rela) const; 657234285Sdim const char *getString(uint32_t section, uint32_t offset) const; 658234285Sdim const char *getString(const Elf_Shdr *section, uint32_t offset) const; 659234285Sdim error_code getSymbolVersion(const Elf_Shdr *section, 660234285Sdim const Elf_Sym *Symb, 661234285Sdim StringRef &Version, 662234285Sdim bool &IsDefault) const; 663234285Sdim void VerifyStrTab(const Elf_Shdr *sh) const; 664234285Sdim 665234285Sdimprotected: 666234285Sdim const Elf_Sym *getSymbol(DataRefImpl Symb) const; // FIXME: Should be private? 667234285Sdim void validateSymbol(DataRefImpl Symb) const; 668251662Sdim StringRef getRelocationTypeName(uint32_t Type) const; 669234285Sdim 670234285Sdimpublic: 671239462Sdim error_code getSymbolName(const Elf_Shdr *section, 672239462Sdim const Elf_Sym *Symb, 673239462Sdim StringRef &Res) const; 674239462Sdim error_code getSectionName(const Elf_Shdr *section, 675239462Sdim StringRef &Res) const; 676234285Sdim const Elf_Dyn *getDyn(DataRefImpl DynData) const; 677234285Sdim error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, 678234285Sdim bool &IsDefault) const; 679249423Sdim uint64_t getSymbolIndex(const Elf_Sym *sym) const; 680234285Sdimprotected: 681234285Sdim virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; 682234285Sdim virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; 683234285Sdim virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const; 684234285Sdim virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; 685251662Sdim virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const; 686234285Sdim virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; 687234285Sdim virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; 688234285Sdim virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; 689234285Sdim virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; 690234285Sdim virtual error_code getSymbolSection(DataRefImpl Symb, 691234285Sdim section_iterator &Res) const; 692243830Sdim virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; 693234285Sdim 694234285Sdim virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const; 695234285Sdim virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const; 696234285Sdim 697234285Sdim virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; 698234285Sdim virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; 699234285Sdim virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; 700234285Sdim virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; 701234285Sdim virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; 702234285Sdim virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const; 703234285Sdim virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; 704234285Sdim virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; 705234285Sdim virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; 706234285Sdim virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, 707234285Sdim bool &Res) const; 708234285Sdim virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; 709234285Sdim virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; 710243830Sdim virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const; 711234285Sdim virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, 712234285Sdim bool &Result) const; 713234285Sdim virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; 714234285Sdim virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const; 715234285Sdim 716234285Sdim virtual error_code getRelocationNext(DataRefImpl Rel, 717234285Sdim RelocationRef &Res) const; 718234285Sdim virtual error_code getRelocationAddress(DataRefImpl Rel, 719234285Sdim uint64_t &Res) const; 720234285Sdim virtual error_code getRelocationOffset(DataRefImpl Rel, 721234285Sdim uint64_t &Res) const; 722234285Sdim virtual error_code getRelocationSymbol(DataRefImpl Rel, 723234285Sdim SymbolRef &Res) const; 724234285Sdim virtual error_code getRelocationType(DataRefImpl Rel, 725234285Sdim uint64_t &Res) const; 726234285Sdim virtual error_code getRelocationTypeName(DataRefImpl Rel, 727234285Sdim SmallVectorImpl<char> &Result) const; 728234285Sdim virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, 729234285Sdim int64_t &Res) const; 730234285Sdim virtual error_code getRelocationValueString(DataRefImpl Rel, 731234285Sdim SmallVectorImpl<char> &Result) const; 732234285Sdim 733234285Sdimpublic: 734234285Sdim ELFObjectFile(MemoryBuffer *Object, error_code &ec); 735249423Sdim 736249423Sdim bool isMips64EL() const { 737249423Sdim return Header->e_machine == ELF::EM_MIPS && 738249423Sdim Header->getFileClass() == ELF::ELFCLASS64 && 739249423Sdim Header->getDataEncoding() == ELF::ELFDATA2LSB; 740249423Sdim } 741249423Sdim 742234285Sdim virtual symbol_iterator begin_symbols() const; 743234285Sdim virtual symbol_iterator end_symbols() const; 744234285Sdim 745234285Sdim virtual symbol_iterator begin_dynamic_symbols() const; 746234285Sdim virtual symbol_iterator end_dynamic_symbols() const; 747234285Sdim 748234285Sdim virtual section_iterator begin_sections() const; 749234285Sdim virtual section_iterator end_sections() const; 750234285Sdim 751234285Sdim virtual library_iterator begin_libraries_needed() const; 752234285Sdim virtual library_iterator end_libraries_needed() const; 753234285Sdim 754249423Sdim const Elf_Shdr *getDynamicSymbolTableSectionHeader() const { 755249423Sdim return SymbolTableSections[0]; 756249423Sdim } 757234285Sdim 758249423Sdim const Elf_Shdr *getDynamicStringTableSectionHeader() const { 759249423Sdim return dot_dynstr_sec; 760249423Sdim } 761243830Sdim 762249423Sdim Elf_Dyn_iterator begin_dynamic_table() const; 763249423Sdim /// \param NULLEnd use one past the first DT_NULL entry as the end instead of 764249423Sdim /// the section size. 765249423Sdim Elf_Dyn_iterator end_dynamic_table(bool NULLEnd = false) const; 766249423Sdim 767249423Sdim Elf_Sym_iterator begin_elf_dynamic_symbols() const { 768249423Sdim const Elf_Shdr *DynSymtab = SymbolTableSections[0]; 769249423Sdim if (DynSymtab) 770249423Sdim return Elf_Sym_iterator(DynSymtab->sh_entsize, 771249423Sdim (const char *)base() + DynSymtab->sh_offset); 772249423Sdim return Elf_Sym_iterator(0, 0); 773243830Sdim } 774243830Sdim 775249423Sdim Elf_Sym_iterator end_elf_dynamic_symbols() const { 776249423Sdim const Elf_Shdr *DynSymtab = SymbolTableSections[0]; 777249423Sdim if (DynSymtab) 778249423Sdim return Elf_Sym_iterator(DynSymtab->sh_entsize, (const char *)base() + 779249423Sdim DynSymtab->sh_offset + DynSymtab->sh_size); 780249423Sdim return Elf_Sym_iterator(0, 0); 781249423Sdim } 782249423Sdim 783249423Sdim Elf_Rela_Iter beginELFRela(const Elf_Shdr *sec) const { 784249423Sdim return Elf_Rela_Iter(sec->sh_entsize, 785249423Sdim (const char *)(base() + sec->sh_offset)); 786249423Sdim } 787249423Sdim 788249423Sdim Elf_Rela_Iter endELFRela(const Elf_Shdr *sec) const { 789249423Sdim return Elf_Rela_Iter(sec->sh_entsize, (const char *) 790243830Sdim (base() + sec->sh_offset + sec->sh_size)); 791243830Sdim } 792243830Sdim 793249423Sdim Elf_Rel_Iter beginELFRel(const Elf_Shdr *sec) const { 794249423Sdim return Elf_Rel_Iter(sec->sh_entsize, 795249423Sdim (const char *)(base() + sec->sh_offset)); 796243830Sdim } 797243830Sdim 798249423Sdim Elf_Rel_Iter endELFRel(const Elf_Shdr *sec) const { 799249423Sdim return Elf_Rel_Iter(sec->sh_entsize, (const char *) 800243830Sdim (base() + sec->sh_offset + sec->sh_size)); 801243830Sdim } 802243830Sdim 803249423Sdim /// \brief Iterate over program header table. 804249423Sdim typedef ELFEntityIterator<const Elf_Phdr> Elf_Phdr_Iter; 805249423Sdim 806249423Sdim Elf_Phdr_Iter begin_program_headers() const { 807249423Sdim return Elf_Phdr_Iter(Header->e_phentsize, 808249423Sdim (const char*)base() + Header->e_phoff); 809249423Sdim } 810249423Sdim 811249423Sdim Elf_Phdr_Iter end_program_headers() const { 812249423Sdim return Elf_Phdr_Iter(Header->e_phentsize, 813249423Sdim (const char*)base() + 814249423Sdim Header->e_phoff + 815249423Sdim (Header->e_phnum * Header->e_phentsize)); 816249423Sdim } 817249423Sdim 818234285Sdim virtual uint8_t getBytesInAddress() const; 819234285Sdim virtual StringRef getFileFormatName() const; 820234285Sdim virtual StringRef getObjectType() const { return "ELF"; } 821234285Sdim virtual unsigned getArch() const; 822234285Sdim virtual StringRef getLoadName() const; 823239462Sdim virtual error_code getSectionContents(const Elf_Shdr *sec, 824239462Sdim StringRef &Res) const; 825234285Sdim 826234285Sdim uint64_t getNumSections() const; 827234285Sdim uint64_t getStringTableIndex() const; 828234285Sdim ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const; 829249423Sdim const Elf_Ehdr *getElfHeader() const; 830234285Sdim const Elf_Shdr *getSection(const Elf_Sym *symb) const; 831239462Sdim const Elf_Shdr *getElfSection(section_iterator &It) const; 832239462Sdim const Elf_Sym *getElfSymbol(symbol_iterator &It) const; 833243830Sdim const Elf_Sym *getElfSymbol(uint32_t index) const; 834234285Sdim 835234285Sdim // Methods for type inquiry through isa, cast, and dyn_cast 836234285Sdim bool isDyldType() const { return isDyldELFObject; } 837234285Sdim static inline bool classof(const Binary *v) { 838249423Sdim return v->getType() == getELFType(ELFT::TargetEndianness == support::little, 839249423Sdim ELFT::Is64Bits); 840234285Sdim } 841234285Sdim}; 842234285Sdim 843234285Sdim// Iterate through the version definitions, and place each Elf_Verdef 844234285Sdim// in the VersionMap according to its index. 845249423Sdimtemplate<class ELFT> 846249423Sdimvoid ELFObjectFile<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const { 847234285Sdim unsigned vd_size = sec->sh_size; // Size of section in bytes 848234285Sdim unsigned vd_count = sec->sh_info; // Number of Verdef entries 849234285Sdim const char *sec_start = (const char*)base() + sec->sh_offset; 850234285Sdim const char *sec_end = sec_start + vd_size; 851234285Sdim // The first Verdef entry is at the start of the section. 852234285Sdim const char *p = sec_start; 853234285Sdim for (unsigned i = 0; i < vd_count; i++) { 854234285Sdim if (p + sizeof(Elf_Verdef) > sec_end) 855234285Sdim report_fatal_error("Section ended unexpectedly while scanning " 856234285Sdim "version definitions."); 857234285Sdim const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p); 858234285Sdim if (vd->vd_version != ELF::VER_DEF_CURRENT) 859234285Sdim report_fatal_error("Unexpected verdef version"); 860234285Sdim size_t index = vd->vd_ndx & ELF::VERSYM_VERSION; 861234285Sdim if (index >= VersionMap.size()) 862234285Sdim VersionMap.resize(index+1); 863234285Sdim VersionMap[index] = VersionMapEntry(vd); 864234285Sdim p += vd->vd_next; 865234285Sdim } 866234285Sdim} 867234285Sdim 868234285Sdim// Iterate through the versions needed section, and place each Elf_Vernaux 869234285Sdim// in the VersionMap according to its index. 870249423Sdimtemplate<class ELFT> 871249423Sdimvoid ELFObjectFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const { 872234285Sdim unsigned vn_size = sec->sh_size; // Size of section in bytes 873234285Sdim unsigned vn_count = sec->sh_info; // Number of Verneed entries 874234285Sdim const char *sec_start = (const char*)base() + sec->sh_offset; 875234285Sdim const char *sec_end = sec_start + vn_size; 876234285Sdim // The first Verneed entry is at the start of the section. 877234285Sdim const char *p = sec_start; 878234285Sdim for (unsigned i = 0; i < vn_count; i++) { 879234285Sdim if (p + sizeof(Elf_Verneed) > sec_end) 880234285Sdim report_fatal_error("Section ended unexpectedly while scanning " 881234285Sdim "version needed records."); 882234285Sdim const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p); 883234285Sdim if (vn->vn_version != ELF::VER_NEED_CURRENT) 884234285Sdim report_fatal_error("Unexpected verneed version"); 885234285Sdim // Iterate through the Vernaux entries 886234285Sdim const char *paux = p + vn->vn_aux; 887234285Sdim for (unsigned j = 0; j < vn->vn_cnt; j++) { 888234285Sdim if (paux + sizeof(Elf_Vernaux) > sec_end) 889234285Sdim report_fatal_error("Section ended unexpected while scanning auxiliary " 890234285Sdim "version needed records."); 891234285Sdim const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux); 892234285Sdim size_t index = vna->vna_other & ELF::VERSYM_VERSION; 893234285Sdim if (index >= VersionMap.size()) 894234285Sdim VersionMap.resize(index+1); 895234285Sdim VersionMap[index] = VersionMapEntry(vna); 896234285Sdim paux += vna->vna_next; 897234285Sdim } 898234285Sdim p += vn->vn_next; 899234285Sdim } 900234285Sdim} 901234285Sdim 902249423Sdimtemplate<class ELFT> 903249423Sdimvoid ELFObjectFile<ELFT>::LoadVersionMap() const { 904234285Sdim // If there is no dynamic symtab or version table, there is nothing to do. 905234285Sdim if (SymbolTableSections[0] == NULL || dot_gnu_version_sec == NULL) 906234285Sdim return; 907234285Sdim 908234285Sdim // Has the VersionMap already been loaded? 909234285Sdim if (VersionMap.size() > 0) 910234285Sdim return; 911234285Sdim 912234285Sdim // The first two version indexes are reserved. 913234285Sdim // Index 0 is LOCAL, index 1 is GLOBAL. 914234285Sdim VersionMap.push_back(VersionMapEntry()); 915234285Sdim VersionMap.push_back(VersionMapEntry()); 916234285Sdim 917234285Sdim if (dot_gnu_version_d_sec) 918234285Sdim LoadVersionDefs(dot_gnu_version_d_sec); 919234285Sdim 920234285Sdim if (dot_gnu_version_r_sec) 921234285Sdim LoadVersionNeeds(dot_gnu_version_r_sec); 922234285Sdim} 923234285Sdim 924249423Sdimtemplate<class ELFT> 925249423Sdimvoid ELFObjectFile<ELFT>::validateSymbol(DataRefImpl Symb) const { 926249423Sdim#ifndef NDEBUG 927234285Sdim const Elf_Sym *symb = getSymbol(Symb); 928234285Sdim const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b]; 929234285Sdim // FIXME: We really need to do proper error handling in the case of an invalid 930234285Sdim // input file. Because we don't use exceptions, I think we'll just pass 931234285Sdim // an error object around. 932234285Sdim if (!( symb 933234285Sdim && SymbolTableSection 934234285Sdim && symb >= (const Elf_Sym*)(base() 935234285Sdim + SymbolTableSection->sh_offset) 936234285Sdim && symb < (const Elf_Sym*)(base() 937234285Sdim + SymbolTableSection->sh_offset 938234285Sdim + SymbolTableSection->sh_size))) 939234285Sdim // FIXME: Proper error handling. 940234285Sdim report_fatal_error("Symb must point to a valid symbol!"); 941249423Sdim#endif 942234285Sdim} 943234285Sdim 944249423Sdimtemplate<class ELFT> 945249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolNext(DataRefImpl Symb, 946249423Sdim SymbolRef &Result) const { 947234285Sdim validateSymbol(Symb); 948234285Sdim const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b]; 949234285Sdim 950234285Sdim ++Symb.d.a; 951234285Sdim // Check to see if we are at the end of this symbol table. 952234285Sdim if (Symb.d.a >= SymbolTableSection->getEntityCount()) { 953234285Sdim // We are at the end. If there are other symbol tables, jump to them. 954234285Sdim // If the symbol table is .dynsym, we are iterating dynamic symbols, 955234285Sdim // and there is only one table of these. 956234285Sdim if (Symb.d.b != 0) { 957234285Sdim ++Symb.d.b; 958234285Sdim Symb.d.a = 1; // The 0th symbol in ELF is fake. 959234285Sdim } 960234285Sdim // Otherwise return the terminator. 961234285Sdim if (Symb.d.b == 0 || Symb.d.b >= SymbolTableSections.size()) { 962234285Sdim Symb.d.a = std::numeric_limits<uint32_t>::max(); 963234285Sdim Symb.d.b = std::numeric_limits<uint32_t>::max(); 964234285Sdim } 965234285Sdim } 966234285Sdim 967234285Sdim Result = SymbolRef(Symb, this); 968234285Sdim return object_error::success; 969234285Sdim} 970234285Sdim 971249423Sdimtemplate<class ELFT> 972249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb, 973249423Sdim StringRef &Result) const { 974234285Sdim validateSymbol(Symb); 975234285Sdim const Elf_Sym *symb = getSymbol(Symb); 976234285Sdim return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result); 977234285Sdim} 978234285Sdim 979249423Sdimtemplate<class ELFT> 980249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef, 981249423Sdim StringRef &Version, 982249423Sdim bool &IsDefault) const { 983234285Sdim DataRefImpl Symb = SymRef.getRawDataRefImpl(); 984234285Sdim validateSymbol(Symb); 985234285Sdim const Elf_Sym *symb = getSymbol(Symb); 986234285Sdim return getSymbolVersion(SymbolTableSections[Symb.d.b], symb, 987234285Sdim Version, IsDefault); 988234285Sdim} 989234285Sdim 990249423Sdimtemplate<class ELFT> 991249423SdimELF::Elf64_Word ELFObjectFile<ELFT> 992249423Sdim ::getSymbolTableIndex(const Elf_Sym *symb) const { 993234285Sdim if (symb->st_shndx == ELF::SHN_XINDEX) 994234285Sdim return ExtendedSymbolTable.lookup(symb); 995234285Sdim return symb->st_shndx; 996234285Sdim} 997234285Sdim 998249423Sdimtemplate<class ELFT> 999249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Shdr * 1000249423SdimELFObjectFile<ELFT>::getSection(const Elf_Sym *symb) const { 1001234285Sdim if (symb->st_shndx == ELF::SHN_XINDEX) 1002234285Sdim return getSection(ExtendedSymbolTable.lookup(symb)); 1003234285Sdim if (symb->st_shndx >= ELF::SHN_LORESERVE) 1004234285Sdim return 0; 1005234285Sdim return getSection(symb->st_shndx); 1006234285Sdim} 1007234285Sdim 1008249423Sdimtemplate<class ELFT> 1009249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Ehdr * 1010249423SdimELFObjectFile<ELFT>::getElfHeader() const { 1011249423Sdim return Header; 1012249423Sdim} 1013249423Sdim 1014249423Sdimtemplate<class ELFT> 1015249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Shdr * 1016249423SdimELFObjectFile<ELFT>::getElfSection(section_iterator &It) const { 1017239462Sdim llvm::object::DataRefImpl ShdrRef = It->getRawDataRefImpl(); 1018239462Sdim return reinterpret_cast<const Elf_Shdr *>(ShdrRef.p); 1019239462Sdim} 1020239462Sdim 1021249423Sdimtemplate<class ELFT> 1022249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Sym * 1023249423SdimELFObjectFile<ELFT>::getElfSymbol(symbol_iterator &It) const { 1024239462Sdim return getSymbol(It->getRawDataRefImpl()); 1025239462Sdim} 1026239462Sdim 1027249423Sdimtemplate<class ELFT> 1028249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Sym * 1029249423SdimELFObjectFile<ELFT>::getElfSymbol(uint32_t index) const { 1030243830Sdim DataRefImpl SymbolData; 1031243830Sdim SymbolData.d.a = index; 1032243830Sdim SymbolData.d.b = 1; 1033243830Sdim return getSymbol(SymbolData); 1034243830Sdim} 1035243830Sdim 1036249423Sdimtemplate<class ELFT> 1037249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb, 1038249423Sdim uint64_t &Result) const { 1039234285Sdim validateSymbol(Symb); 1040234285Sdim const Elf_Sym *symb = getSymbol(Symb); 1041234285Sdim const Elf_Shdr *Section; 1042234285Sdim switch (getSymbolTableIndex(symb)) { 1043234285Sdim case ELF::SHN_COMMON: 1044234285Sdim // Unintialized symbols have no offset in the object file 1045234285Sdim case ELF::SHN_UNDEF: 1046234285Sdim Result = UnknownAddressOrSize; 1047234285Sdim return object_error::success; 1048234285Sdim case ELF::SHN_ABS: 1049234285Sdim Result = symb->st_value; 1050234285Sdim return object_error::success; 1051234285Sdim default: Section = getSection(symb); 1052234285Sdim } 1053234285Sdim 1054234285Sdim switch (symb->getType()) { 1055234285Sdim case ELF::STT_SECTION: 1056249423Sdim Result = Section ? Section->sh_offset : UnknownAddressOrSize; 1057234285Sdim return object_error::success; 1058234285Sdim case ELF::STT_FUNC: 1059234285Sdim case ELF::STT_OBJECT: 1060234285Sdim case ELF::STT_NOTYPE: 1061234285Sdim Result = symb->st_value + 1062234285Sdim (Section ? Section->sh_offset : 0); 1063234285Sdim return object_error::success; 1064234285Sdim default: 1065234285Sdim Result = UnknownAddressOrSize; 1066234285Sdim return object_error::success; 1067234285Sdim } 1068234285Sdim} 1069234285Sdim 1070249423Sdimtemplate<class ELFT> 1071249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, 1072249423Sdim uint64_t &Result) const { 1073234285Sdim validateSymbol(Symb); 1074234285Sdim const Elf_Sym *symb = getSymbol(Symb); 1075234285Sdim const Elf_Shdr *Section; 1076234285Sdim switch (getSymbolTableIndex(symb)) { 1077234285Sdim case ELF::SHN_COMMON: 1078234285Sdim case ELF::SHN_UNDEF: 1079234285Sdim Result = UnknownAddressOrSize; 1080234285Sdim return object_error::success; 1081234285Sdim case ELF::SHN_ABS: 1082234285Sdim Result = symb->st_value; 1083234285Sdim return object_error::success; 1084234285Sdim default: Section = getSection(symb); 1085234285Sdim } 1086234285Sdim 1087234285Sdim switch (symb->getType()) { 1088234285Sdim case ELF::STT_SECTION: 1089234285Sdim Result = Section ? Section->sh_addr : UnknownAddressOrSize; 1090234285Sdim return object_error::success; 1091234285Sdim case ELF::STT_FUNC: 1092234285Sdim case ELF::STT_OBJECT: 1093234285Sdim case ELF::STT_NOTYPE: 1094243830Sdim bool IsRelocatable; 1095243830Sdim switch(Header->e_type) { 1096243830Sdim case ELF::ET_EXEC: 1097243830Sdim case ELF::ET_DYN: 1098243830Sdim IsRelocatable = false; 1099243830Sdim break; 1100243830Sdim default: 1101243830Sdim IsRelocatable = true; 1102243830Sdim } 1103243830Sdim Result = symb->st_value; 1104249423Sdim 1105249423Sdim // Clear the ARM/Thumb indicator flag. 1106249423Sdim if (Header->e_machine == ELF::EM_ARM) 1107249423Sdim Result &= ~1; 1108249423Sdim 1109243830Sdim if (IsRelocatable && Section != 0) 1110243830Sdim Result += Section->sh_addr; 1111234285Sdim return object_error::success; 1112234285Sdim default: 1113234285Sdim Result = UnknownAddressOrSize; 1114234285Sdim return object_error::success; 1115234285Sdim } 1116234285Sdim} 1117234285Sdim 1118249423Sdimtemplate<class ELFT> 1119251662Sdimerror_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb, 1120251662Sdim uint32_t &Res) const { 1121251662Sdim uint32_t flags; 1122251662Sdim getSymbolFlags(Symb, flags); 1123251662Sdim if (flags & SymbolRef::SF_Common) { 1124251662Sdim uint64_t Value; 1125251662Sdim getSymbolValue(Symb, Value); 1126251662Sdim Res = Value; 1127251662Sdim } else { 1128251662Sdim Res = 0; 1129251662Sdim } 1130251662Sdim return object_error::success; 1131251662Sdim} 1132251662Sdim 1133251662Sdimtemplate<class ELFT> 1134249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb, 1135249423Sdim uint64_t &Result) const { 1136234285Sdim validateSymbol(Symb); 1137234285Sdim const Elf_Sym *symb = getSymbol(Symb); 1138234285Sdim if (symb->st_size == 0) 1139234285Sdim Result = UnknownAddressOrSize; 1140234285Sdim Result = symb->st_size; 1141234285Sdim return object_error::success; 1142234285Sdim} 1143234285Sdim 1144249423Sdimtemplate<class ELFT> 1145249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolNMTypeChar(DataRefImpl Symb, 1146249423Sdim char &Result) const { 1147234285Sdim validateSymbol(Symb); 1148234285Sdim const Elf_Sym *symb = getSymbol(Symb); 1149234285Sdim const Elf_Shdr *Section = getSection(symb); 1150234285Sdim 1151234285Sdim char ret = '?'; 1152234285Sdim 1153234285Sdim if (Section) { 1154234285Sdim switch (Section->sh_type) { 1155234285Sdim case ELF::SHT_PROGBITS: 1156234285Sdim case ELF::SHT_DYNAMIC: 1157234285Sdim switch (Section->sh_flags) { 1158234285Sdim case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): 1159234285Sdim ret = 't'; break; 1160234285Sdim case (ELF::SHF_ALLOC | ELF::SHF_WRITE): 1161234285Sdim ret = 'd'; break; 1162234285Sdim case ELF::SHF_ALLOC: 1163234285Sdim case (ELF::SHF_ALLOC | ELF::SHF_MERGE): 1164234285Sdim case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): 1165234285Sdim ret = 'r'; break; 1166234285Sdim } 1167234285Sdim break; 1168234285Sdim case ELF::SHT_NOBITS: ret = 'b'; 1169234285Sdim } 1170234285Sdim } 1171234285Sdim 1172234285Sdim switch (getSymbolTableIndex(symb)) { 1173234285Sdim case ELF::SHN_UNDEF: 1174234285Sdim if (ret == '?') 1175234285Sdim ret = 'U'; 1176234285Sdim break; 1177234285Sdim case ELF::SHN_ABS: ret = 'a'; break; 1178234285Sdim case ELF::SHN_COMMON: ret = 'c'; break; 1179234285Sdim } 1180234285Sdim 1181234285Sdim switch (symb->getBinding()) { 1182234285Sdim case ELF::STB_GLOBAL: ret = ::toupper(ret); break; 1183234285Sdim case ELF::STB_WEAK: 1184234285Sdim if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF) 1185234285Sdim ret = 'w'; 1186234285Sdim else 1187234285Sdim if (symb->getType() == ELF::STT_OBJECT) 1188234285Sdim ret = 'V'; 1189234285Sdim else 1190234285Sdim ret = 'W'; 1191234285Sdim } 1192234285Sdim 1193234285Sdim if (ret == '?' && symb->getType() == ELF::STT_SECTION) { 1194234285Sdim StringRef name; 1195234285Sdim if (error_code ec = getSymbolName(Symb, name)) 1196234285Sdim return ec; 1197234285Sdim Result = StringSwitch<char>(name) 1198234285Sdim .StartsWith(".debug", 'N') 1199234285Sdim .StartsWith(".note", 'n') 1200234285Sdim .Default('?'); 1201234285Sdim return object_error::success; 1202234285Sdim } 1203234285Sdim 1204234285Sdim Result = ret; 1205234285Sdim return object_error::success; 1206234285Sdim} 1207234285Sdim 1208249423Sdimtemplate<class ELFT> 1209249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb, 1210249423Sdim SymbolRef::Type &Result) const { 1211234285Sdim validateSymbol(Symb); 1212234285Sdim const Elf_Sym *symb = getSymbol(Symb); 1213234285Sdim 1214234285Sdim switch (symb->getType()) { 1215234285Sdim case ELF::STT_NOTYPE: 1216234285Sdim Result = SymbolRef::ST_Unknown; 1217234285Sdim break; 1218234285Sdim case ELF::STT_SECTION: 1219234285Sdim Result = SymbolRef::ST_Debug; 1220234285Sdim break; 1221234285Sdim case ELF::STT_FILE: 1222234285Sdim Result = SymbolRef::ST_File; 1223234285Sdim break; 1224234285Sdim case ELF::STT_FUNC: 1225234285Sdim Result = SymbolRef::ST_Function; 1226234285Sdim break; 1227234285Sdim case ELF::STT_OBJECT: 1228234285Sdim case ELF::STT_COMMON: 1229234285Sdim case ELF::STT_TLS: 1230234285Sdim Result = SymbolRef::ST_Data; 1231234285Sdim break; 1232234285Sdim default: 1233234285Sdim Result = SymbolRef::ST_Other; 1234234285Sdim break; 1235234285Sdim } 1236234285Sdim return object_error::success; 1237234285Sdim} 1238234285Sdim 1239249423Sdimtemplate<class ELFT> 1240249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb, 1241249423Sdim uint32_t &Result) const { 1242234285Sdim validateSymbol(Symb); 1243234285Sdim const Elf_Sym *symb = getSymbol(Symb); 1244234285Sdim 1245234285Sdim Result = SymbolRef::SF_None; 1246234285Sdim 1247234285Sdim if (symb->getBinding() != ELF::STB_LOCAL) 1248234285Sdim Result |= SymbolRef::SF_Global; 1249234285Sdim 1250234285Sdim if (symb->getBinding() == ELF::STB_WEAK) 1251234285Sdim Result |= SymbolRef::SF_Weak; 1252234285Sdim 1253234285Sdim if (symb->st_shndx == ELF::SHN_ABS) 1254234285Sdim Result |= SymbolRef::SF_Absolute; 1255234285Sdim 1256234285Sdim if (symb->getType() == ELF::STT_FILE || 1257234285Sdim symb->getType() == ELF::STT_SECTION) 1258234285Sdim Result |= SymbolRef::SF_FormatSpecific; 1259234285Sdim 1260234285Sdim if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF) 1261234285Sdim Result |= SymbolRef::SF_Undefined; 1262234285Sdim 1263234285Sdim if (symb->getType() == ELF::STT_COMMON || 1264234285Sdim getSymbolTableIndex(symb) == ELF::SHN_COMMON) 1265234285Sdim Result |= SymbolRef::SF_Common; 1266234285Sdim 1267234285Sdim if (symb->getType() == ELF::STT_TLS) 1268234285Sdim Result |= SymbolRef::SF_ThreadLocal; 1269234285Sdim 1270234285Sdim return object_error::success; 1271234285Sdim} 1272234285Sdim 1273249423Sdimtemplate<class ELFT> 1274249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, 1275249423Sdim section_iterator &Res) const { 1276234285Sdim validateSymbol(Symb); 1277234285Sdim const Elf_Sym *symb = getSymbol(Symb); 1278234285Sdim const Elf_Shdr *sec = getSection(symb); 1279234285Sdim if (!sec) 1280234285Sdim Res = end_sections(); 1281234285Sdim else { 1282234285Sdim DataRefImpl Sec; 1283234285Sdim Sec.p = reinterpret_cast<intptr_t>(sec); 1284234285Sdim Res = section_iterator(SectionRef(Sec, this)); 1285234285Sdim } 1286234285Sdim return object_error::success; 1287234285Sdim} 1288234285Sdim 1289249423Sdimtemplate<class ELFT> 1290249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb, 1291249423Sdim uint64_t &Val) const { 1292243830Sdim validateSymbol(Symb); 1293243830Sdim const Elf_Sym *symb = getSymbol(Symb); 1294243830Sdim Val = symb->st_value; 1295243830Sdim return object_error::success; 1296243830Sdim} 1297243830Sdim 1298249423Sdimtemplate<class ELFT> 1299249423Sdimerror_code ELFObjectFile<ELFT>::getSectionNext(DataRefImpl Sec, 1300249423Sdim SectionRef &Result) const { 1301234285Sdim const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p); 1302234285Sdim sec += Header->e_shentsize; 1303234285Sdim Sec.p = reinterpret_cast<intptr_t>(sec); 1304234285Sdim Result = SectionRef(Sec, this); 1305234285Sdim return object_error::success; 1306234285Sdim} 1307234285Sdim 1308249423Sdimtemplate<class ELFT> 1309249423Sdimerror_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, 1310249423Sdim StringRef &Result) const { 1311234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1312234285Sdim Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name)); 1313234285Sdim return object_error::success; 1314234285Sdim} 1315234285Sdim 1316249423Sdimtemplate<class ELFT> 1317249423Sdimerror_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec, 1318249423Sdim uint64_t &Result) const { 1319234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1320234285Sdim Result = sec->sh_addr; 1321234285Sdim return object_error::success; 1322234285Sdim} 1323234285Sdim 1324249423Sdimtemplate<class ELFT> 1325249423Sdimerror_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec, 1326249423Sdim uint64_t &Result) const { 1327234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1328234285Sdim Result = sec->sh_size; 1329234285Sdim return object_error::success; 1330234285Sdim} 1331234285Sdim 1332249423Sdimtemplate<class ELFT> 1333249423Sdimerror_code ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec, 1334249423Sdim StringRef &Result) const { 1335234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1336234285Sdim const char *start = (const char*)base() + sec->sh_offset; 1337234285Sdim Result = StringRef(start, sec->sh_size); 1338234285Sdim return object_error::success; 1339234285Sdim} 1340234285Sdim 1341249423Sdimtemplate<class ELFT> 1342249423Sdimerror_code ELFObjectFile<ELFT>::getSectionContents(const Elf_Shdr *Sec, 1343249423Sdim StringRef &Result) const { 1344239462Sdim const char *start = (const char*)base() + Sec->sh_offset; 1345239462Sdim Result = StringRef(start, Sec->sh_size); 1346239462Sdim return object_error::success; 1347239462Sdim} 1348239462Sdim 1349249423Sdimtemplate<class ELFT> 1350249423Sdimerror_code ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec, 1351249423Sdim uint64_t &Result) const { 1352234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1353234285Sdim Result = sec->sh_addralign; 1354234285Sdim return object_error::success; 1355234285Sdim} 1356234285Sdim 1357249423Sdimtemplate<class ELFT> 1358249423Sdimerror_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec, 1359249423Sdim bool &Result) const { 1360234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1361234285Sdim if (sec->sh_flags & ELF::SHF_EXECINSTR) 1362234285Sdim Result = true; 1363234285Sdim else 1364234285Sdim Result = false; 1365234285Sdim return object_error::success; 1366234285Sdim} 1367234285Sdim 1368249423Sdimtemplate<class ELFT> 1369249423Sdimerror_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec, 1370249423Sdim bool &Result) const { 1371234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1372234285Sdim if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) 1373234285Sdim && sec->sh_type == ELF::SHT_PROGBITS) 1374234285Sdim Result = true; 1375234285Sdim else 1376234285Sdim Result = false; 1377234285Sdim return object_error::success; 1378234285Sdim} 1379234285Sdim 1380249423Sdimtemplate<class ELFT> 1381249423Sdimerror_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec, 1382249423Sdim bool &Result) const { 1383234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1384234285Sdim if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) 1385234285Sdim && sec->sh_type == ELF::SHT_NOBITS) 1386234285Sdim Result = true; 1387234285Sdim else 1388234285Sdim Result = false; 1389234285Sdim return object_error::success; 1390234285Sdim} 1391234285Sdim 1392249423Sdimtemplate<class ELFT> 1393249423Sdimerror_code ELFObjectFile<ELFT>::isSectionRequiredForExecution( 1394249423Sdim DataRefImpl Sec, bool &Result) const { 1395234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1396234285Sdim if (sec->sh_flags & ELF::SHF_ALLOC) 1397234285Sdim Result = true; 1398234285Sdim else 1399234285Sdim Result = false; 1400234285Sdim return object_error::success; 1401234285Sdim} 1402234285Sdim 1403249423Sdimtemplate<class ELFT> 1404249423Sdimerror_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec, 1405249423Sdim bool &Result) const { 1406234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1407234285Sdim if (sec->sh_type == ELF::SHT_NOBITS) 1408234285Sdim Result = true; 1409234285Sdim else 1410234285Sdim Result = false; 1411234285Sdim return object_error::success; 1412234285Sdim} 1413234285Sdim 1414249423Sdimtemplate<class ELFT> 1415249423Sdimerror_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec, 1416249423Sdim bool &Result) const { 1417234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1418234285Sdim // For ELF, all zero-init sections are virtual (that is, they occupy no space 1419234285Sdim // in the object image) and vice versa. 1420249423Sdim Result = sec->sh_type == ELF::SHT_NOBITS; 1421234285Sdim return object_error::success; 1422234285Sdim} 1423234285Sdim 1424249423Sdimtemplate<class ELFT> 1425249423Sdimerror_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec, 1426249423Sdim bool &Result) const { 1427243830Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1428243830Sdim if (sec->sh_flags & ELF::SHF_WRITE || sec->sh_flags & ELF::SHF_EXECINSTR) 1429243830Sdim Result = false; 1430243830Sdim else 1431243830Sdim Result = true; 1432243830Sdim return object_error::success; 1433243830Sdim} 1434243830Sdim 1435249423Sdimtemplate<class ELFT> 1436249423Sdimerror_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec, 1437249423Sdim DataRefImpl Symb, 1438249423Sdim bool &Result) const { 1439249423Sdim validateSymbol(Symb); 1440249423Sdim 1441249423Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1442249423Sdim const Elf_Sym *symb = getSymbol(Symb); 1443249423Sdim 1444249423Sdim unsigned shndx = symb->st_shndx; 1445249423Sdim bool Reserved = shndx >= ELF::SHN_LORESERVE 1446249423Sdim && shndx <= ELF::SHN_HIRESERVE; 1447249423Sdim 1448249423Sdim Result = !Reserved && (sec == getSection(symb->st_shndx)); 1449234285Sdim return object_error::success; 1450234285Sdim} 1451234285Sdim 1452249423Sdimtemplate<class ELFT> 1453249423Sdimrelocation_iterator 1454249423SdimELFObjectFile<ELFT>::getSectionRelBegin(DataRefImpl Sec) const { 1455234285Sdim DataRefImpl RelData; 1456234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1457234285Sdim typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); 1458234285Sdim if (sec != 0 && ittr != SectionRelocMap.end()) { 1459234285Sdim RelData.w.a = getSection(ittr->second[0])->sh_info; 1460234285Sdim RelData.w.b = ittr->second[0]; 1461234285Sdim RelData.w.c = 0; 1462234285Sdim } 1463234285Sdim return relocation_iterator(RelocationRef(RelData, this)); 1464234285Sdim} 1465234285Sdim 1466249423Sdimtemplate<class ELFT> 1467249423Sdimrelocation_iterator 1468249423SdimELFObjectFile<ELFT>::getSectionRelEnd(DataRefImpl Sec) const { 1469234285Sdim DataRefImpl RelData; 1470234285Sdim const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1471234285Sdim typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); 1472234285Sdim if (sec != 0 && ittr != SectionRelocMap.end()) { 1473234285Sdim // Get the index of the last relocation section for this section. 1474234285Sdim std::size_t relocsecindex = ittr->second[ittr->second.size() - 1]; 1475234285Sdim const Elf_Shdr *relocsec = getSection(relocsecindex); 1476234285Sdim RelData.w.a = relocsec->sh_info; 1477234285Sdim RelData.w.b = relocsecindex; 1478234285Sdim RelData.w.c = relocsec->sh_size / relocsec->sh_entsize; 1479234285Sdim } 1480234285Sdim return relocation_iterator(RelocationRef(RelData, this)); 1481234285Sdim} 1482234285Sdim 1483234285Sdim// Relocations 1484249423Sdimtemplate<class ELFT> 1485249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel, 1486249423Sdim RelocationRef &Result) const { 1487234285Sdim ++Rel.w.c; 1488234285Sdim const Elf_Shdr *relocsec = getSection(Rel.w.b); 1489234285Sdim if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) { 1490234285Sdim // We have reached the end of the relocations for this section. See if there 1491234285Sdim // is another relocation section. 1492234285Sdim typename RelocMap_t::mapped_type relocseclist = 1493234285Sdim SectionRelocMap.lookup(getSection(Rel.w.a)); 1494234285Sdim 1495234285Sdim // Do a binary search for the current reloc section index (which must be 1496234285Sdim // present). Then get the next one. 1497234285Sdim typename RelocMap_t::mapped_type::const_iterator loc = 1498234285Sdim std::lower_bound(relocseclist.begin(), relocseclist.end(), Rel.w.b); 1499234285Sdim ++loc; 1500234285Sdim 1501234285Sdim // If there is no next one, don't do anything. The ++Rel.w.c above sets Rel 1502234285Sdim // to the end iterator. 1503234285Sdim if (loc != relocseclist.end()) { 1504234285Sdim Rel.w.b = *loc; 1505234285Sdim Rel.w.a = 0; 1506234285Sdim } 1507234285Sdim } 1508234285Sdim Result = RelocationRef(Rel, this); 1509234285Sdim return object_error::success; 1510234285Sdim} 1511234285Sdim 1512249423Sdimtemplate<class ELFT> 1513249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel, 1514249423Sdim SymbolRef &Result) const { 1515234285Sdim uint32_t symbolIdx; 1516234285Sdim const Elf_Shdr *sec = getSection(Rel.w.b); 1517234285Sdim switch (sec->sh_type) { 1518234285Sdim default : 1519234285Sdim report_fatal_error("Invalid section type in Rel!"); 1520234285Sdim case ELF::SHT_REL : { 1521249423Sdim symbolIdx = getRel(Rel)->getSymbol(isMips64EL()); 1522234285Sdim break; 1523234285Sdim } 1524234285Sdim case ELF::SHT_RELA : { 1525249423Sdim symbolIdx = getRela(Rel)->getSymbol(isMips64EL()); 1526234285Sdim break; 1527234285Sdim } 1528234285Sdim } 1529234285Sdim DataRefImpl SymbolData; 1530234285Sdim IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_link); 1531234285Sdim if (it == SymbolTableSectionsIndexMap.end()) 1532234285Sdim report_fatal_error("Relocation symbol table not found!"); 1533234285Sdim SymbolData.d.a = symbolIdx; 1534234285Sdim SymbolData.d.b = it->second; 1535234285Sdim Result = SymbolRef(SymbolData, this); 1536234285Sdim return object_error::success; 1537234285Sdim} 1538234285Sdim 1539249423Sdimtemplate<class ELFT> 1540249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, 1541249423Sdim uint64_t &Result) const { 1542251662Sdim assert((Header->e_type == ELF::ET_EXEC || Header->e_type == ELF::ET_DYN) && 1543251662Sdim "Only executable and shared objects files have addresses"); 1544251662Sdim Result = getROffset(Rel); 1545234285Sdim return object_error::success; 1546234285Sdim} 1547234285Sdim 1548249423Sdimtemplate<class ELFT> 1549249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel, 1550249423Sdim uint64_t &Result) const { 1551251662Sdim assert(Header->e_type == ELF::ET_REL && 1552251662Sdim "Only relocatable object files have relocation offsets"); 1553251662Sdim Result = getROffset(Rel); 1554251662Sdim return object_error::success; 1555251662Sdim} 1556251662Sdim 1557251662Sdimtemplate<class ELFT> 1558251662Sdimuint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const { 1559234285Sdim const Elf_Shdr *sec = getSection(Rel.w.b); 1560234285Sdim switch (sec->sh_type) { 1561251662Sdim default: 1562251662Sdim report_fatal_error("Invalid section type in Rel!"); 1563251662Sdim case ELF::SHT_REL: 1564251662Sdim return getRel(Rel)->r_offset; 1565251662Sdim case ELF::SHT_RELA: 1566251662Sdim return getRela(Rel)->r_offset; 1567234285Sdim } 1568234285Sdim} 1569234285Sdim 1570249423Sdimtemplate<class ELFT> 1571249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel, 1572249423Sdim uint64_t &Result) const { 1573234285Sdim const Elf_Shdr *sec = getSection(Rel.w.b); 1574234285Sdim switch (sec->sh_type) { 1575234285Sdim default : 1576234285Sdim report_fatal_error("Invalid section type in Rel!"); 1577234285Sdim case ELF::SHT_REL : { 1578249423Sdim Result = getRel(Rel)->getType(isMips64EL()); 1579234285Sdim break; 1580234285Sdim } 1581234285Sdim case ELF::SHT_RELA : { 1582249423Sdim Result = getRela(Rel)->getType(isMips64EL()); 1583234285Sdim break; 1584234285Sdim } 1585234285Sdim } 1586234285Sdim return object_error::success; 1587234285Sdim} 1588234285Sdim 1589234285Sdim#define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \ 1590251662Sdim case ELF::enum: Res = #enum; break; 1591234285Sdim 1592249423Sdimtemplate<class ELFT> 1593251662SdimStringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const { 1594251662Sdim StringRef Res = "Unknown"; 1595234285Sdim switch (Header->e_machine) { 1596234285Sdim case ELF::EM_X86_64: 1597251662Sdim switch (Type) { 1598234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE); 1599234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64); 1600234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32); 1601234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT32); 1602234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLT32); 1603234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_COPY); 1604234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GLOB_DAT); 1605234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_JUMP_SLOT); 1606234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_RELATIVE); 1607234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL); 1608234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32); 1609234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32S); 1610234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_16); 1611234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC16); 1612234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_8); 1613234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC8); 1614234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPMOD64); 1615234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF64); 1616234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF64); 1617234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSGD); 1618234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSLD); 1619234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF32); 1620234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTTPOFF); 1621234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF32); 1622234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64); 1623234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64); 1624234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32); 1625251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT64); 1626251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL64); 1627251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC64); 1628251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPLT64); 1629251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLTOFF64); 1630234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32); 1631234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64); 1632234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC); 1633234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL); 1634234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC); 1635251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_IRELATIVE); 1636251662Sdim default: break; 1637234285Sdim } 1638234285Sdim break; 1639234285Sdim case ELF::EM_386: 1640251662Sdim switch (Type) { 1641234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE); 1642234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32); 1643234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32); 1644234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOT32); 1645234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PLT32); 1646234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_COPY); 1647234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GLOB_DAT); 1648234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_JUMP_SLOT); 1649234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_RELATIVE); 1650234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTOFF); 1651234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTPC); 1652234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32PLT); 1653234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF); 1654234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE); 1655234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTIE); 1656234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE); 1657234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD); 1658234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM); 1659234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_16); 1660234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC16); 1661234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_8); 1662234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC8); 1663234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_32); 1664234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_PUSH); 1665234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_CALL); 1666234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_POP); 1667234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_32); 1668234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_PUSH); 1669234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_CALL); 1670234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_POP); 1671234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDO_32); 1672234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE_32); 1673234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE_32); 1674234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPMOD32); 1675234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPOFF32); 1676234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF32); 1677234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTDESC); 1678234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL); 1679234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC); 1680234285Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE); 1681251662Sdim default: break; 1682234285Sdim } 1683234285Sdim break; 1684249423Sdim case ELF::EM_MIPS: 1685251662Sdim switch (Type) { 1686249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NONE); 1687249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_16); 1688249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_32); 1689249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_REL32); 1690249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_26); 1691249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HI16); 1692249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_LO16); 1693249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL16); 1694249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_LITERAL); 1695249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT16); 1696249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PC16); 1697249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL16); 1698249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL32); 1699249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT5); 1700249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT6); 1701249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_64); 1702249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_DISP); 1703249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_PAGE); 1704249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_OFST); 1705249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_HI16); 1706249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_LO16); 1707249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SUB); 1708249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_INSERT_A); 1709249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_INSERT_B); 1710249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_DELETE); 1711249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HIGHER); 1712249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HIGHEST); 1713249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL_HI16); 1714249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL_LO16); 1715249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SCN_DISP); 1716249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_REL16); 1717249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_ADD_IMMEDIATE); 1718249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PJUMP); 1719249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_RELGOT); 1720249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JALR); 1721249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPMOD32); 1722249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL32); 1723249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPMOD64); 1724249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL64); 1725249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_GD); 1726249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_LDM); 1727249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL_HI16); 1728249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL_LO16); 1729249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_GOTTPREL); 1730249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL32); 1731249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL64); 1732249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_HI16); 1733249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_LO16); 1734249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GLOB_DAT); 1735249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_COPY); 1736249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JUMP_SLOT); 1737251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NUM); 1738251662Sdim default: break; 1739249423Sdim } 1740249423Sdim break; 1741249423Sdim case ELF::EM_AARCH64: 1742251662Sdim switch (Type) { 1743249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_NONE); 1744249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS64); 1745249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS32); 1746249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS16); 1747249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL64); 1748249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL32); 1749249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL16); 1750249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G0); 1751249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G0_NC); 1752249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G1); 1753249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G1_NC); 1754249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G2); 1755249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G2_NC); 1756249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G3); 1757249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G0); 1758249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G1); 1759249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G2); 1760249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LD_PREL_LO19); 1761249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_PREL_LO21); 1762249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_PREL_PG_HI21); 1763249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADD_ABS_LO12_NC); 1764249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST8_ABS_LO12_NC); 1765249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TSTBR14); 1766249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_CONDBR19); 1767249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_JUMP26); 1768249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_CALL26); 1769249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST16_ABS_LO12_NC); 1770249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST32_ABS_LO12_NC); 1771249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST64_ABS_LO12_NC); 1772249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST128_ABS_LO12_NC); 1773249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_GOT_PAGE); 1774249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LD64_GOT_LO12_NC); 1775249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G2); 1776249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G1); 1777249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC); 1778249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G0); 1779249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC); 1780249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_HI12); 1781249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_LO12); 1782249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC); 1783249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST8_DTPREL_LO12); 1784249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC); 1785249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST16_DTPREL_LO12); 1786249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC); 1787249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST32_DTPREL_LO12); 1788249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC); 1789249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST64_DTPREL_LO12); 1790249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC); 1791249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1); 1792249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC); 1793249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21); 1794249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC); 1795249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19); 1796249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G2); 1797249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G1); 1798249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC); 1799249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G0); 1800249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC); 1801249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_HI12); 1802249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_LO12); 1803249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC); 1804249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST8_TPREL_LO12); 1805249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC); 1806249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST16_TPREL_LO12); 1807249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC); 1808249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST32_TPREL_LO12); 1809249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC); 1810249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST64_TPREL_LO12); 1811249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC); 1812249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_ADR_PAGE); 1813249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_LD64_LO12_NC); 1814249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_ADD_LO12_NC); 1815249423Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_CALL); 1816251662Sdim default: break; 1817249423Sdim } 1818249423Sdim break; 1819243830Sdim case ELF::EM_ARM: 1820251662Sdim switch (Type) { 1821243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_NONE); 1822243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PC24); 1823243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS32); 1824243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_REL32); 1825243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_PC_G0); 1826243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS16); 1827243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS12); 1828243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_ABS5); 1829243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS8); 1830243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_SBREL32); 1831243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_CALL); 1832243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_PC8); 1833243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_BREL_ADJ); 1834243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_DESC); 1835243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_SWI8); 1836243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_XPC25); 1837243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_XPC22); 1838243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_DTPMOD32); 1839243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_DTPOFF32); 1840243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_TPOFF32); 1841243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_COPY); 1842243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GLOB_DAT); 1843243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_JUMP_SLOT); 1844243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_RELATIVE); 1845243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOTOFF32); 1846243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_BASE_PREL); 1847243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOT_BREL); 1848243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PLT32); 1849243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_CALL); 1850243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_JUMP24); 1851243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP24); 1852243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_BASE_ABS); 1853243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PCREL_7_0); 1854243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PCREL_15_8); 1855243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PCREL_23_15); 1856243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_SBREL_11_0_NC); 1857243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SBREL_19_12_NC); 1858243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SBREL_27_20_CK); 1859243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TARGET1); 1860243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_SBREL31); 1861243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_V4BX); 1862243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TARGET2); 1863243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PREL31); 1864243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVW_ABS_NC); 1865243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVT_ABS); 1866243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVW_PREL_NC); 1867243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVT_PREL); 1868243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVW_ABS_NC); 1869243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVT_ABS); 1870243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVW_PREL_NC); 1871243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVT_PREL); 1872243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP19); 1873243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP6); 1874243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_ALU_PREL_11_0); 1875243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_PC12); 1876243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS32_NOI); 1877243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_REL32_NOI); 1878243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G0_NC); 1879243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G0); 1880243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G1_NC); 1881243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G1); 1882243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G2); 1883243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_PC_G1); 1884243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_PC_G2); 1885243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_PC_G0); 1886243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_PC_G1); 1887243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_PC_G2); 1888243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_PC_G0); 1889243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_PC_G1); 1890243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_PC_G2); 1891243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G0_NC); 1892243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G0); 1893243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G1_NC); 1894243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G1); 1895243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G2); 1896243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_SB_G0); 1897243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_SB_G1); 1898243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_SB_G2); 1899243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_SB_G0); 1900243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_SB_G1); 1901243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_SB_G2); 1902243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_SB_G0); 1903243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_SB_G1); 1904243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_SB_G2); 1905243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVW_BREL_NC); 1906243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVT_BREL); 1907243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVW_BREL); 1908243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVW_BREL_NC); 1909243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVT_BREL); 1910243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVW_BREL); 1911243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_GOTDESC); 1912243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_CALL); 1913243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_DESCSEQ); 1914243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_CALL); 1915243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PLT32_ABS); 1916243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOT_ABS); 1917243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOT_PREL); 1918243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOT_BREL12); 1919243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOTOFF12); 1920243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOTRELAX); 1921243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GNU_VTENTRY); 1922243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GNU_VTINHERIT); 1923243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP11); 1924243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP8); 1925243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_GD32); 1926243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LDM32); 1927243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LDO32); 1928243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_IE32); 1929243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LE32); 1930243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LDO12); 1931243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LE12); 1932243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_IE12GP); 1933243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_0); 1934243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_1); 1935243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_2); 1936243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_3); 1937243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_4); 1938243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_5); 1939243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_6); 1940243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_7); 1941243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_8); 1942243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_9); 1943243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_10); 1944243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_11); 1945243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_12); 1946243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_13); 1947243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_14); 1948243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_15); 1949243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ME_TOO); 1950243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ16); 1951243830Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ32); 1952251662Sdim default: break; 1953243830Sdim } 1954243830Sdim break; 1955239462Sdim case ELF::EM_HEXAGON: 1956251662Sdim switch (Type) { 1957239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_NONE); 1958239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B22_PCREL); 1959239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B15_PCREL); 1960239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B7_PCREL); 1961239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_LO16); 1962239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_HI16); 1963239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_32); 1964239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_16); 1965239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_8); 1966239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_0); 1967239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_1); 1968239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_2); 1969239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_3); 1970239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_HL16); 1971239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B13_PCREL); 1972239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B9_PCREL); 1973239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B32_PCREL_X); 1974239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_32_6_X); 1975239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B22_PCREL_X); 1976239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B15_PCREL_X); 1977239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B13_PCREL_X); 1978239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B9_PCREL_X); 1979239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B7_PCREL_X); 1980239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_16_X); 1981239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_12_X); 1982239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_11_X); 1983239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_10_X); 1984239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_9_X); 1985239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_8_X); 1986239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_7_X); 1987239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_6_X); 1988239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_32_PCREL); 1989239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_COPY); 1990239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GLOB_DAT); 1991239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_JMP_SLOT); 1992239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_RELATIVE); 1993239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_PLT_B22_PCREL); 1994239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_LO16); 1995239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_HI16); 1996239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_32); 1997239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_LO16); 1998239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_HI16); 1999239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_32); 2000239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_16); 2001239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPMOD_32); 2002239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_LO16); 2003239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_HI16); 2004239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_32); 2005239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_16); 2006239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_PLT_B22_PCREL); 2007239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_LO16); 2008239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_HI16); 2009239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_32); 2010239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_16); 2011239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_LO16); 2012239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_HI16); 2013239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_32); 2014239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_LO16); 2015239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_HI16); 2016239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_32); 2017239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_16); 2018239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_LO16); 2019239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_HI16); 2020239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_32); 2021239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_16); 2022239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_6_PCREL_X); 2023239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_32_6_X); 2024239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_16_X); 2025239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_11_X); 2026239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_32_6_X); 2027239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_16_X); 2028239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_11_X); 2029239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_32_6_X); 2030239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_16_X); 2031239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_11_X); 2032239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_32_6_X); 2033239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_16_X); 2034239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_11_X); 2035239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_32_6_X); 2036239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_16_X); 2037239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_32_6_X); 2038239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_16_X); 2039239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_11_X); 2040239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_32_6_X); 2041239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_16_X); 2042239462Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_11_X); 2043251662Sdim default: break; 2044239462Sdim } 2045239462Sdim break; 2046251662Sdim case ELF::EM_PPC: 2047251662Sdim switch (Type) { 2048251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_NONE); 2049251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR32); 2050251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR24); 2051251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16); 2052251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_LO); 2053251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_HI); 2054251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_HA); 2055251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14); 2056251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14_BRTAKEN); 2057251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14_BRNTAKEN); 2058251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL24); 2059251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14); 2060251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14_BRTAKEN); 2061251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14_BRNTAKEN); 2062251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL32); 2063251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_LO); 2064251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_HA); 2065251662Sdim default: break; 2066251662Sdim } 2067251662Sdim break; 2068251662Sdim case ELF::EM_PPC64: 2069251662Sdim switch (Type) { 2070251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_NONE); 2071251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR32); 2072251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_LO); 2073251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HI); 2074251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR14); 2075251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL24); 2076251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL32); 2077251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR64); 2078251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHER); 2079251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHEST); 2080251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL64); 2081251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16); 2082251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO); 2083251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_HA); 2084251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC); 2085251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_DS); 2086251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_LO_DS); 2087251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_DS); 2088251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO_DS); 2089251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLS); 2090251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_LO); 2091251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HA); 2092251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_LO); 2093251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HA); 2094251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_LO); 2095251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_HA); 2096251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_LO); 2097251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_HA); 2098251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_LO_DS); 2099251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_HA); 2100251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSGD); 2101251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSLD); 2102251662Sdim default: break; 2103251662Sdim } 2104251662Sdim break; 2105251662Sdim case ELF::EM_S390: 2106251662Sdim switch (Type) { 2107251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_NONE); 2108251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_8); 2109251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_12); 2110251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_16); 2111251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_32); 2112251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC32); 2113251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT12); 2114251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT32); 2115251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT32); 2116251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_COPY); 2117251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GLOB_DAT); 2118251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_JMP_SLOT); 2119251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_RELATIVE); 2120251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF); 2121251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPC); 2122251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT16); 2123251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC16); 2124251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC16DBL); 2125251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT16DBL); 2126251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC32DBL); 2127251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT32DBL); 2128251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPCDBL); 2129251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_64); 2130251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC64); 2131251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT64); 2132251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT64); 2133251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTENT); 2134251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF16); 2135251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF64); 2136251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT12); 2137251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT16); 2138251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT32); 2139251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT64); 2140251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLTENT); 2141251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF16); 2142251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF32); 2143251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF64); 2144251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LOAD); 2145251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GDCALL); 2146251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDCALL); 2147251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GD32); 2148251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GD64); 2149251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE12); 2150251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE32); 2151251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE64); 2152251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDM32); 2153251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDM64); 2154251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IE32); 2155251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IE64); 2156251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IEENT); 2157251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LE32); 2158251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LE64); 2159251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDO32); 2160251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDO64); 2161251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_DTPMOD); 2162251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_DTPOFF); 2163251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_TPOFF); 2164251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_20); 2165251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT20); 2166251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT20); 2167251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE20); 2168251662Sdim LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_IRELATIVE); 2169251662Sdim default: break; 2170251662Sdim } 2171251662Sdim break; 2172251662Sdim default: break; 2173234285Sdim } 2174251662Sdim return Res; 2175234285Sdim} 2176234285Sdim 2177234285Sdim#undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME 2178234285Sdim 2179249423Sdimtemplate<class ELFT> 2180251662Sdimerror_code ELFObjectFile<ELFT>::getRelocationTypeName( 2181251662Sdim DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 2182251662Sdim const Elf_Shdr *sec = getSection(Rel.w.b); 2183251662Sdim uint32_t type; 2184251662Sdim switch (sec->sh_type) { 2185251662Sdim default : 2186251662Sdim return object_error::parse_failed; 2187251662Sdim case ELF::SHT_REL : { 2188251662Sdim type = getRel(Rel)->getType(isMips64EL()); 2189251662Sdim break; 2190251662Sdim } 2191251662Sdim case ELF::SHT_RELA : { 2192251662Sdim type = getRela(Rel)->getType(isMips64EL()); 2193251662Sdim break; 2194251662Sdim } 2195251662Sdim } 2196251662Sdim 2197251662Sdim if (!isMips64EL()) { 2198251662Sdim StringRef Name = getRelocationTypeName(type); 2199251662Sdim Result.append(Name.begin(), Name.end()); 2200251662Sdim } else { 2201251662Sdim uint8_t Type1 = (type >> 0) & 0xFF; 2202251662Sdim uint8_t Type2 = (type >> 8) & 0xFF; 2203251662Sdim uint8_t Type3 = (type >> 16) & 0xFF; 2204251662Sdim 2205251662Sdim // Concat all three relocation type names. 2206251662Sdim StringRef Name = getRelocationTypeName(Type1); 2207251662Sdim Result.append(Name.begin(), Name.end()); 2208251662Sdim 2209251662Sdim Name = getRelocationTypeName(Type2); 2210251662Sdim Result.append(1, '/'); 2211251662Sdim Result.append(Name.begin(), Name.end()); 2212251662Sdim 2213251662Sdim Name = getRelocationTypeName(Type3); 2214251662Sdim Result.append(1, '/'); 2215251662Sdim Result.append(Name.begin(), Name.end()); 2216251662Sdim } 2217251662Sdim 2218251662Sdim return object_error::success; 2219251662Sdim} 2220251662Sdim 2221251662Sdimtemplate<class ELFT> 2222249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationAdditionalInfo( 2223249423Sdim DataRefImpl Rel, int64_t &Result) const { 2224234285Sdim const Elf_Shdr *sec = getSection(Rel.w.b); 2225234285Sdim switch (sec->sh_type) { 2226234285Sdim default : 2227234285Sdim report_fatal_error("Invalid section type in Rel!"); 2228234285Sdim case ELF::SHT_REL : { 2229234285Sdim Result = 0; 2230234285Sdim return object_error::success; 2231234285Sdim } 2232234285Sdim case ELF::SHT_RELA : { 2233234285Sdim Result = getRela(Rel)->r_addend; 2234234285Sdim return object_error::success; 2235234285Sdim } 2236234285Sdim } 2237234285Sdim} 2238234285Sdim 2239249423Sdimtemplate<class ELFT> 2240249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationValueString( 2241249423Sdim DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 2242234285Sdim const Elf_Shdr *sec = getSection(Rel.w.b); 2243234285Sdim uint8_t type; 2244234285Sdim StringRef res; 2245234285Sdim int64_t addend = 0; 2246234285Sdim uint16_t symbol_index = 0; 2247234285Sdim switch (sec->sh_type) { 2248243830Sdim default: 2249234285Sdim return object_error::parse_failed; 2250243830Sdim case ELF::SHT_REL: { 2251249423Sdim type = getRel(Rel)->getType(isMips64EL()); 2252249423Sdim symbol_index = getRel(Rel)->getSymbol(isMips64EL()); 2253234285Sdim // TODO: Read implicit addend from section data. 2254234285Sdim break; 2255234285Sdim } 2256243830Sdim case ELF::SHT_RELA: { 2257249423Sdim type = getRela(Rel)->getType(isMips64EL()); 2258249423Sdim symbol_index = getRela(Rel)->getSymbol(isMips64EL()); 2259234285Sdim addend = getRela(Rel)->r_addend; 2260234285Sdim break; 2261234285Sdim } 2262234285Sdim } 2263234285Sdim const Elf_Sym *symb = getEntry<Elf_Sym>(sec->sh_link, symbol_index); 2264234285Sdim StringRef symname; 2265234285Sdim if (error_code ec = getSymbolName(getSection(sec->sh_link), symb, symname)) 2266234285Sdim return ec; 2267234285Sdim switch (Header->e_machine) { 2268234285Sdim case ELF::EM_X86_64: 2269234285Sdim switch (type) { 2270243830Sdim case ELF::R_X86_64_PC8: 2271243830Sdim case ELF::R_X86_64_PC16: 2272234285Sdim case ELF::R_X86_64_PC32: { 2273234285Sdim std::string fmtbuf; 2274234285Sdim raw_string_ostream fmt(fmtbuf); 2275234285Sdim fmt << symname << (addend < 0 ? "" : "+") << addend << "-P"; 2276234285Sdim fmt.flush(); 2277234285Sdim Result.append(fmtbuf.begin(), fmtbuf.end()); 2278234285Sdim } 2279234285Sdim break; 2280243830Sdim case ELF::R_X86_64_8: 2281243830Sdim case ELF::R_X86_64_16: 2282243830Sdim case ELF::R_X86_64_32: 2283243830Sdim case ELF::R_X86_64_32S: 2284243830Sdim case ELF::R_X86_64_64: { 2285243830Sdim std::string fmtbuf; 2286243830Sdim raw_string_ostream fmt(fmtbuf); 2287243830Sdim fmt << symname << (addend < 0 ? "" : "+") << addend; 2288243830Sdim fmt.flush(); 2289243830Sdim Result.append(fmtbuf.begin(), fmtbuf.end()); 2290243830Sdim } 2291243830Sdim break; 2292234285Sdim default: 2293234285Sdim res = "Unknown"; 2294234285Sdim } 2295234285Sdim break; 2296249423Sdim case ELF::EM_AARCH64: 2297243830Sdim case ELF::EM_ARM: 2298239462Sdim case ELF::EM_HEXAGON: 2299239462Sdim res = symname; 2300239462Sdim break; 2301234285Sdim default: 2302234285Sdim res = "Unknown"; 2303234285Sdim } 2304234285Sdim if (Result.empty()) 2305234285Sdim Result.append(res.begin(), res.end()); 2306234285Sdim return object_error::success; 2307234285Sdim} 2308234285Sdim 2309234285Sdim// Verify that the last byte in the string table in a null. 2310249423Sdimtemplate<class ELFT> 2311249423Sdimvoid ELFObjectFile<ELFT>::VerifyStrTab(const Elf_Shdr *sh) const { 2312234285Sdim const char *strtab = (const char*)base() + sh->sh_offset; 2313234285Sdim if (strtab[sh->sh_size - 1] != 0) 2314234285Sdim // FIXME: Proper error handling. 2315234285Sdim report_fatal_error("String table must end with a null terminator!"); 2316234285Sdim} 2317234285Sdim 2318249423Sdimtemplate<class ELFT> 2319249423SdimELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec) 2320249423Sdim : ObjectFile(getELFType( 2321249423Sdim static_cast<endianness>(ELFT::TargetEndianness) == support::little, 2322249423Sdim ELFT::Is64Bits), 2323251662Sdim Object) 2324234285Sdim , isDyldELFObject(false) 2325234285Sdim , SectionHeaderTable(0) 2326234285Sdim , dot_shstrtab_sec(0) 2327234285Sdim , dot_strtab_sec(0) 2328234285Sdim , dot_dynstr_sec(0) 2329234285Sdim , dot_dynamic_sec(0) 2330234285Sdim , dot_gnu_version_sec(0) 2331234285Sdim , dot_gnu_version_r_sec(0) 2332234285Sdim , dot_gnu_version_d_sec(0) 2333234285Sdim , dt_soname(0) 2334234285Sdim { 2335234285Sdim 2336234285Sdim const uint64_t FileSize = Data->getBufferSize(); 2337234285Sdim 2338234285Sdim if (sizeof(Elf_Ehdr) > FileSize) 2339234285Sdim // FIXME: Proper error handling. 2340234285Sdim report_fatal_error("File too short!"); 2341234285Sdim 2342234285Sdim Header = reinterpret_cast<const Elf_Ehdr *>(base()); 2343234285Sdim 2344234285Sdim if (Header->e_shoff == 0) 2345234285Sdim return; 2346234285Sdim 2347234285Sdim const uint64_t SectionTableOffset = Header->e_shoff; 2348234285Sdim 2349234285Sdim if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) 2350234285Sdim // FIXME: Proper error handling. 2351234285Sdim report_fatal_error("Section header table goes past end of file!"); 2352234285Sdim 2353234285Sdim // The getNumSections() call below depends on SectionHeaderTable being set. 2354234285Sdim SectionHeaderTable = 2355234285Sdim reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset); 2356234285Sdim const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize; 2357234285Sdim 2358234285Sdim if (SectionTableOffset + SectionTableSize > FileSize) 2359234285Sdim // FIXME: Proper error handling. 2360234285Sdim report_fatal_error("Section table goes past end of file!"); 2361234285Sdim 2362234285Sdim // To find the symbol tables we walk the section table to find SHT_SYMTAB. 2363234285Sdim const Elf_Shdr* SymbolTableSectionHeaderIndex = 0; 2364234285Sdim const Elf_Shdr* sh = SectionHeaderTable; 2365234285Sdim 2366234285Sdim // Reserve SymbolTableSections[0] for .dynsym 2367234285Sdim SymbolTableSections.push_back(NULL); 2368234285Sdim 2369234285Sdim for (uint64_t i = 0, e = getNumSections(); i != e; ++i) { 2370234285Sdim switch (sh->sh_type) { 2371234285Sdim case ELF::SHT_SYMTAB_SHNDX: { 2372234285Sdim if (SymbolTableSectionHeaderIndex) 2373234285Sdim // FIXME: Proper error handling. 2374234285Sdim report_fatal_error("More than one .symtab_shndx!"); 2375234285Sdim SymbolTableSectionHeaderIndex = sh; 2376234285Sdim break; 2377234285Sdim } 2378234285Sdim case ELF::SHT_SYMTAB: { 2379234285Sdim SymbolTableSectionsIndexMap[i] = SymbolTableSections.size(); 2380234285Sdim SymbolTableSections.push_back(sh); 2381234285Sdim break; 2382234285Sdim } 2383234285Sdim case ELF::SHT_DYNSYM: { 2384234285Sdim if (SymbolTableSections[0] != NULL) 2385234285Sdim // FIXME: Proper error handling. 2386234285Sdim report_fatal_error("More than one .dynsym!"); 2387234285Sdim SymbolTableSectionsIndexMap[i] = 0; 2388234285Sdim SymbolTableSections[0] = sh; 2389234285Sdim break; 2390234285Sdim } 2391234285Sdim case ELF::SHT_REL: 2392234285Sdim case ELF::SHT_RELA: { 2393234285Sdim SectionRelocMap[getSection(sh->sh_info)].push_back(i); 2394234285Sdim break; 2395234285Sdim } 2396234285Sdim case ELF::SHT_DYNAMIC: { 2397234285Sdim if (dot_dynamic_sec != NULL) 2398234285Sdim // FIXME: Proper error handling. 2399234285Sdim report_fatal_error("More than one .dynamic!"); 2400234285Sdim dot_dynamic_sec = sh; 2401234285Sdim break; 2402234285Sdim } 2403234285Sdim case ELF::SHT_GNU_versym: { 2404234285Sdim if (dot_gnu_version_sec != NULL) 2405234285Sdim // FIXME: Proper error handling. 2406234285Sdim report_fatal_error("More than one .gnu.version section!"); 2407234285Sdim dot_gnu_version_sec = sh; 2408234285Sdim break; 2409234285Sdim } 2410234285Sdim case ELF::SHT_GNU_verdef: { 2411234285Sdim if (dot_gnu_version_d_sec != NULL) 2412234285Sdim // FIXME: Proper error handling. 2413234285Sdim report_fatal_error("More than one .gnu.version_d section!"); 2414234285Sdim dot_gnu_version_d_sec = sh; 2415234285Sdim break; 2416234285Sdim } 2417234285Sdim case ELF::SHT_GNU_verneed: { 2418234285Sdim if (dot_gnu_version_r_sec != NULL) 2419234285Sdim // FIXME: Proper error handling. 2420234285Sdim report_fatal_error("More than one .gnu.version_r section!"); 2421234285Sdim dot_gnu_version_r_sec = sh; 2422234285Sdim break; 2423234285Sdim } 2424234285Sdim } 2425234285Sdim ++sh; 2426234285Sdim } 2427234285Sdim 2428234285Sdim // Sort section relocation lists by index. 2429234285Sdim for (typename RelocMap_t::iterator i = SectionRelocMap.begin(), 2430234285Sdim e = SectionRelocMap.end(); i != e; ++i) { 2431234285Sdim std::sort(i->second.begin(), i->second.end()); 2432234285Sdim } 2433234285Sdim 2434234285Sdim // Get string table sections. 2435234285Sdim dot_shstrtab_sec = getSection(getStringTableIndex()); 2436234285Sdim if (dot_shstrtab_sec) { 2437234285Sdim // Verify that the last byte in the string table in a null. 2438234285Sdim VerifyStrTab(dot_shstrtab_sec); 2439234285Sdim } 2440234285Sdim 2441234285Sdim // Merge this into the above loop. 2442234285Sdim for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable), 2443234285Sdim *e = i + getNumSections() * Header->e_shentsize; 2444234285Sdim i != e; i += Header->e_shentsize) { 2445234285Sdim const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i); 2446234285Sdim if (sh->sh_type == ELF::SHT_STRTAB) { 2447234285Sdim StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name)); 2448234285Sdim if (SectionName == ".strtab") { 2449234285Sdim if (dot_strtab_sec != 0) 2450234285Sdim // FIXME: Proper error handling. 2451234285Sdim report_fatal_error("Already found section named .strtab!"); 2452234285Sdim dot_strtab_sec = sh; 2453234285Sdim VerifyStrTab(dot_strtab_sec); 2454234285Sdim } else if (SectionName == ".dynstr") { 2455234285Sdim if (dot_dynstr_sec != 0) 2456234285Sdim // FIXME: Proper error handling. 2457234285Sdim report_fatal_error("Already found section named .dynstr!"); 2458234285Sdim dot_dynstr_sec = sh; 2459234285Sdim VerifyStrTab(dot_dynstr_sec); 2460234285Sdim } 2461234285Sdim } 2462234285Sdim } 2463234285Sdim 2464234285Sdim // Build symbol name side-mapping if there is one. 2465234285Sdim if (SymbolTableSectionHeaderIndex) { 2466234285Sdim const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() + 2467234285Sdim SymbolTableSectionHeaderIndex->sh_offset); 2468234285Sdim error_code ec; 2469234285Sdim for (symbol_iterator si = begin_symbols(), 2470234285Sdim se = end_symbols(); si != se; si.increment(ec)) { 2471234285Sdim if (ec) 2472234285Sdim report_fatal_error("Fewer extended symbol table entries than symbols!"); 2473234285Sdim if (*ShndxTable != ELF::SHN_UNDEF) 2474234285Sdim ExtendedSymbolTable[getSymbol(si->getRawDataRefImpl())] = *ShndxTable; 2475234285Sdim ++ShndxTable; 2476234285Sdim } 2477234285Sdim } 2478234285Sdim} 2479234285Sdim 2480249423Sdim// Get the symbol table index in the symtab section given a symbol 2481249423Sdimtemplate<class ELFT> 2482249423Sdimuint64_t ELFObjectFile<ELFT>::getSymbolIndex(const Elf_Sym *Sym) const { 2483249423Sdim assert(SymbolTableSections.size() == 1 && "Only one symbol table supported!"); 2484249423Sdim const Elf_Shdr *SymTab = *SymbolTableSections.begin(); 2485249423Sdim uintptr_t SymLoc = uintptr_t(Sym); 2486249423Sdim uintptr_t SymTabLoc = uintptr_t(base() + SymTab->sh_offset); 2487249423Sdim assert(SymLoc > SymTabLoc && "Symbol not in symbol table!"); 2488249423Sdim uint64_t SymOffset = SymLoc - SymTabLoc; 2489249423Sdim assert(SymOffset % SymTab->sh_entsize == 0 && 2490249423Sdim "Symbol not multiple of symbol size!"); 2491249423Sdim return SymOffset / SymTab->sh_entsize; 2492249423Sdim} 2493249423Sdim 2494249423Sdimtemplate<class ELFT> 2495249423Sdimsymbol_iterator ELFObjectFile<ELFT>::begin_symbols() const { 2496234285Sdim DataRefImpl SymbolData; 2497234285Sdim if (SymbolTableSections.size() <= 1) { 2498234285Sdim SymbolData.d.a = std::numeric_limits<uint32_t>::max(); 2499234285Sdim SymbolData.d.b = std::numeric_limits<uint32_t>::max(); 2500234285Sdim } else { 2501234285Sdim SymbolData.d.a = 1; // The 0th symbol in ELF is fake. 2502234285Sdim SymbolData.d.b = 1; // The 0th table is .dynsym 2503234285Sdim } 2504234285Sdim return symbol_iterator(SymbolRef(SymbolData, this)); 2505234285Sdim} 2506234285Sdim 2507249423Sdimtemplate<class ELFT> 2508249423Sdimsymbol_iterator ELFObjectFile<ELFT>::end_symbols() const { 2509234285Sdim DataRefImpl SymbolData; 2510234285Sdim SymbolData.d.a = std::numeric_limits<uint32_t>::max(); 2511234285Sdim SymbolData.d.b = std::numeric_limits<uint32_t>::max(); 2512234285Sdim return symbol_iterator(SymbolRef(SymbolData, this)); 2513234285Sdim} 2514234285Sdim 2515249423Sdimtemplate<class ELFT> 2516249423Sdimsymbol_iterator ELFObjectFile<ELFT>::begin_dynamic_symbols() const { 2517234285Sdim DataRefImpl SymbolData; 2518234285Sdim if (SymbolTableSections[0] == NULL) { 2519234285Sdim SymbolData.d.a = std::numeric_limits<uint32_t>::max(); 2520234285Sdim SymbolData.d.b = std::numeric_limits<uint32_t>::max(); 2521234285Sdim } else { 2522234285Sdim SymbolData.d.a = 1; // The 0th symbol in ELF is fake. 2523234285Sdim SymbolData.d.b = 0; // The 0th table is .dynsym 2524234285Sdim } 2525234285Sdim return symbol_iterator(SymbolRef(SymbolData, this)); 2526234285Sdim} 2527234285Sdim 2528249423Sdimtemplate<class ELFT> 2529249423Sdimsymbol_iterator ELFObjectFile<ELFT>::end_dynamic_symbols() const { 2530234285Sdim DataRefImpl SymbolData; 2531234285Sdim SymbolData.d.a = std::numeric_limits<uint32_t>::max(); 2532234285Sdim SymbolData.d.b = std::numeric_limits<uint32_t>::max(); 2533234285Sdim return symbol_iterator(SymbolRef(SymbolData, this)); 2534234285Sdim} 2535234285Sdim 2536249423Sdimtemplate<class ELFT> 2537249423Sdimsection_iterator ELFObjectFile<ELFT>::begin_sections() const { 2538234285Sdim DataRefImpl ret; 2539234285Sdim ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff); 2540234285Sdim return section_iterator(SectionRef(ret, this)); 2541234285Sdim} 2542234285Sdim 2543249423Sdimtemplate<class ELFT> 2544249423Sdimsection_iterator ELFObjectFile<ELFT>::end_sections() const { 2545234285Sdim DataRefImpl ret; 2546234285Sdim ret.p = reinterpret_cast<intptr_t>(base() 2547234285Sdim + Header->e_shoff 2548234285Sdim + (Header->e_shentsize*getNumSections())); 2549234285Sdim return section_iterator(SectionRef(ret, this)); 2550234285Sdim} 2551234285Sdim 2552249423Sdimtemplate<class ELFT> 2553249423Sdimtypename ELFObjectFile<ELFT>::Elf_Dyn_iterator 2554249423SdimELFObjectFile<ELFT>::begin_dynamic_table() const { 2555249423Sdim if (dot_dynamic_sec) 2556249423Sdim return Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize, 2557249423Sdim (const char *)base() + dot_dynamic_sec->sh_offset); 2558249423Sdim return Elf_Dyn_iterator(0, 0); 2559234285Sdim} 2560234285Sdim 2561249423Sdimtemplate<class ELFT> 2562249423Sdimtypename ELFObjectFile<ELFT>::Elf_Dyn_iterator 2563249423SdimELFObjectFile<ELFT>::end_dynamic_table(bool NULLEnd) const { 2564249423Sdim if (dot_dynamic_sec) { 2565249423Sdim Elf_Dyn_iterator Ret(dot_dynamic_sec->sh_entsize, 2566249423Sdim (const char *)base() + dot_dynamic_sec->sh_offset + 2567249423Sdim dot_dynamic_sec->sh_size); 2568234285Sdim 2569249423Sdim if (NULLEnd) { 2570249423Sdim Elf_Dyn_iterator Start = begin_dynamic_table(); 2571249423Sdim while (Start != Ret && Start->getTag() != ELF::DT_NULL) 2572249423Sdim ++Start; 2573234285Sdim 2574249423Sdim // Include the DT_NULL. 2575249423Sdim if (Start != Ret) 2576249423Sdim ++Start; 2577249423Sdim Ret = Start; 2578249423Sdim } 2579249423Sdim return Ret; 2580234285Sdim } 2581249423Sdim return Elf_Dyn_iterator(0, 0); 2582234285Sdim} 2583234285Sdim 2584249423Sdimtemplate<class ELFT> 2585249423SdimStringRef ELFObjectFile<ELFT>::getLoadName() const { 2586234285Sdim if (!dt_soname) { 2587234285Sdim // Find the DT_SONAME entry 2588249423Sdim Elf_Dyn_iterator it = begin_dynamic_table(); 2589249423Sdim Elf_Dyn_iterator ie = end_dynamic_table(); 2590249423Sdim while (it != ie && it->getTag() != ELF::DT_SONAME) 2591249423Sdim ++it; 2592249423Sdim 2593234285Sdim if (it != ie) { 2594234285Sdim if (dot_dynstr_sec == NULL) 2595234285Sdim report_fatal_error("Dynamic string table is missing"); 2596234285Sdim dt_soname = getString(dot_dynstr_sec, it->getVal()); 2597234285Sdim } else { 2598234285Sdim dt_soname = ""; 2599234285Sdim } 2600234285Sdim } 2601234285Sdim return dt_soname; 2602234285Sdim} 2603234285Sdim 2604249423Sdimtemplate<class ELFT> 2605249423Sdimlibrary_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const { 2606234285Sdim // Find the first DT_NEEDED entry 2607249423Sdim Elf_Dyn_iterator i = begin_dynamic_table(); 2608249423Sdim Elf_Dyn_iterator e = end_dynamic_table(); 2609249423Sdim while (i != e && i->getTag() != ELF::DT_NEEDED) 2610249423Sdim ++i; 2611249423Sdim 2612249423Sdim DataRefImpl DRI; 2613249423Sdim DRI.p = reinterpret_cast<uintptr_t>(i.get()); 2614249423Sdim return library_iterator(LibraryRef(DRI, this)); 2615234285Sdim} 2616234285Sdim 2617249423Sdimtemplate<class ELFT> 2618249423Sdimerror_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data, 2619249423Sdim LibraryRef &Result) const { 2620234285Sdim // Use the same DataRefImpl format as DynRef. 2621249423Sdim Elf_Dyn_iterator i = Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize, 2622249423Sdim reinterpret_cast<const char *>(Data.p)); 2623249423Sdim Elf_Dyn_iterator e = end_dynamic_table(); 2624234285Sdim 2625249423Sdim // Skip the current dynamic table entry and find the next DT_NEEDED entry. 2626249423Sdim do 2627249423Sdim ++i; 2628249423Sdim while (i != e && i->getTag() != ELF::DT_NEEDED); 2629234285Sdim 2630249423Sdim DataRefImpl DRI; 2631249423Sdim DRI.p = reinterpret_cast<uintptr_t>(i.get()); 2632249423Sdim Result = LibraryRef(DRI, this); 2633234285Sdim return object_error::success; 2634234285Sdim} 2635234285Sdim 2636249423Sdimtemplate<class ELFT> 2637249423Sdimerror_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data, 2638249423Sdim StringRef &Res) const { 2639249423Sdim Elf_Dyn_iterator i = Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize, 2640249423Sdim reinterpret_cast<const char *>(Data.p)); 2641234285Sdim if (i == end_dynamic_table()) 2642234285Sdim report_fatal_error("getLibraryPath() called on iterator end"); 2643234285Sdim 2644234285Sdim if (i->getTag() != ELF::DT_NEEDED) 2645234285Sdim report_fatal_error("Invalid library_iterator"); 2646234285Sdim 2647234285Sdim // This uses .dynstr to lookup the name of the DT_NEEDED entry. 2648234285Sdim // THis works as long as DT_STRTAB == .dynstr. This is true most of 2649234285Sdim // the time, but the specification allows exceptions. 2650234285Sdim // TODO: This should really use DT_STRTAB instead. Doing this requires 2651234285Sdim // reading the program headers. 2652234285Sdim if (dot_dynstr_sec == NULL) 2653234285Sdim report_fatal_error("Dynamic string table is missing"); 2654234285Sdim Res = getString(dot_dynstr_sec, i->getVal()); 2655234285Sdim return object_error::success; 2656234285Sdim} 2657234285Sdim 2658249423Sdimtemplate<class ELFT> 2659249423Sdimlibrary_iterator ELFObjectFile<ELFT>::end_libraries_needed() const { 2660249423Sdim Elf_Dyn_iterator e = end_dynamic_table(); 2661249423Sdim DataRefImpl DRI; 2662249423Sdim DRI.p = reinterpret_cast<uintptr_t>(e.get()); 2663249423Sdim return library_iterator(LibraryRef(DRI, this)); 2664234285Sdim} 2665234285Sdim 2666249423Sdimtemplate<class ELFT> 2667249423Sdimuint8_t ELFObjectFile<ELFT>::getBytesInAddress() const { 2668249423Sdim return ELFT::Is64Bits ? 8 : 4; 2669234285Sdim} 2670234285Sdim 2671249423Sdimtemplate<class ELFT> 2672249423SdimStringRef ELFObjectFile<ELFT>::getFileFormatName() const { 2673234285Sdim switch(Header->e_ident[ELF::EI_CLASS]) { 2674234285Sdim case ELF::ELFCLASS32: 2675234285Sdim switch(Header->e_machine) { 2676234285Sdim case ELF::EM_386: 2677234285Sdim return "ELF32-i386"; 2678234285Sdim case ELF::EM_X86_64: 2679234285Sdim return "ELF32-x86-64"; 2680234285Sdim case ELF::EM_ARM: 2681234285Sdim return "ELF32-arm"; 2682239462Sdim case ELF::EM_HEXAGON: 2683239462Sdim return "ELF32-hexagon"; 2684249423Sdim case ELF::EM_MIPS: 2685249423Sdim return "ELF32-mips"; 2686234285Sdim default: 2687234285Sdim return "ELF32-unknown"; 2688234285Sdim } 2689234285Sdim case ELF::ELFCLASS64: 2690234285Sdim switch(Header->e_machine) { 2691234285Sdim case ELF::EM_386: 2692234285Sdim return "ELF64-i386"; 2693234285Sdim case ELF::EM_X86_64: 2694234285Sdim return "ELF64-x86-64"; 2695249423Sdim case ELF::EM_AARCH64: 2696249423Sdim return "ELF64-aarch64"; 2697243830Sdim case ELF::EM_PPC64: 2698243830Sdim return "ELF64-ppc64"; 2699251662Sdim case ELF::EM_S390: 2700251662Sdim return "ELF64-s390"; 2701234285Sdim default: 2702234285Sdim return "ELF64-unknown"; 2703234285Sdim } 2704234285Sdim default: 2705234285Sdim // FIXME: Proper error handling. 2706234285Sdim report_fatal_error("Invalid ELFCLASS!"); 2707234285Sdim } 2708234285Sdim} 2709234285Sdim 2710249423Sdimtemplate<class ELFT> 2711249423Sdimunsigned ELFObjectFile<ELFT>::getArch() const { 2712234285Sdim switch(Header->e_machine) { 2713234285Sdim case ELF::EM_386: 2714234285Sdim return Triple::x86; 2715234285Sdim case ELF::EM_X86_64: 2716234285Sdim return Triple::x86_64; 2717249423Sdim case ELF::EM_AARCH64: 2718249423Sdim return Triple::aarch64; 2719234285Sdim case ELF::EM_ARM: 2720234285Sdim return Triple::arm; 2721239462Sdim case ELF::EM_HEXAGON: 2722239462Sdim return Triple::hexagon; 2723243830Sdim case ELF::EM_MIPS: 2724249423Sdim return (ELFT::TargetEndianness == support::little) ? 2725243830Sdim Triple::mipsel : Triple::mips; 2726243830Sdim case ELF::EM_PPC64: 2727243830Sdim return Triple::ppc64; 2728251662Sdim case ELF::EM_S390: 2729251662Sdim return Triple::systemz; 2730234285Sdim default: 2731234285Sdim return Triple::UnknownArch; 2732234285Sdim } 2733234285Sdim} 2734234285Sdim 2735249423Sdimtemplate<class ELFT> 2736249423Sdimuint64_t ELFObjectFile<ELFT>::getNumSections() const { 2737234285Sdim assert(Header && "Header not initialized!"); 2738234285Sdim if (Header->e_shnum == ELF::SHN_UNDEF) { 2739234285Sdim assert(SectionHeaderTable && "SectionHeaderTable not initialized!"); 2740234285Sdim return SectionHeaderTable->sh_size; 2741234285Sdim } 2742234285Sdim return Header->e_shnum; 2743234285Sdim} 2744234285Sdim 2745249423Sdimtemplate<class ELFT> 2746234285Sdimuint64_t 2747249423SdimELFObjectFile<ELFT>::getStringTableIndex() const { 2748234285Sdim if (Header->e_shnum == ELF::SHN_UNDEF) { 2749234285Sdim if (Header->e_shstrndx == ELF::SHN_HIRESERVE) 2750234285Sdim return SectionHeaderTable->sh_link; 2751234285Sdim if (Header->e_shstrndx >= getNumSections()) 2752234285Sdim return 0; 2753234285Sdim } 2754234285Sdim return Header->e_shstrndx; 2755234285Sdim} 2756234285Sdim 2757249423Sdimtemplate<class ELFT> 2758234285Sdimtemplate<typename T> 2759234285Sdiminline const T * 2760249423SdimELFObjectFile<ELFT>::getEntry(uint16_t Section, uint32_t Entry) const { 2761234285Sdim return getEntry<T>(getSection(Section), Entry); 2762234285Sdim} 2763234285Sdim 2764249423Sdimtemplate<class ELFT> 2765234285Sdimtemplate<typename T> 2766234285Sdiminline const T * 2767249423SdimELFObjectFile<ELFT>::getEntry(const Elf_Shdr * Section, uint32_t Entry) const { 2768234285Sdim return reinterpret_cast<const T *>( 2769234285Sdim base() 2770234285Sdim + Section->sh_offset 2771234285Sdim + (Entry * Section->sh_entsize)); 2772234285Sdim} 2773234285Sdim 2774249423Sdimtemplate<class ELFT> 2775249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Sym * 2776249423SdimELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const { 2777234285Sdim return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a); 2778234285Sdim} 2779234285Sdim 2780249423Sdimtemplate<class ELFT> 2781249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Rel * 2782249423SdimELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const { 2783234285Sdim return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c); 2784234285Sdim} 2785234285Sdim 2786249423Sdimtemplate<class ELFT> 2787249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Rela * 2788249423SdimELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { 2789234285Sdim return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c); 2790234285Sdim} 2791234285Sdim 2792249423Sdimtemplate<class ELFT> 2793249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Shdr * 2794249423SdimELFObjectFile<ELFT>::getSection(DataRefImpl Symb) const { 2795234285Sdim const Elf_Shdr *sec = getSection(Symb.d.b); 2796234285Sdim if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM) 2797234285Sdim // FIXME: Proper error handling. 2798234285Sdim report_fatal_error("Invalid symbol table section!"); 2799234285Sdim return sec; 2800234285Sdim} 2801234285Sdim 2802249423Sdimtemplate<class ELFT> 2803249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Shdr * 2804249423SdimELFObjectFile<ELFT>::getSection(uint32_t index) const { 2805234285Sdim if (index == 0) 2806234285Sdim return 0; 2807234285Sdim if (!SectionHeaderTable || index >= getNumSections()) 2808234285Sdim // FIXME: Proper error handling. 2809234285Sdim report_fatal_error("Invalid section index!"); 2810234285Sdim 2811234285Sdim return reinterpret_cast<const Elf_Shdr *>( 2812234285Sdim reinterpret_cast<const char *>(SectionHeaderTable) 2813234285Sdim + (index * Header->e_shentsize)); 2814234285Sdim} 2815234285Sdim 2816249423Sdimtemplate<class ELFT> 2817249423Sdimconst char *ELFObjectFile<ELFT>::getString(uint32_t section, 2818249423Sdim ELF::Elf32_Word offset) const { 2819234285Sdim return getString(getSection(section), offset); 2820234285Sdim} 2821234285Sdim 2822249423Sdimtemplate<class ELFT> 2823249423Sdimconst char *ELFObjectFile<ELFT>::getString(const Elf_Shdr *section, 2824249423Sdim ELF::Elf32_Word offset) const { 2825234285Sdim assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!"); 2826234285Sdim if (offset >= section->sh_size) 2827234285Sdim // FIXME: Proper error handling. 2828234285Sdim report_fatal_error("Symbol name offset outside of string table!"); 2829234285Sdim return (const char *)base() + section->sh_offset + offset; 2830234285Sdim} 2831234285Sdim 2832249423Sdimtemplate<class ELFT> 2833249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolName(const Elf_Shdr *section, 2834249423Sdim const Elf_Sym *symb, 2835249423Sdim StringRef &Result) const { 2836234285Sdim if (symb->st_name == 0) { 2837234285Sdim const Elf_Shdr *section = getSection(symb); 2838234285Sdim if (!section) 2839234285Sdim Result = ""; 2840234285Sdim else 2841234285Sdim Result = getString(dot_shstrtab_sec, section->sh_name); 2842234285Sdim return object_error::success; 2843234285Sdim } 2844234285Sdim 2845234285Sdim if (section == SymbolTableSections[0]) { 2846234285Sdim // Symbol is in .dynsym, use .dynstr string table 2847234285Sdim Result = getString(dot_dynstr_sec, symb->st_name); 2848234285Sdim } else { 2849234285Sdim // Use the default symbol table name section. 2850234285Sdim Result = getString(dot_strtab_sec, symb->st_name); 2851234285Sdim } 2852234285Sdim return object_error::success; 2853234285Sdim} 2854234285Sdim 2855249423Sdimtemplate<class ELFT> 2856249423Sdimerror_code ELFObjectFile<ELFT>::getSectionName(const Elf_Shdr *section, 2857249423Sdim StringRef &Result) const { 2858239462Sdim Result = StringRef(getString(dot_shstrtab_sec, section->sh_name)); 2859239462Sdim return object_error::success; 2860239462Sdim} 2861239462Sdim 2862249423Sdimtemplate<class ELFT> 2863249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolVersion(const Elf_Shdr *section, 2864249423Sdim const Elf_Sym *symb, 2865249423Sdim StringRef &Version, 2866249423Sdim bool &IsDefault) const { 2867234285Sdim // Handle non-dynamic symbols. 2868234285Sdim if (section != SymbolTableSections[0]) { 2869234285Sdim // Non-dynamic symbols can have versions in their names 2870234285Sdim // A name of the form 'foo@V1' indicates version 'V1', non-default. 2871234285Sdim // A name of the form 'foo@@V2' indicates version 'V2', default version. 2872234285Sdim StringRef Name; 2873234285Sdim error_code ec = getSymbolName(section, symb, Name); 2874234285Sdim if (ec != object_error::success) 2875234285Sdim return ec; 2876234285Sdim size_t atpos = Name.find('@'); 2877234285Sdim if (atpos == StringRef::npos) { 2878234285Sdim Version = ""; 2879234285Sdim IsDefault = false; 2880234285Sdim return object_error::success; 2881234285Sdim } 2882234285Sdim ++atpos; 2883234285Sdim if (atpos < Name.size() && Name[atpos] == '@') { 2884234285Sdim IsDefault = true; 2885234285Sdim ++atpos; 2886234285Sdim } else { 2887234285Sdim IsDefault = false; 2888234285Sdim } 2889234285Sdim Version = Name.substr(atpos); 2890234285Sdim return object_error::success; 2891234285Sdim } 2892234285Sdim 2893234285Sdim // This is a dynamic symbol. Look in the GNU symbol version table. 2894234285Sdim if (dot_gnu_version_sec == NULL) { 2895234285Sdim // No version table. 2896234285Sdim Version = ""; 2897234285Sdim IsDefault = false; 2898234285Sdim return object_error::success; 2899234285Sdim } 2900234285Sdim 2901234285Sdim // Determine the position in the symbol table of this entry. 2902234285Sdim const char *sec_start = (const char*)base() + section->sh_offset; 2903234285Sdim size_t entry_index = ((const char*)symb - sec_start)/section->sh_entsize; 2904234285Sdim 2905234285Sdim // Get the corresponding version index entry 2906234285Sdim const Elf_Versym *vs = getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index); 2907234285Sdim size_t version_index = vs->vs_index & ELF::VERSYM_VERSION; 2908234285Sdim 2909234285Sdim // Special markers for unversioned symbols. 2910234285Sdim if (version_index == ELF::VER_NDX_LOCAL || 2911234285Sdim version_index == ELF::VER_NDX_GLOBAL) { 2912234285Sdim Version = ""; 2913234285Sdim IsDefault = false; 2914234285Sdim return object_error::success; 2915234285Sdim } 2916234285Sdim 2917234285Sdim // Lookup this symbol in the version table 2918234285Sdim LoadVersionMap(); 2919234285Sdim if (version_index >= VersionMap.size() || VersionMap[version_index].isNull()) 2920234285Sdim report_fatal_error("Symbol has version index without corresponding " 2921234285Sdim "define or reference entry"); 2922234285Sdim const VersionMapEntry &entry = VersionMap[version_index]; 2923234285Sdim 2924234285Sdim // Get the version name string 2925234285Sdim size_t name_offset; 2926234285Sdim if (entry.isVerdef()) { 2927234285Sdim // The first Verdaux entry holds the name. 2928234285Sdim name_offset = entry.getVerdef()->getAux()->vda_name; 2929234285Sdim } else { 2930234285Sdim name_offset = entry.getVernaux()->vna_name; 2931234285Sdim } 2932234285Sdim Version = getString(dot_dynstr_sec, name_offset); 2933234285Sdim 2934234285Sdim // Set IsDefault 2935234285Sdim if (entry.isVerdef()) { 2936234285Sdim IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN); 2937234285Sdim } else { 2938234285Sdim IsDefault = false; 2939234285Sdim } 2940234285Sdim 2941234285Sdim return object_error::success; 2942234285Sdim} 2943234285Sdim 2944234285Sdim/// This is a generic interface for retrieving GNU symbol version 2945234285Sdim/// information from an ELFObjectFile. 2946234285Sdimstatic inline error_code GetELFSymbolVersion(const ObjectFile *Obj, 2947234285Sdim const SymbolRef &Sym, 2948234285Sdim StringRef &Version, 2949234285Sdim bool &IsDefault) { 2950234285Sdim // Little-endian 32-bit 2951249423Sdim if (const ELFObjectFile<ELFType<support::little, 4, false> > *ELFObj = 2952249423Sdim dyn_cast<ELFObjectFile<ELFType<support::little, 4, false> > >(Obj)) 2953234285Sdim return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 2954234285Sdim 2955234285Sdim // Big-endian 32-bit 2956249423Sdim if (const ELFObjectFile<ELFType<support::big, 4, false> > *ELFObj = 2957249423Sdim dyn_cast<ELFObjectFile<ELFType<support::big, 4, false> > >(Obj)) 2958234285Sdim return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 2959234285Sdim 2960234285Sdim // Little-endian 64-bit 2961249423Sdim if (const ELFObjectFile<ELFType<support::little, 8, true> > *ELFObj = 2962249423Sdim dyn_cast<ELFObjectFile<ELFType<support::little, 8, true> > >(Obj)) 2963234285Sdim return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 2964234285Sdim 2965234285Sdim // Big-endian 64-bit 2966249423Sdim if (const ELFObjectFile<ELFType<support::big, 8, true> > *ELFObj = 2967249423Sdim dyn_cast<ELFObjectFile<ELFType<support::big, 8, true> > >(Obj)) 2968234285Sdim return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 2969234285Sdim 2970234285Sdim llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF"); 2971234285Sdim} 2972234285Sdim 2973249423Sdim/// This function returns the hash value for a symbol in the .dynsym section 2974249423Sdim/// Name of the API remains consistent as specified in the libelf 2975249423Sdim/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash 2976249423Sdimstatic inline unsigned elf_hash(StringRef &symbolName) { 2977249423Sdim unsigned h = 0, g; 2978249423Sdim for (unsigned i = 0, j = symbolName.size(); i < j; i++) { 2979249423Sdim h = (h << 4) + symbolName[i]; 2980249423Sdim g = h & 0xf0000000L; 2981249423Sdim if (g != 0) 2982249423Sdim h ^= g >> 24; 2983249423Sdim h &= ~g; 2984249423Sdim } 2985249423Sdim return h; 2986234285Sdim} 2987249423Sdim 2988234285Sdim} 2989249423Sdim} 2990234285Sdim 2991234285Sdim#endif 2992