blob: dae5dd89895291196b23e881f28168228c591590 [file] [log] [blame]
/*
* 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;
}