Ejemplo n.º 1
0
static
Elf64_Half get_type(Elf* elf)
{
  Elf64_Ehdr* ehdr64 = elf64_getehdr(elf);
  if (ehdr64)
    return ehdr64->e_type;
  Elf32_Ehdr* ehdr32 = elf32_getehdr(elf);
  if (ehdr32)
    return ehdr32->e_type;
  xbt_die("Could not get ELF heeader");
}
Ejemplo n.º 2
0
int32_t __tgt_rtl_is_valid_binary(__tgt_device_image *image) {
// If we don't have a valid ELF ID we can just fail.
#if TARGET_ELF_ID < 1
  return 0;
#else
  // Is the library version incompatible with the header file?
  if (elf_version(EV_CURRENT) == EV_NONE) {
    DP("Incompatible ELF library!\n");
    return 0;
  }

  char *img_begin = (char *)image->ImageStart;
  char *img_end = (char *)image->ImageEnd;
  size_t img_size = img_end - img_begin;

  // Obtain elf handler
  Elf *e = elf_memory(img_begin, img_size);
  if (!e) {
    DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1));
    return 0;
  }

  // Check if ELF is the right kind
  if (elf_kind(e) != ELF_K_ELF) {
    DP("Unexpected ELF type!\n");
    return 0;
  }
  Elf64_Ehdr *eh64 = elf64_getehdr(e);
  Elf32_Ehdr *eh32 = elf32_getehdr(e);

  if (!eh64 && !eh32) {
    DP("Unable to get machine ID from ELF file!\n");
    elf_end(e);
    return 0;
  }

  uint16_t MachineID;
  if (eh64 && !eh32)
    MachineID = eh64->e_machine;
  else if (eh32 && !eh64)
    MachineID = eh32->e_machine;
  else {
    DP("Ambiguous ELF header!\n");
    elf_end(e);
    return 0;
  }
  elf_end(e);

  return MachineID == TARGET_ELF_ID;
