From 34dfcf56ea9cb5306449ebcb8d96d00c07cab44e Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sat, 4 Jun 2011 00:52:04 +0000 Subject: [PATCH] Beginning to swap endian when necessary --- include/Asm.h | 6 ++++++ src/format/elf.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/include/Asm.h b/include/Asm.h index bb2d02a..0c09461 100644 --- a/include/Asm.h +++ b/include/Asm.h @@ -46,6 +46,9 @@ | (((a) & 0xff0000000000) >> 24) \ | (((a) & 0xff000000000000) >> 40) \ | (((a) & 0xff00000000000000) >> 56) +# define _bswap16(a) _htol16(a) +# define _bswap32(a) _htol32(a) +# define _bswap64(a) _htol64(a) # elif _BYTE_ORDER == _LITTLE_ENDIAN # define _htob16(a) (((a) & 0xff) << 8 | ((a) & 0xff00) >> 8) # define _htol16(a) (a) @@ -59,6 +62,9 @@ | (((a) & 0xff000000000000) >> 40) \ | (((a) & 0xff00000000000000) >> 56) # define _htol64(a) (a) +# define _bswap16(a) _htob16(a) +# define _bswap32(a) _htob32(a) +# define _bswap64(a) _htob64(a) # else # warning "Could not determine endian on your system" # endif diff --git a/src/format/elf.c b/src/format/elf.c index f2ae327..a73e325 100644 --- a/src/format/elf.c +++ b/src/format/elf.c @@ -75,11 +75,13 @@ static int _elf_decode64(FormatPlugin * format); static int _init_32(FormatPlugin * format); static int _exit_32(FormatPlugin * format); static int _section_32(FormatPlugin * format, char const * name); +static void _swap_32_ehdr(Elf32_Ehdr * ehdr); /* ELF64 */ static int _init_64(FormatPlugin * format); static int _exit_64(FormatPlugin * format); static int _section_64(FormatPlugin * format, char const * name); +static void _swap_64_ehdr(Elf64_Ehdr * ehdr); /* ElfStrtab */ static int _elfstrtab_set(FormatPlugin * format, ElfStrtab * strtab, @@ -98,6 +100,17 @@ static ElfArch elf_arch[] = { "sparc64", EM_SPARCV9, ELFCLASS64, ELFDATA2MSB }, { NULL, '\0', '\0', '\0' } }; +#if defined(__amd64__) +static const ElfArch * elf_arch_native = &elf_arch[0]; +#elif defined(__i386__) +static const ElfArch * elf_arch_native = &elf_arch[1]; +#elif defined(__sparc64__) +static const ElfArch * elf_arch_native = &elf_arch[6]; +#elif defined(__sparc__) +static const ElfArch * elf_arch_native = &elf_arch[5]; +#else +# error "Unsupported architecture" +#endif static ElfSectionValues elf_section_values[] = { @@ -257,6 +270,8 @@ static char const * _elf_detect(FormatPlugin * format) static char const * _detect_32(FormatPlugin * format, Elf32_Ehdr * ehdr) { format->decode = _elf_decode32; + if(ehdr->e_ident[EI_DATA] != elf_arch_native->endian) + _swap_32_ehdr(ehdr); switch(ehdr->e_machine) { case EM_386: @@ -280,6 +295,8 @@ static char const * _detect_32(FormatPlugin * format, Elf32_Ehdr * ehdr) static char const * _detect_64(FormatPlugin * format, Elf64_Ehdr * ehdr) { format->decode = _elf_decode64; + if(ehdr->e_ident[EI_DATA] != elf_arch_native->endian) + _swap_64_ehdr(ehdr); switch(ehdr->e_machine) { case EM_SPARC: @@ -755,6 +772,25 @@ static int _section_32(FormatPlugin * format, char const * name) } +/* swap_32_ehdr */ +static void _swap_32_ehdr(Elf32_Ehdr * ehdr) +{ + ehdr->e_type = _bswap16(ehdr->e_type); + ehdr->e_machine = _bswap16(ehdr->e_machine); + ehdr->e_version = _bswap32(ehdr->e_version); + ehdr->e_entry = _bswap32(ehdr->e_entry); + ehdr->e_phoff = _bswap32(ehdr->e_phoff); + ehdr->e_shoff = _bswap32(ehdr->e_shoff); + ehdr->e_flags = _bswap32(ehdr->e_flags); + ehdr->e_ehsize = _bswap16(ehdr->e_ehsize); + ehdr->e_phentsize = _bswap16(ehdr->e_phentsize); + ehdr->e_phnum = _bswap16(ehdr->e_phnum); + ehdr->e_shentsize = _bswap16(ehdr->e_shentsize); + ehdr->e_shnum = _bswap16(ehdr->e_shnum); + ehdr->e_shstrndx = _bswap16(ehdr->e_shstrndx); +} + + /* ELF64 */ /* variables */ static Elf64_Shdr * es64 = NULL; @@ -916,6 +952,25 @@ static int _section_64(FormatPlugin * format, char const * name) } +/* swap_64_ehdr */ +static void _swap_64_ehdr(Elf64_Ehdr * ehdr) +{ + ehdr->e_type = _bswap16(ehdr->e_type); + ehdr->e_machine = _bswap16(ehdr->e_machine); + ehdr->e_version = _bswap32(ehdr->e_version); + ehdr->e_entry = _bswap64(ehdr->e_entry); + ehdr->e_phoff = _bswap64(ehdr->e_phoff); + ehdr->e_shoff = _bswap64(ehdr->e_shoff); + ehdr->e_flags = _bswap32(ehdr->e_flags); + ehdr->e_ehsize = _bswap16(ehdr->e_ehsize); + ehdr->e_phentsize = _bswap16(ehdr->e_phentsize); + ehdr->e_phnum = _bswap16(ehdr->e_phnum); + ehdr->e_shentsize = _bswap16(ehdr->e_shentsize); + ehdr->e_shnum = _bswap16(ehdr->e_shnum); + ehdr->e_shstrndx = _bswap16(ehdr->e_shstrndx); +} + + /* ElfStrtab */ /* private */ /* functions */