mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
442 lines
15 KiB
C++
442 lines
15 KiB
C++
/* p_elf.h --
|
|
|
|
This file is part of the UPX executable compressor.
|
|
|
|
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
|
Copyright (C) 1996-2017 Laszlo Molnar
|
|
All Rights Reserved.
|
|
|
|
UPX and the UCL library are free software; you can redistribute them
|
|
and/or modify them under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of
|
|
the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; see the file COPYING.
|
|
If not, write to the Free Software Foundation, Inc.,
|
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
Markus F.X.J. Oberhumer Laszlo Molnar
|
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
|
*/
|
|
|
|
|
|
#ifndef __UPX_P_ELF_H
|
|
#define __UPX_P_ELF_H 1
|
|
|
|
|
|
/*************************************************************************
|
|
// N_Elf
|
|
**************************************************************************/
|
|
|
|
namespace N_Elf {
|
|
|
|
// integral types
|
|
template <class THalf, class TWord, class TXword, class TAddr, class TOff>
|
|
struct ElfITypes
|
|
{
|
|
typedef THalf Half;
|
|
typedef TWord Word;
|
|
typedef TXword Xword;
|
|
typedef TAddr Addr;
|
|
typedef TOff Off;
|
|
typedef THalf Section;
|
|
typedef THalf Versym;
|
|
};
|
|
|
|
|
|
// The ELF file header. This appears at the start of every ELF file.
|
|
template <class TElfITypes>
|
|
__packed_struct(Ehdr)
|
|
typedef typename TElfITypes::Half Half;
|
|
typedef typename TElfITypes::Word Word;
|
|
typedef typename TElfITypes::Addr Addr;
|
|
typedef typename TElfITypes::Off Off;
|
|
|
|
unsigned char e_ident[16]; /* Magic number and other info */
|
|
Half e_type; /* Object file type */
|
|
Half e_machine; /* Architecture */
|
|
Word e_version; /* Object file version */
|
|
Addr e_entry; /* Entry point virtual address */
|
|
Off e_phoff; /* Program header table file offset */
|
|
Off e_shoff; /* Section header table file offset */
|
|
Word e_flags; /* Processor-specific flags */
|
|
Half e_ehsize; /* ELF header size in bytes */
|
|
Half e_phentsize; /* Program header table entry size */
|
|
Half e_phnum; /* Program header table entry count */
|
|
Half e_shentsize; /* Section header table entry size */
|
|
Half e_shnum; /* Section header table entry count */
|
|
Half e_shstrndx; /* Section header string table index */
|
|
|
|
# define WANT_EHDR_ENUM 1
|
|
# include "p_elf_enum.h"
|
|
__packed_struct_end()
|
|
|
|
|
|
template <class TElfITypes>
|
|
__packed_struct(Dyn)
|
|
typedef typename TElfITypes::Xword Xword;
|
|
typedef typename TElfITypes::Addr Addr;
|
|
|
|
Xword d_tag;
|
|
Addr d_val;
|
|
|
|
# define WANT_DYN_ENUM 1
|
|
# include "p_elf_enum.h"
|
|
__packed_struct_end()
|
|
|
|
|
|
template <class TElfITypes>
|
|
__packed_struct(Rel)
|
|
typedef typename TElfITypes::Xword Xword;
|
|
typedef typename TElfITypes::Addr Addr;
|
|
|
|
Addr r_offset;
|
|
Xword r_info;
|
|
__packed_struct_end()
|
|
|
|
|
|
template <class TElfITypes>
|
|
__packed_struct(Rela)
|
|
typedef typename TElfITypes::Xword Xword;
|
|
typedef typename TElfITypes::Addr Addr;
|
|
|
|
Addr r_offset;
|
|
Xword r_info;
|
|
Xword r_addend;
|
|
__packed_struct_end()
|
|
|
|
|
|
template <class TElfITypes>
|
|
__packed_struct(External_Note)
|
|
typedef typename TElfITypes::Word Word;
|
|
|
|
Word xn_namesz; // includes terminating '\0'
|
|
Word xn_datasz;
|
|
Word xn_type;
|
|
//char xn_name[N]; // terminate with '\0'
|
|
//char xn_data[M]; // aligned to 0 mod 4
|
|
__packed_struct_end()
|
|
|
|
|
|
} // namespace N_Elf
|
|
|
|
|
|
/*************************************************************************
|
|
// N_Elf32
|
|
**************************************************************************/
|
|
|
|
namespace N_Elf32 {
|
|
|
|
template <class TElfITypes>
|
|
__packed_struct(Phdr)
|
|
typedef typename TElfITypes::Word Word;
|
|
typedef typename TElfITypes::Addr Addr;
|
|
typedef typename TElfITypes::Off Off;
|
|
|
|
Word p_type; /* Segment type */
|
|
Off p_offset; /* Segment file offset */
|
|
Addr p_vaddr; /* Segment virtual address */
|
|
Addr p_paddr; /* Segment physical address */
|
|
Word p_filesz; /* Segment size in file */
|
|
Word p_memsz; /* Segment size in memory */
|
|
Word p_flags; /* Segment flags */
|
|
Word p_align; /* Segment alignment */
|
|
|
|
# define WANT_PHDR_ENUM 1
|
|
# include "p_elf_enum.h"
|
|
__packed_struct_end()
|
|
|
|
|
|
template <class TElfITypes>
|
|
__packed_struct(Shdr)
|
|
typedef typename TElfITypes::Word Word;
|
|
typedef typename TElfITypes::Addr Addr;
|
|
typedef typename TElfITypes::Off Off;
|
|
|
|
Word sh_name; /* Section name (string tbl index) */
|
|
Word sh_type; /* Section type */
|
|
Word sh_flags; /* Section flags */
|
|
Addr sh_addr; /* Section virtual addr at execution */
|
|
Off sh_offset; /* Section file offset */
|
|
Word sh_size; /* Section size in bytes */
|
|
Word sh_link; /* Link to another section */
|
|
Word sh_info; /* Additional section information */
|
|
Word sh_addralign; /* Section alignment */
|
|
Word sh_entsize; /* Entry size if section holds table */
|
|
|
|
# define WANT_SHDR_ENUM 1
|
|
# include "p_elf_enum.h"
|
|
__packed_struct_end()
|
|
|
|
|
|
template <class TElfITypes>
|
|
__packed_struct(Sym)
|
|
typedef typename TElfITypes::Word Word;
|
|
typedef typename TElfITypes::Addr Addr;
|
|
typedef typename TElfITypes::Section Section;
|
|
|
|
Word st_name; /* symbol name (index into string table) */
|
|
Addr st_value; /* symbol value */
|
|
Word st_size; /* symbol size */
|
|
unsigned char st_info; /* symbol type and binding */
|
|
unsigned char st_other; /* symbol visibility */
|
|
Section st_shndx; /* section index */
|
|
|
|
# define WANT_SYM_ENUM 1
|
|
# include "p_elf_enum.h"
|
|
|
|
static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); }
|
|
static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
|
|
static unsigned char make_st_info(unsigned bind, unsigned type)
|
|
{ return (unsigned char) (((bind<<4) + (0xf & type)) & 0xff); }
|
|
__packed_struct_end()
|
|
|
|
|
|
} // namespace N_Elf32
|
|
|
|
|
|
/*************************************************************************
|
|
// N_Elf64
|
|
**************************************************************************/
|
|
|
|
namespace N_Elf64 {
|
|
|
|
template <class TElfITypes>
|
|
__packed_struct(Phdr)
|
|
typedef typename TElfITypes::Word Word;
|
|
typedef typename TElfITypes::Xword Xword;
|
|
typedef typename TElfITypes::Addr Addr;
|
|
typedef typename TElfITypes::Off Off;
|
|
|
|
Word p_type; /* Segment type */
|
|
Word p_flags; /* Segment flags */
|
|
Off p_offset; /* Segment file offset */
|
|
Addr p_vaddr; /* Segment virtual address */
|
|
Addr p_paddr; /* Segment physical address */
|
|
Xword p_filesz; /* Segment size in file */
|
|
Xword p_memsz; /* Segment size in memory */
|
|
Xword p_align; /* Segment alignment */
|
|
|
|
# define WANT_PHDR_ENUM 1
|
|
# include "p_elf_enum.h"
|
|
__packed_struct_end()
|
|
|
|
|
|
template <class TElfITypes>
|
|
__packed_struct(Shdr)
|
|
typedef typename TElfITypes::Word Word;
|
|
typedef typename TElfITypes::Xword Xword;
|
|
typedef typename TElfITypes::Addr Addr;
|
|
typedef typename TElfITypes::Off Off;
|
|
|
|
Word sh_name; /* Section name (string tbl index) */
|
|
Word sh_type; /* Section type */
|
|
Xword sh_flags; /* Section flags */
|
|
Addr sh_addr; /* Section virtual addr at execution */
|
|
Off sh_offset; /* Section file offset */
|
|
Xword sh_size; /* Section size in bytes */
|
|
Word sh_link; /* Link to another section */
|
|
Word sh_info; /* Additional section information */
|
|
Xword sh_addralign; /* Section alignment */
|
|
Xword sh_entsize; /* Entry size if section holds table */
|
|
|
|
# define WANT_SHDR_ENUM 1
|
|
# include "p_elf_enum.h"
|
|
__packed_struct_end()
|
|
|
|
|
|
template <class TElfITypes>
|
|
__packed_struct(Sym)
|
|
typedef typename TElfITypes::Word Word;
|
|
typedef typename TElfITypes::Xword Xword;
|
|
typedef typename TElfITypes::Addr Addr;
|
|
typedef typename TElfITypes::Section Section;
|
|
|
|
Word st_name; /* symbol name (index into string table) */
|
|
unsigned char st_info; /* symbol type and binding */
|
|
unsigned char st_other; /* symbol visibility */
|
|
Section st_shndx; /* section index */
|
|
Addr st_value; /* symbol value */
|
|
Xword st_size; /* symbol size */
|
|
|
|
# define WANT_SYM_ENUM 1
|
|
# include "p_elf_enum.h"
|
|
|
|
static unsigned int get_st_bind(unsigned x) { return 0xf & (x>>4); }
|
|
static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
|
|
static unsigned char make_st_info(unsigned bind, unsigned type)
|
|
{ return (unsigned char) (((bind<<4) + (0xf & type)) & 0xff); }
|
|
__packed_struct_end()
|
|
|
|
|
|
} // namespace N_Elf64
|
|
|
|
|
|
/*************************************************************************
|
|
// aggregate types into an ElfClass
|
|
**************************************************************************/
|
|
|
|
namespace N_Elf {
|
|
|
|
template <class TP>
|
|
struct ElfClass_32
|
|
{
|
|
typedef TP BeLePolicy;
|
|
|
|
// integral types (target endianness)
|
|
typedef typename TP::U16 TE16;
|
|
typedef typename TP::U32 TE32;
|
|
typedef typename TP::U64 TE64;
|
|
typedef N_Elf::ElfITypes<TE16, TE32, TE32, TE32, TE32> ElfITypes;
|
|
|
|
// ELF types
|
|
typedef N_Elf ::Ehdr<ElfITypes> Ehdr;
|
|
typedef N_Elf32::Phdr<ElfITypes> Phdr;
|
|
typedef N_Elf32::Shdr<ElfITypes> Shdr;
|
|
typedef N_Elf ::Dyn <ElfITypes> Dyn;
|
|
typedef N_Elf ::Rel <ElfITypes> Rel;
|
|
typedef N_Elf ::Rela<ElfITypes> Rela;
|
|
typedef N_Elf32::Sym <ElfITypes> Sym;
|
|
typedef N_Elf ::External_Note<ElfITypes> External_Note;
|
|
|
|
static void compileTimeAssertions() {
|
|
BeLePolicy::compileTimeAssertions();
|
|
COMPILE_TIME_ASSERT(sizeof(Ehdr) == 52)
|
|
COMPILE_TIME_ASSERT(sizeof(Phdr) == 32)
|
|
COMPILE_TIME_ASSERT(sizeof(Shdr) == 40)
|
|
COMPILE_TIME_ASSERT(sizeof(Dyn) == 8)
|
|
COMPILE_TIME_ASSERT(sizeof(Rel) == 8)
|
|
COMPILE_TIME_ASSERT(sizeof(Rela) == 12)
|
|
COMPILE_TIME_ASSERT(sizeof(Sym) == 16)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Ehdr)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Phdr)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Shdr)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Dyn)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Rel)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Rela)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Sym)
|
|
}
|
|
};
|
|
|
|
|
|
template <class TP>
|
|
struct ElfClass_64
|
|
{
|
|
typedef TP BeLePolicy;
|
|
|
|
// integral types (target endianness)
|
|
typedef typename TP::U16 TE16;
|
|
typedef typename TP::U32 TE32;
|
|
typedef typename TP::U64 TE64;
|
|
typedef N_Elf::ElfITypes<TE16, TE32, TE64, TE64, TE64> ElfITypes;
|
|
|
|
// ELF types
|
|
typedef N_Elf ::Ehdr<ElfITypes> Ehdr;
|
|
typedef N_Elf64::Phdr<ElfITypes> Phdr;
|
|
typedef N_Elf64::Shdr<ElfITypes> Shdr;
|
|
typedef N_Elf ::Dyn <ElfITypes> Dyn;
|
|
typedef N_Elf ::Rel <ElfITypes> Rel;
|
|
typedef N_Elf ::Rela<ElfITypes> Rela;
|
|
typedef N_Elf64::Sym <ElfITypes> Sym;
|
|
typedef N_Elf ::External_Note<ElfITypes> External_Note;
|
|
|
|
static void compileTimeAssertions() {
|
|
BeLePolicy::compileTimeAssertions();
|
|
COMPILE_TIME_ASSERT(sizeof(Ehdr) == 64)
|
|
COMPILE_TIME_ASSERT(sizeof(Phdr) == 56)
|
|
COMPILE_TIME_ASSERT(sizeof(Shdr) == 64)
|
|
COMPILE_TIME_ASSERT(sizeof(Dyn) == 16)
|
|
COMPILE_TIME_ASSERT(sizeof(Rel) == 16)
|
|
COMPILE_TIME_ASSERT(sizeof(Rela) == 24)
|
|
COMPILE_TIME_ASSERT(sizeof(Sym) == 24)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Ehdr)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Phdr)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Shdr)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Dyn)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Rel)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Rela)
|
|
COMPILE_TIME_ASSERT_ALIGNED1(Sym)
|
|
}
|
|
};
|
|
|
|
|
|
} // namespace N_Elf
|
|
|
|
|
|
typedef N_Elf::ElfClass_32<N_BELE_CTP::HostPolicy> ElfClass_Host32;
|
|
typedef N_Elf::ElfClass_64<N_BELE_CTP::HostPolicy> ElfClass_Host64;
|
|
typedef N_Elf::ElfClass_32<N_BELE_CTP::BEPolicy> ElfClass_BE32;
|
|
typedef N_Elf::ElfClass_64<N_BELE_CTP::BEPolicy> ElfClass_BE64;
|
|
typedef N_Elf::ElfClass_32<N_BELE_CTP::LEPolicy> ElfClass_LE32;
|
|
typedef N_Elf::ElfClass_64<N_BELE_CTP::LEPolicy> ElfClass_LE64;
|
|
|
|
|
|
/*************************************************************************
|
|
// shortcuts
|
|
**************************************************************************/
|
|
|
|
typedef ElfClass_Host32::Ehdr Elf32_Ehdr;
|
|
typedef ElfClass_Host32::Phdr Elf32_Phdr;
|
|
typedef ElfClass_Host32::Shdr Elf32_Shdr;
|
|
typedef ElfClass_Host32::Dyn Elf32_Dyn;
|
|
typedef ElfClass_Host32::Rel Elf32_Rel;
|
|
typedef ElfClass_Host32::Rela Elf32_Rela;
|
|
typedef ElfClass_Host32::Sym Elf32_Sym;
|
|
typedef ElfClass_Host32::External_Note Elf32_External_Note;
|
|
|
|
typedef ElfClass_Host64::Ehdr Elf64_Ehdr;
|
|
typedef ElfClass_Host64::Phdr Elf64_Phdr;
|
|
typedef ElfClass_Host64::Shdr Elf64_Shdr;
|
|
typedef ElfClass_Host64::Dyn Elf64_Dyn;
|
|
typedef ElfClass_Host64::Rel Elf64_Rel;
|
|
typedef ElfClass_Host64::Rela Elf64_Rela;
|
|
typedef ElfClass_Host64::Sym Elf64_Sym;
|
|
typedef ElfClass_Host64::External_Note Elf64_External_Note;
|
|
|
|
typedef ElfClass_BE32::Ehdr Elf_BE32_Ehdr;
|
|
typedef ElfClass_BE32::Phdr Elf_BE32_Phdr;
|
|
typedef ElfClass_BE32::Shdr Elf_BE32_Shdr;
|
|
typedef ElfClass_BE32::Dyn Elf_BE32_Dyn;
|
|
typedef ElfClass_BE32::Rel Elf_BE32_Rel;
|
|
typedef ElfClass_BE32::Rela Elf_BE32_Rela;
|
|
typedef ElfClass_BE32::Sym Elf_BE32_Sym;
|
|
typedef ElfClass_BE32::External_Note Elf_BE32_External_Note;
|
|
|
|
typedef ElfClass_BE64::Ehdr Elf_BE64_Ehdr;
|
|
typedef ElfClass_BE64::Phdr Elf_BE64_Phdr;
|
|
typedef ElfClass_BE64::Shdr Elf_BE64_Shdr;
|
|
typedef ElfClass_BE64::Dyn Elf_BE64_Dyn;
|
|
typedef ElfClass_BE64::Rel Elf_BE64_Rel;
|
|
typedef ElfClass_BE64::Rela Elf_BE64_Rela;
|
|
typedef ElfClass_BE64::Sym Elf_BE64_Sym;
|
|
typedef ElfClass_BE64::External_Note Elf_BE64_External_Note;
|
|
|
|
typedef ElfClass_LE32::Ehdr Elf_LE32_Ehdr;
|
|
typedef ElfClass_LE32::Phdr Elf_LE32_Phdr;
|
|
typedef ElfClass_LE32::Shdr Elf_LE32_Shdr;
|
|
typedef ElfClass_LE32::Dyn Elf_LE32_Dyn;
|
|
typedef ElfClass_LE32::Rel Elf_LE32_Rel;
|
|
typedef ElfClass_LE32::Rela Elf_LE32_Rela;
|
|
typedef ElfClass_LE32::Sym Elf_LE32_Sym;
|
|
typedef ElfClass_LE32::External_Note Elf_LE32_External_Note;
|
|
|
|
typedef ElfClass_LE64::Ehdr Elf_LE64_Ehdr;
|
|
typedef ElfClass_LE64::Phdr Elf_LE64_Phdr;
|
|
typedef ElfClass_LE64::Shdr Elf_LE64_Shdr;
|
|
typedef ElfClass_LE64::Dyn Elf_LE64_Dyn;
|
|
typedef ElfClass_LE64::Rel Elf_LE64_Rel;
|
|
typedef ElfClass_LE64::Rela Elf_LE64_Rela;
|
|
typedef ElfClass_LE64::Sym Elf_LE64_Sym;
|
|
typedef ElfClass_LE64::External_Note Elf_LE64_External_Note;
|
|
|
|
|
|
#endif /* already included */
|
|
|
|
/* vim:set ts=4 sw=4 et: */
|