#endif
}
Ejemplo n.º 3
0
Elf_Scn* getSection(Elf *elf,const char *name)
{
	Elf64_Ehdr *ehdr = elf64_getehdr(elf);
	if(!ehdr) return NULL;

	Elf_Data *data = elf_getdata(elf_getscn(elf,ehdr->e_shstrndx),NULL);
	if(!data) return NULL;

	for(Elf_Scn *scn = NULL;(scn = elf_nextscn(elf,scn));) {
		Elf64_Shdr *shdr = elf64_getshdr(scn);
		if(shdr && !strcmp(name,(const char*)data->d_buf + shdr->sh_name)) return scn;
	}
	return NULL;
}
Ejemplo n.º 4
0
/* Check for correct relocation type use.  */
bool
x86_64_reloc_valid_use (Elf *elf, int type)
{
  if (type < R_X86_64_NONE || type >= R_X86_64_NUM
      || reloc_map_table[type].name == NULL)
    return false;

  Elf64_Ehdr *ehdr = elf64_getehdr (elf);
  assert (ehdr != NULL);

  if (reloc_map_table[type].appear == rel)
    return ehdr->e_type == ET_REL;

  if (reloc_map_table[type].appear == exec)
    return ehdr->e_type != ET_REL;

  assert (reloc_map_table[type].appear == both);
  return true;
}
Ejemplo n.º 5
0
int
write_ehdr(elf_data_t *elf, char **err)
{
  off_t off;
  size_t n, ehdr_size;
  void *ehdr_buf;

  if(!gelf_update_ehdr(elf->e, &elf->ehdr)) {
    (*err) = "failed to update executable header";
    return -1;
  }

  if(elf->bits == 32) {
    ehdr_buf = elf32_getehdr(elf->e);
    ehdr_size = sizeof(Elf32_Ehdr);
  } else {
    ehdr_buf = elf64_getehdr(elf->e);
    ehdr_size = sizeof(Elf64_Ehdr);
  }

  if(!ehdr_buf) {
    (*err) = "failed to get executable header";
    return -1;
  }

  off = lseek(elf->fd, 0, SEEK_SET);
  if(off < 0) {
    (*err) = "lseek failed";
    return -1;
  }

  n = write(elf->fd, ehdr_buf, ehdr_size);
  if(n != ehdr_size) {
    (*err) = "write failed";
    return -1;
  }

  return 0;
}
Ejemplo n.º 6
0
int
xlate_named_init_elf(Elf * elf, const char *section_name,
	xlate_table_con * ret_tab_ptr)
{
   int retstatus  = XLATE_TB_STATUS_NO_ERROR;
   xlate_table_con newtab = 0;
   Elf_Scn *scn = 0;
   int is64bit = 0;
   char *ident;
   size_t identsize;
   Elf_Scn *xlscn = 0;
   Elf64_Shdr *shdr64 = 0;
   Elf32_Shdr *shdr32 = 0;
   Elf32_Ehdr *ehdr32 = 0;
   Elf64_Ehdr *ehdr64 = 0;
   Elf_Data   *xlatedata = 0;
   int stringindex = 0;
   char * sec_name;

   if(elf_kind(elf) != ELF_K_ELF) {
	return XLATE_TB_STATUS_NOT_ELF;
   }
   ident = elf_getident(elf,&identsize);

   if(ident == 0 || identsize < EI_NIDENT) {
     return  XLATE_TB_STATUS_ELF_IDENT_BAD;
   }
   if(ident[EI_CLASS] ==  ELFCLASS64) {
	is64bit = 1;
   }
   if(is64bit) {
	ehdr64 = elf64_getehdr(elf);
	if(ehdr64 == 0 ) {
	  return XLATE_TB_STATUS_ELF_EHDR_BAD;
	}
	stringindex = ehdr64->e_shstrndx;
   } else {
	ehdr32 = elf32_getehdr(elf);
	if(ehdr32 == 0 ) {
	  return XLATE_TB_STATUS_ELF_EHDR_BAD;
	}
	stringindex = ehdr32->e_shstrndx;
   }

   for(scn = elf_nextscn(elf,scn);  
	scn != 0 && xlscn == 0
		; scn = elf_nextscn(elf,scn)) {
	if(is64bit) {
	  shdr64 = elf64_getshdr(scn);
	  if(shdr64 == 0) {
	    return XLATE_TB_STATUS_ELF_SHDR_BAD;
	  }
	  sec_name = elf_strptr(elf,stringindex,shdr64->sh_name);
	  if(sec_name == 0) {
	    return XLATE_TB_STATUS_ELF_STRPTR_BAD;
	  }
	  if(shdr64->sh_type    != SHT_MIPS_XLATE &&
		shdr64->sh_type != SHT_MIPS_XLATE_DEBUG &&
		shdr64->sh_type != SHT_MIPS_XLATE_OLD ) {
		continue;
	  }
	  if(!streq(section_name,sec_name)) {
		continue;
	  }
	  xlscn = scn;
	  break;
	} else {
	  shdr32 = elf32_getshdr(scn);
	  if(shdr32 == 0) {
	    return XLATE_TB_STATUS_ELF_SHDR_BAD;
	  }
	  sec_name = elf_strptr(elf,stringindex,shdr32->sh_name);
	  if(sec_name == 0) {
	    return XLATE_TB_STATUS_ELF_STRPTR_BAD;
	  }
	  if(shdr32->sh_type    != SHT_MIPS_XLATE  &&
		shdr32->sh_type != SHT_MIPS_XLATE_DEBUG &&
		shdr32->sh_type != SHT_MIPS_XLATE_OLD ) {
		continue;
	  }
	  if(!streq(section_name,sec_name)) {
		continue;
	  }
	  xlscn = scn;
	  break;
	}
   }
   if(xlscn == 0) {
	return XLATE_TB_STATUS_NO_XLATE;
   }

   xlatedata = elf_getdata(xlscn,NULL);
   if(xlatedata == NULL || xlatedata->d_size == 0) {
	return XLATE_TB_STATUS_NO_XLATE_DATA;
   }
   
   newtab = (xlate_table_con)malloc(sizeof(struct xlate_table_con_s));
   if(newtab == NULL) {
	return XLATE_TB_STATUS_ALLOC_FAIL;
   }
   bzero(newtab,sizeof(struct xlate_table_con_s));


   newtab->xc_elf = elf;


   newtab->xc_section_data = xlatedata->d_buf;
   newtab->xc_data_size = xlatedata->d_size;
   if(newtab->xc_data_size != xlatedata->d_size) {
	/* we have a gigantic section and are compiled only 32 bit.
	** we simply cannot handle and I don't think the
        ** mmap would have worked anyway so we cannot really
	** get here.
	*/
     free(newtab);
     return XLATE_TB_STATUS_SECTION_TOO_BIG;
   }

   retstatus = _xlate_fill_in_table_data(newtab,is64bit);
   if(retstatus != XLATE_TB_STATUS_NO_ERROR) {
     free(newtab);
     return retstatus;
   }

   newtab->xc_valid_table         = VALID_TABLE_MAGIC;
   *ret_tab_ptr = newtab;
   return retstatus;
}
Ejemplo n.º 7
0
/* load_kernel loads an ELF file as a kernel. */
uintptr_t
load_kernel(char *filename)
{
	Elf64_Ehdr *ehdr;
	Elf *elf;
	size_t phnum = 0;
	Elf64_Phdr *hdrs;
	int fd;

	elf_version(EV_CURRENT);
	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "Can't open %s: %r\n", filename);
		return 0;
	}

	elf = elf_begin(fd, ELF_C_READ, NULL);
	if (elf == NULL) {
		fprintf(stderr, "%s: cannot read %s ELF file.\n", __func__, filename);
		close(fd);
		return 0;
	}

	ehdr = elf64_getehdr(elf);
	if (ehdr == NULL) {
		fprintf(stderr, "%s: cannot get exec header of %s.\n",
		        __func__, filename);
		goto fail;
	}
	fprintf(stderr, "%s ELF entry point is %p\n", filename,
		(void *)ehdr->e_entry);

	if (elf_getphdrnum(elf, &phnum) < 0) {
		fprintf(stderr, "%s: cannot get program header num of %s.\n",
		        __func__, filename);
		goto fail;
	}
	fprintf(stderr, "%s has %p program headers\n", filename, phnum);

	hdrs = elf64_getphdr(elf);
	if (hdrs == NULL) {
		fprintf(stderr, "%s: cannot get program headers of %s.\n",
		        __func__, filename);
		goto fail;
	}

	for (int i = 0; i < phnum; i++) {
		size_t tot;
		Elf64_Phdr *h = &hdrs[i];
		uintptr_t pa;

		fprintf(stderr,
		        "%d: type 0x%lx flags 0x%lx  offset 0x%lx vaddr 0x%lx paddr 0x%lx size 0x%lx  memsz 0x%lx align 0x%lx\n",
		        i,
		        h->p_type,		/* Segment type */
		        h->p_flags,		/* Segment flags */
		        h->p_offset,		/* Segment file offset */
		        h->p_vaddr,		/* Segment virtual address */
		        h->p_paddr,		/* Segment physical address */
		        h->p_filesz,		/* Segment size in file */
		        h->p_memsz,		/* Segment size in memory */
		        h->p_align		/* Segment alignment */);
		if (h->p_type != PT_LOAD)
			continue;
		if ((h->p_flags & (PF_R | PF_W | PF_X)) == 0)
			continue;

		pa = h->p_paddr;
		fprintf(stderr,
		        "Read header %d @offset %p to %p (elf PA is %p) %d bytes:",
		        i, h->p_offset, pa, h->p_paddr, h->p_filesz);
		tot = 0;
		while (tot < h->p_filesz) {
			int amt = pread(fd, (void *)(pa + tot), h->p_filesz - tot,
			                h->p_offset + tot);
			if (amt < 1)
				break;
			tot += amt;
		}
		fprintf(stderr, "read a total of %d bytes\n", tot);
		if (tot < h->p_filesz) {
			fprintf(stderr, "%s: got %d bytes, wanted %d bytes\n",
			        filename, tot, h->p_filesz);
			goto fail;
		}
	}

	close(fd);
	elf_end(elf);
	return ehdr->e_entry;
 fail:
	close(fd);
	elf_end(elf);
	return 0;
}
Ejemplo n.º 8
0
static void print_relocinfo_64 (Dwarf_Debug dbg, Elf *elf)
{
#ifdef HAVE_ELF64_GETEHDR
    Elf_Scn *scn = NULL;
    Elf_Data *data;
    Elf64_Ehdr	    *ehdr64;
    Elf64_Shdr      *shdr64;
    char *scn_name;
    int i;

    if ((ehdr64 = elf64_getehdr(elf)) == NULL) {
	print_error(dbg, "DW_ELF_GETEHDR_ERROR",DW_DLV_OK, err); 
    }

    while ((scn = elf_nextscn(elf, scn)) != NULL) {

	if ((shdr64 = elf64_getshdr(scn)) == NULL) {
	    print_error(dbg, "DW_ELF_GETSHDR_ERROR",DW_DLV_OK, err); 
	}
	if ((scn_name = elf_strptr(elf,ehdr64->e_shstrndx, shdr64->sh_name)) 
	    == NULL) {
	    print_error(dbg, "DW_ELF_STRPTR_ERROR",DW_DLV_OK, err); 
	}
	if (shdr64->sh_type == SHT_SYMTAB) {
	    size_t sym_size = 0;
	    size_t count = 0;
	    if ((sym_64 = (Elf64_Sym *) get_scndata(scn, &sym_size)) == NULL) {
		print_error(dbg, "no symbol table data",DW_DLV_OK, err); 
	    }
	    count = sym_size / sizeof (Elf64_Sym);
	    sym_64 ++;
	    if ((sym_data_64 = read_64_syms(sym_64, count, elf, 
					    shdr64->sh_link)) == NULL) {
		print_error(dbg, "problem reading symbol table data",DW_DLV_OK, err); 
	    }
	}
	else if (strncmp(scn_name, ".rel.debug_", 11))
	    continue;
	else if (strcmp(scn_name, ".rel.debug_info") == 0) {
	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_INFO)
	}
	else if (strcmp(scn_name, ".rel.debug_line") == 0) {
	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_LINE)
	}
	else if (strcmp(scn_name, ".rel.debug_pubname") == 0) {
	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_PUBNAME)
	}
	else if (strcmp(scn_name, ".rel.debug_aranges") == 0) {
	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_ARANGES)
	}
	else if (strcmp(scn_name, ".rel.debug_abbrev") == 0) {
	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_ABBREV)
	}
	else if (strcmp(scn_name, ".rel.debug_frame") == 0) {
	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_FRAME)
	}
    } /* while */

    for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i ++) {
	if (sect_data[i].buf != NULL && sect_data[i].size > 0) {
	    print_reloc_information_64(i, sect_data[i].buf, sect_data[i].size);
	}
    }
