X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FObject%2FELF.h;h=02840230f5c03e64d07c76890e1d1e5a138ea224;hb=43239078adac6f32315cadbef9709f2f0f499707;hp=dbae933445e129cc72e5fb6477d2ec3290cc5884;hpb=2c6f997290f589b80da903e33718175666557dd7;p=oota-llvm.git diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index dbae933445e..02840230f5c 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -81,9 +81,8 @@ template struct ELFDataTypeTypedefHelper; /// ELF 32bit types. -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct ELFDataTypeTypedefHelper > +template +struct ELFDataTypeTypedefHelper > : ELFDataTypeTypedefHelperCommon { typedef uint32_t value_type; typedef support::detail::packed_endian_specific_integral @@ -95,9 +94,8 @@ struct ELFDataTypeTypedefHelper > }; /// ELF 64bit types. -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct ELFDataTypeTypedefHelper > +template +struct ELFDataTypeTypedefHelper > : ELFDataTypeTypedefHelperCommon { typedef uint64_t value_type; typedef support::detail::packed_endian_specific_integral @@ -109,27 +107,29 @@ struct ELFDataTypeTypedefHelper > }; // I really don't like doing this, but the alternative is copypasta. -#define LLVM_ELF_IMPORT_TYPES(ELFT) \ -typedef typename ELFDataTypeTypedefHelper ::Elf_Addr Elf_Addr; \ -typedef typename ELFDataTypeTypedefHelper ::Elf_Off Elf_Off; \ -typedef typename ELFDataTypeTypedefHelper ::Elf_Half Elf_Half; \ -typedef typename ELFDataTypeTypedefHelper ::Elf_Word Elf_Word; \ -typedef typename ELFDataTypeTypedefHelper ::Elf_Sword Elf_Sword; \ -typedef typename ELFDataTypeTypedefHelper ::Elf_Xword Elf_Xword; \ -typedef typename ELFDataTypeTypedefHelper ::Elf_Sxword Elf_Sxword; - -// This is required to get template types into a macro :( -#define LLVM_ELF_COMMA , - - // Section header. +#define LLVM_ELF_IMPORT_TYPES(E, M, W) \ +typedef typename ELFDataTypeTypedefHelper >::Elf_Addr Elf_Addr; \ +typedef typename ELFDataTypeTypedefHelper >::Elf_Off Elf_Off; \ +typedef typename ELFDataTypeTypedefHelper >::Elf_Half Elf_Half; \ +typedef typename ELFDataTypeTypedefHelper >::Elf_Word Elf_Word; \ +typedef typename \ + ELFDataTypeTypedefHelper >::Elf_Sword Elf_Sword; \ +typedef typename \ + ELFDataTypeTypedefHelper >::Elf_Xword Elf_Xword; \ +typedef typename \ + ELFDataTypeTypedefHelper >::Elf_Sxword Elf_Sxword; + +#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \ + LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment, \ + ELFT::Is64Bits) + +// Section header. template struct Elf_Shdr_Base; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Shdr_Base > { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Shdr_Base > { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) Elf_Word sh_name; // Section name (index into string table) Elf_Word sh_type; // Section type (SHT_*) Elf_Word sh_flags; // Section flags (SHF_*) @@ -142,11 +142,9 @@ struct Elf_Shdr_Base > { Elf_Word sh_entsize; // Size of records contained within the section }; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Shdr_Base > { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Shdr_Base > { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) Elf_Word sh_name; // Section name (index into string table) Elf_Word sh_type; // Section type (SHT_*) Elf_Xword sh_flags; // Section flags (SHF_*) @@ -175,11 +173,9 @@ struct Elf_Shdr_Impl : Elf_Shdr_Base { template struct Elf_Sym_Base; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Sym_Base > { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Sym_Base > { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) Elf_Word st_name; // Symbol name (index into string table) Elf_Addr st_value; // Value or address associated with the symbol Elf_Word st_size; // Size of the symbol @@ -188,11 +184,9 @@ struct Elf_Sym_Base > { Elf_Half st_shndx; // Which section (header table index) it's defined in }; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Sym_Base > { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Sym_Base > { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) Elf_Word st_name; // Symbol name (index into string table) unsigned char st_info; // Symbol's type and binding attributes unsigned char st_other; // Must be zero; reserved @@ -220,7 +214,7 @@ struct Elf_Sym_Impl : Elf_Sym_Base { /// (.gnu.version). This structure is identical for ELF32 and ELF64. template struct Elf_Versym_Impl { - LLVM_ELF_IMPORT_TYPES(ELFT) + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN) }; @@ -231,7 +225,7 @@ struct Elf_Verdaux_Impl; /// (.gnu.version_d). This structure is identical for ELF32 and ELF64. template struct Elf_Verdef_Impl { - LLVM_ELF_IMPORT_TYPES(ELFT) + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) typedef Elf_Verdaux_Impl Elf_Verdaux; Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT) Elf_Half vd_flags; // Bitwise flags (VER_DEF_*) @@ -251,7 +245,7 @@ struct Elf_Verdef_Impl { /// section (.gnu.version_d). This structure is identical for ELF32 and ELF64. template struct Elf_Verdaux_Impl { - LLVM_ELF_IMPORT_TYPES(ELFT) + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) Elf_Word vda_name; // Version name (offset in string table) Elf_Word vda_next; // Offset to next Verdaux entry (in bytes) }; @@ -260,7 +254,7 @@ struct Elf_Verdaux_Impl { /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64. template struct Elf_Verneed_Impl { - LLVM_ELF_IMPORT_TYPES(ELFT) + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT) Elf_Half vn_cnt; // Number of associated Vernaux entries Elf_Word vn_file; // Library name (string table offset) @@ -272,7 +266,7 @@ struct Elf_Verneed_Impl { /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64. template struct Elf_Vernaux_Impl { - LLVM_ELF_IMPORT_TYPES(ELFT) + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) Elf_Word vna_hash; // Hash of dependency name Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*) Elf_Half vna_other; // Version index, used in .gnu.version entries @@ -285,11 +279,9 @@ struct Elf_Vernaux_Impl { template struct Elf_Dyn_Base; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Dyn_Base > { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Dyn_Base > { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) Elf_Sword d_tag; union { Elf_Word d_val; @@ -297,11 +289,9 @@ struct Elf_Dyn_Base > { } d_un; }; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Dyn_Base > { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Dyn_Base > { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) Elf_Sxword d_tag; union { Elf_Xword d_val; @@ -323,11 +313,9 @@ struct Elf_Dyn_Impl : Elf_Dyn_Base { template struct Elf_Rel_Base; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Rel_Base, false> { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Rel_Base, false> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Word r_info; // Symbol table index and type of relocation to apply @@ -340,11 +328,9 @@ struct Elf_Rel_Base, false> { } }; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Rel_Base, false> { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Rel_Base, false> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Xword r_info; // Symbol table index and type of relocation to apply @@ -365,11 +351,9 @@ struct Elf_Rel_Base, false> { } }; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Rel_Base, true> { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Rel_Base, true> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Word r_info; // Symbol table index and type of relocation to apply Elf_Sword r_addend; // Compute value for relocatable field by adding this @@ -383,11 +367,9 @@ struct Elf_Rel_Base, true> { } }; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Rel_Base, true> { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Rel_Base, true> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Xword r_info; // Symbol table index and type of relocation to apply Elf_Sxword r_addend; // Compute value for relocatable field by adding this. @@ -411,12 +393,10 @@ struct Elf_Rel_Base, true> { template struct Elf_Rel_Impl; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign, bool isRela> -struct Elf_Rel_Impl, isRela> - : Elf_Rel_Base, isRela> { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Rel_Impl, isRela> + : Elf_Rel_Base, isRela> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, // and ELF64_R_INFO macros defined in the ELF specification: @@ -433,12 +413,10 @@ struct Elf_Rel_Impl, isRela> } }; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign, bool isRela> -struct Elf_Rel_Impl, isRela> - : Elf_Rel_Base, isRela> { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Rel_Impl, isRela> + : Elf_Rel_Base, isRela> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, // and ELF32_R_INFO macros defined in the ELF specification: @@ -457,7 +435,7 @@ struct Elf_Rel_Impl, isRela> template struct Elf_Ehdr_Impl { - LLVM_ELF_IMPORT_TYPES(ELFT) + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes Elf_Half e_type; // Type of file (see ET_*) Elf_Half e_machine; // Required architecture for this file (see EM_*) @@ -483,11 +461,9 @@ struct Elf_Ehdr_Impl { template struct Elf_Phdr_Impl; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Phdr_Impl > { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Phdr_Impl > { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) Elf_Word p_type; // Type of segment Elf_Off p_offset; // FileOffset where segment is located, in bytes Elf_Addr p_vaddr; // Virtual Address of beginning of segment @@ -498,11 +474,9 @@ struct Elf_Phdr_Impl > { Elf_Word p_align; // Segment alignment constraint }; -template class ELFT, - endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Phdr_Impl > { - LLVM_ELF_IMPORT_TYPES(ELFT) +template +struct Elf_Phdr_Impl > { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) Elf_Word p_type; // Type of segment Elf_Word p_flags; // Segment flags Elf_Off p_offset; // FileOffset where segment is located, in bytes @@ -515,7 +489,7 @@ struct Elf_Phdr_Impl > { template class ELFObjectFile : public ObjectFile { - LLVM_ELF_IMPORT_TYPES(ELFT) + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) public: /// \brief Iterate over constant sized entities. @@ -689,6 +663,7 @@ public: protected: const Elf_Sym *getSymbol(DataRefImpl Symb) const; // FIXME: Should be private? void validateSymbol(DataRefImpl Symb) const; + StringRef getRelocationTypeName(uint32_t Type) const; public: error_code getSymbolName(const Elf_Shdr *section, @@ -1607,29 +1582,14 @@ error_code ELFObjectFile::getRelocationType(DataRefImpl Rel, } #define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \ - case ELF::enum: res = #enum; break; + case ELF::enum: Res = #enum; break; template -error_code ELFObjectFile::getRelocationTypeName( - DataRefImpl Rel, SmallVectorImpl &Result) const { - const Elf_Shdr *sec = getSection(Rel.w.b); - uint32_t type; - StringRef res; - switch (sec->sh_type) { - default : - return object_error::parse_failed; - case ELF::SHT_REL : { - type = getRel(Rel)->getType(isMips64EL()); - break; - } - case ELF::SHT_RELA : { - type = getRela(Rel)->getType(isMips64EL()); - break; - } - } +StringRef ELFObjectFile::getRelocationTypeName(uint32_t Type) const { + StringRef Res = "Unknown"; switch (Header->e_machine) { case ELF::EM_X86_64: - switch (type) { + switch (Type) { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32); @@ -1657,17 +1617,22 @@ error_code ELFObjectFile::getRelocationTypeName( LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPLT64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLTOFF64); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC); - default: - res = "Unknown"; + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_IRELATIVE); + default: break; } break; case ELF::EM_386: - switch (type) { + switch (Type) { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32); @@ -1708,12 +1673,11 @@ error_code ELFObjectFile::getRelocationTypeName( LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE); - default: - res = "Unknown"; + default: break; } break; case ELF::EM_MIPS: - switch (type) { + switch (Type) { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NONE); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_32); @@ -1765,12 +1729,12 @@ error_code ELFObjectFile::getRelocationTypeName( LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GLOB_DAT); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_COPY); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JUMP_SLOT); - default: - res = "Unknown"; + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NUM); + default: break; } break; case ELF::EM_AARCH64: - switch (type) { + switch (Type) { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_NONE); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS64); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS32); @@ -1844,13 +1808,11 @@ error_code ELFObjectFile::getRelocationTypeName( LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_LD64_LO12_NC); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_ADD_LO12_NC); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_CALL); - - default: - res = "Unknown"; + default: break; } break; case ELF::EM_ARM: - switch (type) { + switch (Type) { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_NONE); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PC24); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS32); @@ -1982,12 +1944,11 @@ error_code ELFObjectFile::getRelocationTypeName( LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ME_TOO); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ32); - default: - res = "Unknown"; + default: break; } break; case ELF::EM_HEXAGON: - switch (type) { + switch (Type) { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_NONE); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B22_PCREL); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B15_PCREL); @@ -2074,19 +2035,117 @@ error_code ELFObjectFile::getRelocationTypeName( LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_32_6_X); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_16_X); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_11_X); - default: - res = "Unknown"; + default: break; } break; - default: - res = "Unknown"; + case ELF::EM_PPC: + switch (Type) { + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_NONE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR24); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14_BRTAKEN); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14_BRNTAKEN); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL24); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14_BRTAKEN); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14_BRNTAKEN); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_HA); + default: break; + } + break; + case ELF::EM_PPC64: + switch (Type) { + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_NONE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR14); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL24); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHER); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHEST); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_LO_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_LO_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSGD); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSLD); + default: break; + } + break; + default: break; } - Result.append(res.begin(), res.end()); - return object_error::success; + return Res; } #undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME +template +error_code ELFObjectFile::getRelocationTypeName( + DataRefImpl Rel, SmallVectorImpl &Result) const { + const Elf_Shdr *sec = getSection(Rel.w.b); + uint32_t type; + switch (sec->sh_type) { + default : + return object_error::parse_failed; + case ELF::SHT_REL : { + type = getRel(Rel)->getType(isMips64EL()); + break; + } + case ELF::SHT_RELA : { + type = getRela(Rel)->getType(isMips64EL()); + break; + } + } + + if (!isMips64EL()) { + StringRef Name = getRelocationTypeName(type); + Result.append(Name.begin(), Name.end()); + } else { + uint8_t Type1 = (type >> 0) & 0xFF; + uint8_t Type2 = (type >> 8) & 0xFF; + uint8_t Type3 = (type >> 16) & 0xFF; + + // Concat all three relocation type names. + StringRef Name = getRelocationTypeName(Type1); + Result.append(Name.begin(), Name.end()); + + Name = getRelocationTypeName(Type2); + Result.append(1, '/'); + Result.append(Name.begin(), Name.end()); + + Name = getRelocationTypeName(Type3); + Result.append(1, '/'); + Result.append(Name.begin(), Name.end()); + } + + return object_error::success; +} + template error_code ELFObjectFile::getRelocationAdditionalInfo( DataRefImpl Rel, int64_t &Result) const {