diff options
Diffstat (limited to 'elfcpp/elfcpp_internal.h')
-rw-r--r-- | elfcpp/elfcpp_internal.h | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/elfcpp/elfcpp_internal.h b/elfcpp/elfcpp_internal.h new file mode 100644 index 00000000000..f4dd8bd5195 --- /dev/null +++ b/elfcpp/elfcpp_internal.h @@ -0,0 +1,238 @@ +// elfcpp_internal.h -- internals for elfcpp -*- C++ -*- + +// This is included by elfcpp.h, the external interface, but holds +// information which we want to keep private. + +#include "elfcpp_config.h" + +#include <byteswap.h> + +#ifndef ELFCPP_INTERNAL_H +#define ELFCPP_INTERNAL_H + +namespace elfcpp +{ + +namespace internal +{ + +#ifdef WORDS_BIG_ENDIAN +const bool host_big_endian = true; +#else +const bool host_big_endian = false; +#endif + +// Conversion routines between target and host. + +// Convert Elf_Half. + +template<bool same_endian> +Elf_Half +convert_half_host(Elf_Half v); + +template<> +inline Elf_Half +convert_half_host<true>(Elf_Half v) +{ + return v; +} + +template<> +inline Elf_Half +convert_half_host<false>(Elf_Half v) +{ + return bswap_16(v); +} + +template<bool big_endian> +inline Elf_Half +convert_half(Elf_Half v) +{ + return convert_half_host<big_endian == host_big_endian>(v); +} + +// Convert Elf_Word. + +template<bool same_endian> +Elf_Word +convert_word_host(Elf_Word v); + +template<> +inline Elf_Word +convert_word_host<true>(Elf_Word v) +{ + return v; +} + +template<> +inline Elf_Word +convert_word_host<false>(Elf_Word v) +{ + return bswap_32(v); +} + +template<bool big_endian> +inline Elf_Word +convert_word(Elf_Word v) +{ + return convert_word_host<big_endian == host_big_endian>(v); +} + +// Convert Elf_Xword. + +template<bool same_endian> +Elf_Xword +convert_xword_host(Elf_Xword v); + +template<> +inline Elf_Xword +convert_xword_host<true>(Elf_Xword v) +{ + return v; +} + +template<> +inline Elf_Xword +convert_xword_host<false>(Elf_Xword v) +{ + return bswap_64(v); +} + +template<bool big_endian> +inline Elf_Xword +convert_xword(Elf_Xword v) +{ + return convert_xword_host<big_endian == host_big_endian>(v); +} + +// Convert Elf_addr. + +template<int size, bool same_endian> +typename Elf_types<size>::Elf_Addr +convert_addr_size(typename Elf_types<size>::Elf_Addr); + +template<> +inline Elf_types<32>::Elf_Addr +convert_addr_size<32, true>(Elf_types<32>::Elf_Addr v) +{ + return v; +} + +template<> +inline Elf_types<64>::Elf_Addr +convert_addr_size<64, true>(Elf_types<64>::Elf_Addr v) +{ + return v; +} + +template<> +inline Elf_types<32>::Elf_Addr +convert_addr_size<32, false>(Elf_types<32>::Elf_Addr v) +{ + return bswap_32(v); +} + +template<> +inline Elf_types<64>::Elf_Addr +convert_addr_size<64, false>(Elf_types<64>::Elf_Addr v) +{ + return bswap_64(v); +} + +template<int size, bool big_endian> +inline typename Elf_types<size>::Elf_Addr +convert_addr(typename Elf_types<size>::Elf_Addr v) +{ + return convert_addr_size<size, big_endian == host_big_endian>(v); +} + +// Convert Elf_Off. + +template<int size, bool big_endian> +inline typename Elf_types<size>::Elf_Off +convert_off(typename Elf_types<size>::Elf_Off v) +{ + return convert_addr_size<size, big_endian == host_big_endian>(v); +} + +// Convert Elf_WXword. + +template<int size, bool big_endian> +inline typename Elf_types<size>::Elf_Off +convert_wxword(typename Elf_types<size>::Elf_Off v) +{ + return convert_addr_size<size, big_endian == host_big_endian>(v); +} + +// The ELF file header. + +template<int size> +struct Ehdr_data +{ + unsigned char e_ident[EI_NIDENT]; + Elf_Half e_type; + Elf_Half e_machine; + Elf_Word e_version; + typename Elf_types<size>::Elf_Addr e_entry; + typename Elf_types<size>::Elf_Off e_phoff; + typename Elf_types<size>::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; +}; + +// An Elf section header. + +template<int size> +struct Shdr_data +{ + Elf_Word sh_name; + Elf_Word sh_type; + typename Elf_types<size>::Elf_WXword sh_flags; + typename Elf_types<size>::Elf_Addr sh_addr; + typename Elf_types<size>::Elf_Off sh_offset; + typename Elf_types<size>::Elf_WXword sh_size; + Elf_Word sh_link; + Elf_Word sh_info; + typename Elf_types<size>::Elf_WXword sh_addralign; + typename Elf_types<size>::Elf_WXword sh_entsize; +}; + +// An ELF symbol table entry. We use template specialization for the +// 32-bit and 64-bit versions because the fields are in a different +// order. + +template<int size> +struct Sym_data; + +template<> +struct Sym_data<32> +{ + Elf_Word st_name; + Elf_types<32>::Elf_Addr st_value; + Elf_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf_Half st_shndx; +}; + +template<> +struct Sym_data<64> +{ + Elf_Word st_name; + unsigned char st_info; + unsigned char st_other; + Elf_Half st_shndx; + Elf_types<64>::Elf_Addr st_value; + Elf_Xword st_size; +}; + +} // End namespace internal. + +} // End namespace elfcpp. + +#endif // !defined(ELFCPP_INTERNAL_H) |