#endif
}
Ejemplo n.º 9
0
/*
    Given an Elf ptr, set up dbg with pointers
    to all the Dwarf data sections.
    Return NULL on error.

    This function is also responsible for determining
    whether the given object contains Dwarf information
    or not.  The test currently used is that it contains
    either a .debug_info or a .debug_frame section.  If 
    not, it returns DW_DLV_NO_ENTRY causing dwarf_init() also to 
    return DW_DLV_NO_ENTRY.  Earlier, we had thought of using only 
    the presence/absence of .debug_info to test, but we 
    added .debug_frame since there could be stripped objects 
    that have only a .debug_frame section for exception 
    processing.
    DW_DLV_NO_ENTRY or DW_DLV_OK or DW_DLV_ERROR
*/
static int
_dwarf_setup(Dwarf_Debug dbg, dwarf_elf_handle elf, Dwarf_Error * error)
{
#ifdef __SGI_FAST_LIBELF
    Elf64_Ehdr ehdr;
    Elf64_Shdr shdr;
    enum elf_sgi_error_type sres;
    unsigned char const* ehdr_ident;
#else
    Elf32_Ehdr *ehdr32;

#ifdef HAVE_ELF64_GETEHDR
    Elf64_Ehdr *ehdr64;
#endif
    Elf32_Shdr *shdr32;

#ifdef HAVE_ELF64_GETSHDR
    Elf64_Shdr *shdr64;
#endif
    Elf_Scn *scn;
    char *ehdr_ident;
#endif /* !defined(__SGI_FAST_LIBELF) */
    Dwarf_Half machine;
    char *scn_name;
    int is_64bit;
    int foundDwarf;

    Dwarf_Unsigned section_size;
    Dwarf_Unsigned section_count;
    Dwarf_Half section_index;

    foundDwarf = FALSE;
    dbg->de_elf = elf;

    dbg->de_assume_string_in_bounds = _dwarf_assume_string_bad;

#ifdef __SGI_FAST_LIBELF
    sres = elf_sgi_ehdr(elf, &ehdr);
    if (sres != ELF_SGI_ERROR_OK) {
	DWARF_DBG_ERROR(dbg, _dwarf_error_code_from_elf_sgi_error_code(sres),
			DW_DLV_ERROR);
    }
    ehdr_ident = ehdr.e_ident;
    section_count = ehdr.e_shnum;
    machine = ehdr.e_machine;
#else
    if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {
	DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETIDENT_ERROR, DW_DLV_ERROR);
    }
