Logo Search packages:      
Sourcecode: palo version File versions  Download package

elf64.c

/* 
 * 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
/* prevent inclusion of Linux types.h */
#   define _LINUX_TYPES_H
    typedef unsigned long long uint64_t;
#endif
#include "common.h"
#include "load.h"

#ifndef __hpux
#   include <stdint.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#include <linux/elf.h>

/* check that the address is zeros in the top 32 bits, then return
 * the bottom 32 bits
 */
static uint32_t
addr32(uint64_t a)
{
    const int mask32 = 0xffffffff;
    const int mask16 = 0xffff;
    a = __be64_to_cpu(a);
    if (0) printf("checkaddr32(%04x:%04x:%04x:%04x)\r\n",
          (uint32_t)(a >> (16 * 3)) & mask16,
          (uint32_t)(a >> (16 * 2)) & mask16,
          (uint32_t)(a >> (16 * 1)) & mask16,
          (uint32_t)(a >> (16 * 0)) & mask16);
    if ((a & ~mask32) != 0)
    {
      printf("checkaddr32(%04x:%04x:%04x:%04x) not valid 32 bit\n",
            (uint32_t)(a >> (16 * 3)) & mask16,
            (uint32_t)(a >> (16 * 2)) & mask16,
            (uint32_t)(a >> (16 * 1)) & mask16,
            (uint32_t)(a >> (16 * 0)) & mask16);
      while(1);
    }

    return (uint32_t)(a & mask32);
}

int prepare_ELF64_loadable(int fd, struct loadable *loadable, int *wide)
{
    struct elf64_hdr eh;
    uint32_t last = 0;
    int i;

    *wide = 1;

    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] != ELFCLASS64 ||
      __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("ELF64 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 elf64_phdr ep;
      struct loadsegment *seg;
      uint32_t start, end;

      STRUCTREAD(fd, ep, addr32(eh.e_phoff) + i * sizeof ep);
      if (__be32_to_cpu(ep.p_type) != PT_LOAD)
          continue;

      /* vaddr or paddr? HP-UX kernel elf seems to use vaddr */
      start = addr32(ep.p_vaddr);
      if (loadable->first == 0 || start < loadable->first)
      {
          loadable->first = start;
      }
      end = addr32(ep.p_vaddr) + addr32(ep.p_filesz);
      if (end > last)
          last = end;

      seg = &loadable->segment[loadable->n++];
      seg->offset = addr32(ep.p_offset);

      if (loadable->offset0 == 0 || seg->offset < loadable->offset0)
      {
          loadable->offset0 = seg->offset;
      }
      seg->length = addr32(ep.p_filesz);
      seg->mem = start;
      seg->zeros = addr32(ep.p_memsz) - addr32(ep.p_filesz);
    }

    loadable->size = last - loadable->first;
    /* is entry a virtual or physical address? */
    loadable->entry = addr32(eh.e_entry);

    return PREPARE_OK;
}

Generated by  Doxygen 1.6.0   Back to index