diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libelf/elf.c | 13 | ||||
-rw-r--r-- | lib/libelf/elf64.c | 7 |
2 files changed, 18 insertions, 2 deletions
diff --git a/lib/libelf/elf.c b/lib/libelf/elf.c index 1340103..27fd51d 100644 --- a/lib/libelf/elf.c +++ b/lib/libelf/elf.c @@ -80,7 +80,9 @@ elf_check_file(unsigned long *file_addr) * @param pre_load handler that is called before copying a segment * @param post_load handler that is called after copying a segment * @return 1 for a 32 bit file - * 2 for a 64 bit file + * 2 for a 64 bit BE file + * 3 for a 64 bit LE ABIv1 file + * 3 for a 64 bit LE ABIv2 file * anything else means an error during load */ int @@ -89,6 +91,7 @@ elf_load_file(void *file_addr, unsigned long *entry, void (*post_load)(void*, long)) { int type = elf_check_file(file_addr); + struct ehdr *ehdr = (struct ehdr *) file_addr; switch (type) { case 1: @@ -96,9 +99,15 @@ elf_load_file(void *file_addr, unsigned long *entry, break; case 2: *entry = elf_load_segments64(file_addr, 0, pre_load, post_load); + if (ehdr->ei_data != ELFDATA2MSB) { + uint32_t flags = elf_get_eflags_64(file_addr); + if ((flags & 0x3) == 2) + type = 4; /* LE64 ABIv2 */ + else + type = 3; /* LE64 ABIv1 */ + } break; } - return type; } diff --git a/lib/libelf/elf64.c b/lib/libelf/elf64.c index faddbfb..62ac885 100644 --- a/lib/libelf/elf64.c +++ b/lib/libelf/elf64.c @@ -462,3 +462,10 @@ elf_byteswap_header64(void *file_addr) phdr = (struct phdr64 *)(((uint8_t *)phdr) + ehdr->e_phentsize); } } + +uint32_t elf_get_eflags_64(void *file_addr) +{ + struct ehdr64 *ehdr = (struct ehdr64 *) file_addr; + + return ehdr->e_flags; +} |