コード例 #1
0
ファイル: elf_loader.c プロジェクト: MatchPointDarko/MikeOS
error_code_t load_elf(task_t* task)
{
    if(task == NULL)
    {
        return INVALID_ARGUMENT;
    }

    file_t* elf_file = file_open(task->name, "r");

    if(elf_file == NULL)
    {
        return NO_SUCH_FILE;
    }

    uint8_t elf_header_buf[ELF_HEADER_SIZE] = {0};
    Elf32_Ehdr* elf_header = (Elf32_Ehdr*)elf_header_buf;

    if(file_read(elf_file, elf_header_buf, ELF_HEADER_SIZE) == 0)
    {
        //This can't be, this file is empty..
        return FAILURE;
    }

    if(check_elf_header(elf_header) != SUCCESS)
    {
        //This is not an elf file.
        return FAILURE;
    }

    if(check_elf_supported(elf_header) != SUCCESS)
    {
        return FAILURE;
    }

    switch(elf_header->e_type)
    {
        case ET_EXEC:
        {
            load_segments(task, elf_header, elf_file);
        }
        break;

        case ET_REL:
        {
            //TODO
        }
        break;
    }

    return SUCCESS;
}
int main( int argc, char** argv)
{
	/* map the .so, and locate interesting pieces */
	char *dynstr;
	char *thefilename = argv[1];
	FILE *thefile;
	struct stat statbuf;
	Elf32_Ehdr *ehdr = 0;
	Elf32_Shdr *dynsec;
	Elf32_Dyn *dynamic;

	if (argc < 2 || !thefilename) {
		fprintf(stderr, "No filename specified.\n");
		exit(EXIT_FAILURE);
	}
	if (!(thefile = fopen(thefilename, "r"))) {
		perror(thefilename);
		exit(EXIT_FAILURE);
	}
	if (fstat(fileno(thefile), &statbuf) < 0) {
		perror(thefilename);
		exit(EXIT_FAILURE);
	}

	if ((size_t)statbuf.st_size < sizeof(Elf32_Ehdr))
		goto foo;

	/* mmap the file to make reading stuff from it effortless */
	ehdr = (Elf32_Ehdr *)mmap(0, statbuf.st_size, 
			PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(thefile), 0);

foo:
	/* Check if this looks legit */
	if (check_elf_header(ehdr)) {
		fprintf(stderr, "This does not appear to be an ELF file.\n");
		exit(EXIT_FAILURE);
	}
	describe_elf_hdr(ehdr);
	describe_elf_interpreter(ehdr);

	dynsec = elf_find_section_type(SHT_DYNAMIC, ehdr);
	if (dynsec) {
		dynamic = (Elf32_Dyn*)(byteswap32_to_host(dynsec->sh_offset) + (intptr_t)ehdr);
		dynstr = (char *)elf_find_dynamic(DT_STRTAB, dynamic, ehdr, 0);
		list_needed_libraries(dynamic, dynstr);
	}

	return 0;
}
コード例 #3
0
ファイル: libelf.c プロジェクト: netsoftwang/aajvm
int parse_elf_section(const char *binary_path)
{
    if (elf_init(binary_path) == -1)
        return -1;

    elf_hdr = (Elf64_Ehdr *)elf_mem;

    if (check_elf_header(elf_hdr) == -1)
        return -1;

    if (parse_elf_section_name(elf_hdr) == -1)
        return -1;

    if (__parse_elf_section(elf_hdr) == -1)
        return -1;

    return 0;
}
コード例 #4
0
ファイル: loader.c プロジェクト: Distrotech/guile
static SCM
load_thunk_from_memory (char *data, size_t len, int is_read_only)
#define FUNC_NAME "load-thunk-from-memory"
{
  Elf_Ehdr *header;
  Elf_Phdr *ph;
  const char *err_msg = 0;
  size_t n, alignment = 8;
  int i;
  int dynamic_segment = -1;
  SCM init = SCM_BOOL_F, entry = SCM_BOOL_F;
  char *frame_maps = 0;

  if (len < sizeof *header)
    ABORT ("object file too small");

  header = (Elf_Ehdr*) data;
  
  if ((err_msg = check_elf_header (header)))
    goto cleanup;

  if (header->e_phnum == 0)
    ABORT ("no loadable segments");
  n = header->e_phnum;

  if (len < header->e_phoff + n * sizeof (Elf_Phdr))
    ABORT ("object file too small");

  ph = (Elf_Phdr*) (data + header->e_phoff);

  /* Check that the segment table is sane.  */
  for (i = 0; i < n; i++)
    {
      if (ph[i].p_filesz != ph[i].p_memsz)
        ABORT ("expected p_filesz == p_memsz");

      if (!ph[i].p_flags)
        ABORT ("expected nonzero segment flags");

      if (ph[i].p_align < alignment)
        {
          if (ph[i].p_align % alignment)
            ABORT ("expected new alignment to be multiple of old");
          alignment = ph[i].p_align;
        }

      if (ph[i].p_type == PT_DYNAMIC)
        {
          if (dynamic_segment >= 0)
            ABORT ("expected only one PT_DYNAMIC segment");
          dynamic_segment = i;
          continue;
        }

      if (ph[i].p_type != PT_LOAD)
        ABORT ("unknown segment type");

      if (i == 0)
        {
          if (ph[i].p_vaddr != 0)
            ABORT ("first loadable vaddr is not 0");
        }
      else
        {
          if (ph[i].p_vaddr < ph[i-1].p_vaddr + ph[i-1].p_memsz)
            ABORT ("overlapping segments");

          if (ph[i].p_offset + ph[i].p_filesz > len)
            ABORT ("segment beyond end of byte array");
        }
    }

  if (dynamic_segment < 0)
    ABORT ("no PT_DYNAMIC segment");

  if (!IS_ALIGNED ((scm_t_uintptr) data, alignment))
    ABORT ("incorrectly aligned base");

  /* Allow writes to writable pages.  */
  if (is_read_only)
    {
#ifdef HAVE_SYS_MMAN_H
      for (i = 0; i < n; i++)
        {
          if (ph[i].p_type != PT_LOAD)
            continue;
          if (ph[i].p_flags == PF_R)
            continue;
          if (ph[i].p_align != 4096)
            continue;

          if (mprotect (data + ph[i].p_vaddr,
                        ph[i].p_memsz,
                        segment_flags_to_prot (ph[i].p_flags)))
            goto cleanup;
        }
#else
      ABORT ("expected writable pages");
#endif
    }

  if ((err_msg = process_dynamic_segment (data, &ph[dynamic_segment],
                                          &init, &entry, &frame_maps)))
    goto cleanup;

  if (scm_is_true (init))
    scm_call_0 (init);

  register_elf (data, len, frame_maps);

  /* Finally!  Return the thunk.  */
  return entry;

 cleanup:
  {
    if (errno)
      SCM_SYSERROR;
    scm_misc_error (FUNC_NAME, err_msg ? err_msg : "error loading ELF file",
                    SCM_EOL);
  }
}
コード例 #5
0
ファイル: objcodes.c プロジェクト: ijp/guile
static SCM
load_thunk_from_memory (char *data, size_t len)
#define FUNC_NAME "load-thunk-from-memory"
{
  Elf_Ehdr header;
  Elf_Phdr *ph;
  const char *err_msg = 0;
  char *base = 0;
  size_t n, memsz = 0, alignment = 8;
  int i;
  int first_loadable = -1;
  int start_segment = -1;
  int prev_segment = -1;
  int dynamic_segment = -1;
  SCM init = SCM_BOOL_F, entry = SCM_BOOL_F;

  if (len < sizeof header)
    ABORT ("object file too small");

  memcpy (&header, data, sizeof header);

  if ((err_msg = check_elf_header (&header)))
    goto cleanup;

  n = header.e_phnum;
  if (len < header.e_phoff + n * sizeof (Elf_Phdr))
    goto cleanup;
  ph = (Elf_Phdr*) (data + header.e_phoff);

  for (i = 0; i < n; i++)
    {
      if (!ph[i].p_memsz)
        continue;

      if (ph[i].p_filesz != ph[i].p_memsz)
        ABORT ("expected p_filesz == p_memsz");

      if (!ph[i].p_flags)
        ABORT ("expected nonzero segment flags");

      if (ph[i].p_align < alignment)
        {
          if (ph[i].p_align % alignment)
            ABORT ("expected new alignment to be multiple of old");
          alignment = ph[i].p_align;
        }

      if (ph[i].p_type == PT_DYNAMIC)
        {
          if (dynamic_segment >= 0)
            ABORT ("expected only one PT_DYNAMIC segment");
          dynamic_segment = i;
        }

      if (first_loadable < 0)
        {
          if (ph[i].p_vaddr)
            ABORT ("first loadable vaddr is not 0");

          first_loadable = i;
        }

      if (ph[i].p_vaddr < memsz)
        ABORT ("overlapping segments");

      if (ph[i].p_offset + ph[i].p_filesz > len)
        ABORT ("segment beyond end of byte array");

      memsz = ph[i].p_vaddr + ph[i].p_memsz;
    }

  if (first_loadable < 0)
    ABORT ("no loadable segments");

  if (dynamic_segment < 0)
    ABORT ("no PT_DYNAMIC segment");

  /* Now copy segments.  */

  /* We leak this memory, as we leak the memory mappings in
     load_thunk_from_fd_using_mmap.

     If the file is has an alignment of 8, use the standard malloc.
     (FIXME to ensure alignment on non-GNU malloc.)  Otherwise use
     posix_memalign.  We only use mprotect if the aligment is 4096.  */
  if (alignment == 8)
    {
      base = malloc (memsz);
      if (!base)
        goto cleanup;
    }
  else
    if ((errno = posix_memalign ((void **) &base, alignment, memsz)))
      goto cleanup;

  memset (base, 0, memsz);

  for (i = 0; i < n; i++)
    {
      if (!ph[i].p_memsz)
        continue;

      memcpy (base + ph[i].p_vaddr,
              data + ph[i].p_offset,
              ph[i].p_memsz);

      if (start_segment < 0)
        {
          start_segment = prev_segment = i;
          continue;
        }

      if (ph[i].p_flags == ph[start_segment].p_flags)
        {
          prev_segment = i;
          continue;
        }

      if (alignment == 4096)
        if (mprotect_segments (base, &ph[start_segment], &ph[prev_segment]))
          goto cleanup;

      /* Open a new set of segments.  */
      start_segment = prev_segment = i;
    }

  /* Mprotect the last segments.  */
  if (alignment == 4096)
    if (mprotect_segments (base, &ph[start_segment], &ph[prev_segment]))
      goto cleanup;

  if ((err_msg = process_dynamic_segment (base, &ph[dynamic_segment],
                                          &init, &entry)))
    goto cleanup;

  if (scm_is_true (init))
    scm_call_0 (init);

  /* Finally!  Return the thunk.  */
  return entry;

 cleanup:
  {
    if (errno)
      SCM_SYSERROR;
    scm_misc_error (FUNC_NAME, err_msg ? err_msg : "error loading ELF file",
                    SCM_EOL);
  }
}
コード例 #6
0
ファイル: objcodes.c プロジェクト: ijp/guile
static SCM
load_thunk_from_fd_using_mmap (int fd)
#define FUNC_NAME "load-thunk-from-disk"
{
  Elf_Ehdr header;
  Elf_Phdr *ph;
  const char *err_msg = 0;
  char *base = 0;
  size_t n;
  int i;
  int start_segment = -1;
  int prev_segment = -1;
  int dynamic_segment = -1;
  SCM init = SCM_BOOL_F, entry = SCM_BOOL_F;

  if (full_read (fd, &header, sizeof header) != sizeof header)
    ABORT ("object file too small");

  if ((err_msg = check_elf_header (&header)))
    goto cleanup;

  if (lseek (fd, header.e_phoff, SEEK_SET) == (off_t) -1)
    goto cleanup;
  
  n = header.e_phnum;
  ph = scm_gc_malloc_pointerless (n * sizeof (Elf_Phdr), "segment headers");

  if (full_read (fd, ph, n * sizeof (Elf_Phdr)) != n * sizeof (Elf_Phdr))
    ABORT ("failed to read program headers");
      
  for (i = 0; i < n; i++)
    {
      if (!ph[i].p_memsz)
        continue;

      if (ph[i].p_filesz != ph[i].p_memsz)
        ABORT ("expected p_filesz == p_memsz");
      
      if (!ph[i].p_flags)
        ABORT ("expected nonzero segment flags");

      if (ph[i].p_type == PT_DYNAMIC)
        {
          if (dynamic_segment >= 0)
            ABORT ("expected only one PT_DYNAMIC segment");
          dynamic_segment = i;
        }

      if (start_segment < 0)
        {
          if (!base && ph[i].p_vaddr)
            ABORT ("first loadable vaddr is not 0");
            
          start_segment = prev_segment = i;
          continue;
        }

      if (ph[i].p_flags == ph[start_segment].p_flags)
        {
          if (ph[i].p_vaddr - ph[prev_segment].p_vaddr 
              != ph[i].p_offset - ph[prev_segment].p_offset)
            ABORT ("coalesced segments not contiguous");

          prev_segment = i;
          continue;
        }

      /* Otherwise we have a new kind of segment.  Map previous
         segments.  */
      if (map_segments (fd, &base, &ph[start_segment], &ph[prev_segment]))
        goto cleanup;

      /* Open a new set of segments.  */
      start_segment = prev_segment = i;
    }

  /* Map last segments.  */
  if (start_segment < 0)
    ABORT ("no loadable segments");

  if (map_segments (fd, &base, &ph[start_segment], &ph[prev_segment]))
    goto cleanup;

  if (dynamic_segment < 0)
    ABORT ("no PT_DYNAMIC segment");

  if ((err_msg = process_dynamic_segment (base, &ph[dynamic_segment],
                                          &init, &entry)))
    goto cleanup;

  if (scm_is_true (init))
    scm_call_0 (init);

  /* Finally!  Return the thunk.  */
  return entry;

  /* FIXME: munmap on error? */
 cleanup:
  {
    int errno_save = errno;
    (void) close (fd);
    errno = errno_save;
    if (errno)
      SCM_SYSERROR;
    scm_misc_error (FUNC_NAME, err_msg ? err_msg : "error loading ELF file",
                    SCM_EOL);
  }
}
コード例 #7
0
ファイル: libelf.c プロジェクト: netsoftwang/aajvm
int parse_elf_header(const char *binary_path)
{
    if (elf_init(binary_path) == -1)
        return -1;

    elf_hdr = (Elf64_Ehdr *)elf_mem;

    if (check_elf_header(elf_hdr) == -1)
        return -1;

    print_elf_hdr_ident(elf_hdr);
    if (print_elf_hdr_class(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_endian(elf_hdr) == -1)
        return -1;

    print_elf_hdr_version(elf_hdr);
    if (print_elf_hdr_osabi(elf_hdr) == -1)
        return -1;

    print_elf_hdr_abiversion(elf_hdr);
    if (print_elf_hdr_object_type(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_machine(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_elf_version(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_entry(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_phoff(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_shoff(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_flags(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_size(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_phentsize(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_phnum(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_shentsize(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_shnum(elf_hdr) == -1)
        return -1;

    if (print_elf_hdr_shstrndx(elf_hdr) == -1)
        return -1;

    elf_exit();
}