#ifndef LLVM_OBJECT_ELFTYPES_H
#define LLVM_OBJECT_ELFTYPES_H
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
namespace llvm {
namespace object {
using support::endianness;
template <endianness target_endianness, std::size_t max_alignment,
bool is64Bits>
struct ELFType {
static const endianness TargetEndianness = target_endianness;
static const std::size_t MaxAlignment = max_alignment;
static const bool Is64Bits = is64Bits;
};
template <typename T, int max_align> struct MaximumAlignment {
enum { value = AlignOf<T>::Alignment > max_align ? max_align
: AlignOf<T>::Alignment
};
};
template <endianness target_endianness, std::size_t max_alignment>
struct ELFDataTypeTypedefHelperCommon {
typedef support::detail::packed_endian_specific_integral<
uint16_t, target_endianness,
MaximumAlignment<uint16_t, max_alignment>::value> Elf_Half;
typedef support::detail::packed_endian_specific_integral<
uint32_t, target_endianness,
MaximumAlignment<uint32_t, max_alignment>::value> Elf_Word;
typedef support::detail::packed_endian_specific_integral<
int32_t, target_endianness,
MaximumAlignment<int32_t, max_alignment>::value> Elf_Sword;
typedef support::detail::packed_endian_specific_integral<
uint64_t, target_endianness,
MaximumAlignment<uint64_t, max_alignment>::value> Elf_Xword;
typedef support::detail::packed_endian_specific_integral<
int64_t, target_endianness,
MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword;
};
template <class ELFT> struct ELFDataTypeTypedefHelper;
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<
value_type, TargetEndianness,
MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
typedef support::detail::packed_endian_specific_integral<
value_type, TargetEndianness,
MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
};
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<
value_type, TargetEndianness,
MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
typedef support::detail::packed_endian_specific_integral<
value_type, TargetEndianness,
MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
};
#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)
template <class ELFT> struct Elf_Shdr_Base;
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; Elf_Word sh_type; Elf_Word sh_flags; Elf_Addr sh_addr; Elf_Off sh_offset; Elf_Word sh_size; Elf_Word sh_link; Elf_Word sh_info; Elf_Word sh_addralign; Elf_Word sh_entsize; };
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; Elf_Word sh_type; Elf_Xword sh_flags; Elf_Addr sh_addr; Elf_Off sh_offset; Elf_Xword sh_size; Elf_Word sh_link; Elf_Word sh_info; Elf_Xword sh_addralign; Elf_Xword sh_entsize; };
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;
unsigned getEntityCount() const {
if (sh_entsize == 0)
return 0;
return sh_size / sh_entsize;
}
};
template <class ELFT> struct Elf_Sym_Base;
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; Elf_Addr st_value; Elf_Word st_size; unsigned char st_info; unsigned char st_other; Elf_Half st_shndx; };
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; unsigned char st_info; unsigned char st_other; Elf_Half st_shndx; Elf_Addr st_value; Elf_Xword st_size; };
template <class ELFT>
struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
using Elf_Sym_Base<ELFT>::st_info;
unsigned char getBinding() const { return st_info >> 4; }
unsigned char getType() const { return st_info & 0x0f; }
void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
void setBindingAndType(unsigned char b, unsigned char t) {
st_info = (b << 4) + (t & 0x0f);
}
};
template <class ELFT>
struct Elf_Versym_Impl {
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
Elf_Half vs_index; };
template <class ELFT> struct Elf_Verdaux_Impl;
template <class ELFT>
struct Elf_Verdef_Impl {
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
Elf_Half vd_version; Elf_Half vd_flags; Elf_Half vd_ndx; Elf_Half vd_cnt; Elf_Word vd_hash; Elf_Word vd_aux; Elf_Word vd_next;
const Elf_Verdaux *getAux() const {
return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux);
}
};
template <class ELFT>
struct Elf_Verdaux_Impl {
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
Elf_Word vda_name; Elf_Word vda_next; };
template <class ELFT>
struct Elf_Verneed_Impl {
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
Elf_Half vn_version; Elf_Half vn_cnt; Elf_Word vn_file; Elf_Word vn_aux; Elf_Word vn_next; };
template <class ELFT>
struct Elf_Vernaux_Impl {
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
Elf_Word vna_hash; Elf_Half vna_flags; Elf_Half vna_other; Elf_Word vna_name; Elf_Word vna_next; };
template <class ELFT> struct Elf_Dyn_Base;
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;
Elf_Addr d_ptr;
} d_un;
};
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;
Elf_Addr d_ptr;
} 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 <class ELFT, bool isRela> struct Elf_Rel_Base;
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; Elf_Word r_info;
uint32_t getRInfo(bool isMips64EL) const {
assert(!isMips64EL);
return r_info;
}
void setRInfo(uint32_t R) { r_info = R; }
};
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; Elf_Xword r_info;
uint64_t getRInfo(bool isMips64EL) const {
uint64_t t = r_info;
if (!isMips64EL)
return t;
return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
}
void setRInfo(uint64_t R) {
r_info = R;
}
};
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; Elf_Word r_info; Elf_Sword r_addend;
uint32_t getRInfo(bool isMips64EL) const {
assert(!isMips64EL);
return r_info;
}
void setRInfo(uint32_t R) { r_info = R; }
};
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; Elf_Xword r_info; Elf_Sxword r_addend;
uint64_t getRInfo(bool isMips64EL) const {
uint64_t t = r_info;
if (!isMips64EL)
return t;
return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
}
void setRInfo(uint64_t R) {
r_info = R;
}
};
template <class ELFT, bool isRela> struct Elf_Rel_Impl;
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)
uint32_t getSymbol(bool isMips64EL) const {
return (uint32_t)(this->getRInfo(isMips64EL) >> 32);
}
uint32_t getType(bool isMips64EL) const {
return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL);
}
void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
void setType(uint32_t t) { setSymbolAndType(getSymbol(), t); }
void setSymbolAndType(uint32_t s, uint32_t t) {
this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL));
}
};
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)
uint32_t getSymbol(bool isMips64EL) const {
return this->getRInfo(isMips64EL) >> 8;
}
unsigned char getType(bool isMips64EL) const {
return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
}
void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
void setSymbolAndType(uint32_t s, unsigned char t) {
this->setRInfo((s << 8) + t);
}
};
template <class ELFT>
struct Elf_Ehdr_Impl {
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
unsigned char e_ident[ELF::EI_NIDENT]; Elf_Half e_type; Elf_Half e_machine; Elf_Word e_version; Elf_Addr e_entry; Elf_Off e_phoff; Elf_Off e_shoff; Elf_Word e_flags; Elf_Half e_ehsize; Elf_Half e_phentsize; Elf_Half e_phnum; Elf_Half e_shentsize; Elf_Half e_shnum; Elf_Half e_shstrndx; bool checkMagic() const {
return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
}
unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
};
template <class ELFT> struct Elf_Phdr_Impl;
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; Elf_Off p_offset; Elf_Addr p_vaddr; Elf_Addr p_paddr; Elf_Word p_filesz; Elf_Word p_memsz; Elf_Word p_flags; Elf_Word p_align; };
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; Elf_Word p_flags; Elf_Off p_offset; Elf_Addr p_vaddr; Elf_Addr p_paddr; Elf_Xword p_filesz; Elf_Xword p_memsz; Elf_Xword p_align; };
} }
#endif