#endif

    is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64);


    dbg->de_same_endian = 1;
    dbg->de_copy_word = memcpy;
#ifdef WORDS_BIGENDIAN
    dbg->de_big_endian_object = 1;
    if (ehdr_ident[EI_DATA] == ELFDATA2LSB) {
	dbg->de_same_endian = 0;
	dbg->de_big_endian_object = 0;
	dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
    }
#else /* little endian */
    dbg->de_big_endian_object = 0;
    if (ehdr_ident[EI_DATA] == ELFDATA2MSB) {
	dbg->de_same_endian = 0;
        dbg->de_big_endian_object = 1;
	dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
    }
#endif /* !WORDS_BIGENDIAN */

    /* The following de_length_size is Not Too Significant.
	Only used one calculation, and an appoximate one at that. */
    dbg->de_length_size = is_64bit ? 8 : 4;
    dbg->de_pointer_size = is_64bit ? 8 : 4;


#ifdef __SGI_FAST_LIBELF
    /* We've already loaded the ELF header, so there's nothing to do here */
#else
#ifdef HAVE_ELF64_GETEHDR
    if (is_64bit) {
	ehdr64 = elf64_getehdr(elf);
	if (ehdr64 == NULL) {
	    DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR,
			    DW_DLV_ERROR);
	}
        section_count = ehdr64->e_shnum;
        machine = ehdr64->e_machine;
    } else
#endif
    {
	ehdr32 = elf32_getehdr(elf);
	if (ehdr32 == NULL) {
	    DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR,
			    DW_DLV_ERROR);
	}
        section_count = ehdr32->e_shnum;
        machine = ehdr32->e_machine;
    }
#endif /* !defined(__SGI_FAST_LIBELF) */

    if (is_64bit && machine != EM_MIPS) {
        /* MIPS/IRIX makes pointer size and length size 8 for -64.
           Other platforms make length 4 always. */
        /* 4 here supports 32bit-offset dwarf2, as emitted by
           cygnus tools, and the dwarfv2.1 64bit extension setting. */
        dbg->de_length_size = 4;
    }

    /* We start at index 1 to skip the initial empty section. */
    for (section_index = 1; section_index < section_count; ++section_index) {

#ifdef __SGI_FAST_LIBELF
	sres = elf_sgi_shdr(elf, section_index, &shdr);
	if (sres != ELF_SGI_ERROR_OK) {
	    DWARF_DBG_ERROR(dbg, _dwarf_error_code_from_elf_sgi_error_code(sres),
			    DW_DLV_ERROR);
	}

	section_size = shdr.sh_size;

	sres = elf_sgi_string(elf, ehdr.e_shstrndx, shdr.sh_name, (char const** )&scn_name);
	if (sres != ELF_SGI_ERROR_OK) {
	    DWARF_DBG_ERROR(dbg, _dwarf_error_code_from_elf_sgi_error_code(sres),
			    DW_DLV_ERROR);
	}
#else /* !defined(__SGI_FAST_LIBELF) */
	scn = elf_getscn(elf, section_index);
	if (scn == NULL) {
	    DWARF_DBG_ERROR(dbg, DW_DLE_MDE,
			    DW_DLV_ERROR);
	}

#ifdef HAVE_ELF64_GETSHDR
	if (is_64bit) {
	    shdr64 = elf64_getshdr(scn);
	    if (shdr64 == NULL) {
		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR,
				DW_DLV_ERROR);
	    }

	    section_size = shdr64->sh_size;

	    if ((scn_name = elf_strptr(elf, ehdr64->e_shstrndx,
				       shdr64->sh_name))
		== NULL) {
		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR,
				DW_DLV_ERROR);
	    }
	} else
