aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Object/ELF.h
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2013-01-31 10:07:41 -0800
committerDerek Schuff <dschuff@chromium.org>2013-01-31 10:07:41 -0800
commit3d5de9e56f3e5af59772bdf2cbedb0903d938bb8 (patch)
tree300b7a72c61b009f0122ec1d8a155672c74459fd /include/llvm/Object/ELF.h
parent659ebb8c18832df528effd5c970bfde7662ea368 (diff)
parent9ccb76998f741a7d3f0f217392a783dfb99c6e87 (diff)
Cherry-pick r174067
Diffstat (limited to 'include/llvm/Object/ELF.h')
-rw-r--r--include/llvm/Object/ELF.h908
1 files changed, 418 insertions, 490 deletions
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index 735accdf7e..c47b9cdf32 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -35,6 +35,15 @@ namespace object {
using support::endianness;
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+struct ELFType {
+ enum {
+ TargetEndianness = target_endianness,
+ MaxAlignment = max_alignment,
+ Is64Bits = is64Bits
+ };
+};
+
template<typename T, int max_align>
struct MaximumAlignment {
enum {value = AlignOf<T>::Alignment > max_align ? max_align
@@ -70,59 +79,59 @@ struct ELFDataTypeTypedefHelperCommon {
MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword;
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct ELFDataTypeTypedefHelper;
/// ELF 32bit types.
-template<endianness target_endianness, std::size_t max_alignment>
-struct ELFDataTypeTypedefHelper<target_endianness, max_alignment, false>
- : ELFDataTypeTypedefHelperCommon<target_endianness, max_alignment> {
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, false> >
+ : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
typedef uint32_t value_type;
typedef support::detail::packed_endian_specific_integral
- <value_type, target_endianness,
- MaximumAlignment<value_type, max_alignment>::value> Elf_Addr;
+ <value_type, TargetEndianness,
+ MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
typedef support::detail::packed_endian_specific_integral
- <value_type, target_endianness,
- MaximumAlignment<value_type, max_alignment>::value> Elf_Off;
+ <value_type, TargetEndianness,
+ MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
};
/// ELF 64bit types.
-template<endianness target_endianness, std::size_t max_alignment>
-struct ELFDataTypeTypedefHelper<target_endianness, max_alignment, true>
- : ELFDataTypeTypedefHelperCommon<target_endianness, max_alignment>{
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, true> >
+ : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
typedef uint64_t value_type;
typedef support::detail::packed_endian_specific_integral
- <value_type, target_endianness,
- MaximumAlignment<value_type, max_alignment>::value> Elf_Addr;
+ <value_type, TargetEndianness,
+ MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
typedef support::detail::packed_endian_specific_integral
- <value_type, target_endianness,
- MaximumAlignment<value_type, max_alignment>::value> Elf_Off;
+ <value_type, TargetEndianness,
+ MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
};
// I really don't like doing this, but the alternative is copypasta.
-#define LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits) \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Addr Elf_Addr; \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Off Elf_Off; \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Half Elf_Half; \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Word Elf_Word; \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Sword Elf_Sword; \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Xword Elf_Xword; \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Sxword Elf_Sxword;
+#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.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Shdr_Base;
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Shdr_Base<target_endianness, max_alignment, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+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>)
Elf_Word sh_name; // Section name (index into string table)
Elf_Word sh_type; // Section type (SHT_*)
Elf_Word sh_flags; // Section flags (SHF_*)
@@ -135,9 +144,11 @@ struct Elf_Shdr_Base<target_endianness, max_alignment, false> {
Elf_Word sh_entsize; // Size of records contained within the section
};
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Shdr_Base<target_endianness, max_alignment, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+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>)
Elf_Word sh_name; // Section name (index into string table)
Elf_Word sh_type; // Section type (SHT_*)
Elf_Xword sh_flags; // Section flags (SHF_*)
@@ -150,11 +161,10 @@ struct Elf_Shdr_Base<target_endianness, max_alignment, true> {
Elf_Xword sh_entsize; // Size of records contained within the section
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-struct Elf_Shdr_Impl
- : Elf_Shdr_Base<target_endianness, max_alignment, is64Bits> {
- using Elf_Shdr_Base<target_endianness, max_alignment, is64Bits>::sh_entsize;
- using Elf_Shdr_Base<target_endianness, max_alignment, is64Bits>::sh_size;
+template<class ELFT>
+struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
+ using Elf_Shdr_Base<ELFT>::sh_entsize;
+ using Elf_Shdr_Base<ELFT>::sh_size;
/// @brief Get the number of entities this section contains if it has any.
unsigned getEntityCount() const {
@@ -164,14 +174,14 @@ struct Elf_Shdr_Impl
}
};
-template< endianness target_endianness
- , std::size_t max_alignment
- , bool is64Bits>
+template<class ELFT>
struct Elf_Sym_Base;
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Sym_Base<target_endianness, max_alignment, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+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>)
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
@@ -180,9 +190,11 @@ struct Elf_Sym_Base<target_endianness, max_alignment, false> {
Elf_Half st_shndx; // Which section (header table index) it's defined in
};
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Sym_Base<target_endianness, max_alignment, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+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>)
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
@@ -191,10 +203,9 @@ struct Elf_Sym_Base<target_endianness, max_alignment, true> {
Elf_Xword st_size; // Size of the symbol
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-struct Elf_Sym_Impl
- : Elf_Sym_Base<target_endianness, max_alignment, is64Bits> {
- using Elf_Sym_Base<target_endianness, max_alignment, is64Bits>::st_info;
+template<class ELFT>
+struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
+ using Elf_Sym_Base<ELFT>::st_info;
// These accessors and mutators correspond to the ELF32_ST_BIND,
// ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
@@ -209,22 +220,21 @@ struct Elf_Sym_Impl
/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
/// (.gnu.version). This structure is identical for ELF32 and ELF64.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Versym_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(ELFT)
Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Verdaux_Impl;
/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Verdef_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
- typedef
- Elf_Verdaux_Impl<target_endianness, max_alignment, is64Bits> Elf_Verdaux;
+ LLVM_ELF_IMPORT_TYPES(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_*)
Elf_Half vd_ndx; // Version index, used in .gnu.version entries
@@ -241,18 +251,18 @@ struct Elf_Verdef_Impl {
/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Verdaux_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(ELFT)
Elf_Word vda_name; // Version name (offset in string table)
Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
};
/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Verneed_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(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)
@@ -262,9 +272,9 @@ struct Elf_Verneed_Impl {
/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Vernaux_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(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
@@ -274,12 +284,14 @@ struct Elf_Vernaux_Impl {
/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
/// table section (.dynamic) look like.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Dyn_Base;
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Dyn_Base<target_endianness, max_alignment, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+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>)
Elf_Sword d_tag;
union {
Elf_Word d_val;
@@ -287,9 +299,11 @@ struct Elf_Dyn_Base<target_endianness, max_alignment, false> {
} d_un;
};
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Dyn_Base<target_endianness, max_alignment, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+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>)
Elf_Sxword d_tag;
union {
Elf_Xword d_val;
@@ -298,24 +312,24 @@ struct Elf_Dyn_Base<target_endianness, max_alignment, true> {
};
/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and setters.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-struct Elf_Dyn_Impl : Elf_Dyn_Base<target_endianness, max_alignment, is64Bits> {
- using Elf_Dyn_Base<target_endianness, max_alignment, is64Bits>::d_tag;
- using Elf_Dyn_Base<target_endianness, max_alignment, is64Bits>::d_un;
+template<class ELFT>
+struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
+ using Elf_Dyn_Base<ELFT>::d_tag;
+ using Elf_Dyn_Base<ELFT>::d_un;
int64_t getTag() const { return d_tag; }
uint64_t getVal() const { return d_un.d_val; }
uint64_t getPtr() const { return d_un.ptr; }
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
class ELFObjectFile;
// DynRefImpl: Reference to an entry in the dynamic table
// This is an ELF-specific interface.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
class DynRefImpl {
- typedef Elf_Dyn_Impl<target_endianness, max_alignment, is64Bits> Elf_Dyn;
- typedef ELFObjectFile<target_endianness, max_alignment, is64Bits> OwningType;
+ typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
+ typedef ELFObjectFile<ELFT> OwningType;
DataRefImpl DynPimpl;
const OwningType *OwningObject;
@@ -337,53 +351,57 @@ public:
};
// Elf_Rel: Elf Relocation
-template< endianness target_endianness
- , std::size_t max_alignment
- , bool is64Bits
- , bool isRela>
+template<class ELFT, bool isRela>
struct Elf_Rel_Base;
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Rel_Base<target_endianness, max_alignment, false, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+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>)
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<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Rel_Base<target_endianness, max_alignment, true, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+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>)
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<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Rel_Base<target_endianness, max_alignment, false, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+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>)
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<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Rel_Base<target_endianness, max_alignment, true, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+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>)
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< endianness target_endianness
- , std::size_t max_alignment
- , bool is64Bits
- , bool isRela>
+template<class ELFT, bool isRela>
struct Elf_Rel_Impl;
-template<endianness target_endianness, std::size_t max_alignment, bool isRela>
-struct Elf_Rel_Impl<target_endianness, max_alignment, true, isRela>
- : Elf_Rel_Base<target_endianness, max_alignment, true, isRela> {
- using Elf_Rel_Base<target_endianness, max_alignment, true, isRela>::r_info;
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+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> {
+ using Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, isRela>::r_info;
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA true>)
// These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
// and ELF64_R_INFO macros defined in the ELF specification:
@@ -398,11 +416,13 @@ struct Elf_Rel_Impl<target_endianness, max_alignment, true, isRela>
}
};
-template<endianness target_endianness, std::size_t max_alignment, bool isRela>
-struct Elf_Rel_Impl<target_endianness, max_alignment, false, isRela>
- : Elf_Rel_Base<target_endianness, max_alignment, false, isRela> {
- using Elf_Rel_Base<target_endianness, max_alignment, false, isRela>::r_info;
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+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> {
+ using Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, isRela>::r_info;
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA false>)
// These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
// and ELF32_R_INFO macros defined in the ELF specification:
@@ -415,9 +435,9 @@ struct Elf_Rel_Impl<target_endianness, max_alignment, false, isRela>
}
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Ehdr_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(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_*)
@@ -440,12 +460,14 @@ struct Elf_Ehdr_Impl {
unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Phdr_Impl;
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Phdr_Impl<target_endianness, max_alignment, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+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>)
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
@@ -456,9 +478,11 @@ struct Elf_Phdr_Impl<target_endianness, max_alignment, false> {
Elf_Word p_align; // Segment alignment constraint
};
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Phdr_Impl<target_endianness, max_alignment, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+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>)
Elf_Word p_type; // Type of segment
Elf_Word p_flags; // Segment flags
Elf_Off p_offset; // FileOffset where segment is located, in bytes
@@ -469,30 +493,23 @@ struct Elf_Phdr_Impl<target_endianness, max_alignment, true> {
Elf_Xword p_align; // Segment alignment constraint
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
class ELFObjectFile : public ObjectFile {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
-
- typedef Elf_Ehdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Ehdr;
- typedef Elf_Shdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Shdr;
- typedef Elf_Sym_Impl<target_endianness, max_alignment, is64Bits> Elf_Sym;
- typedef Elf_Dyn_Impl<target_endianness, max_alignment, is64Bits> Elf_Dyn;
- typedef Elf_Phdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Phdr;
- typedef
- Elf_Rel_Impl<target_endianness, max_alignment, is64Bits, false> Elf_Rel;
- typedef
- Elf_Rel_Impl<target_endianness, max_alignment, is64Bits, true> Elf_Rela;
- typedef
- Elf_Verdef_Impl<target_endianness, max_alignment, is64Bits> Elf_Verdef;
- typedef
- Elf_Verdaux_Impl<target_endianness, max_alignment, is64Bits> Elf_Verdaux;
- typedef
- Elf_Verneed_Impl<target_endianness, max_alignment, is64Bits> Elf_Verneed;
- typedef
- Elf_Vernaux_Impl<target_endianness, max_alignment, is64Bits> Elf_Vernaux;
- typedef
- Elf_Versym_Impl<target_endianness, max_alignment, is64Bits> Elf_Versym;
- typedef DynRefImpl<target_endianness, max_alignment, is64Bits> DynRef;
+ LLVM_ELF_IMPORT_TYPES(ELFT)
+
+ typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
+ typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
+ typedef Elf_Sym_Impl<ELFT> Elf_Sym;
+ typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
+ typedef Elf_Phdr_Impl<ELFT> Elf_Phdr;
+ typedef Elf_Rel_Impl<ELFT, false> Elf_Rel;
+ typedef Elf_Rel_Impl<ELFT, true> Elf_Rela;
+ typedef Elf_Verdef_Impl<ELFT> Elf_Verdef;
+ typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
+ typedef Elf_Verneed_Impl<ELFT> Elf_Verneed;
+ typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux;
+ typedef Elf_Versym_Impl<ELFT> Elf_Versym;
+ typedef DynRefImpl<ELFT> DynRef;
typedef content_iterator<DynRef> dyn_iterator;
protected:
@@ -659,7 +676,7 @@ protected:
section_iterator &Res) const;
virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
- friend class DynRefImpl<target_endianness, max_alignment, is64Bits>;
+ friend class DynRefImpl<ELFT>;
virtual error_code getDynNext(DataRefImpl DynData, DynRef &Result) const;
virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const;
@@ -775,16 +792,15 @@ public:
// Methods for type inquiry through isa, cast, and dyn_cast
bool isDyldType() const { return isDyldELFObject; }
static inline bool classof(const Binary *v) {
- return v->getType() == getELFType(target_endianness == support::little,
- is64Bits);
+ return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
+ ELFT::Is64Bits);
}
};
// Iterate through the version definitions, and place each Elf_Verdef
// in the VersionMap according to its index.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-void ELFObjectFile<target_endianness, max_alignment, is64Bits>::
- LoadVersionDefs(const Elf_Shdr *sec) const {
+template<class ELFT>
+void ELFObjectFile<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
unsigned vd_size = sec->sh_size; // Size of section in bytes
unsigned vd_count = sec->sh_info; // Number of Verdef entries
const char *sec_start = (const char*)base() + sec->sh_offset;
@@ -808,9 +824,8 @@ void ELFObjectFile<target_endianness, max_alignment, is64Bits>::
// Iterate through the versions needed section, and place each Elf_Vernaux
// in the VersionMap according to its index.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-void ELFObjectFile<target_endianness, max_alignment, is64Bits>::
- LoadVersionNeeds(const Elf_Shdr *sec) const {
+template<class ELFT>
+void ELFObjectFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
unsigned vn_size = sec->sh_size; // Size of section in bytes
unsigned vn_count = sec->sh_info; // Number of Verneed entries
const char *sec_start = (const char*)base() + sec->sh_offset;
@@ -841,9 +856,8 @@ void ELFObjectFile<target_endianness, max_alignment, is64Bits>::
}
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-void ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::LoadVersionMap() const {
+template<class ELFT>
+void ELFObjectFile<ELFT>::LoadVersionMap() const {
// If there is no dynamic symtab or version table, there is nothing to do.
if (SymbolTableSections[0] == NULL || dot_gnu_version_sec == NULL)
return;
@@ -864,9 +878,8 @@ void ELFObjectFile<target_endianness, max_alignment, is64Bits>
LoadVersionNeeds(dot_gnu_version_r_sec);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-void ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::validateSymbol(DataRefImpl Symb) const {
+template<class ELFT>
+void ELFObjectFile<ELFT>::validateSymbol(DataRefImpl Symb) const {
const Elf_Sym *symb = getSymbol(Symb);
const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
// FIXME: We really need to do proper error handling in the case of an invalid
@@ -883,10 +896,9 @@ void ELFObjectFile<target_endianness, max_alignment, is64Bits>
report_fatal_error("Symb must point to a valid symbol!");
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolNext(DataRefImpl Symb,
- SymbolRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolNext(DataRefImpl Symb,
+ SymbolRef &Result) const {
validateSymbol(Symb);
const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
@@ -911,20 +923,18 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolName(DataRefImpl Symb,
- StringRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
+ StringRef &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolVersion(SymbolRef SymRef,
- StringRef &Version,
- bool &IsDefault) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef,
+ StringRef &Version,
+ bool &IsDefault) const {
DataRefImpl Symb = SymRef.getRawDataRefImpl();
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
@@ -932,19 +942,17 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
Version, IsDefault);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-ELF::Elf64_Word ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolTableIndex(const Elf_Sym *symb) const {
+template<class ELFT>
+ELF::Elf64_Word ELFObjectFile<ELFT>
+ ::getSymbolTableIndex(const Elf_Sym *symb) const {
if (symb->st_shndx == ELF::SHN_XINDEX)
return ExtendedSymbolTable.lookup(symb);
return symb->st_shndx;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Shdr *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSection(const Elf_Sym *symb) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Shdr *
+ELFObjectFile<ELFT>::getSection(const Elf_Sym *symb) const {
if (symb->st_shndx == ELF::SHN_XINDEX)
return getSection(ExtendedSymbolTable.lookup(symb));
if (symb->st_shndx >= ELF::SHN_LORESERVE)
@@ -952,38 +960,31 @@ ELFObjectFile<target_endianness, max_alignment, is64Bits>
return getSection(symb->st_shndx);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Shdr *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getElfSection(section_iterator &It) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Shdr *
+ELFObjectFile<ELFT>::getElfSection(section_iterator &It) const {
llvm::object::DataRefImpl ShdrRef = It->getRawDataRefImpl();
return reinterpret_cast<const Elf_Shdr *>(ShdrRef.p);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Sym *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getElfSymbol(symbol_iterator &It) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Sym *
+ELFObjectFile<ELFT>::getElfSymbol(symbol_iterator &It) const {
return getSymbol(It->getRawDataRefImpl());
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Sym *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getElfSymbol(uint32_t index) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Sym *
+ELFObjectFile<ELFT>::getElfSymbol(uint32_t index) const {
DataRefImpl SymbolData;
SymbolData.d.a = index;
SymbolData.d.b = 1;
return getSymbol(SymbolData);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolFileOffset(DataRefImpl Symb,
- uint64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb,
+ uint64_t &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
const Elf_Shdr *Section;
@@ -1015,10 +1016,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
}
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolAddress(DataRefImpl Symb,
- uint64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
const Elf_Shdr *Section;
@@ -1059,10 +1059,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
}
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolSize(DataRefImpl Symb,
- uint64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
+ uint64_t &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
if (symb->st_size == 0)
@@ -1071,10 +1070,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolNMTypeChar(DataRefImpl Symb,
- char &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolNMTypeChar(DataRefImpl Symb,
+ char &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
const Elf_Shdr *Section = getSection(symb);
@@ -1136,10 +1134,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
@@ -1168,10 +1165,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolFlags(DataRefImpl Symb,
- uint32_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb,
+ uint32_t &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
@@ -1203,10 +1199,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const {