| /* |
| * This file is subject to the terms and conditions of the GNU General Public |
| * License. See the file "COPYING" in the main directory of this archive |
| * for more details. |
| * |
| * Copyright (C) Hewlett-Packard (Paul Bame) paul_bame@hp.com |
| */ |
| #ifdef __hpux |
| # define _LINUX_TYPES_H |
| #endif |
| #include "common.h" |
| #include "load.h" |
| |
| #include <linux/elf.h> |
| #include <stdio.h> |
| |
| int prepare_ELF32_loadable(int fd, struct loadable *loadable, int *wide) |
| { |
| struct elf32_hdr eh; |
| unsigned last = 0; |
| int i; |
| |
| *wide = 0; |
| |
| STRUCTREAD(fd, eh, 0); |
| |
| if (eh.e_ident[EI_MAG0] != ELFMAG0 || |
| eh.e_ident[EI_MAG1] != ELFMAG1 || |
| eh.e_ident[EI_MAG2] != ELFMAG2 || |
| eh.e_ident[EI_MAG3] != ELFMAG3 || |
| eh.e_ident[EI_CLASS] != ELFCLASS32 || |
| __be16_to_cpu(eh.e_type) != ET_EXEC) |
| { |
| return PREPARE_CONTINUE; |
| } |
| |
| if (__be16_to_cpu(eh.e_machine) != EM_PARISC) |
| { |
| printf("Fatal - ELF, but not for PARISC\n"); |
| return PREPARE_FATAL; |
| } |
| |
| printf("ELF32 executable\n"); |
| |
| /* We like this kind of ELF... */ |
| eh.e_phnum = __be16_to_cpu(eh.e_phnum); |
| for (i = 0; i < eh.e_phnum; i++) |
| { |
| struct elf32_phdr ep; |
| struct loadsegment *seg = &loadable->segment[loadable->n++]; |
| unsigned start, end; |
| |
| STRUCTREAD(fd, ep, __be32_to_cpu(eh.e_phoff) + i * sizeof ep); |
| if (__be32_to_cpu(ep.p_type) != PT_LOAD) |
| continue; |
| |
| /* vaddr or paddr? */ |
| start = __be32_to_cpu(ep.p_vaddr); |
| if (loadable->n == 1 || start < loadable->first) |
| { |
| loadable->first = start; |
| } |
| end = __be32_to_cpu(ep.p_vaddr) + __be32_to_cpu(ep.p_filesz); |
| if (end > last) |
| last = end; |
| |
| seg->offset = __be32_to_cpu(ep.p_offset); |
| |
| if (loadable->n == 1 || seg->offset < loadable->offset0) |
| { |
| loadable->offset0 = seg->offset; |
| } |
| seg->length = __be32_to_cpu(ep.p_filesz); |
| seg->mem = start; |
| seg->zeros = __be32_to_cpu(ep.p_memsz) - __be32_to_cpu(ep.p_filesz); |
| } |
| |
| loadable->size = last - loadable->first; |
| /* is entry a virtual or physical address? */ |
| loadable->entry = __be32_to_cpu(eh.e_entry); |
| |
| return PREPARE_OK; |
| } |