#endif /* HAVE_ELF64_GETSHDR */
	{
	    if ((shdr32 = elf32_getshdr(scn)) == NULL) {
		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR, 0);
	    }

	    section_size = shdr32->sh_size;

	    if ((scn_name = elf_strptr(elf, ehdr32->e_shstrndx,
				       shdr32->sh_name)) == NULL) {
		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR,
				DW_DLV_ERROR);
	    }
	}
#endif /* !defined(__SGI_FAST_LIBELF) */

	if (strncmp(scn_name, ".debug_", 7)
	    && strcmp(scn_name, ".eh_frame")
	    )
	    continue;

	else if (strcmp(scn_name, ".debug_info") == 0) {
	    if (dbg->de_debug_info != NULL) {
		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* Know no reason to allow empty debug_info section */
		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_NULL,
				DW_DLV_ERROR);
	    }
	    foundDwarf = TRUE;
	    dbg->de_debug_info_index = section_index;
	    dbg->de_debug_info_size = section_size;
	}

	else if (strcmp(scn_name, ".debug_abbrev") == 0) {
	    if (dbg->de_debug_abbrev != NULL) {
		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* Know no reason to allow empty debug_abbrev section */
		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_NULL,
				DW_DLV_ERROR);
	    }
	    dbg->de_debug_abbrev_index = section_index;
	    dbg->de_debug_abbrev_size = section_size;
	}

	else if (strcmp(scn_name, ".debug_aranges") == 0) {
	    if (dbg->de_debug_aranges_index != 0) {
		DWARF_DBG_ERROR(dbg,
				DW_DLE_DEBUG_ARANGES_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* a zero size section is just empty. Ok, no error */
		continue;
	    }
	    dbg->de_debug_aranges_index = section_index;
	    dbg->de_debug_aranges_size = section_size;
	}

	else if (strcmp(scn_name, ".debug_line") == 0) {
	    if (dbg->de_debug_line_index != 0) {
		DWARF_DBG_ERROR(dbg,
				DW_DLE_DEBUG_LINE_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* a zero size section is just empty. Ok, no error */
		continue;
	    }
	    dbg->de_debug_line_index = section_index;
	    dbg->de_debug_line_size = section_size;
	}

	else if (strcmp(scn_name, ".debug_frame") == 0) {
	    if (dbg->de_debug_frame_index != 0) {
		DWARF_DBG_ERROR(dbg,
				DW_DLE_DEBUG_FRAME_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* a zero size section is just empty. Ok, no error */
		continue;
	    }
	    dbg->de_debug_frame_index = section_index;
	    dbg->de_debug_frame_size = section_size;
	    foundDwarf = TRUE;
	} else if (strcmp(scn_name, ".eh_frame") == 0) {
	    /* gnu egcs-1.1.2 data */
	    if (dbg->de_debug_frame_eh_gnu_index != 0) {
		DWARF_DBG_ERROR(dbg,
				DW_DLE_DEBUG_FRAME_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* a zero size section is just empty. Ok, no error */
		continue;
	    }
	    dbg->de_debug_frame_eh_gnu_index = section_index;
	    dbg->de_debug_frame_size_eh_gnu = section_size;
	    foundDwarf = TRUE;
	}

	else if (strcmp(scn_name, ".debug_loc") == 0) {
	    if (dbg->de_debug_loc_index != 0) {
		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_LOC_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* a zero size section is just empty. Ok, no error */
		continue;
	    }
	    dbg->de_debug_loc_index = section_index;
	    dbg->de_debug_loc_size = section_size;
	}


	else if (strcmp(scn_name, ".debug_pubnames") == 0) {
	    if (dbg->de_debug_pubnames_index != 0) {
		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_PUBNAMES_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* a zero size section is just empty. Ok, no error */
		continue;
	    }
	    dbg->de_debug_pubnames_index = section_index;
	    dbg->de_debug_pubnames_size = section_size;
	}

	else if (strcmp(scn_name, ".debug_str") == 0) {
	    if (dbg->de_debug_str_index != 0) {
		DWARF_DBG_ERROR(dbg,
				DW_DLE_DEBUG_STR_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* a zero size section is just empty. Ok, no error */
		continue;
	    }
	    dbg->de_debug_str_index = section_index;
	    dbg->de_debug_str_size = section_size;
	}

	else if (strcmp(scn_name, ".debug_funcnames") == 0) {
	    if (dbg->de_debug_funcnames_index != 0) {
		DWARF_DBG_ERROR(dbg,
				DW_DLE_DEBUG_FUNCNAMES_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* a zero size section is just empty. Ok, no error */
		continue;
	    }
	    dbg->de_debug_funcnames_index = section_index;
	    dbg->de_debug_funcnames_size = section_size;
	}

	else if (strcmp(scn_name, ".debug_typenames") == 0) {
	    if (dbg->de_debug_typenames_index != 0) {
		DWARF_DBG_ERROR(dbg,
				DW_DLE_DEBUG_TYPENAMES_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* a zero size section is just empty. Ok, no error */
		continue;
	    }
	    dbg->de_debug_typenames_index = section_index;
	    dbg->de_debug_typenames_size = section_size;
	}

	else if (strcmp(scn_name, ".debug_varnames") == 0) {
	    if (dbg->de_debug_varnames_index != 0) {
		DWARF_DBG_ERROR(dbg,
				DW_DLE_DEBUG_VARNAMES_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* a zero size section is just empty. Ok, no error */
		continue;
	    }
	    dbg->de_debug_varnames_index = section_index;
	    dbg->de_debug_varnames_size = section_size;
	}

	else if (strcmp(scn_name, ".debug_weaknames") == 0) {
	    if (dbg->de_debug_weaknames_index != 0) {
		DWARF_DBG_ERROR(dbg,
				DW_DLE_DEBUG_WEAKNAMES_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* a zero size section is just empty. Ok, no error */
		continue;
	    }
	    dbg->de_debug_weaknames_index = section_index;
	    dbg->de_debug_weaknames_size = section_size;
	} else if (strcmp(scn_name, ".debug_macinfo") == 0) {
	    if (dbg->de_debug_macinfo_index != 0) {
		DWARF_DBG_ERROR(dbg,
				DW_DLE_DEBUG_MACINFO_DUPLICATE,
				DW_DLV_ERROR);
	    }
	    if (section_size == 0) {
		/* a zero size section is just empty. Ok, no error */
		continue;
	    }
	    dbg->de_debug_macinfo_index = section_index;
	    dbg->de_debug_macinfo_size = section_size;
	}
    }
    if (foundDwarf) {
	return DW_DLV_OK;
    }

    return (DW_DLV_NO_ENTRY);
}
Ejemplo n.º 10
0
int
xlate_init_elf(Elf * elf, int open_debug_table,
	xlate_table_con * ret_tab_ptr)
{
   int res;
   Elf32_Word wanttype;
   Elf_Scn *scn = 0;
   int is64bit = 0;
   char *ident;
   size_t identsize;
   Elf64_Shdr *shdr64 = 0;
   Elf32_Shdr *shdr32 = 0;
   Elf32_Ehdr *ehdr32 = 0;
   Elf64_Ehdr *ehdr64 = 0;
   int stringindex = 0;
   char * sec_name;

   if(elf_kind(elf) != ELF_K_ELF) {
	return XLATE_TB_STATUS_NOT_ELF;
   }
   ident = elf_getident(elf,&identsize);

   if(open_debug_table == XLATE_OPEN_STD_TABLE) {
	/* we take the first SHT_MIPS_XLATE*/
	wanttype = SHT_MIPS_XLATE;
   } else if(open_debug_table == XLATE_OPEN_DEBUG_TABLE) {
	/* we take the first SHT_MIPS_XLATE_DEBUG */
	wanttype = SHT_MIPS_XLATE_DEBUG;
   } else {
	return XLATE_TB_STATUS_NO_XLATE;
   }
   res = XLATE_TB_STATUS_NO_XLATE;
   if(ident == 0 || identsize < EI_NIDENT) {
     return  XLATE_TB_STATUS_ELF_IDENT_BAD;
   }
   if(ident[EI_CLASS] ==  ELFCLASS64) {
	is64bit = 1;
   }
   if(is64bit) {
	ehdr64 = elf64_getehdr(elf);
	if(ehdr64 == 0 ) {
	  return XLATE_TB_STATUS_ELF_EHDR_BAD;
	}
	stringindex = ehdr64->e_shstrndx;
   } else {
	ehdr32 = elf32_getehdr(elf);
	if(ehdr32 == 0 ) {
	  return XLATE_TB_STATUS_ELF_EHDR_BAD;
	}
	stringindex = ehdr32->e_shstrndx;
   }

   for(scn = elf_nextscn(elf,scn);  
	scn != 0 
		; scn = elf_nextscn(elf,scn)) {
	if(is64bit) {
	  shdr64 = elf64_getshdr(scn);
	  if(shdr64 == 0) {
	    return XLATE_TB_STATUS_ELF_SHDR_BAD;
	  }
	  sec_name = elf_strptr(elf,stringindex,shdr64->sh_name);
	  if(sec_name == 0) {
	    return XLATE_TB_STATUS_ELF_STRPTR_BAD;
	  }
	  if(shdr64->sh_type != wanttype) {
		continue;
	  }
	  res = xlate_named_init_elf(elf,
		sec_name,ret_tab_ptr);
	  return res;
	} else {
	  shdr32 = elf32_getshdr(scn);
	  if(shdr32 == 0) {
	    return XLATE_TB_STATUS_ELF_SHDR_BAD;
	  }
	  sec_name = elf_strptr(elf,stringindex,shdr32->sh_name);
	  if(sec_name == 0) {
	    return XLATE_TB_STATUS_ELF_STRPTR_BAD;
	  }
	  if(shdr32->sh_type != wanttype) {
		continue;
	  }
	  res = xlate_named_init_elf(elf,
		sec_name,ret_tab_ptr);
	  return res;
	}
   }

   return res;
}
Ejemplo n.º 11
0
////////////////////////////////////////////////////////////////////////////////
/// adds a target shared library to the target execution image
EXTERN void __tgt_register_lib(__tgt_bin_desc *desc){

  //Is the library version incompatible with the header file?
  if (elf_version(EV_CURRENT) == EV_NONE){
    DP("Incompatible ELF library!\n");
    return;
  }

  // Can't read the host entries??
  if (!desc) {
    DP("Invalid descr!\n");
    return;
  }
  if (!desc->EntriesBegin){
    DP("Invalid Host entries!\n");
    return;
  }

  DP("Registering entries starting at %016lx...\n", 
    (Elf64_Addr)desc->EntriesBegin->addr);

  HostEntriesBeginToTransTableTy::iterator TransTableIt =
      HostEntriesBeginToTransTable.find(desc->EntriesBegin);

  if (TransTableIt != HostEntriesBeginToTransTable.end()){
    DP("Already registered!\n");
    return;
  }

  // Initialize translation table for this
  TranslationTable &TransTable = HostEntriesBeginToTransTable[desc->EntriesBegin];
  TransTable.HostTable.EntriesBegin = desc->EntriesBegin;
  TransTable.HostTable.EntriesEnd = desc->EntriesEnd;

  // Scan all the device images
  for(int32_t i=0; i<desc->NumDevices; ++i){

    __tgt_device_image &img = desc->DeviceImages[i];
    char *img_begin = (char*)img.ImageStart;
    char *img_end   = (char*)img.ImageEnd;
    size_t img_size = img_end - img_begin;

    //Obtain elf handler
    Elf *e = elf_memory(img_begin, img_size);
    if (!e){
      DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1));
      continue;
    }

    //Check if ELF is the right kind
    if (elf_kind(e) != ELF_K_ELF){
      DP("Unexpected ELF type!\n");
      continue;
    }
    Elf64_Ehdr *eh64 = elf64_getehdr(e);
    Elf32_Ehdr *eh32 = elf32_getehdr(e);
    uint16_t MachineID;
    if (eh64 && !eh32)
      MachineID = eh64->e_machine;
    else if (eh32 && !eh64)
      MachineID = eh32->e_machine;
    else{
      DP("Ambiguous ELF header!\n");
      continue;
    }

    DTypeToRTLMapTy::iterator RTLHandler = DTypeToRTLMap.find(MachineID);

    // We already have an handler for this device's RTL?
    // If so insert the Image <-> RTL Map entry and continue
    if (RTLHandler != DTypeToRTLMap.end()){

      // We were unable to find a runtime for this device before...
      if (RTLHandler->second == 0)
        continue;

      RegisterImageIntoTranslationTable(TransTable, *RTLHandler->second, &img);
      continue;
    }

    // Locate the library name and create an handler
    void *dynlib_handle = 0;

    DP("Looking for RTL libraries: with machine id %d\n", MachineID);
    for(int32_t j=0; j<targets_info.Number_of_Entries; ++j){
      if (targets_info.Entries[j].Machine_Elf_ID == MachineID){
        DP("Found library %s!\n", targets_info.Entries[j].Machine_RTL_Lib);
        
        dynlib_handle = dlopen(targets_info.Entries[j].Machine_RTL_Lib, RTLD_NOW);
        
        if (!dynlib_handle)
          DP("Error opening library for target %d: %s!\n", MachineID, dlerror());

        break;
      }
      else
        DP("Machine ID %d != %d!\n", targets_info.Entries[j].Machine_Elf_ID, MachineID);
    }

    RTLInfoTy *&RTL = DTypeToRTLMap[MachineID];
    RTL = 0;

    if (!dynlib_handle){
      DP("No valid library for target %d, %s!\n", MachineID, dlerror());
      continue;
    }

    // Create the handler and try to retrieve the functions
    RTLInfoTy R;

    R.LibraryHandler    = dynlib_handle;
    if (!(R.device_type       = (RTLInfoTy::device_type_ty*)      dlsym(dynlib_handle, "__tgt_rtl_device_type"))) continue;
    if (!(R.number_of_devices = (RTLInfoTy::number_of_devices_ty*)dlsym(dynlib_handle, "__tgt_rtl_number_of_devices"))) continue;
    if (!(R.init_device       = (RTLInfoTy::init_device_ty*)      dlsym(dynlib_handle, "__tgt_rtl_init_device"))) continue;
    if (!(R.load_binary       = (RTLInfoTy::load_binary_ty*)      dlsym(dynlib_handle, "__tgt_rtl_load_binary"))) continue;
    if (!(R.data_alloc        = (RTLInfoTy::data_alloc_ty*)       dlsym(dynlib_handle, "__tgt_rtl_data_alloc"))) continue;
    if (!(R.data_submit       = (RTLInfoTy::data_submit_ty*)      dlsym(dynlib_handle, "__tgt_rtl_data_submit"))) continue;
    if (!(R.data_retrieve     = (RTLInfoTy::data_retrieve_ty*)    dlsym(dynlib_handle, "__tgt_rtl_data_retrieve"))) continue;
    if (!(R.data_delete       = (RTLInfoTy::data_delete_ty*)      dlsym(dynlib_handle, "__tgt_rtl_data_delete"))) continue;
    if (!(R.run_region        = (RTLInfoTy::run_region_ty*)       dlsym(dynlib_handle, "__tgt_rtl_run_target_region"))) continue;
    if (!(R.run_team_region   = (RTLInfoTy::run_team_region_ty*)  dlsym(dynlib_handle, "__tgt_rtl_run_target_team_region"))) continue;

    // No devices are supported by this RTL?
    if (!(R.NumberOfDevices = R.number_of_devices())) {
      DP("No device support this RTL\n");
      continue;
    }

    R.Idx = (RTLs.empty()) ? 0 : RTLs.back().Idx + RTLs.back().NumberOfDevices;

    DP("Registered RTL supporting %d devices at index %d!\n", 
      R.NumberOfDevices, R.Idx);

    // The RTL is valid!
    RTLs.push_back(R);
    RTL = &RTLs.back();

    // Add devices
    DeviceTy device(RTL);

    size_t start = Devices.size();
    Devices.resize(start + RTL->NumberOfDevices, device);
    for (int32_t device_id = 0; device_id < RTL->NumberOfDevices; device_id++) {
      // global device ID
      Devices[start + device_id].DeviceID = start + device_id;
      // RTL local device ID
      Devices[start + device_id].RTLDeviceID = device_id;

      // Save pointer to device in RTL in case we want to unregister the RTL
      RTL->Devices.push_back(&Devices[start + device_id]);
    }

    DP("Registering image %016lx with RTL!\n", (Elf64_Addr)img_begin);
    RegisterImageIntoTranslationTable(TransTable, *RTL, &img);
  }
  
  DP("Done register entries!\n");
}
Ejemplo n.º 12
0
/* dwarf_elf_object_access_internals_init() */
static int
dwarf_elf_object_access_internals_init(void* obj_in,
    dwarf_elf_handle elf,
    int* error)
{
    dwarf_elf_object_access_internals_t*obj =
        (dwarf_elf_object_access_internals_t*)obj_in;
    char *ehdr_ident = 0;
    Dwarf_Half machine = 0;
    obj->elf = elf;

    if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {
        *error = DW_DLE_ELF_GETIDENT_ERROR;
        return DW_DLV_ERROR;
    }

    obj->is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64);


    if (ehdr_ident[EI_DATA] == ELFDATA2LSB){
        obj->endianness = DW_OBJECT_LSB;
    } else if (ehdr_ident[EI_DATA] == ELFDATA2MSB){
        obj->endianness = DW_OBJECT_MSB;
    }

    if (obj->is_64bit) {
#ifdef HAVE_ELF64_GETEHDR
        obj->ehdr64 = elf64_getehdr(elf);
        if (obj->ehdr64 == NULL) {
            *error = DW_DLE_ELF_GETEHDR_ERROR;
            return DW_DLV_ERROR;
        }
        obj->section_count = obj->ehdr64->e_shnum;
        machine = obj->ehdr64->e_machine;
        obj->machine = machine;
#else
        *error = DW_DLE_NO_ELF64_SUPPORT;
        return DW_DLV_ERROR;
#endif
    } else {
        obj->ehdr32 = elf32_getehdr(elf);
        if (obj->ehdr32 == NULL) {
            *error = DW_DLE_ELF_GETEHDR_ERROR;
            return DW_DLV_ERROR;
        }
        obj->section_count = obj->ehdr32->e_shnum;
        machine = obj->ehdr32->e_machine;
        obj->machine = machine;
    }

    /*  The following length_size is Not Too Significant. Only used
        one calculation, and an approximate one at that. */
    obj->length_size = obj->is_64bit ? 8 : 4;
    obj->pointer_size = obj->is_64bit ? 8 : 4;

    if (obj->is_64bit && machine != EM_MIPS) {
        /*  MIPS/IRIX makes pointer size and length size 8 for -64.
            Other platforms make length 4 always. */
        /*  4 here supports 32bit-offset dwarf2, as emitted by cygnus
            tools, and the dwarfv2.1 64bit extension setting.
            This is not the same as the size-of-an-offset, which
            is 4 in 32bit dwarf and 8 in 64bit dwarf.  */
        obj->length_size = 4;
    }
    return DW_DLV_OK;
}