struct ELFDataTypeTypedefHelper;
/// ELF 32bit types.
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, false> >
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, false> >
: ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
typedef uint32_t value_type;
typedef support::detail::packed_endian_specific_integral
};
/// ELF 64bit types.
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, true> >
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, true> >
: ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
typedef uint64_t value_type;
typedef support::detail::packed_endian_specific_integral
};
// I really don't like doing this, but the alternative is copypasta.
-#define LLVM_ELF_IMPORT_TYPES(ELFT) \
-typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Addr Elf_Addr; \
-typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Off Elf_Off; \
-typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Half Elf_Half; \
-typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Word Elf_Word; \
-typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Sword Elf_Sword; \
-typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Xword Elf_Xword; \
-typedef typename ELFDataTypeTypedefHelper <ELFT>::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<ELFType<E,M,W> >::Elf_Addr Elf_Addr; \
+typedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Off Elf_Off; \
+typedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Half Elf_Half; \
+typedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Word Elf_Word; \
+typedef typename \
+ ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Sword Elf_Sword; \
+typedef typename \
+ ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Xword Elf_Xword; \
+typedef typename \
+ ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Sxword Elf_Sxword;
+
+#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
+ LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment, \
+ ELFT::Is64Bits)
+
+// Section header.
template<class ELFT>
struct Elf_Shdr_Base;
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Shdr_Base<ELFT<TargetEndianness, MaxAlign, false> > {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA false>)
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > {
+ 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_*)
Elf_Word sh_entsize; // Size of records contained within the section
};
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Shdr_Base<ELFT<TargetEndianness, MaxAlign, true> > {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA true>)
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, true> > {
+ 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_*)
template<class ELFT>
struct Elf_Sym_Base;
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Sym_Base<ELFT<TargetEndianness, MaxAlign, false> > {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA false>)
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > {
+ 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
Elf_Half st_shndx; // Which section (header table index) it's defined in
};
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Sym_Base<ELFT<TargetEndianness, MaxAlign, true> > {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA true>)
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > {
+ 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
/// (.gnu.version). This structure is identical for ELF32 and ELF64.
template<class ELFT>
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)
};
/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
template<class ELFT>
struct Elf_Verdef_Impl {
- LLVM_ELF_IMPORT_TYPES(ELFT)
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
Elf_Half vd_flags; // Bitwise flags (VER_DEF_*)
/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
template<class ELFT>
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)
};
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
template<class ELFT>
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)
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
template<class ELFT>
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
template<class ELFT>
struct Elf_Dyn_Base;
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Dyn_Base<ELFT<TargetEndianness, MaxAlign, false> > {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA false>)
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
Elf_Sword d_tag;
union {
Elf_Word d_val;
} d_un;
};
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Dyn_Base<ELFT<TargetEndianness, MaxAlign, true> > {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA true>)
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, true> > {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
Elf_Sxword d_tag;
union {
Elf_Xword d_val;
template<class ELFT, bool isRela>
struct Elf_Rel_Base;
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, false> {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA false>)
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, 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
}
};
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, false> {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA true>)
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, 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
}
};
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, true> {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA false>)
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, 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
}
};
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, true> {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA true>)
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, 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.
template<class ELFT, bool isRela>
struct Elf_Rel_Impl;
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
-struct Elf_Rel_Impl<ELFT<TargetEndianness, MaxAlign, true>, isRela>
- : Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, isRela> {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA true>)
+template<endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>, isRela>
+ : Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, 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:
}
};
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
-struct Elf_Rel_Impl<ELFT<TargetEndianness, MaxAlign, false>, isRela>
- : Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, isRela> {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA false>)
+template<endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, false>, isRela>
+ : Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, 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:
template<class ELFT>
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_*)
template<class ELFT>
struct Elf_Phdr_Impl;
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Phdr_Impl<ELFT<TargetEndianness, MaxAlign, false> > {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA false>)
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > {
+ 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
Elf_Word p_align; // Segment alignment constraint
};
-template<template<endianness, std::size_t, bool> class ELFT,
- endianness TargetEndianness, std::size_t MaxAlign>
-struct Elf_Phdr_Impl<ELFT<TargetEndianness, MaxAlign, true> > {
- LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
- MaxAlign LLVM_ELF_COMMA true>)
+template<endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > {
+ 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
template<class ELFT>
class ELFObjectFile : public ObjectFile {
- LLVM_ELF_IMPORT_TYPES(ELFT)
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
public:
/// \brief Iterate over constant sized entities.
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,
}
#define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \
- case ELF::enum: res = #enum; break;
+ case ELF::enum: Res = #enum; break;
template<class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationTypeName(
- DataRefImpl Rel, SmallVectorImpl<char> &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<ELFT>::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);
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);
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);
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);
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);
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);
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<class ELFT>
+error_code ELFObjectFile<ELFT>::getRelocationTypeName(
+ DataRefImpl Rel, SmallVectorImpl<char> &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<class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationAdditionalInfo(
DataRefImpl Rel, int64_t &Result) const {