Add program segments.
This commit is contained in:
parent
3c68c38feb
commit
39081c14cf
2 changed files with 128 additions and 13 deletions
108
elfcpp/elfcpp.h
108
elfcpp/elfcpp.h
|
@ -26,14 +26,7 @@ typedef int64_t Elf_Sxword;
|
|||
// template parameter should be 32 or 64.
|
||||
|
||||
template<int size>
|
||||
struct Elf_types
|
||||
{
|
||||
// Dummy types which should not be used.
|
||||
typedef unsigned char Elf_Addr;
|
||||
typedef unsigned char Elf_Off;
|
||||
// WXword is for fields which are Elf32_Word and Elf64_Xword.
|
||||
typedef unsigned char Elf_WXword;
|
||||
};
|
||||
struct Elf_types;
|
||||
|
||||
template<>
|
||||
struct Elf_types<32>
|
||||
|
@ -49,9 +42,6 @@ struct Elf_types<64>
|
|||
typedef uint64_t Elf_Addr;
|
||||
typedef uint64_t Elf_Off;
|
||||
typedef uint64_t Elf_WXword;
|
||||
static const int ehdr_size;
|
||||
static const int shdr_size;
|
||||
static const int sym_size;
|
||||
};
|
||||
|
||||
// Offsets within the Ehdr e_ident field.
|
||||
|
@ -299,7 +289,7 @@ enum
|
|||
|
||||
// The valid values found in the Shdr sh_type field.
|
||||
|
||||
enum
|
||||
enum SHT
|
||||
{
|
||||
SHT_NULL = 0,
|
||||
SHT_PROGBITS = 1,
|
||||
|
@ -340,7 +330,7 @@ enum
|
|||
|
||||
// The valid bit flags found in the Shdr sh_flags field.
|
||||
|
||||
enum
|
||||
enum SHF
|
||||
{
|
||||
SHF_WRITE = 0x1,
|
||||
SHF_ALLOC = 0x2,
|
||||
|
@ -366,6 +356,43 @@ enum
|
|||
GRP_MASKPROC = 0xf0000000
|
||||
};
|
||||
|
||||
// The valid values found in the Phdr p_type field.
|
||||
|
||||
enum PT
|
||||
{
|
||||
PT_NULL = 0,
|
||||
PT_LOAD = 1,
|
||||
PT_DYNAMIC = 2,
|
||||
PT_INTERP = 3,
|
||||
PT_NOTE = 4,
|
||||
PT_SHLIB = 5,
|
||||
PT_PHDR = 6,
|
||||
PT_TLS = 7,
|
||||
PT_LOOS = 0x60000000,
|
||||
PT_HIOS = 0x6fffffff,
|
||||
PT_LOPROC = 0x70000000,
|
||||
PT_HIPROC = 0x7fffffff,
|
||||
// The remaining values are not in the standard.
|
||||
// Frame unwind information.
|
||||
PT_GNU_EH_FRAME = 0x6474e550,
|
||||
PT_SUNW_EH_FRAME = 0x6474e550,
|
||||
// Stack flags.
|
||||
PT_GNU_STACK = 0x6474e551,
|
||||
// Read only after relocation.
|
||||
PT_GNU_RELRO = 0x6474e552
|
||||
};
|
||||
|
||||
// The valid bit flags found in the Phdr p_flags field.
|
||||
|
||||
enum PF
|
||||
{
|
||||
PF_X = 0x1,
|
||||
PF_W = 0x2,
|
||||
PF_R = 0x4,
|
||||
PF_MASKOS = 0x0ff00000,
|
||||
PF_MASKPROC = 0xf0000000
|
||||
};
|
||||
|
||||
// Symbol binding from Sym st_info field.
|
||||
|
||||
enum STB
|
||||
|
@ -469,6 +496,15 @@ struct Elf_sizes
|
|||
static const int sym_size = sizeof(internal::Sym_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);
|
||||
}
|
||||
|
||||
// Accessor class for the ELF file header.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
|
@ -594,6 +630,52 @@ class Shdr
|
|||
const internal::Shdr_data<size>* p_;
|
||||
};
|
||||
|
||||
// Accessor class for an ELF segment header.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
class Phdr
|
||||
{
|
||||
public:
|
||||
Phdr(const unsigned char* p)
|
||||
: p_(reinterpret_cast<const internal::Phdr_data<size>*>(p))
|
||||
{ }
|
||||
|
||||
Elf_Word
|
||||
get_p_type() const
|
||||
{ return internal::convert_word<big_endian>(this->p_->p_type); }
|
||||
|
||||
typename Elf_types<size>::Elf_Off
|
||||
get_p_offset() const
|
||||
{ return internal::convert_off<size, big_endian>(this->p_->p_offset); }
|
||||
|
||||
typename Elf_types<size>::Elf_Addr
|
||||
get_p_vaddr() const
|
||||
{ return internal::convert_addr<size, big_endian>(this->p_->p_vaddr); }
|
||||
|
||||
typename Elf_types<size>::Elf_Addr
|
||||
get_p_paddr() const
|
||||
{ return internal::convert_addr<size, big_endian>(this->p_->p_paddr); }
|
||||
|
||||
typename Elf_types<size>::Elf_WXword
|
||||
get_p_filesz() const
|
||||
{ return internal::convert_wxword<size, big_endian>(this->p_->p_filesz); }
|
||||
|
||||
typename Elf_types<size>::Elf_WXword
|
||||
get_p_memsz() const
|
||||
{ return internal::convert_wxword<size, big_endian>(this->p_->p_memsz); }
|
||||
|
||||
Elf_Word
|
||||
get_p_flags() const
|
||||
{ return internal::convert_word<big_endian>(this->p_->p_flags); }
|
||||
|
||||
typename Elf_types<size>::Elf_WXword
|
||||
get_p_align() const
|
||||
{ return internal::convert_wxword<size, big_endian>(this->p_->p_align); }
|
||||
|
||||
private:
|
||||
const internal::Phdr_data<size>* p_;
|
||||
};
|
||||
|
||||
// Accessor class for an ELF symbol table entry.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
|
|
|
@ -202,6 +202,39 @@ struct Shdr_data
|
|||
typename Elf_types<size>::Elf_WXword sh_entsize;
|
||||
};
|
||||
|
||||
// An ELF segment header. We use template specialization for the
|
||||
// 32-bit and 64-bit versions because the fields are in a different
|
||||
// order.
|
||||
|
||||
template<int size>
|
||||
struct Phdr_data;
|
||||
|
||||
template<>
|
||||
struct Phdr_data<32>
|
||||
{
|
||||
Elf_Word p_type;
|
||||
Elf_types<32>::Elf_Off p_offset;
|
||||
Elf_types<32>::Elf_Addr p_vaddr;
|
||||
Elf_types<32>::Elf_Addr p_paddr;
|
||||
Elf_Word p_filesz;
|
||||
Elf_Word p_memsz;
|
||||
Elf_Word p_flags;
|
||||
Elf_Word p_align;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Phdr_data<64>
|
||||
{
|
||||
Elf_Word p_type;
|
||||
Elf_Word p_flags;
|
||||
Elf_types<64>::Elf_Off p_offset;
|
||||
Elf_types<64>::Elf_Addr p_vaddr;
|
||||
Elf_types<64>::Elf_Addr p_paddr;
|
||||
Elf_Xword p_filesz;
|
||||
Elf_Xword p_memsz;
|
||||
Elf_Xword p_align;
|
||||
};
|
||||
|
||||
// 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.
|
||||
|
|
Loading…
Reference in a new issue