Rework swapping code.
This commit is contained in:
parent
000ef4f0ec
commit
8d9455b422
3 changed files with 426 additions and 252 deletions
169
elfcpp/elfcpp.h
169
elfcpp/elfcpp.h
|
@ -6,6 +6,7 @@
|
||||||
#define ELFCPP_H
|
#define ELFCPP_H
|
||||||
|
|
||||||
#include "elfcpp_config.h"
|
#include "elfcpp_config.h"
|
||||||
|
#include "elfcpp_swap.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@ -559,24 +560,6 @@ struct Elf_sizes
|
||||||
static const int rela_size = sizeof(internal::Rela_data<size>);
|
static const int rela_size = sizeof(internal::Rela_data<size>);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Given the address of an Elf_Word, return the value.
|
|
||||||
|
|
||||||
template<bool big_endian>
|
|
||||||
inline Elf_Word
|
|
||||||
read_elf_word(const Elf_Word* p)
|
|
||||||
{
|
|
||||||
return internal::convert_word<big_endian>(*p);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store an Elf_Word into an address.
|
|
||||||
|
|
||||||
template<bool big_endian>
|
|
||||||
inline void
|
|
||||||
write_elf_word(Elf_Word* p, Elf_Word v)
|
|
||||||
{
|
|
||||||
*p = internal::convert_word<big_endian>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accessor class for the ELF file header.
|
// Accessor class for the ELF file header.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
|
@ -593,55 +576,55 @@ class Ehdr
|
||||||
|
|
||||||
Elf_Half
|
Elf_Half
|
||||||
get_e_type() const
|
get_e_type() const
|
||||||
{ return internal::convert_half<big_endian>(this->p_->e_type); }
|
{ return Convert<16, big_endian>::convert_host(this->p_->e_type); }
|
||||||
|
|
||||||
Elf_Half
|
Elf_Half
|
||||||
get_e_machine() const
|
get_e_machine() const
|
||||||
{ return internal::convert_half<big_endian>(this->p_->e_machine); }
|
{ return Convert<16, big_endian>::convert_host(this->p_->e_machine); }
|
||||||
|
|
||||||
Elf_Word
|
Elf_Word
|
||||||
get_e_version() const
|
get_e_version() const
|
||||||
{ return internal::convert_word<big_endian>(this->p_->e_version); }
|
{ return Convert<32, big_endian>::convert_host(this->p_->e_version); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_Addr
|
typename Elf_types<size>::Elf_Addr
|
||||||
get_e_entry() const
|
get_e_entry() const
|
||||||
{ return internal::convert_addr<size, big_endian>(this->p_->e_entry); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->e_entry); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_Off
|
typename Elf_types<size>::Elf_Off
|
||||||
get_e_phoff() const
|
get_e_phoff() const
|
||||||
{ return internal::convert_off<size, big_endian>(this->p_->e_phoff); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->e_phoff); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_Off
|
typename Elf_types<size>::Elf_Off
|
||||||
get_e_shoff() const
|
get_e_shoff() const
|
||||||
{ return internal::convert_off<size, big_endian>(this->p_->e_shoff); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->e_shoff); }
|
||||||
|
|
||||||
Elf_Word
|
Elf_Word
|
||||||
get_e_flags() const
|
get_e_flags() const
|
||||||
{ return internal::convert_word<big_endian>(this->p_->e_flags); }
|
{ return Convert<32, big_endian>::convert_host(this->p_->e_flags); }
|
||||||
|
|
||||||
Elf_Half
|
Elf_Half
|
||||||
get_e_ehsize() const
|
get_e_ehsize() const
|
||||||
{ return internal::convert_half<big_endian>(this->p_->e_ehsize); }
|
{ return Convert<16, big_endian>::convert_host(this->p_->e_ehsize); }
|
||||||
|
|
||||||
Elf_Half
|
Elf_Half
|
||||||
get_e_phentsize() const
|
get_e_phentsize() const
|
||||||
{ return internal::convert_half<big_endian>(this->p_->e_phentsize); }
|
{ return Convert<16, big_endian>::convert_host(this->p_->e_phentsize); }
|
||||||
|
|
||||||
Elf_Half
|
Elf_Half
|
||||||
get_e_phnum() const
|
get_e_phnum() const
|
||||||
{ return internal::convert_half<big_endian>(this->p_->e_phnum); }
|
{ return Convert<16, big_endian>::convert_host(this->p_->e_phnum); }
|
||||||
|
|
||||||
Elf_Half
|
Elf_Half
|
||||||
get_e_shentsize() const
|
get_e_shentsize() const
|
||||||
{ return internal::convert_half<big_endian>(this->p_->e_shentsize); }
|
{ return Convert<16, big_endian>::convert_host(this->p_->e_shentsize); }
|
||||||
|
|
||||||
Elf_Half
|
Elf_Half
|
||||||
get_e_shnum() const
|
get_e_shnum() const
|
||||||
{ return internal::convert_half<big_endian>(this->p_->e_shnum); }
|
{ return Convert<16, big_endian>::convert_host(this->p_->e_shnum); }
|
||||||
|
|
||||||
Elf_Half
|
Elf_Half
|
||||||
get_e_shstrndx() const
|
get_e_shstrndx() const
|
||||||
{ return internal::convert_half<big_endian>(this->p_->e_shstrndx); }
|
{ return Convert<16, big_endian>::convert_host(this->p_->e_shstrndx); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const internal::Ehdr_data<size>* p_;
|
const internal::Ehdr_data<size>* p_;
|
||||||
|
@ -663,55 +646,55 @@ class Ehdr_write
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_type(Elf_Half v)
|
put_e_type(Elf_Half v)
|
||||||
{ this->p_->e_type = internal::convert_half<big_endian>(v); }
|
{ this->p_->e_type = Convert<16, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_machine(Elf_Half v)
|
put_e_machine(Elf_Half v)
|
||||||
{ this->p_->e_machine = internal::convert_half<big_endian>(v); }
|
{ this->p_->e_machine = Convert<16, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_version(Elf_Word v)
|
put_e_version(Elf_Word v)
|
||||||
{ this->p_->e_version = internal::convert_word<big_endian>(v); }
|
{ this->p_->e_version = Convert<32, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_entry(typename Elf_types<size>::Elf_Addr v)
|
put_e_entry(typename Elf_types<size>::Elf_Addr v)
|
||||||
{ this->p_->e_entry = internal::convert_addr<size, big_endian>(v); }
|
{ this->p_->e_entry = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_phoff(typename Elf_types<size>::Elf_Off v)
|
put_e_phoff(typename Elf_types<size>::Elf_Off v)
|
||||||
{ this->p_->e_phoff = internal::convert_off<size, big_endian>(v); }
|
{ this->p_->e_phoff = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_shoff(typename Elf_types<size>::Elf_Off v)
|
put_e_shoff(typename Elf_types<size>::Elf_Off v)
|
||||||
{ this->p_->e_shoff = internal::convert_off<size, big_endian>(v); }
|
{ this->p_->e_shoff = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_flags(Elf_Word v)
|
put_e_flags(Elf_Word v)
|
||||||
{ this->p_->e_flags = internal::convert_word<big_endian>(v); }
|
{ this->p_->e_flags = Convert<32, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_ehsize(Elf_Half v)
|
put_e_ehsize(Elf_Half v)
|
||||||
{ this->p_->e_ehsize = internal::convert_half<big_endian>(v); }
|
{ this->p_->e_ehsize = Convert<16, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_phentsize(Elf_Half v)
|
put_e_phentsize(Elf_Half v)
|
||||||
{ this->p_->e_phentsize = internal::convert_half<big_endian>(v); }
|
{ this->p_->e_phentsize = Convert<16, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_phnum(Elf_Half v)
|
put_e_phnum(Elf_Half v)
|
||||||
{ this->p_->e_phnum = internal::convert_half<big_endian>(v); }
|
{ this->p_->e_phnum = Convert<16, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_shentsize(Elf_Half v)
|
put_e_shentsize(Elf_Half v)
|
||||||
{ this->p_->e_shentsize = internal::convert_half<big_endian>(v); }
|
{ this->p_->e_shentsize = Convert<16, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_shnum(Elf_Half v)
|
put_e_shnum(Elf_Half v)
|
||||||
{ this->p_->e_shnum = internal::convert_half<big_endian>(v); }
|
{ this->p_->e_shnum = Convert<16, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_e_shstrndx(Elf_Half v)
|
put_e_shstrndx(Elf_Half v)
|
||||||
{ this->p_->e_shstrndx = internal::convert_half<big_endian>(v); }
|
{ this->p_->e_shstrndx = Convert<16, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
internal::Ehdr_data<size>* p_;
|
internal::Ehdr_data<size>* p_;
|
||||||
|
@ -729,44 +712,44 @@ class Shdr
|
||||||
|
|
||||||
Elf_Word
|
Elf_Word
|
||||||
get_sh_name() const
|
get_sh_name() const
|
||||||
{ return internal::convert_word<big_endian>(this->p_->sh_name); }
|
{ return Convert<32, big_endian>::convert_host(this->p_->sh_name); }
|
||||||
|
|
||||||
Elf_Word
|
Elf_Word
|
||||||
get_sh_type() const
|
get_sh_type() const
|
||||||
{ return internal::convert_word<big_endian>(this->p_->sh_type); }
|
{ return Convert<32, big_endian>::convert_host(this->p_->sh_type); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_WXword
|
typename Elf_types<size>::Elf_WXword
|
||||||
get_sh_flags() const
|
get_sh_flags() const
|
||||||
{ return internal::convert_wxword<size, big_endian>(this->p_->sh_flags); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->sh_flags); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_Addr
|
typename Elf_types<size>::Elf_Addr
|
||||||
get_sh_addr() const
|
get_sh_addr() const
|
||||||
{ return internal::convert_addr<size, big_endian>(this->p_->sh_addr); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->sh_addr); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_Off
|
typename Elf_types<size>::Elf_Off
|
||||||
get_sh_offset() const
|
get_sh_offset() const
|
||||||
{ return internal::convert_off<size, big_endian>(this->p_->sh_offset); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->sh_offset); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_WXword
|
typename Elf_types<size>::Elf_WXword
|
||||||
get_sh_size() const
|
get_sh_size() const
|
||||||
{ return internal::convert_wxword<size, big_endian>(this->p_->sh_size); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->sh_size); }
|
||||||
|
|
||||||
Elf_Word
|
Elf_Word
|
||||||
get_sh_link() const
|
get_sh_link() const
|
||||||
{ return internal::convert_word<big_endian>(this->p_->sh_link); }
|
{ return Convert<32, big_endian>::convert_host(this->p_->sh_link); }
|
||||||
|
|
||||||
Elf_Word
|
Elf_Word
|
||||||
get_sh_info() const
|
get_sh_info() const
|
||||||
{ return internal::convert_word<big_endian>(this->p_->sh_info); }
|
{ return Convert<32, big_endian>::convert_host(this->p_->sh_info); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_WXword
|
typename Elf_types<size>::Elf_WXword
|
||||||
get_sh_addralign() const
|
get_sh_addralign() const
|
||||||
{ return
|
{ return
|
||||||
internal::convert_wxword<size, big_endian>(this->p_->sh_addralign); }
|
Convert<size, big_endian>::convert_host(this->p_->sh_addralign); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_WXword
|
typename Elf_types<size>::Elf_WXword
|
||||||
get_sh_entsize() const
|
get_sh_entsize() const
|
||||||
{ return internal::convert_wxword<size, big_endian>(this->p_->sh_entsize); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->sh_entsize); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const internal::Shdr_data<size>* p_;
|
const internal::Shdr_data<size>* p_;
|
||||||
|
@ -784,43 +767,43 @@ class Shdr_write
|
||||||
|
|
||||||
void
|
void
|
||||||
put_sh_name(Elf_Word v)
|
put_sh_name(Elf_Word v)
|
||||||
{ this->p_->sh_name = internal::convert_word<big_endian>(v); }
|
{ this->p_->sh_name = Convert<32, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_sh_type(Elf_Word v)
|
put_sh_type(Elf_Word v)
|
||||||
{ this->p_->sh_type = internal::convert_word<big_endian>(v); }
|
{ this->p_->sh_type = Convert<32, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_sh_flags(typename Elf_types<size>::Elf_WXword v)
|
put_sh_flags(typename Elf_types<size>::Elf_WXword v)
|
||||||
{ this->p_->sh_flags = internal::convert_wxword<size, big_endian>(v); }
|
{ this->p_->sh_flags = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_sh_addr(typename Elf_types<size>::Elf_Addr v)
|
put_sh_addr(typename Elf_types<size>::Elf_Addr v)
|
||||||
{ this->p_->sh_addr = internal::convert_addr<size, big_endian>(v); }
|
{ this->p_->sh_addr = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_sh_offset(typename Elf_types<size>::Elf_Off v)
|
put_sh_offset(typename Elf_types<size>::Elf_Off v)
|
||||||
{ this->p_->sh_offset = internal::convert_off<size, big_endian>(v); }
|
{ this->p_->sh_offset = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_sh_size(typename Elf_types<size>::Elf_WXword v)
|
put_sh_size(typename Elf_types<size>::Elf_WXword v)
|
||||||
{ this->p_->sh_size = internal::convert_wxword<size, big_endian>(v); }
|
{ this->p_->sh_size = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_sh_link(Elf_Word v)
|
put_sh_link(Elf_Word v)
|
||||||
{ this->p_->sh_link = internal::convert_word<big_endian>(v); }
|
{ this->p_->sh_link = Convert<32, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_sh_info(Elf_Word v)
|
put_sh_info(Elf_Word v)
|
||||||
{ this->p_->sh_info = internal::convert_word<big_endian>(v); }
|
{ this->p_->sh_info = Convert<32, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_sh_addralign(typename Elf_types<size>::Elf_WXword v)
|
put_sh_addralign(typename Elf_types<size>::Elf_WXword v)
|
||||||
{ this->p_->sh_addralign = internal::convert_wxword<size, big_endian>(v); }
|
{ this->p_->sh_addralign = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_sh_entsize(typename Elf_types<size>::Elf_WXword v)
|
put_sh_entsize(typename Elf_types<size>::Elf_WXword v)
|
||||||
{ this->p_->sh_entsize = internal::convert_wxword<size, big_endian>(v); }
|
{ this->p_->sh_entsize = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
internal::Shdr_data<size>* p_;
|
internal::Shdr_data<size>* p_;
|
||||||
|
@ -838,35 +821,35 @@ class Phdr
|
||||||
|
|
||||||
Elf_Word
|
Elf_Word
|
||||||
get_p_type() const
|
get_p_type() const
|
||||||
{ return internal::convert_word<big_endian>(this->p_->p_type); }
|
{ return Convert<32, big_endian>::convert_host(this->p_->p_type); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_Off
|
typename Elf_types<size>::Elf_Off
|
||||||
get_p_offset() const
|
get_p_offset() const
|
||||||
{ return internal::convert_off<size, big_endian>(this->p_->p_offset); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->p_offset); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_Addr
|
typename Elf_types<size>::Elf_Addr
|
||||||
get_p_vaddr() const
|
get_p_vaddr() const
|
||||||
{ return internal::convert_addr<size, big_endian>(this->p_->p_vaddr); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->p_vaddr); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_Addr
|
typename Elf_types<size>::Elf_Addr
|
||||||
get_p_paddr() const
|
get_p_paddr() const
|
||||||
{ return internal::convert_addr<size, big_endian>(this->p_->p_paddr); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->p_paddr); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_WXword
|
typename Elf_types<size>::Elf_WXword
|
||||||
get_p_filesz() const
|
get_p_filesz() const
|
||||||
{ return internal::convert_wxword<size, big_endian>(this->p_->p_filesz); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->p_filesz); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_WXword
|
typename Elf_types<size>::Elf_WXword
|
||||||
get_p_memsz() const
|
get_p_memsz() const
|
||||||
{ return internal::convert_wxword<size, big_endian>(this->p_->p_memsz); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->p_memsz); }
|
||||||
|
|
||||||
Elf_Word
|
Elf_Word
|
||||||
get_p_flags() const
|
get_p_flags() const
|
||||||
{ return internal::convert_word<big_endian>(this->p_->p_flags); }
|
{ return Convert<32, big_endian>::convert_host(this->p_->p_flags); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_WXword
|
typename Elf_types<size>::Elf_WXword
|
||||||
get_p_align() const
|
get_p_align() const
|
||||||
{ return internal::convert_wxword<size, big_endian>(this->p_->p_align); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->p_align); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const internal::Phdr_data<size>* p_;
|
const internal::Phdr_data<size>* p_;
|
||||||
|
@ -884,35 +867,35 @@ class Phdr_write
|
||||||
|
|
||||||
void
|
void
|
||||||
put_p_type(Elf_Word v)
|
put_p_type(Elf_Word v)
|
||||||
{ this->p_->p_type = internal::convert_word<big_endian>(v); }
|
{ this->p_->p_type = Convert<32, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_p_offset(typename Elf_types<size>::Elf_Off v)
|
put_p_offset(typename Elf_types<size>::Elf_Off v)
|
||||||
{ this->p_->p_offset = internal::convert_off<size, big_endian>(v); }
|
{ this->p_->p_offset = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_p_vaddr(typename Elf_types<size>::Elf_Addr v)
|
put_p_vaddr(typename Elf_types<size>::Elf_Addr v)
|
||||||
{ this->p_->p_vaddr = internal::convert_addr<size, big_endian>(v); }
|
{ this->p_->p_vaddr = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_p_paddr(typename Elf_types<size>::Elf_Addr v)
|
put_p_paddr(typename Elf_types<size>::Elf_Addr v)
|
||||||
{ this->p_->p_paddr = internal::convert_addr<size, big_endian>(v); }
|
{ this->p_->p_paddr = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_p_filesz(typename Elf_types<size>::Elf_WXword v)
|
put_p_filesz(typename Elf_types<size>::Elf_WXword v)
|
||||||
{ this->p_->p_filesz = internal::convert_wxword<size, big_endian>(v); }
|
{ this->p_->p_filesz = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_p_memsz(typename Elf_types<size>::Elf_WXword v)
|
put_p_memsz(typename Elf_types<size>::Elf_WXword v)
|
||||||
{ this->p_->p_memsz = internal::convert_wxword<size, big_endian>(v); }
|
{ this->p_->p_memsz = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_p_flags(Elf_Word v)
|
put_p_flags(Elf_Word v)
|
||||||
{ this->p_->p_flags = internal::convert_word<big_endian>(v); }
|
{ this->p_->p_flags = Convert<32, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_p_align(typename Elf_types<size>::Elf_WXword v)
|
put_p_align(typename Elf_types<size>::Elf_WXword v)
|
||||||
{ this->p_->p_align = internal::convert_wxword<size, big_endian>(v); }
|
{ this->p_->p_align = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
internal::Phdr_data<size>* p_;
|
internal::Phdr_data<size>* p_;
|
||||||
|
@ -930,15 +913,15 @@ class Sym
|
||||||
|
|
||||||
Elf_Word
|
Elf_Word
|
||||||
get_st_name() const
|
get_st_name() const
|
||||||
{ return internal::convert_word<big_endian>(this->p_->st_name); }
|
{ return Convert<32, big_endian>::convert_host(this->p_->st_name); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_Addr
|
typename Elf_types<size>::Elf_Addr
|
||||||
get_st_value() const
|
get_st_value() const
|
||||||
{ return internal::convert_addr<size, big_endian>(this->p_->st_value); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->st_value); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_WXword
|
typename Elf_types<size>::Elf_WXword
|
||||||
get_st_size() const
|
get_st_size() const
|
||||||
{ return internal::convert_wxword<size, big_endian>(this->p_->st_size); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->st_size); }
|
||||||
|
|
||||||
unsigned char
|
unsigned char
|
||||||
get_st_info() const
|
get_st_info() const
|
||||||
|
@ -966,7 +949,7 @@ class Sym
|
||||||
|
|
||||||
Elf_Half
|
Elf_Half
|
||||||
get_st_shndx() const
|
get_st_shndx() const
|
||||||
{ return internal::convert_half<big_endian>(this->p_->st_shndx); }
|
{ return Convert<16, big_endian>::convert_host(this->p_->st_shndx); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const internal::Sym_data<size>* p_;
|
const internal::Sym_data<size>* p_;
|
||||||
|
@ -984,15 +967,15 @@ class Sym_write
|
||||||
|
|
||||||
void
|
void
|
||||||
put_st_name(Elf_Word v)
|
put_st_name(Elf_Word v)
|
||||||
{ this->p_->st_name = internal::convert_word<big_endian>(v); }
|
{ this->p_->st_name = Convert<32, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_st_value(typename Elf_types<size>::Elf_Addr v)
|
put_st_value(typename Elf_types<size>::Elf_Addr v)
|
||||||
{ this->p_->st_value = internal::convert_addr<size, big_endian>(v); }
|
{ this->p_->st_value = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_st_size(typename Elf_types<size>::Elf_WXword v)
|
put_st_size(typename Elf_types<size>::Elf_WXword v)
|
||||||
{ this->p_->st_size = internal::convert_wxword<size, big_endian>(v); }
|
{ this->p_->st_size = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
void
|
void
|
||||||
put_st_info(unsigned char v)
|
put_st_info(unsigned char v)
|
||||||
|
@ -1012,7 +995,7 @@ class Sym_write
|
||||||
|
|
||||||
void
|
void
|
||||||
put_st_shndx(Elf_Half v)
|
put_st_shndx(Elf_Half v)
|
||||||
{ this->p_->st_shndx = internal::convert_half<big_endian>(v); }
|
{ this->p_->st_shndx = Convert<16, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
Sym<size, big_endian>
|
Sym<size, big_endian>
|
||||||
sym()
|
sym()
|
||||||
|
@ -1034,11 +1017,11 @@ class Rel
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_Addr
|
typename Elf_types<size>::Elf_Addr
|
||||||
get_r_offset() const
|
get_r_offset() const
|
||||||
{ return internal::convert_addr<size, big_endian>(this->p_->r_offset); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->r_offset); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_WXword
|
typename Elf_types<size>::Elf_WXword
|
||||||
get_r_info() const
|
get_r_info() const
|
||||||
{ return internal::convert_wxword<size, big_endian>(this->p_->r_info); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->r_info); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const internal::Rel_data<size>* p_;
|
const internal::Rel_data<size>* p_;
|
||||||
|
@ -1054,15 +1037,15 @@ class Rela
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_Addr
|
typename Elf_types<size>::Elf_Addr
|
||||||
get_r_offset() const
|
get_r_offset() const
|
||||||
{ return internal::convert_addr<size, big_endian>(this->p_->r_offset); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->r_offset); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_WXword
|
typename Elf_types<size>::Elf_WXword
|
||||||
get_r_info() const
|
get_r_info() const
|
||||||
{ return internal::convert_wxword<size, big_endian>(this->p_->r_info); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->r_info); }
|
||||||
|
|
||||||
typename Elf_types<size>::Elf_Swxword
|
typename Elf_types<size>::Elf_Swxword
|
||||||
get_r_addend() const
|
get_r_addend() const
|
||||||
{ return internal::convert_swxword<size, big_endian>(this->p_->r_addend); }
|
{ return Convert<size, big_endian>::convert_host(this->p_->r_addend); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const internal::Rela_data<size>* p_;
|
const internal::Rela_data<size>* p_;
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
|
|
||||||
#include "elfcpp_config.h"
|
#include "elfcpp_config.h"
|
||||||
|
|
||||||
#include <byteswap.h>
|
|
||||||
|
|
||||||
#ifndef ELFCPP_INTERNAL_H
|
#ifndef ELFCPP_INTERNAL_H
|
||||||
#define ELFCPP_INTERNAL_H
|
#define ELFCPP_INTERNAL_H
|
||||||
|
|
||||||
|
@ -16,163 +14,6 @@ namespace elfcpp
|
||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
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_WXword
|
|
||||||
convert_wxword(typename Elf_types<size>::Elf_WXword v)
|
|
||||||
{
|
|
||||||
return convert_addr_size<size, big_endian == host_big_endian>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert ELF_Swxword.
|
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
|
||||||
inline typename Elf_types<size>::Elf_Swxword
|
|
||||||
convert_swxword(typename Elf_types<size>::Elf_Swxword v)
|
|
||||||
{
|
|
||||||
return convert_addr_size<size, big_endian == host_big_endian>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The ELF file header.
|
// The ELF file header.
|
||||||
|
|
||||||
template<int size>
|
template<int size>
|
||||||
|
|
350
elfcpp/elfcpp_swap.h
Normal file
350
elfcpp/elfcpp_swap.h
Normal file
|
@ -0,0 +1,350 @@
|
||||||
|
// elfcpp_swap.h -- Handle swapping for elfcpp -*- C++ -*-
|
||||||
|
|
||||||
|
// This header file defines basic template classes to efficiently swap
|
||||||
|
// numbers between host form and target form. When the host and
|
||||||
|
// target have the same endianness, these turn into no-ops.
|
||||||
|
|
||||||
|
#ifndef ELFCPP_SWAP_H
|
||||||
|
#define ELFCPP_SWAP_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <endian.h>
|
||||||
|
#include <byteswap.h>
|
||||||
|
|
||||||
|
namespace elfcpp
|
||||||
|
{
|
||||||
|
|
||||||
|
// Endian simply indicates whether the host is big endian or not.
|
||||||
|
|
||||||
|
struct Endian
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Used for template specializations.
|
||||||
|
static const bool host_big_endian = __BYTE_ORDER == __BIG_ENDIAN;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Valtype_base is a template based on size (8, 16, 32, 64) which
|
||||||
|
// defines the type Valtype as the unsigned integer of the specified
|
||||||
|
// size.
|
||||||
|
|
||||||
|
template<int size>
|
||||||
|
struct Valtype_base;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Valtype_base<8>
|
||||||
|
{
|
||||||
|
typedef unsigned char Valtype;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Valtype_base<16>
|
||||||
|
{
|
||||||
|
typedef uint16_t Valtype;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Valtype_base<32>
|
||||||
|
{
|
||||||
|
typedef uint32_t Valtype;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Valtype_base<64>
|
||||||
|
{
|
||||||
|
typedef uint64_t Valtype;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convert_endian is a template based on size and on whether the host
|
||||||
|
// and target have the same endianness. It defines the type Valtype
|
||||||
|
// as Valtype_base does, and also defines a function convert_host
|
||||||
|
// which takes an argument of type Valtype and returns the same value,
|
||||||
|
// but swapped if the host and target have different endianness.
|
||||||
|
|
||||||
|
template<int size, bool same_endian>
|
||||||
|
struct Convert_endian;
|
||||||
|
|
||||||
|
template<int size>
|
||||||
|
struct Convert_endian<size, true>
|
||||||
|
{
|
||||||
|
typedef typename Valtype_base<size>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
convert_host(Valtype v)
|
||||||
|
{ return v; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Convert_endian<8, false>
|
||||||
|
{
|
||||||
|
typedef Valtype_base<8>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
convert_host(Valtype v)
|
||||||
|
{ return v; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Convert_endian<16, false>
|
||||||
|
{
|
||||||
|
typedef Valtype_base<16>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
convert_host(Valtype v)
|
||||||
|
{ return bswap_16(v); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Convert_endian<32, false>
|
||||||
|
{
|
||||||
|
typedef Valtype_base<32>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
convert_host(Valtype v)
|
||||||
|
{ return bswap_32(v); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Convert_endian<64, false>
|
||||||
|
{
|
||||||
|
typedef Valtype_base<64>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
convert_host(Valtype v)
|
||||||
|
{ return bswap_64(v); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convert is a template based on size and on whether the target is
|
||||||
|
// big endian. It defines Valtype and convert_host like
|
||||||
|
// Convert_endian. That is, it is just like Convert_endian except in
|
||||||
|
// the meaning of the second template parameter.
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
struct Convert
|
||||||
|
{
|
||||||
|
typedef typename Valtype_base<size>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
convert_host(Valtype v)
|
||||||
|
{
|
||||||
|
return Convert_endian<size, big_endian == Endian::host_big_endian>
|
||||||
|
::convert_host(v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Swap is a template based on size and on whether the target is big
|
||||||
|
// endian. It defines the type Valtype and the functions readval and
|
||||||
|
// writeval. The functions read and write values of the appropriate
|
||||||
|
// size out of buffers, swapping them if necessary. readval and
|
||||||
|
// writeval are overloaded to take pointers to the appropriate type or
|
||||||
|
// pointers to unsigned char.
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
struct Swap
|
||||||
|
{
|
||||||
|
typedef typename Valtype_base<size>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
readval(const Valtype* wv)
|
||||||
|
{ return Convert<size, big_endian>::convert_host(*wv); }
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
writeval(Valtype* wv, Valtype v)
|
||||||
|
{ *wv = Convert<size, big_endian>::convert_host(v); }
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
readval(const unsigned char* wv)
|
||||||
|
{ return readval(reinterpret_cast<const Valtype*>(wv)); }
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
writeval(unsigned char* wv, Valtype v)
|
||||||
|
{ writeval(reinterpret_cast<Valtype*>(wv), v); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// We need to specialize the 8-bit version of Swap to avoid
|
||||||
|
// conflicting overloads, since both versions of readval and writeval
|
||||||
|
// will have the same type parameters.
|
||||||
|
|
||||||
|
template<bool big_endian>
|
||||||
|
struct Swap<8, big_endian>
|
||||||
|
{
|
||||||
|
typedef typename Valtype_base<8>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
readval(const Valtype* wv)
|
||||||
|
{ return *wv; }
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
writeval(Valtype* wv, Valtype v)
|
||||||
|
{ *wv = v; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Swap_unaligned is a template based on size and on whether the
|
||||||
|
// target is big endian. It defines the type Valtype and the
|
||||||
|
// functions readval_unaligned and writeval_unaligned. The functions
|
||||||
|
// read and write values of the appropriate size out of buffers which
|
||||||
|
// may be misaligned.
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
struct Swap_unaligned;
|
||||||
|
|
||||||
|
template<bool big_endian>
|
||||||
|
struct Swap_unaligned<8, big_endian>
|
||||||
|
{
|
||||||
|
typedef typename Valtype_base<8>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
readval_unaligned(const unsigned char* wv)
|
||||||
|
{ return *wv; }
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
writeval_unaligned(unsigned char* wv, Valtype v)
|
||||||
|
{ *wv = v; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Swap_unaligned<16, false>
|
||||||
|
{
|
||||||
|
typedef Valtype_base<16>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
readval_unaligned(const unsigned char* wv)
|
||||||
|
{
|
||||||
|
return (wv[1] << 8) | wv[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
writeval_unaligned(unsigned char* wv, Valtype v)
|
||||||
|
{
|
||||||
|
wv[1] = v >> 8;
|
||||||
|
wv[0] = v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Swap_unaligned<16, true>
|
||||||
|
{
|
||||||
|
typedef Valtype_base<16>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
readval_unaligned(const unsigned char* wv)
|
||||||
|
{
|
||||||
|
return (wv[0] << 8) | wv[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
writeval_unaligned(unsigned char* wv, Valtype v)
|
||||||
|
{
|
||||||
|
wv[0] = v >> 8;
|
||||||
|
wv[1] = v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Swap_unaligned<32, false>
|
||||||
|
{
|
||||||
|
typedef Valtype_base<32>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
readval_unaligned(const unsigned char* wv)
|
||||||
|
{
|
||||||
|
return (wv[3] << 24) | (wv[2] << 16) | (wv[1] << 8) | wv[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
writeval_unaligned(unsigned char* wv, Valtype v)
|
||||||
|
{
|
||||||
|
wv[3] = v >> 24;
|
||||||
|
wv[2] = v >> 16;
|
||||||
|
wv[1] = v >> 8;
|
||||||
|
wv[0] = v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Swap_unaligned<32, true>
|
||||||
|
{
|
||||||
|
typedef Valtype_base<32>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
readval_unaligned(const unsigned char* wv)
|
||||||
|
{
|
||||||
|
return (wv[0] << 24) | (wv[1] << 16) | (wv[2] << 8) | wv[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
writeval_unaligned(unsigned char* wv, Valtype v)
|
||||||
|
{
|
||||||
|
wv[0] = v >> 24;
|
||||||
|
wv[1] = v >> 16;
|
||||||
|
wv[2] = v >> 8;
|
||||||
|
wv[3] = v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Swap_unaligned<64, false>
|
||||||
|
{
|
||||||
|
typedef Valtype_base<64>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
readval_unaligned(const unsigned char* wv)
|
||||||
|
{
|
||||||
|
return ((static_cast<Valtype>(wv[7]) << 56)
|
||||||
|
| (static_cast<Valtype>(wv[6]) << 48)
|
||||||
|
| (static_cast<Valtype>(wv[5]) << 40)
|
||||||
|
| (static_cast<Valtype>(wv[4]) << 32)
|
||||||
|
| (static_cast<Valtype>(wv[3]) << 24)
|
||||||
|
| (static_cast<Valtype>(wv[2]) << 16)
|
||||||
|
| (static_cast<Valtype>(wv[1]) << 8)
|
||||||
|
| static_cast<Valtype>(wv[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
writeval_unaligned(unsigned char* wv, Valtype v)
|
||||||
|
{
|
||||||
|
wv[7] = v >> 56;
|
||||||
|
wv[6] = v >> 48;
|
||||||
|
wv[5] = v >> 40;
|
||||||
|
wv[4] = v >> 32;
|
||||||
|
wv[3] = v >> 24;
|
||||||
|
wv[2] = v >> 16;
|
||||||
|
wv[1] = v >> 8;
|
||||||
|
wv[0] = v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Swap_unaligned<64, true>
|
||||||
|
{
|
||||||
|
typedef Valtype_base<64>::Valtype Valtype;
|
||||||
|
|
||||||
|
static inline Valtype
|
||||||
|
readval_unaligned(const unsigned char* wv)
|
||||||
|
{
|
||||||
|
return ((static_cast<Valtype>(wv[0]) << 56)
|
||||||
|
| (static_cast<Valtype>(wv[1]) << 48)
|
||||||
|
| (static_cast<Valtype>(wv[2]) << 40)
|
||||||
|
| (static_cast<Valtype>(wv[3]) << 32)
|
||||||
|
| (static_cast<Valtype>(wv[4]) << 24)
|
||||||
|
| (static_cast<Valtype>(wv[5]) << 16)
|
||||||
|
| (static_cast<Valtype>(wv[6]) << 8)
|
||||||
|
| static_cast<Valtype>(wv[7]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
writeval_unaligned(unsigned char* wv, Valtype v)
|
||||||
|
{
|
||||||
|
wv[7] = v >> 56;
|
||||||
|
wv[6] = v >> 48;
|
||||||
|
wv[5] = v >> 40;
|
||||||
|
wv[4] = v >> 32;
|
||||||
|
wv[3] = v >> 24;
|
||||||
|
wv[2] = v >> 16;
|
||||||
|
wv[1] = v >> 8;
|
||||||
|
wv[0] = v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End namespace elfcpp.
|
||||||
|
|
||||||
|
#endif // !defined(ELFCPP_SWAP_H)
|
Loading…
Add table
Reference in a new issue