Esempio n. 1
0
static int
get_file_header(FILE *file)
{
  /* Read in the identity array: */
  if (fread(elf_header.e_ident, EI_NIDENT, 1, file) != 1)
    return 0;

  /* Determine how to read the rest of the header.  */
  switch (elf_header.e_ident[EI_DATA])
    {
    default: /* fall through to: */
    case ELFDATANONE: /* fall through to: */
    case ELFDATA2LSB:
      byte_get = byte_get_little_endian;
      byte_put = byte_put_little_endian;
      break;
    case ELFDATA2MSB:
      byte_get = byte_get_big_endian;
      byte_put = byte_put_big_endian;
      break;
    }

  /* Read in the rest of the header.  For now we only support 32 bit
     and 64 bit ELF files.  */
  switch (elf_header.e_ident[EI_CLASS])
    {
    default:
      error(_("Unsupported EI_CLASS: %d\n"),
            elf_header.e_ident[EI_CLASS]);
      return 0;

    case ELFCLASS32:
      if (fread(ehdr32.e_type, (sizeof(ehdr32) - EI_NIDENT),
                1, file) != 1)
	return 0;

      elf_header.e_type = (unsigned short)BYTE_GET(ehdr32.e_type);
      elf_header.e_machine = (unsigned short)BYTE_GET(ehdr32.e_machine);
      elf_header.e_version = (unsigned long)BYTE_GET(ehdr32.e_version);
      elf_header.e_entry = BYTE_GET(ehdr32.e_entry);
      elf_header.e_phoff = BYTE_GET(ehdr32.e_phoff);
      elf_header.e_shoff = BYTE_GET(ehdr32.e_shoff);
      elf_header.e_flags = (unsigned long)BYTE_GET(ehdr32.e_flags);
      elf_header.e_ehsize = (unsigned int)BYTE_GET(ehdr32.e_ehsize);
      elf_header.e_phentsize = (unsigned int)BYTE_GET(ehdr32.e_phentsize);
      elf_header.e_phnum = (unsigned int)BYTE_GET(ehdr32.e_phnum);
      elf_header.e_shentsize = (unsigned int)BYTE_GET(ehdr32.e_shentsize);
      elf_header.e_shnum = (unsigned int)BYTE_GET(ehdr32.e_shnum);
      elf_header.e_shstrndx = (unsigned int)BYTE_GET(ehdr32.e_shstrndx);

      memcpy(&ehdr32, &elf_header, EI_NIDENT);
      break;

    case ELFCLASS64:
      /* If we have been compiled with sizeof(bfd_vma) == 4UL, then
	 we will not be able to cope with the 64bit data found in
	 64 ELF files.  Detect this now and abort before we start
	 overwriting things.  */
      if (sizeof(bfd_vma) < 8UL)
	{
	  error(_("This executable has been built without support for a\n\
64 bit data type and so it cannot process 64 bit ELF files.\n"));
	  return 0;
	}

      if (fread(ehdr64.e_type, (sizeof(ehdr64) - EI_NIDENT),
                1, file) != 1)
	return 0;

      elf_header.e_type = (unsigned short)BYTE_GET(ehdr64.e_type);
      elf_header.e_machine = (unsigned short)BYTE_GET(ehdr64.e_machine);
      elf_header.e_version = (unsigned long)BYTE_GET(ehdr64.e_version);
      elf_header.e_entry = BYTE_GET(ehdr64.e_entry);
      elf_header.e_phoff = BYTE_GET(ehdr64.e_phoff);
      elf_header.e_shoff = BYTE_GET(ehdr64.e_shoff);
      elf_header.e_flags = (unsigned long)BYTE_GET(ehdr64.e_flags);
      elf_header.e_ehsize = (unsigned int)BYTE_GET(ehdr64.e_ehsize);
      elf_header.e_phentsize = (unsigned int)BYTE_GET(ehdr64.e_phentsize);
      elf_header.e_phnum = (unsigned int)BYTE_GET(ehdr64.e_phnum);
      elf_header.e_shentsize = (unsigned int)BYTE_GET(ehdr64.e_shentsize);
      elf_header.e_shnum = (unsigned int)BYTE_GET(ehdr64.e_shnum);
      elf_header.e_shstrndx = (unsigned int)BYTE_GET(ehdr64.e_shstrndx);

      memcpy(&ehdr64, &elf_header, EI_NIDENT);
      break;
    }
Esempio n. 2
0
//Loading binary application
int ac_load_elf(char* filename, char* data_mem, unsigned int data_mem_size)
{
  Elf32_Ehdr    ehdr;
  Elf32_Shdr    shdr;
  Elf32_Phdr    phdr;
  FILE          *fd;
  unsigned int  i;

  /*
   Most code was taken from the Binutils readelf application
  */

  /* Open up the file for reading */
  fd = fopen (filename, "rb");
  if (fd == NULL) {
    AC_ERROR("Opening application file '" << filename << "': " << strerror(errno) << endl);
    exit(EXIT_FAILURE);
  }

 /* Read in the identity array.  */
  if (fread (ehdr.e_ident, EI_NIDENT, 1, fd) != 1) {
    AC_ERROR("Error reading file '" << filename << endl);
    exit(EXIT_FAILURE);
  }
    

  /* Determine how to read the rest of the header.  */
  switch (ehdr.e_ident[EI_DATA]) {
  default: /* fall through */
  case ELFDATANONE: /* fall through */
  case ELFDATA2LSB:
    byte_get = byte_get_little_endian;
    //    byte_put = byte_put_little_endian;
    break;
  case ELFDATA2MSB:
    byte_get = byte_get_big_endian;
    //    byte_put = byte_put_big_endian;
    break;
  }


  // TODO: Consider the case when the file is not 32-bit

  /* Get the rest of the header data */
  if (fread ((unsigned char *)&ehdr.e_type, sizeof (ehdr) - EI_NIDENT, 1, fd) != 1) {
    AC_ERROR("Error reading file %s\n" << filename << endl);
    exit(EXIT_FAILURE);
  }

  ehdr.e_type      = BYTE_GET (&ehdr.e_type);
  ehdr.e_machine   = BYTE_GET (&ehdr.e_machine);
  ehdr.e_version   = BYTE_GET (&ehdr.e_version);
  ehdr.e_entry     = BYTE_GET (&ehdr.e_entry);
  ehdr.e_phoff     = BYTE_GET (&ehdr.e_phoff);
  ehdr.e_shoff     = BYTE_GET (&ehdr.e_shoff);
  ehdr.e_flags     = BYTE_GET (&ehdr.e_flags);
  ehdr.e_ehsize    = BYTE_GET (&ehdr.e_ehsize);
  ehdr.e_phentsize = BYTE_GET (&ehdr.e_phentsize);
  ehdr.e_phnum     = BYTE_GET (&ehdr.e_phnum);
  ehdr.e_shentsize = BYTE_GET (&ehdr.e_shentsize);
  ehdr.e_shnum     = BYTE_GET (&ehdr.e_shnum);
  ehdr.e_shstrndx  = BYTE_GET (&ehdr.e_shstrndx);


  /* Check if the file is in fact an ELF */
  if (   ehdr.e_ident[EI_MAG0] != ELFMAG0
      || ehdr.e_ident[EI_MAG1] != ELFMAG1
      || ehdr.e_ident[EI_MAG2] != ELFMAG2
      || ehdr.e_ident[EI_MAG3] != ELFMAG3)
  {
    fclose(fd);
    return EXIT_FAILURE;
  }


  //Set start address
  ac_start_addr = ehdr.e_entry;
  if (ac_start_addr > data_mem_size) {
    AC_ERROR("the start address of the application is beyond model memory\n");
    fclose(fd);
    exit(EXIT_FAILURE);
  }

  if (ehdr.e_type == ET_EXEC) {
    //It is an ELF file
    AC_SAY("Reading ELF application file: " << filename << endl);

    //Get program headers and load segments
    //    lseek(fd, convert_endian(4,ehdr.e_phoff), SEEK_SET);
    for (i=0; i < ehdr.e_phnum; i++) {

      //Get program headers and load segments
      fseek(fd, ehdr.e_phoff + ehdr.e_phentsize*i, SEEK_SET);
      if (fread(&phdr, sizeof(phdr), 1, fd) != 1) {
        AC_ERROR("reading ELF program header\n");
        fclose(fd);
        exit(EXIT_FAILURE);
      }

      if (BYTE_GET (&phdr.p_type) == PT_LOAD) {
        Elf32_Word j;
        Elf32_Addr p_vaddr  = BYTE_GET (&phdr.p_vaddr);
        Elf32_Word p_memsz  = BYTE_GET (&phdr.p_memsz);
        Elf32_Word p_filesz = BYTE_GET (&phdr.p_filesz);
        Elf32_Off  p_offset = BYTE_GET (&phdr.p_offset);

        //Error if segment greater then memory
        if (data_mem_size < p_vaddr + p_memsz) {
          AC_ERROR("not enough memory in ArchC model to load application.\n");
          fclose(fd);
          exit(EXIT_FAILURE);
        }

        //Set heap to the end of the segment
        if (ac_heap_ptr < p_vaddr + p_memsz) ac_heap_ptr = p_vaddr + p_memsz;

        //Load and correct endian
        fseek(fd, p_offset, SEEK_SET);
        for (j=0; j < p_filesz; j+=sizeof(ac_fetch)) {
          int tmp;
          fread(&tmp, sizeof(ac_fetch), 1, fd);
          *(ac_fetch *) (data_mem + p_vaddr + j) = byte_get((unsigned char *)&tmp, sizeof(ac_fetch));
        }
        memset(data_mem + p_vaddr + p_filesz, 0, p_memsz - p_filesz);
      }

    }
  }
  else if (ehdr.e_type == ET_REL) {

    AC_SAY("Reading ELF relocatable file: " << filename << endl);

    // first load the section name string table
    char *string_table;
    int   shoff  = ehdr.e_shoff;
    short shndx  = ehdr.e_shstrndx;
    short shsize = ehdr.e_shentsize;

    fseek(fd, shoff+(shndx*shsize), SEEK_SET);
    if (fread(&shdr, sizeof(shdr), 1, fd) != 1) {
      AC_ERROR("reading ELF section header\n");
      fclose(fd);
      exit(EXIT_FAILURE);
    }
    
    string_table = (char *) malloc(BYTE_GET (&shdr.sh_size));
    fseek(fd, BYTE_GET (&shdr.sh_offset), SEEK_SET);
    fread(string_table, BYTE_GET (&shdr.sh_size), 1, fd);

    // load .text, .data and .bss sections    
    for (i=0; i < ehdr.e_shnum; i++) {

      fseek(fd, shoff + shsize*i, SEEK_SET);
      
      if (fread(&shdr, sizeof(shdr), 1, fd) != 1) {
        AC_ERROR("reading ELF section header\n");
        fclose(fd);
        exit(EXIT_FAILURE);
      }

      Elf32_Word name = BYTE_GET (&shdr.sh_name);
      if (!strcmp(string_table+name, ".text") ||
          !strcmp(string_table+name, ".data") ||
          !strcmp(string_table+name, ".bss")) {
        
        //        printf("Section %s:\n", string_table+convert_endian(4,shdr.sh_name));

        Elf32_Off  tshoff  = BYTE_GET (&shdr.sh_offset);
        Elf32_Word tshsize = BYTE_GET (&shdr.sh_size);
        Elf32_Addr tshaddr = BYTE_GET (&shdr.sh_addr);

        if (tshsize == 0) {
          // printf("--- empty ---\n");
          continue;
        }

        if (data_mem_size < tshaddr + tshsize) {
          AC_ERROR("not enough memory in ArchC model to load application.\n");
          fclose(fd);
          exit(EXIT_FAILURE);
        }

        //Set heap to the end of the segment
        if (ac_heap_ptr < tshaddr + tshsize) ac_heap_ptr = tshaddr + tshsize;

        if (!strcmp(string_table+BYTE_GET (&shdr.sh_name), ".bss")) {
          memset(data_mem + tshaddr, 0, tshsize);
          //continue;
          break; // .bss is supposed to be the last one
        }

        //Load and correct endian
        fseek(fd, tshoff, SEEK_SET);
        for (Elf32_Word j=0; j < tshsize; j+=sizeof(ac_fetch)) {
          int tmp;
          fread(&tmp, sizeof(ac_fetch), 1, fd);
          *(ac_fetch *) (data_mem + tshaddr + j) = byte_get((unsigned char *)&tmp, sizeof(ac_fetch));

          // printf("0x%08x %08x \n", tshaddr+j, *(ac_fetch *) (data_mem+tshaddr+j));
        }
        //        printf("\n");        
      }

    }
  }
    
  //Close file
  fclose(fd);

  return EXIT_SUCCESS;
}
Esempio n. 3
0
#include <string.h>
#include <assert.h>
#include <alloca.h>

#include <obj.h>
#include <util.h>




int obj_relocate (struct obj_file *f, ElfW(Addr) base)
{
    int i, n = BYTE_GET(f->header.e_shnum);
    int ret = 1;
    DEBUG("==========================================\n");
    DEBUG("obj_relocate start\n");
    /* Finalize the addresses of the sections.  */
    arch_finalize_section_address(f, base);

    /* And iterate over all of the relocations.  */
    for (i = 0; i < n; ++i)
    {
        struct obj_section *relsec, *symsec, *targsec, *strsec;
        ElfW(RelM) *rel, *relend;
        ElfW(Sym) *symtab;
        const char *strtab;
        unsigned long nsyms;

        relsec = f->sections[i];
        if (BYTE_GET(relsec->header.sh_type) != SHT_RELM)
	        continue;