Exemple #1
0
//---------------------------------------------------------------------
Elf_Scn* getELFSectionByName(Elf* elf, char* secName)
{
  Elf32_Ehdr* ehdr;
  Elf_Scn *scn;
  Elf32_Shdr *shdr;

  // Get the ELF Header
  ehdr = elf32_getehdr(elf);
  if (NULL == ehdr){
    fprintf(stderr, "getELFSectionByName: Error reading ELF header\n");
    return NULL;
  }  

  scn = NULL;
  while ((scn = elf_nextscn(elf, scn)) != NULL){
    if ((shdr = elf32_getshdr(scn)) != NULL){
      char* CurrSecName = NULL;
      CurrSecName = elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name);
      if (strcmp(CurrSecName, secName) == 0)
	return scn;
    }
  }

  return NULL;
}
Exemple #2
0
Elf_Scn *
get_scnbyname(Elf *elf, char *name, int *num)
{
	Elf32_Ehdr	* ehdr;
	Elf_Scn		* scn;
	Elf32_Shdr	* shdr;
	Elf_Data	* data;
	int		  cnt,
			  tmp;

	if (!num)
		num = &tmp;
	
	*num = 0;

	if ((ehdr = elf32_getehdr(elf))==NULL)
		return NULL;

	if (((scn = elf_getscn(elf, ehdr->e_shstrndx)) == NULL) ||
	    ((data = elf_getdata(scn, NULL)) == NULL))
		return NULL;

	for (cnt = 1, scn = NULL; (scn = elf_nextscn(elf, scn)); cnt++) {
		if ((shdr = elf32_getshdr(scn)) == NULL)
			return NULL;

		if (! strcmp(name, (char *)data->d_buf + shdr->sh_name)) {
			*num = cnt;
			return scn;
		}
	}
	return NULL;
}
Exemple #3
0
Elf32_Ehdr *xelf32_getehdr(Elf *e)
{
  Elf32_Ehdr *ehdr = elf32_getehdr(e);
  if (ehdr == NULL)
	{
	  eprintf("elf_getehdr() failed: %s", elf_errmsg(-1));
	  exit(EXIT_FAILURE);
	}
  return ehdr;
}
Exemple #4
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");
}
Exemple #5
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
}
Exemple #6
0
static Elf32_Half download_machine( const char *filename )
{
    Elf *elf;
    Elf32_Ehdr *ehdr;
    int fd;
    Elf32_Half machine = 0;
    
    if ((fd = open(filename, O_RDONLY | O_BINARY)) != -1)
    {
        if (elf_version(EV_CURRENT) != EV_NONE)
        {
            elf = elf_begin(fd, ELF_C_READ, NULL);
            if (elf)
            {
                ehdr = elf32_getehdr( elf );
                if (ehdr )
                {
                    machine = ehdr->e_machine;
                }
                else
                {
                    fprintf( stderr,
                             "Failed to get ELF header: %s\n",
                             elf_errmsg(-1) );
                }
                elf_end(elf);
            }
            else
            {
                fprintf( stderr, "download_machine: elf_begin - %s\n",
                         elf_errmsg(-1) );
            }
        }
        else
        {
            fprintf(stderr, "Elf library is out of date\n" );
        }
        if (close( fd ) != 0)
            perror("Error closing executable");
    }
    else
    {
        perror("Error opening executable" );
    }
    return machine;
}
int main(int argc, char *argv[]) {
	if (argc < 2) {
		fprintf(stderr, "%s input\n", argv[0]);
		return 1;
	}
	const char* elfinput = argv[1];

	if (elf_version(EV_CURRENT) == EV_NONE) {
		fprintf(stderr, "Elf library out of date\n");
		return 1;
	}

	int fd = open(elfinput, O_RDONLY);
	if (fd < 0) {
		perror(elfinput);
		return 1;
	}

	Elf* elf = elf_begin(fd, ELF_C_READ, NULL);
	Elf32_Ehdr* ehdr = elf32_getehdr(elf);

	Elf_Scn* section = NULL;
	while ((section = elf_nextscn(elf, section)) != NULL) {
		Elf32_Shdr* shdr;
		if ((shdr = elf32_getshdr(section)) != NULL) {
			const char* name = elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name);
			if (strcmp(name, ".directive"))
				continue;
			Elf_Data* data = NULL;
			if ((data = elf_rawdata(section, data)) == NULL || data->d_size == 0 || data->d_buf == 0)
				continue;
			fwrite(data->d_buf, 1, data->d_size, stdout);
			fprintf(stdout, "\n");

			elf_end(elf);
			close(fd);
			return 0;
		}
	}

	fprintf(stderr, "No .directive section found!\n");
	elf_end(elf);
	close(fd);
	return 1;
}
Exemple #8
0
//---------------------------------------------------------------------
char* getELFSectionName(Elf* elf, int ndx)
{
  Elf32_Ehdr* ehdr;
  Elf_Scn *scn;
  Elf32_Shdr *shdr;

  if ((ehdr = elf32_getehdr(elf)) == NULL){
    fprintf(stderr, "Error reading ELF header\n");
    return NULL;
  }  
  if ((scn = elf_getscn(elf, ndx)) == NULL){
    fprintf(stderr, "Error reading ELF section table.\n");
    return NULL;
  }
  if ((shdr = elf32_getshdr(scn)) == NULL){
    fprintf(stderr, "Error reading ELF section header.\n");
    return NULL;
  };

  return elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name);
}
Exemple #9
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;
}
/*
    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);
}
bool saveSharedLibrary::readNewLib(){
	Elf32_Shdr *newsh, *shdr;
	Elf_Scn *scn, *newScn;
	Elf32_Ehdr *ehdr;
	Elf32_Phdr *oldPhdr;
	Elf_Data  *strdata, *newdata, *olddata;

	if ((ehdr = elf32_getehdr(newElf)) == NULL){ 
		fprintf(stderr," FAILED obtaining ehdr readNewLib\n");
		return false;
	}


	if((scn = elf_getscn(newElf, ehdr->e_shstrndx)) != NULL){
	    	if((strdata = elf_getdata(scn, NULL)) == NULL){
		 	fprintf(stderr," Failed obtaining .shstrtab data buffer \n");
			return false;
		}
	}else{
		fprintf(stderr," FAILED obtaining .shstrtab scn\n");
	}

	unsigned int newScnName =0;
	scn = NULL;
	Elf_Data shstrtabData;
#if  defined(i386_unknown_linux2_0) \
 || defined(x86_64_unknown_linux2_4) 
	/* save the PHDR from the library */
     oldPhdr = elf32_getphdr(newElf);
	Elf32_Phdr phdrBuffer[ehdr->e_phnum];
	/* 	copy it over to a buffer because, on linux, we will close newElf and reopen it.
		This closing of newElf should dealloc the data pointed to by oldPhdr
	*/
	memcpy(phdrBuffer, oldPhdr, ehdr->e_phnum * ehdr->e_phentsize);
#endif

	for (int cnt = 1; (scn = elf_nextscn(newElf, scn)); cnt++) {
		 //copy sections from newElf to newElf.

		 shdr = elf32_getshdr(scn);
		 olddata = elf_getdata(scn,NULL);


		 if(!strcmp( (char *)strdata->d_buf + shdr->sh_name, ".text")){
			    textAddr = shdr->sh_addr;
				textData = olddata;
				textSize = shdr->sh_size;
		 }

		 if(!strcmp( (char*) strdata->d_buf + shdr->sh_name, ".shstrtab")){
			    const char *secname =".dyninst_mutated\0";
			    shstrtabData.d_size = olddata->d_size+strlen(secname)+1;
				newShstrtabData_d_buf = new  char[shstrtabData.d_size];
			    shstrtabData.d_buf = newShstrtabData_d_buf;
			    memcpy( shstrtabData.d_buf,  olddata->d_buf, olddata->d_size);
			    memcpy(&(((char*) shstrtabData.d_buf)[olddata->d_size]), secname,
					  strlen(secname)+1);

			    newScnName = olddata->d_size;
			    olddata->d_buf = shstrtabData.d_buf;
			    olddata->d_size = shstrtabData.d_size;

			    shdr->sh_size +=strlen(secname)+1;

				/* 	if the section header table is past this section in the
					ELF file, calculate the new offset*/
				if(ehdr ->e_shoff > shdr->sh_offset){
					ehdr->e_shoff += strlen(secname)+1;
				}
				elf_flagscn(scn,ELF_C_SET,ELF_F_DIRTY);

		 }

	}



	ehdr-> e_shnum++;
	newScn = elf_newscn(newElf);

	newsh = elf32_getshdr(newScn);

	newsh->sh_name = newScnName;
	newsh->sh_type = SHT_NOBITS; // SHT_NOTE;
	newsh->sh_flags=0;
	newsh->sh_addr = 0x0;
	newsh->sh_offset = shdr->sh_offset;
	newsh->sh_size=0;
	newsh->sh_link=0;
	newsh->sh_info=0;
	newsh->sh_addralign = 0x1; //Values 0 and 1 mean the section has no alignment constraints.
	newsh->sh_entsize = 0;


	newdata = elf_newdata(newScn);
	newdata->d_size =0;
	newdata->d_buf=0;

	elf_update(newElf, ELF_C_NULL);

	/* 	elfutils on linux does not write data back to an ELF file you
		have opened correctly. Specifically, if you add a section the
		section's section header has space allocated for it in the file
		but no data is written to it. lovely, eh?

		to combat this, we reopen the file we just closed, and find the
		empty section header and fill it with data.
	*/

#if  defined(i386_unknown_linux2_0) \
 || defined(x86_64_unknown_linux2_4) 

	elf_update(newElf, ELF_C_WRITE);
  	elf_end(newElf);
	P_close(newfd);

	if((newfd = (open(newpathname, O_RDWR)))==-1){
		fprintf(stderr,"%s[%d]: cannot open new SO : %s\n",FILE__, __LINE__, newpathname);
		perror(" FAIL ");
		return false;;
	}
	if((newElf = elf_begin(newfd, ELF_C_RDWR, NULL)) ==NULL){
		fprintf(stderr,"cannot open ELF %s \n", newpathname);
		return false;;
	}
	if ((ehdr = elf32_getehdr(newElf)) == NULL){ 
		fprintf(stderr," FAILED obtaining ehdr readNewLib\n");
		return false;
	}


	if((scn = elf_getscn(newElf, ehdr->e_shstrndx)) != NULL){
	    	if((strdata = elf_getdata(scn, NULL)) == NULL){
		 	fprintf(stderr," Failed obtaining .shstrtab data buffer \n");
			return false;
		}
	}else{
		fprintf(stderr," FAILED obtaining .shstrtab scn\n");
	}

	scn = NULL;
	bool foundText=false; 
	for (int cnt = 1; (scn = elf_nextscn(newElf, scn)); cnt++) {
		 //copy sections from newElf to newElf.

		 shdr = elf32_getshdr(scn);
		 olddata = elf_getdata(scn,NULL);


		if(!foundText && !strcmp( (char *)strdata->d_buf + shdr->sh_name, ".text")){
			textAddr = shdr->sh_addr;
			textData = olddata;
			textSize = shdr->sh_size;
			elf_flagscn(scn,ELF_C_SET,ELF_F_DIRTY);
			foundText = true;
		}	

	}

		/**UPDATE THE LAST SHDR **/
	memset(shdr,'\0', sizeof(Elf32_Shdr));	
	shdr->sh_name = newScnName;
	shdr->sh_addr = 0x0;
	shdr->sh_type = 7;

	/* 	update the PHDR, well just make sure it is reset to 
		what was in the original library */
     Elf32_Phdr *newPhdr = elf32_getphdr(newElf);
	memcpy(newPhdr,phdrBuffer, ehdr->e_phnum * ehdr->e_phentsize);

	/* be extra sure, set the DIRTY flag */
	elf_flagphdr(newElf, ELF_C_SET,ELF_F_DIRTY);
	elf_flagscn(scn,ELF_C_SET,ELF_F_DIRTY);
	elf_update(newElf, ELF_C_NULL);
#endif
	return true;

}
/**
 * @brief Parse a .elf file into the section cache
 *
 * Parse a .elf file and extract the text (code) and data segments, creating
 * code and data segments in the cache.
 *
 * @param filename The pathanme of the .elf file
 * @param start_address Pointer to the TFTF start_address field. This will
 *        be set to the .elf file entrypoint (e_entry) if not already set
 *        by the "--start" parameter.
 * @param start_symbol Name of the symbol to use for the TFTF start_address
 *        field, or NULL indicating not to use one.
 *
 * @returns True if successful, false otherwise.
 */
bool load_elf(const char * filename, uint32_t * start_address,
              const char *start_symbol) {
    bool success = false;
    int fd = -1;
    Elf *elf = NULL;
    Elf_Scn *scn = NULL;
    size_t shstrndx;
    int sections_created = 0;
    GElf_Addr start_symbol_addr;
    Elf32_Ehdr * ehdr = NULL;

    if (!filename) {
        goto cleanup;
    }

    if (elf_version(EV_CURRENT) == EV_NONE) {
        fprintf(stderr, "ELF library initialization failed: %s\n",
                elf_errmsg(-1));
        goto cleanup;
    }

    if ((fd = open(filename, O_RDONLY, 0)) < 0) {
        fprintf(stderr, "ERROR: Can't open '%s' (err %d)\n", filename, errno);
        goto cleanup;
    }

    if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
        fprintf(stderr, "elf_begin() failed: %s\n", elf_errmsg(-1));
        goto cleanup;
    }

    if (elf_kind(elf) != ELF_K_ELF) {
        fprintf(stderr,  "%s is not an ELF object\n", filename);
        goto cleanup;
    }

    if (elf_getshdrstrndx(elf, &shstrndx) != 0) {
        fprintf(stderr, "elf_getshdrstrndx() failed: %s\n", elf_errmsg(-1));
        goto cleanup;
    }

    /**
     * Extract the .text and .data segments and add them to the section cache
     */
    scn = elf_getscn_byname(elf, ".text");
    if (scn != NULL) {
        success = elf_add_section_cache_entry(scn, TFTF_SECTION_RAW_CODE);
        if (success) {
            /* Extract entrypoint (e_entry) */

            ehdr = elf32_getehdr(elf);
            if (ehdr != NULL) {
                if (start_address && *start_address == 0) {
                    *start_address = (uint32_t)ehdr->e_entry;
                }
            } else {
                fprintf(stderr, "ERROR: elf32_getehdr failed\n");
            }

            sections_created++;
        }
    }

    scn = elf_getscn_byname(elf, ".data");
    if (scn != NULL) {
        success = elf_add_section_cache_entry(scn, TFTF_SECTION_RAW_DATA);
        if (success) {
            sections_created++;
        }
    }

    if (start_symbol && start_address) {
        if (*start_address == ehdr->e_entry) {
            start_symbol_addr = elf_getsymaddr_byname(elf, start_symbol);
            if (start_symbol_addr) {
                *start_address = start_symbol_addr;
            }
        }
        else {
            fprintf(stderr, "ERROR: explicit start address (0x%.8x) and \
                    explicit start symbol (%s) both supplied\n",
                    *start_address, start_symbol);
            success = false;
        }
    }

    if (sections_created >= 1) {
        success = true;
    } else {
        fprintf(stderr, "ERROR: no code or data segments in '%s'\n", filename);
        success = false;
    }


cleanup:
    if (elf != NULL) {
        elf_end(elf);
    }
    if (fd != -1) {
        close(fd);
    }
    return success;
}
Exemple #13
0
void leaky::readSymbols(const char *fileName)
{
    int fd = ::open(fileName, O_RDONLY);
    if (fd < 0) {
	fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName,
		fileName);
	exit(-1);
    }

    elf_version(EV_CURRENT);
    Elf *elf = elf_begin(fd, ELF_C_READ, 0);
    if (!elf) {
	fprintf(stderr, "%s: \"%s\": has no symbol table\n", applicationName,
		fileName);
	exit(-1);
    }

    long alloced = 10000;
    Symbol* syms = (Symbol*) malloc(sizeof(Symbol) * 10000);
    Symbol* sp = syms;
    Symbol* last = syms + alloced;

    // Get each of the relevant sections and add them to the list of
    // symbols.
    Elf32_Ehdr *ehdr = elf32_getehdr(elf);
    if (!ehdr) {
	fprintf(stderr, "%s: elf library lossage\n", applicationName);
	exit(-1);
    }
#if 0
    Elf32_Half ndx = ehdr->e_shstrndx;
#endif

    Elf_Scn *scn = 0;
    int strtabndx = -1;
    for (int i = 1; (scn = elf_nextscn(elf, scn)) != 0; i++) {
	Elf32_Shdr *shdr = elf32_getshdr(scn);
#if 0
	char *name = elf_strptr(elf, ndx, (size_t) shdr->sh_name);
	printf("Section %s (%d 0x%x)\n", name ? name : "(null)",
	       shdr->sh_type, shdr->sh_type);
#endif
	if (shdr->sh_type == SHT_STRTAB) {
	    /* We assume here that string tables preceed symbol tables... */
	    strtabndx = i;
	    continue;
	}
#if 0
	if (shdr->sh_type == SHT_DYNAMIC) {
	    /* Dynamic */
	    Elf_Data *data = elf_getdata(scn, 0);
	    if (!data || !data->d_size) {
		printf("No data...");
		continue;
	    }

	    Elf32_Dyn *dyn = (Elf32_Dyn*) data->d_buf;
	    Elf32_Dyn *lastdyn =
		(Elf32_Dyn*) ((char*) data->d_buf + data->d_size);
	    for (; dyn < lastdyn; dyn++) {
		printf("tag=%d value=0x%x\n", dyn->d_tag, dyn->d_un.d_val);
	    }
	} else
#endif
	if ((shdr->sh_type == SHT_SYMTAB) ||
	    (shdr->sh_type == SHT_DYNSYM)) {
	    /* Symbol table */
	    Elf_Data *data = elf_getdata(scn, 0);
	    if (!data || !data->d_size) {
		printf("No data...");
		continue;
	    }

	    /* In theory we now have the symbols... */
	    Elf32_Sym *esym = (Elf32_Sym*) data->d_buf;
	    Elf32_Sym *lastsym =
		(Elf32_Sym*) ((char*) data->d_buf + data->d_size);
	    for (; esym < lastsym; esym++) {
#if 0
		char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
		printf("%20s 0x%08x %02x %02x\n",
		       nm, esym->st_value, ELF32_ST_BIND(esym->st_info),
		       ELF32_ST_TYPE(esym->st_info));
#endif
		if ((esym->st_value == 0) ||
		    (ELF32_ST_BIND(esym->st_info) == STB_WEAK) ||
		    (ELF32_ST_BIND(esym->st_info) == STB_NUM) ||
		    (ELF32_ST_TYPE(esym->st_info) != STT_FUNC)) {
		    continue;
		}
#if 1
		char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
#endif
		sp->name = nm ? strdup(nm) : "(no name)";
		sp->address = esym->st_value;
		sp++;
		if (sp >= last) {
		    long n = alloced + 10000;
		    syms = (Symbol*)
			realloc(syms, (size_t) (sizeof(Symbol) * n));
		    last = syms + n;
		    sp = syms + alloced;
		    alloced = n;
		}
	    }
	}
    }

    int interesting = sp - syms;
    if (!quiet) {
	printf("Total of %d symbols\n", interesting);
    }
    usefulSymbols = interesting;
    externalSymbols = syms;
}
Exemple #14
0
unsigned int *NWMouse_findcookie(char *filename)
{
	Elf			*elf_ptr; 
	int			fd; 
	Elf32_Ehdr		*ehdr; 
	Elf_Scn			*section; 
	Elf32_Shdr		*section_header;
	Elf32_Shdr		*code_header;
	unsigned char		*buffer, *entry; 
	unsigned char		*buffer_ptr; 
	unsigned char		*cookie_address; 
	struct		stat	statbuf; 

	static	unsigned int	calls[7]; 			/* Return things in this array */
	unsigned int		*ptr_calls; 
	int			instruction_size;
	struct 		instr 	instruction;

	int			i, j; 
	unsigned int		*table_ptr;
	int			done; 

	/* Dynamic Linking, we only use this stuff if we need it */

	void			*dlhandle; 

	dlhandle = dlopen("nwmouse/libdis/libdisasm.so", RTLD_NOW); 
	if( !dlhandle ) { 
		fprintf(stderr, "ERROR: NWMouse: (cookie) dlopen of libdisasm.so failed: %s\n", dlerror()); 
		abort(); 
	}

	NWMouse_disassemble_init_ptr = (int (*)())dlsym(dlhandle, "disassemble_init"); 
	if( NWMouse_disassemble_init_ptr == NULL ) { 
		fprintf(stderr, "ERROR: NWMouse: (cookie) dlsym(disassemble_init) failed: %s\n", dlerror()); 
		abort(); 
	}
	NWMouse_disassemble_address_ptr = (int (*)())dlsym(dlhandle, "disassemble_address"); 
	if( NWMouse_disassemble_address_ptr == NULL ) { 
		fprintf(stderr, "ERROR: NWMouse: (cookie) dlsym(disassemble_address) failed: %s\n", dlerror()); 
		abort(); 
	}
	NWMouse_disassemble_cleanup_ptr = (int (*)())dlsym(dlhandle, "disassemble_cleanup"); 
	if( NWMouse_disassemble_cleanup_ptr == NULL ) { 
		fprintf(stderr, "ERROR: NWMouse: (cookie) dlsym(disassemble_cleanup) failed: %s\n", dlerror()); 
		abort(); 
	}
	NWMouse_disassemble_init_ptr(0, INTEL_SYNTAX); 
		
/* Initialize the elves. */

	if (elf_version(EV_CURRENT) == EV_NONE) {
		fprintf(stderr, "ERROR: NWMouse: (cookie) libelf version mismatch.\n"); 
		abort(); 
	}

/* open library */ 	

	fd = open(filename, O_RDONLY); 
	if( fd < 0 ) { 
		fprintf(stderr, "ERROR: NWMouse: (cookie) Unable to open shared library: %s (%d)\n", filename, errno); 
		abort(); 
	}
	if( fstat(fd, &statbuf) < 0 ) { 
		fprintf(stderr, "ERROR: NWMouse: (cookie) Unable to stat shared library: %s (%d) Howd that happen?\n", filename, errno); 
		abort(); 
	}
	buffer = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
	if( buffer == NULL ) { 
		fprintf(stderr, "ERROR: NWMouse: (cookie) Unable to mmap executable: %s (%d)\n", filename, errno); 
		abort(); 
	}
	elf_ptr = elf_begin(fd, ELF_C_READ, (Elf *)0);
	if( elf_ptr == NULL) { 
		fprintf(stderr, "ERROR: NWMouse: (cookie) elf_begin failed: %s.\n", elf_errmsg(elf_errno())); 
		abort(); 
	} 

	/* Get the Header */
	if ( (ehdr = elf32_getehdr(elf_ptr)) == NULL) { 
		fprintf(stderr, "ERROR: NWMouse: (cookie) Unable to get Elf header: %s\n",  elf_errmsg(elf_errno()) ); 
		abort(); 
	}
	section = 0; 
	code_header = NULL; 
	while( (section = elf_nextscn( elf_ptr, section )) ) { 
		section_header = elf32_getshdr(section); 
		if( 	ehdr->e_entry >= section_header->sh_addr &&
			ehdr->e_entry < (section_header->sh_addr + section_header->sh_size)) {
				code_header = section_header; 
				break; 
		}
	}
	if( code_header == NULL ) { 
		fprintf(stderr, "ERROR: NWMouse: (cookie) Unable to locate appropriate code section.\n"); 
		abort(); 
	}

	/* Found start of program */
	entry = (unsigned char *)ehdr->e_entry - (code_header->sh_addr - code_header->sh_offset);
	fprintf(stderr, "NOTICE: NWMouse: (cookie) Entry point determined: %p\n", entry); 
	buffer_ptr = (unsigned char *) (int)entry + (int)buffer; 

	calls[0] = (NWMouse_search(buffer_ptr, (unsigned char *)ehdr->e_entry, code_header->sh_size, NWMouse_cookie0, 0, -1, 1))[0]; 
	fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie0 location: 0x%08x\n", (unsigned int)calls[0] + (unsigned int)code_header->sh_addr);

	ptr_calls = NWMouse_search(buffer_ptr, (unsigned char *)ehdr->e_entry, code_header->sh_size, NWMouse_cookie1, 0, 1, 1);

	calls[1] = ptr_calls[0]; 
	calls[2] = ptr_calls[1]; 

	instruction_size = NWMouse_disassemble_address_ptr((char *)buffer_ptr + calls[2], &instruction ); 
	if( ! instruction_size ) { 
		fprintf(stderr, "ERROR: NWMouse: (cookie) Curious: Invalid instruction disassembled: %08x\n", calls[2]); 
		fprintf(stderr, "ERROR: NWMouse: (cookie) This really shouldn't happen.\n"); 
		fprintf(stderr, "ERROR: NWMouse: (cookie)    Please contact David Holland ([email protected])\n"); 
		abort();
	}
	if( strcmp(instruction.mnemonic, "mov") || strtol( instruction.src, (char **)NULL, 16) < code_header->sh_addr ) { 
		fprintf(stderr, "ERROR: NWMouse: (cookie) Unexpected opcode found: %s %s\n", instruction.mnemonic, instruction.src); 
		fprintf(stderr, "ERROR: NWMouse: (cookie)    Please contact David Holland ([email protected])\n"); 
		abort();
	}
	calls[2] = strtol( instruction.src, (char **)NULL, 16);
	fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie1 location: 0x%08x\n", (unsigned int)calls[1] + (unsigned int)code_header->sh_addr);
	fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie2 location: 0x%08x\n", (unsigned int)calls[2]); 

	calls[3] = (NWMouse_search(buffer_ptr, (unsigned char *)ehdr->e_entry, code_header->sh_size, NWMouse_cookie2, 0, 1, 1))[0]; 
	fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie3 location: 0x%08x\n", (unsigned int)calls[3] + (unsigned int)code_header->sh_addr);

	calls[4] = (NWMouse_search(buffer_ptr, (unsigned char *)ehdr->e_entry, code_header->sh_size, NWMouse_cookie3, 0, 1, 1))[0]; 
	fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie4 location: 0x%08x\n", (unsigned int)calls[4] + (unsigned int)code_header->sh_addr);

	calls[5] = (NWMouse_search(buffer_ptr, (unsigned char *)ehdr->e_entry, code_header->sh_size, NWMouse_cookie4, 0, 1, 1))[1]; 
	fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie5 location: 0x%08x\n", (unsigned int)calls[5] + (unsigned int)code_header->sh_addr);

/* Calls "loaded".  Correct into virtual addresses */

	calls[0] = calls[0] + code_header->sh_addr; 		/* Function outside of end of table */
	calls[1] = calls[1] + code_header->sh_addr; 		/* Constructor */
	// calls[2] = calls[2] + code_header->sh_addr;  - Do not add to this one - Already corrected. /* Table Start */
	calls[3] = calls[3] + code_header->sh_addr; 		/* Render */
	calls[4] = calls[4] + code_header->sh_addr; 		/* Texture */
	calls[5] = calls[5] + code_header->sh_addr; 		/* Constructed object */

/* Find the Orientation function, ugh... */
	fprintf(stderr, "NOTICE: NWMouse: (cookie) Searching for proper Orientation function, this may take a while...\n"); 

/* Partially cloned from nwmouse.c */ 
	table_ptr = (void *)calls[2];
        i = 1; done = 0;
        while( table_ptr[i] != 0x0 && table_ptr[i] != calls[0] && !done ) {
		calls[6] = 
			(NWMouse_search(buffer_ptr, 			/* Secondary in memory copy 		*/
				(unsigned char *)ehdr->e_entry,		/* Kinda useless, unless _NOTDEF_ defd	*/
				table_ptr[i] - code_header->sh_addr + NWMouse_cookie5_size,	/* routine length. - hardcoded - blah 	*/
				NWMouse_cookie5, 			/* Search cookie			*/
				table_ptr[i] - code_header->sh_addr, 	/* start position 			*/
				1,					/* First occurance 			*/
				0					/* Abort if not found? 			*/
			))[0]; 
		if( calls[6] != 0 ) { 
			j = 0; 
			while( j < NWMouse_cookie5_size ) { 
				memset(&instruction, 0, sizeof(struct code));
				instruction_size = NWMouse_disassemble_address_ptr((char *)buffer_ptr + calls[6] + j, &instruction );
				if( !instruction_size ) { 

			fprintf(stderr, "ERROR: NWMouse: (cookie) Huh...: Invalid instruction disassembled: %08x\n", calls[2]); 
			fprintf(stderr, "ERROR: NWMouse: (cookie) This really shouldn't happen.\n"); 
			fprintf(stderr, "ERROR: NWMouse: (cookie)    Please contact David Holland ([email protected])\n"); 

					abort();

				}
				if( !strcmp(instruction.mnemonic, "mov") && 
					strtol( instruction.src, (char **)NULL, 16) == 0x4 &&
					!strcmp(instruction.dest, "ecx") ) { 
					done = 1; 
					j = NWMouse_cookie5_size; 
				}
				j += instruction_size; 
			}
		}
		i++; 
        }
	fprintf(stderr, "NOTICE: NWMouse: (cookie) Cookie6 location: 0x%08x\n", (unsigned int)calls[6] + (unsigned int)code_header->sh_addr);
	calls[6] = calls[6] + code_header->sh_addr; 		/* Set Orientation */

	elf_end(elf_ptr); 
	munmap(buffer, statbuf.st_size ); 
	close(fd); 
	dlclose(dlhandle); 
	return(calls); 
}
Exemple #15
0
u_long
symval(char *lib, char *name)
{
int fd;
int i, nsym;
u_long addr = 0;
Elf32_Shdr *shdr;
Elf *elf;
Elf_Scn *scn = (Elf_Scn *)0;
Elf32_Ehdr *ehdr;
Elf_Data *dp;
Elf32_Sym *symbol;
char *np;

fd = open(lib, O_RDONLY);
if (fd < 0) {
perror("open");
exit(1);
}

/* Initializations, see elf(3E) */
(void) elf_version(EV_CURRENT);
elf = elf_begin(fd, ELF_C_READ, 0);
if (elf == (Elf *)0)
elferr();

ehdr = elf32_getehdr(elf);
if (ehdr == (Elf32_Ehdr*)0)
elferr();

/*
* Loop through sections looking for the dynamic symbol table.
*/
while ((scn = elf_nextscn(elf, scn))) {

shdr = elf32_getshdr(scn);
if (shdr == (Elf32_Shdr *)0)
elferr();

if (shdr->sh_type == SHT_DYNSYM)
break;
}

if (scn == (Elf_Scn *)0) {
fprintf(stderr, "%s: dynamic symbol table not found\n", prog);
exit(1);
}

dp = elf_getdata(scn, (Elf_Data *)0);
if (dp == (Elf_Data *)0)
elferr();

if (dp->d_size == 0) {
fprintf(stderr, "%s: .dynamic symbol table empty\n", prog);
exit(1);
}

symbol = (Elf32_Sym *)dp->d_buf;
nsym = dp->d_size / sizeof (*symbol);

for (i = 0; i < nsym; i++) {
np = elf_strptr(elf, shdr->sh_link, (size_t)
symbol[i].st_name);
if (np && !strcmp(np, name))
break;

}

if (i < nsym)
addr = symbol[i].st_value;

(void) elf_end(elf);
(void) close(fd);

return (addr);
}
Exemple #16
0
// read symbol table from elf_file
struct symtab *build_symtab(const char *elf_file) {
  int fd;
  Elf *elf;
  Elf32_Ehdr *ehdr;
  char *names;
  struct symtab *symtab = NULL;

  if ((fd = open(elf_file, O_RDONLY)) < 0) {
    perror("open");
    return NULL;
  }

  elf = elf_begin(fd, ELF_C_READ, NULL);
  if (elf == NULL || elf_kind(elf) != ELF_K_ELF) {
    // not an elf
    close(fd);
    return NULL;
  }

  // read ELF header
  if ((ehdr = elf32_getehdr(elf)) != NULL) {
    Elf_Scn *scn;
    struct elf_section *scn_cache, *scn_cache_ptr;
    int cnt;

    // read section headers into scn_cache
    scn_cache = (struct elf_section *)
                malloc(ehdr->e_shnum * sizeof(struct elf_section));
    scn_cache_ptr = scn_cache;
    scn_cache_ptr++;

    for (scn = NULL; scn = elf_nextscn(elf, scn); scn_cache_ptr++) {
      scn_cache_ptr->c_shdr = elf32_getshdr(scn);
      scn_cache_ptr->c_data = elf_getdata(scn, NULL);
    }

    for (cnt = 1; cnt < ehdr->e_shnum; cnt++) {
      Elf32_Shdr *shdr = scn_cache[cnt].c_shdr;

      if (shdr->sh_type == SHT_SYMTAB) {
        Elf32_Sym  *syms;
        int j, n, rslt;
        size_t size;

        // FIXME: there could be multiple data buffers associated with the
        // same ELF section. Here we can handle only one buffer. See man page
        // for elf_getdata on Solaris.

        guarantee(symtab == NULL, "multiple symtab");
        symtab = (struct symtab *)calloc(1, sizeof(struct symtab));

        // the symbol table
        syms = (Elf32_Sym *)scn_cache[cnt].c_data->d_buf;

        // number of symbols
        n = shdr->sh_size / shdr->sh_entsize;

        // create hash table, we use hcreate_r, hsearch_r and hdestroy_r to
        // manipulate the hash table.
        symtab->hash_table = calloc(1, sizeof(struct hsearch_data));
        rslt = hcreate_r(n, symtab->hash_table);
        guarantee(rslt, "unexpected failure: hcreate_r");

        // shdr->sh_link points to the section that contains the actual strings
        // for symbol names. the st_name field in Elf32_Sym is just the
        // string table index. we make a copy of the string table so the
        // strings will not be destroyed by elf_end.
        size = scn_cache[shdr->sh_link].c_data->d_size;
        symtab->strs = (char *)malloc(size);
        memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data->d_buf, size);

        // allocate memory for storing symbol offset and size;
        symtab->symbols = (struct elf_symbol *)malloc(n * sizeof(struct elf_symbol));

        // copy symbols info our symtab and enter them info the hash table
        for (j = 0; j < n; j++, syms++) {
          ENTRY item, *ret;
          char *sym_name = symtab->strs + syms->st_name;

          symtab->symbols[j].name   = sym_name;
          symtab->symbols[j].offset = syms->st_value;
          symtab->symbols[j].size   = syms->st_size;

          // skip empty strings
          if (*sym_name == '\0') continue;

          item.key = sym_name;
          item.data = (void *)&(symtab->symbols[j]);

          hsearch_r(item, ENTER, &ret, symtab->hash_table);
        }
      }
    }

    free(scn_cache);
  }

  elf_end(elf);
  close(fd);

  return symtab;
}
Exemple #17
0
/* Extract ROM code+data from an ELF file and convert it into a C array */
int main(int argc,char *argv[])
{   
   unsigned char buffer[8];
   m_uint32_t vaddr,start;
   Elf32_Ehdr *ehdr;
   Elf32_Phdr *phdr;
   Elf *img_elf;
   size_t len,clen;
   int i,j,fd;
   FILE *bfd,*fd_out;

   if (argc != 4) {
      fprintf(stderr,"Usage: %s <input_file> <output_file> <addr>\n",argv[0]);
      exit(EXIT_FAILURE);
   }

   start = strtoul(argv[3],NULL,0);

   if ((fd = open(argv[1],O_RDONLY)) == -1)
      return(-1);

   if (elf_version(EV_CURRENT) == EV_NONE) {
      fprintf(stderr,"load_elf_image: library out of date\n");
      return(-1);
   }

   if (!(img_elf = elf_begin(fd,ELF_C_READ,NULL))) {
      fprintf(stderr,"load_elf_image: elf_begin: %s\n",
              elf_errmsg(elf_errno()));
      return(-1);
   }

   if (!(phdr = elf32_getphdr(img_elf))) {
      fprintf(stderr,"load_elf_image: elf32_getphdr: %s\n",
              elf_errmsg(elf_errno()));
      return(-1);
   }

   if (!(fd_out = fopen(argv[2],"w"))) {
      fprintf(stderr,"Unable to create file \"%s\"\n",argv[2]);
      exit(EXIT_FAILURE);
   }

   ehdr = elf32_getehdr(img_elf);
   phdr = elf32_getphdr(img_elf);

   printf("Extracting ROM from ELF file '%s'...\n",argv[1]);
   bfd = fdopen(fd,"r");

   if (!bfd) {
      perror("load_elf_image: fdopen");
      return(-1);
   }

   for(i=0;i<ehdr->e_phnum;i++,phdr++)
   {
      fseek(bfd,phdr->p_offset,SEEK_SET);

      vaddr = (m_uint64_t)phdr->p_vaddr;
      len = phdr->p_filesz;

      if (vaddr != start)
         continue;

      while(len > 0)
      {
         clen = fread(buffer,1,sizeof(buffer),bfd);

         if (clen == 0)
            break;

         fprintf(fd_out,"   ");

         for(j=0;j<clen;j++)
            fprintf(fd_out,"0x%2.2x, ",buffer[j]);

         fprintf(fd_out,"\n");
         len -= clen;
      }
   }

   fclose(fd_out);
   return(0);
}
Exemple #18
0
int
main (int argc, char *argv[])
{
  Elf *elf;
  int result = 0;
  int fd;
  char fname[] = "newfile-XXXXXX";

  fd = mkstemp (fname);
  if (fd == -1)
    {
      printf ("cannot create temporary file: %m\n");
      exit (1);
    }
  /* Remove the file when we exit.  */
  unlink (fname);

  elf_version (EV_CURRENT);
  elf = elf_begin (fd, ELF_C_WRITE, NULL);
  if (elf == NULL)
    {
      printf ("elf_begin: %s\n", elf_errmsg (-1));
      result = 1;
    }
  else
    {
      if (elf32_newehdr (elf) == NULL)
	{
	  printf ("elf32_newehdr: %s\n", elf_errmsg (-1));
	  result = 1;
	}
      else
        {
	  Elf32_Ehdr *ehdr = elf32_getehdr (elf);

	  if (ehdr == NULL)
	    {
	      printf ("elf32_getehdr: %s\n", elf_errmsg (-1));
	      result = 1;
	    }
	  else
	    {
	      int i;

	      if (argc > 1)
		/* Use argc as a debugging flag.  */
		print_ehdr (ehdr);

	      /* Some tests.  */
	      for (i = 0; i < EI_NIDENT; ++i)
		if (ehdr->e_ident[i] != 0)
		  {
		    printf ("ehdr->e_ident[%d] != 0\n", i);
		    result = 1;
		    break;
		  }

#define VALUE_TEST(name, val) \
	      if (ehdr->name != val)					      \
	        {							      \
		  printf ("ehdr->%s != %d\n", #name, val);		      \
		  result = 1;						      \
		}
#define ZERO_TEST(name) VALUE_TEST (name, 0)
	      ZERO_TEST (e_type);
	      ZERO_TEST (e_machine);
	      ZERO_TEST (e_version);
	      ZERO_TEST (e_entry);
	      ZERO_TEST (e_phoff);
	      ZERO_TEST (e_shoff);
	      ZERO_TEST (e_flags);
	      ZERO_TEST (e_ehsize);
	      ZERO_TEST (e_phentsize);
	      ZERO_TEST (e_phnum);
	      ZERO_TEST (e_shentsize);
	      ZERO_TEST (e_shnum);
	      ZERO_TEST (e_shstrndx);

	      if (elf32_newphdr (elf, 10) == NULL)
		{
		  printf ("elf32_newphdr: %s\n", elf_errmsg (-1));
		  result = 1;
		}
	      else
		{
		  if (argc > 1)
		    print_ehdr (ehdr);

		  ehdr = elf32_getehdr (elf);
		  if (ehdr == NULL)
		    {
		      printf ("elf32_getehdr (#2): %s\n", elf_errmsg (-1));
		      result = 1;
		    }
		  else
		    {
		      ZERO_TEST (e_type);
		      ZERO_TEST (e_machine);
		      ZERO_TEST (e_version);
		      ZERO_TEST (e_entry);
		      ZERO_TEST (e_phoff);
		      ZERO_TEST (e_shoff);
		      ZERO_TEST (e_flags);
		      ZERO_TEST (e_ehsize);
		      VALUE_TEST (e_phentsize, (int) sizeof (Elf32_Phdr));
		      VALUE_TEST (e_phnum, 10);
		      ZERO_TEST (e_shentsize);
		      ZERO_TEST (e_shnum);
		      ZERO_TEST (e_shstrndx);
		    }
		}
	    }
        }

      (void) elf_end (elf);
    }

  return result;
}
Exemple #19
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;
}
Exemple #20
0
static OBJECT_FILE *object_open( const char *file_name )
{
    OBJECT_FILE *file;
    Elf_Scn *section;
    Elf_Data *symtab;
    Elf32_Shdr *shdr;
    int compare;

    // search for the file in the list of already open objects
    for (file = objects ; file ; file = file->next_object)
    {
        compare = strcmp( file_name, file->name );
        if ( compare == 0 ) // if we found it
        {
            return file;
        }
        else if ( compare < 0 )  // if we didn't find it
        {
            break;
        }
    }

    // try to add a new file to the list of open objects
    file = (OBJECT_FILE *)malloc( sizeof(OBJECT_FILE) );
    assert(file);
    if ( file )
    {
        memset( file, 0, sizeof(*file) );
        if ((file->fd = open(file_name, O_RDONLY | O_BINARY)) != -1)
        {
            file->elf = elf_begin(file->fd, ELF_C_READ, NULL);
            if (file->elf)
            {
                file->ehdr = elf32_getehdr(file->elf);
                if (file->ehdr)
                {
                    if ( file->ehdr->e_machine == out_file_machine )
                    {
                        Elf_Data *string_data;
                        OBJECT_FILE **scan;
                        int compare;

                        exec_getsection( file->elf, file->ehdr->e_shstrndx,
                                         NULL, &string_data );
                        file->strings = (char *)string_data->d_buf;
                        file->name = strdup( file_name );

                        section = NULL;
                        while ((section =
                                elf_nextscn(file->elf, section)) != 0)
                        {
                            shdr = elf32_getshdr(section);
                            elfcheck( shdr != NULL );
                            if (shdr->sh_type == SHT_SYMTAB)
                            {
                                symtab = exec_getdata(section);
                                file->symbols = symtab->d_buf;
                                file->symbol_count = symtab->d_size /
                                    sizeof(Elf32_Sym);
                                file->first_global = shdr->sh_info;
                                file->string_index = shdr->sh_link;
                                if ( file->symbol_count > max_symbols )
                                {
                                    max_symbols = file->symbol_count;
                                }
                                break;
                            }
                        }

                        // ordered insert into the file list
                        assert( file->name );
                        for ( scan = &objects ; *scan ;
                              scan = &(*scan)->next_object )
                        {
                            compare = strcmp(file_name, (*scan)->name );
                            // if this file already exists we should have found
                            // it instead of creating it
                            assert( compare != 0 );
                            if (compare < 0)
                            {
                                break;
                            }
                        }
                        file->next_object = *scan;
                        *scan = file;
                        return file;
                    }
                    else
                    {
                        yyerror(
                            "Input file machine type doesn't match architecture" );
                    }
                }
                else
                {
                    yyerror( "File %s is not a valid ELF file: %s",
                             file_name, elf_errmsg(-1) );
                }
                elf_end(file->elf);
            }
            else
            {
                yyerror( "Elf_begin on %s failed: %s",
                         file_name, elf_errmsg(-1) );
            }
            close( file->fd );
        }
        else
        {
            yyerror( "File %s not found", file_name );
        }
        free( file );
        file = NULL;
    }
    return file;
}
Exemple #21
0
Func_DWARF *SET_fill_func_dwarf(char *name, uint32_t *func_addr, int len, uint32_t off)
{
    int fd;
    Elf_Cmd cmd;
    Elf *arf;   /* Used for an archive */
    Elf *elf;
    int ret;

    if (elf_version(EV_CURRENT) == EV_NONE)
    {
        fprintf(stderr, "SET dwarf: libelf.a is out of date\n");
        return NULL;
    }

    fd = open(name, O_RDONLY);
    if (fd == -1)
    {
        fprintf(stderr, "SET dwarf: Cannot open %s\n", name);
        return NULL;
    }

    /* Function DWARF table */
    func_dwarf = (Func_DWARF *) malloc(sizeof(Func_DWARF) * len);
    if (func_dwarf == NULL)
    {
        fprintf(stderr, "SET dwarf: No memory space to allocate DWARF table!\n");
        close(fd);
        return NULL;
    }
    memset(func_dwarf, 0, sizeof(Func_DWARF) * len);

    local_func_addr = func_addr;
    local_func_len = len;
    local_offset = off;

    cmd = ELF_C_READ;
    arf = elf_begin(fd, cmd, NULL);
    while ((elf = elf_begin(fd, cmd, arf)) != NULL)
    {
        Elf32_Ehdr *eh32;

        eh32 = elf32_getehdr(elf);
        if (eh32 == NULL)
        {
            fprintf(stderr, "SET dwarf: %s is not a 32-bit ELF file\n", name);
            goto fail;
        }
        else
        {
            ret = process_one_file(elf);
            if (ret != 0)
                goto fail;
        }

        cmd = elf_next(elf);
        elf_end(elf);
    }
    elf_end(arf);
    close(fd);
    return func_dwarf;

fail:
    elf_end(elf);
    elf_end(arf);
    free(func_dwarf);
    close(fd);
    return NULL;
}
Exemple #22
0
u_long
plt_offset(char *lib, char *func)
{
int fd;
Elf *elf;
Elf_Scn *scn = (Elf_Scn *)0;
Elf_Data *dp;
Elf32_Ehdr *ehdr;
Elf32_Rela *relocp = (Elf32_Rela *)0;
Elf32_Word pltsz = 0;
Elf32_Shdr *shdr;
Elf_Scn *symtab;
Elf32_Sym *symbols;
char *np;
u_long offset = 0;
u_long plt;

fd = open(lib, O_RDONLY);
if (fd < 0) {
perror("open");
exit(1);
}

/* Initializations, see elf(3E) */
(void) elf_version(EV_CURRENT);
elf = elf_begin(fd, ELF_C_READ, 0);
if (elf == (Elf *)0)
elferr();

ehdr = elf32_getehdr(elf);
if (ehdr == (Elf32_Ehdr *)0)
elferr();

/*
* Loop through sections looking for the relocation entries
* associated with the procedure linkage table.
*/
while ((scn = elf_nextscn(elf, scn))) {

shdr = elf32_getshdr(scn);
if (shdr == (Elf32_Shdr *)0)
elferr();

if (shdr->sh_type == SHT_RELA) {
np = elf_strptr(elf, ehdr->e_shstrndx, (size_t) shdr->sh_name);
if (np && !strcmp(np, ".rela.plt"))
break;
}

}

if (scn == (Elf_Scn *)0) {
fprintf(stderr, "%s: .rela.plt section not found\n", prog);
exit(1);
}

dp = elf_getdata(scn, (Elf_Data *)0);
if (dp == (Elf_Data *)0)
elferr();

if (dp->d_size == 0) {
fprintf(stderr, "%s: .rela.plt section empty\n", prog);
exit(1);
}

/*
* The .rela.plt section contains an array of relocation entries,
* the first 4 are not used.
*/
relocp = (Elf32_Rela *)dp->d_buf;
pltsz = dp->d_size / sizeof (*relocp);

relocp += 4;
pltsz -= 4;

/*
* Find the symbol table associated with this section.
*/
symtab = elf_getscn(elf, shdr->sh_link);
if (symtab == (Elf_Scn *)0)
elferr();

shdr = elf32_getshdr(symtab);
if (shdr == (Elf32_Shdr *)0)
elferr();

dp = elf_getdata(symtab, (Elf_Data *)0);
if (dp == (Elf_Data *)0)
elferr();

if (dp->d_size == 0) {
fprintf(stderr, "%s: dynamic symbol table empty\n", prog);
exit(1);
}

symbols = (Elf32_Sym *)dp->d_buf;

/*
* Loop through the relocation list, looking for the desired
* symbol.
*/
while (pltsz-- > 0) {
Elf32_Word ndx = ELF32_R_SYM(relocp->r_info);

np = elf_strptr(elf, shdr->sh_link, (size_t)
symbols[ndx].st_name);
if (np && !strcmp(np, func))
break;

relocp++;
}

if (relocp) {
plt = symval(lib, PLT_SYMBOL);
offset = relocp->r_offset - plt;
}

(void) elf_end(elf);
(void) close(fd);

return (offset);
}
Exemple #23
0
static void print_relocinfo_32 (Dwarf_Debug dbg, Elf *elf)
{
    Elf_Scn *scn = NULL;
    Elf_Data *data;
    Elf32_Ehdr      *ehdr32;
    Elf32_Shdr      *shdr32;
    char *scn_name;
    int i;

    if ((ehdr32 = elf32_getehdr(elf)) == NULL) {
	print_error(dbg, "DW_ELF_GETEHDR_ERROR",DW_DLV_OK, err); 
    }
    while ((scn = elf_nextscn(elf, scn)) != NULL) {
	if ((shdr32 = elf32_getshdr(scn)) == NULL) {
	    print_error(dbg, "DW_ELF_GETSHDR_ERROR",DW_DLV_OK, err); 
	}
	if ((scn_name = elf_strptr(elf,ehdr32->e_shstrndx, shdr32->sh_name)
	     ) == NULL) {
	    print_error(dbg, "DW_ELF_STRPTR_ERROR",DW_DLV_OK, err); 
	}
	if (shdr32->sh_type == SHT_SYMTAB) {
	    size_t sym_size = 0;
	    size_t count = 0;
	    if ((sym = (Elf32_Sym *) get_scndata(scn, &sym_size)) == NULL) {
		print_error(dbg, "no symbol table data",DW_DLV_OK, err); 
	    }
	    sym = (Elf32_Sym *) get_scndata(scn, &sym_size);
	    count = sym_size / sizeof (Elf32_Sym);
	    sym ++;
	    if ((sym_data = readsyms(sym, count, elf, 
				     shdr32->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_32(i, sect_data[i].buf, sect_data[i].size);
	}
    }
}
Exemple #24
0
void *NWMovies_lookup_symbol(char *filename, char *function)
{
	Elf		*elf_ptr; 
	int		fd; 
	Elf32_Ehdr	*ehdr; 
	Elf_Scn		*section; 
	Elf32_Shdr	*section_header;
	Elf32_Sym	*symtab_start, *symtab_current; 
	int		symtab_count, i; 
	char		*strtab; 
	int		strtab_type; 

	char		*symstrtab; 
	void		*return_val; 
		
/* Initialize the elves. */

	if (elf_version(EV_CURRENT) == EV_NONE) {
		fprintf(stderr, "ERROR: NWMovies: libelf version mismatch.\n"); 
		abort(); 
	}

/* open shared library */ 	

	fd = open(filename, O_RDONLY); 
	if( fd < 0 ) { 
		fprintf(stderr, "ERROR: NWMovies: Unable to open shared library: %s (%d)\n", filename, errno); 
		abort(); 
	}
	elf_ptr = elf_begin(fd, ELF_C_READ, (Elf *)0);
	if( elf_ptr == NULL) { 
		fprintf(stderr, "ERROR: NWMovies: elf_begin failed: %s.\n", elf_errmsg(elf_errno())); 
		abort(); 
	} 

	/* Get the Header */
	if ( (ehdr = elf32_getehdr(elf_ptr)) == NULL) { 
		fprintf(stderr, "ERROR: NWMovies: Unable to get Elf header: %s\n",  elf_errmsg(elf_errno()) ); 
		abort(); 
	}
	/* Find the section string table */
	section = elf_getscn(elf_ptr, ehdr->e_shstrndx); 
	symstrtab = elf_getdata(section, NULL)->d_buf; 

	section = 0; 
	symtab_start = NULL; 
	strtab = NULL; 
	strtab_type = -1; 
	while( (section = elf_nextscn( elf_ptr, section )) ) { 
		section_header = elf32_getshdr(section); 
		/* DYNSYM is better than nothing */
		if( symtab_start == NULL && section_header->sh_type == SHT_DYNSYM ) { 
			symtab_start = elf_getdata(section, NULL)->d_buf; 
			symtab_count = section_header->sh_size / section_header->sh_entsize;
			strtab_type = 0; 
		} 
		/* However, we prefer SYMTAB */ 
		if(  section_header->sh_type == SHT_SYMTAB ) {
			symtab_start = elf_getdata(section, NULL)->d_buf;
			symtab_count = section_header->sh_size / section_header->sh_entsize;
			strtab_type = 1; 
		}
	}

	if( strtab_type == -1 ) {
		fprintf(stderr, "ERROR: NWMovies: didn't find any symbol tables. Positively won't work.\n");
		fprintf(stderr, "ERROR: NWMovies: Try a different %s library\n", filename); 
		abort(); 
	}

	section = 0; 
	while((section = elf_nextscn(elf_ptr, section))) { 
		section_header = elf32_getshdr(section); 
		if( section_header->sh_type == SHT_STRTAB ) { 
			if( strtab_type == 0 && strcmp(section_header->sh_name + symstrtab, ".dynstr") == 0 ) { 
				strtab = elf_getdata(section, NULL)->d_buf; 
				break; 
			}
			if( strtab_type == 1 && strcmp(section_header->sh_name + symstrtab, ".strtab") == 0 ) { 
				strtab = elf_getdata(section, NULL)->d_buf; 
				break;
			}
		}
	}
	symtab_current = symtab_start; 
	for(i=0; i<symtab_count; i++) { 
		// fprintf(stderr, "DEBUG: INDEX: %d: %d\n", i, symtab_current->st_name); 
		if( symtab_current->st_name != 0 ) { 
			// fprintf(stderr, "DEBUG: Testing: %s\n", symtab_current->st_name + strtab); 
			if( ! strcmp(symtab_current->st_name+strtab,function) ) { 
				break; 
			}
		}
		symtab_current++;
	}
	if( i >= symtab_count ) {
			elf_end(elf_ptr); 
			close(fd); 
			return(NULL); 
	} else { 
		return_val = (void *)symtab_current->st_value; 
		elf_end(elf_ptr); 
		close(fd); 
		return(return_val); 
	}
}
Exemple #25
0
static int
_elf_nlist(Elf *elf, struct nlist *nl) {
    Elf_Scn *symtab = NULL;
    Elf_Scn *strtab = NULL;
    Elf_Data *symdata;
    Elf_Data *strdata;
    Elf32_Ehdr *ehdr;
    Elf32_Shdr *shdr;
    Elf_Scn *scn;
    Elf32_Sym *symbols;
    const char *strings;
    unsigned nsymbols;
    unsigned nstrings;
    unsigned i;
    const char *name;
    struct hash *table;
    unsigned nhash;
    unsigned long hash;
    unsigned long j;
    long val;

    if (!(ehdr = elf32_getehdr(elf))) {
	return -1;
    }
    scn = NULL;
    elf_errno();
    while ((scn = elf_nextscn(elf, scn))) {
	if (!(shdr = elf32_getshdr(scn))) {
	    return -1;
	}
	if (shdr->sh_type != SHT_SYMTAB && shdr->sh_type != SHT_DYNSYM) {
	    continue;
	}
	symtab = scn;
	strtab = elf_getscn(elf, shdr->sh_link);
	if (shdr->sh_type == SHT_SYMTAB) {
	    break;
	}
    }
    if (elf_errno()) {
	return -1;
    }
    symdata = elf_getdata(symtab, NULL);
    strdata = elf_getdata(strtab, NULL);
    if (!symdata || !strdata) {
	return -1;
    }
    symbols = (Elf32_Sym*)symdata->d_buf;
    strings = (const char*)strdata->d_buf;
    nsymbols = symdata->d_size / sizeof(Elf32_Sym);
    nstrings = strdata->d_size;
    if (!symbols || !strings || !nsymbols || !nstrings) {
	return -1;
    }

    /*
     * build a simple hash table
     */
    nhash = 3 * nsymbols - 4;
    if (!(table = (struct hash*)malloc(nhash * sizeof(*table)))) {
	return -1;
    }
    for (i = 0; i < nhash; i++) {
	table[i].name = NULL;
	table[i].sym = NULL;
    }
    for (i = 1; i < nsymbols; i++) {
	if (symbols[i].st_name < 0 || symbols[i].st_name >= nstrings) {
	    free(table);
	    return -1;
	}
	if (symbols[i].st_name == 0) {
	    continue;
	}
	name = strings + symbols[i].st_name;
	hash = elf_hash(name);
	for (j = hash; table[j %= nhash].name; j += 3) {
	    if (table[j].hash != hash) {
		continue;
	    }
	    if (table[j].name == name || !strcmp(table[j].name, name)) {
		break;
	    }
	}
	table[j].hash = hash;
	table[j].name = name;
	table[j].sym = &symbols[i];
    }

    /*
     * symbol lookup
     */
    for (i = 0; (name = nl[i].n_name) && *name ; i++) {
      val = nl[i].n_value;

      if (!strcmp("__UNKNOWN__", name)) {
	for (j=0; j < nhash; j++) 
	  if ((table[j].sym != NULL) && (table[j].sym->st_value == val)) {
	    break;
	  }
	if (j != nhash) {
	  if ((nl[i].n_name = malloc(strlen(table[j].name)+1)) == NULL) 
	    return -1;
	    
	  strcpy(nl[i].n_name,table[j].name);
	  nl[i].n_scnum = table[j].sym->st_shndx;
	}
	else {
	  nl[i].n_name = NULL;
	  nl[i].n_scnum = 0;
	}
      }
      else {
	hash = elf_hash(name);
	for (j = hash; table[j %= nhash].name; j += 3) {
	  if ( (table[j].hash == hash) && (!strcmp(table[j].name, name)) )  {
	    break;
	  }
	}
	
	
	if (table[j].name) {
	    nl[i].n_value = table[j].sym->st_value;
	    nl[i].n_scnum = table[j].sym->st_shndx;
	}
	else {
	    nl[i].n_value = 0;
	    nl[i].n_scnum = 0;
	}
      }
	/*
	 * this needs more work
	 */
	nl[i].n_type = 0;
	nl[i].n_sclass = 0;
	nl[i].n_numaux = 0;
    }
    free(table);
    return 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;
}
Exemple #27
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");
}
Exemple #28
0
int ar_diff(int fd1, int fd2, char *sections, int verbose) {
  int i=0, retval = ED_SUCCESS;
  Elf *arf[2];
  Elf *elf[2];
  Elf_Cmd cmd[2];

  if ((arf[0] = elf_begin(fd1,ELF_C_READ,NULL))==NULL) {
    if (verbose) fprintf(stderr, "elfdiff: Error reading AR information from first input file.\n");
    return ED_ELFFAIL;
  }

  if ((arf[1] = elf_begin(fd2,ELF_C_READ,NULL))==NULL) {
    if (verbose) fprintf(stderr, "elfdiff: Error reading AR information from second input file.\n");
    elf_end(elf[0]);
    return ED_ELFFAIL;
  }

  if (arf[0]->e_numsyms != arf[1]->e_numsyms) { 
    retval = ED_HDRFAIL;
  } else {

    ////////////////////////////////////////////////////////
    //FIXME: this section should correlate the items by name
    ////////////////////////////////////////////////////////

    cmd[0] = cmd[1] = ELF_C_READ;

    while (((elf[0] = elf_begin(fd1, cmd[0], arf[0])) != 0) && !retval) {
      if (elf32_getehdr(elf[0]) != 0) {

        while ((elf[1] = elf_begin(fd2, cmd[1], arf[1])) != 0) {
          if (elf32_getehdr(elf[1]) != 0) {

            if (strcmp(elf[0]->e_arhdrp->ar_name, elf[1]->e_arhdrp->ar_name) != 0) {
              if (verbose>1) fprintf(stderr, "elfdiff: Internal object order does not match.  ('%s' != '%s')\n", elf[0]->e_arhdrp->ar_name, elf[1]->e_arhdrp->ar_name);
              retval = ED_HDRFAIL;
            } else {
              retval = ohdr_diff(elf, verbose);
              if (!retval && sections) retval=shdr_diff(elf, sections, verbose);
              if (retval) {
                if (verbose>1) fprintf(stderr, "elfdiff: Internal object '%s' - FAIL\n", elf[0]->e_arhdrp->ar_name);
              } else {
                if (verbose>1) fprintf(stdout, "elfdiff: Internal object '%s'- PASS\n", elf[0]->e_arhdrp->ar_name);
              }
            }

            cmd[1]=elf_next(elf[1]);
            elf_end(elf[1]);
            break;
          }
          cmd[1]=elf_next(elf[1]);
          elf_end(elf[1]);
        }

      }
      cmd[0]=elf_next(elf[0]);
      elf_end(elf[0]);
    }

  }

  for (i=0;i<2;i++) {
    elf_end(arf[i]);
  }
 
  if (verbose) {
    if (retval) {
      fprintf(stderr, "elfdiff: Files do not match\n");
    } else {
      printf("elfdiff: Files match.\n");
    }
  }

  return retval;
}
Exemple #29
0
//--------------------------------------------------------------------------------
static int convElfToMiniFile(char* elffilename, char* melffilename)
{
  int fdelf, fdmelf, modhdrsymndx;
  Elf* elf;
  Elf32_Ehdr *ehdr;
  Elf_Scn *relatextscn, *textscn, *symtabscn, *strtabscn;
  
  Melf_Scn *m_relatextscn, *m_textscn, *m_symtabscn;
  Melf* melf;
  symbol_map_t* symmap;
  Melf_Data *relatextdata, *symtabdata, *textdata;
  symbol_map_t symmap_storage;

  printf("ELF File: %s\n", elffilename);
  printf("Mini-ELF File: %s\n", melffilename);
  
  symmap = &symmap_storage;
  // Open ELF file for reading
  if ((fdelf = open(elffilename, O_RDONLY)) < 0){
    fprintf(stderr, "%s: ", elffilename);
    perror("convElfToMini -> fopen: ");
    exit(EXIT_FAILURE);
  }

  // Open Mini-ELF file for writing
  if ((fdmelf = open(melffilename, (O_RDWR | O_CREAT | O_EXCL), (S_IRWXU | S_IRWXG | S_IRWXO))) < 0){
    fprintf(stderr, "%s: ", melffilename);
    perror("convElfToMini -> fopen: ");
    exit(EXIT_FAILURE);
  }

  // Check version of ELF Library
  if (elf_version(EV_CURRENT) == EV_NONE){
    fprintf(stderr, "Library version is out of date.\n");
    exit(EXIT_FAILURE);
  }

  // Get the ELF descriptor
  elf = elf_begin(fdelf, ELF_C_READ, NULL);
  if (NULL == elf){
    fprintf(stderr, "elf_begin: Error getting elf descriptor\n");
    exit(EXIT_FAILURE);
  }

  // Ensure that it is an ELF format file
  if (elf_kind(elf) != ELF_K_ELF){
    fprintf(stderr, "This program can only read ELF format files.\n");
    exit(EXIT_FAILURE);
  }

  // Get the ELF Header
  ehdr = elf32_getehdr(elf);
  if (NULL == ehdr){
    fprintf(stderr, "Error reading ELF header\n");
    exit(EXIT_FAILURE);
  }

  // Verify if the ELF is AVR specific
  if (ehdr->e_machine != EM_AVR && ehdr->e_machine != EM_MSP430){
    fprintf(stderr, "This ELF binary is not supported.\n");
    exit(EXIT_FAILURE);
  }
  e_machine = ehdr->e_machine;
                                                         
  // Create a new Mini-ELF (MELF) descriptor
  if ((melf = melf_new(fdmelf)) == NULL){
    fprintf(stderr, "Error creating a new MELF descriptor\n");
    exit(EXIT_FAILURE);
  }

  // Get the pointer to .symtab section
  if ((symtabscn = getELFSectionByName(elf, ".symtab")) == NULL){
    fprintf(stderr, "Error getting .symtab section.\n");
    exit(EXIT_FAILURE);
  }

  // Get the pointer to .rela.text section
  /*
  if ((relatextscn = getELFSectionByName(elf, ".rela.text")) == NULL){
    fprintf(stderr, "Error getting .rela.text section.\n");
    exit(EXIT_FAILURE);
  }
  */
  relatextscn = getELFSectionByName(elf, ".rela.text");

  // Get the pointer to .text section
  if ((textscn = getELFSectionByName(elf, ".text")) == NULL){
    fprintf(stderr, "Error getting .text section.\n");
    exit(EXIT_FAILURE);
  }
  
  if ((strtabscn = getELFSectionByName(elf, ".strtab")) == NULL ) {
	fprintf(stderr, "Error getting .strtab section. \n");
	exit(EXIT_FAILURE);
  }

  // DEBUG info. to verify we have the correct sections
  DEBUG("Section Number (.text): %d\n", (int)elf_ndxscn(textscn));
  if( relatextscn != NULL ) {
	  DEBUG("Section Number (.rela.text): %d\n", (int)elf_ndxscn(relatextscn));
  }
  DEBUG("Section Number (.symtab): %d\n", (int)elf_ndxscn(symtabscn));

  // Initialize Symbol Map
  if (initSymbolMap(symmap, symtabscn) < 0){
    fprintf(stderr, "Error initializing symbol map.\n");
    exit(EXIT_FAILURE);
  }
  
  //
  // Set string table to symbol map
  //
  addStrTabToSymbolMap( symmap, strtabscn );
  addTxtScnToSymbolMap( symmap, textscn );
  

  // Convert Relocation Table
  // Simon: convert relocation before text section
  //        because some symbols will be patched in .text section
  if( relatextscn != NULL ) {
  if ((relatextdata = convRelaScn(relatextscn, symmap)) == NULL){
    fprintf(stderr, "Error converting Rela table.\n");
    exit(EXIT_FAILURE);
  }
  }

  // Convert Text Section
  if ((textdata = convProgbitsScn(textscn)) == NULL){
    fprintf(stderr, "Error converting text section.\n");
    exit(EXIT_FAILURE);
  }

  // Add mod_header symbol
  if ((modhdrsymndx = getELFSymbolTableNdx(elf, "mod_header")) == -1){
    fprintf(stderr, "Could not locate symbol: mod_header. Not a valid SOS module\n");
    exit(EXIT_FAILURE);
  }
  addMelfSymbol(symmap, modhdrsymndx);
  melf_setModHdrSymNdx(melf, symmap->etommap[modhdrsymndx]);

  // Convert Symbol Table
  if ((symtabdata = convSymScn(symmap)) == NULL){
    fprintf(stderr, "Error convering symbol table.\n");
    exit(EXIT_FAILURE);
  }
  
  // Create a new MELF Symbol table section
  if ((m_symtabscn = melf_new_scn(melf)) == NULL){
    fprintf(stderr, "Error creating symbol table MELF section.\n");
    exit(EXIT_FAILURE);
  }
  convElfHdr(m_symtabscn, symtabscn);
  melf_add_data_to_scn(m_symtabscn, symtabdata);

  // Create a new MELF Relocation table section
  if( relatextscn != NULL ) {
  if ((m_relatextscn = melf_new_scn(melf)) == NULL){
    fprintf(stderr, "Error creating relocation table MELF section.\n");
    exit(EXIT_FAILURE);
  }
  convElfHdr(m_relatextscn, relatextscn);
  melf_add_data_to_scn(m_relatextscn, relatextdata);
  }

  // Create a new MELF Symbol table section
  if ((m_textscn = melf_new_scn(melf)) == NULL){
    fprintf(stderr, "Error creating .text MELF section.\n");
    exit(EXIT_FAILURE);
  }
  convElfHdr(m_textscn, textscn);
  melf_add_data_to_scn(m_textscn, textdata);
  
  // Sort the MELF Sections (Enable single pass writing on the nodes)
  melf_sortScn(melf);

  // Set the section offsets
  melf_setScnOffsets(melf);

  // Write the MELF File
  melf_write(melf);

#ifdef DBGMODE
  prettyPrintMELF(melf);
#endif

  // Close ELF Descriptor
  elf_end(elf);
  // Close ELF File
  close(fdelf);
  // Close MELF File
  close(fdmelf);
  return 0;
}
Exemple #30
0
int
main( int argc, char **argv )
{
    int         fd;
    Elf_Scn    *section;
    int         scndx;
    Elf32_Shdr *sheader;
    Elf32_Ehdr *eheader;
    int         strings;
    int         len;
    int         what_to_do;
    Elf        *elf;
    char       *filep;

    if( argc != 3 ) {
	fprintf(stderr, "%s: <what> <filename>\n", argv[0]);
	return(1);
    }

    if (strcmp("vindex",argv[1]) == 0)
	what_to_do = 1;
    else if (strcmp("type",argv[1]) == 0)
	what_to_do = 2;
    else if (strcmp("vtable",argv[1]) == 0)
	what_to_do = 3;
    else {
	fprintf(stderr, "%s: unknown command> %s\n", argv[0], argv[1] );
	return(1);
    }

    sprintf(program,"%s<%s>",argv[0],argv[1]);
    elf_version(EV_CURRENT);
    fd = open(argv[2], OPEN_FLAGS);
    if( fd < 0 ) {
	fprintf(stderr, "%s: open of file %s failed\n", argv[0], argv[2] );
	return(1);
    }

    len = lseek(fd, 0, SEEK_END);

#if MAPFILE
    /* printf("Mapping file %s [len %d]\n", argv[1], len); */
    filep = (char *) mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,fd,0);
    if (filep == (char *)-1) {
	perror("mmap");
	return(1);
    }
#else
    filep = (char*)malloc(len);
    lseek(fd,0,SEEK_SET);
    if (len != read(fd,filep,len)) {
	perror("mmap");
	return(1);
    }
#endif
    elf = elf_begin(fd, ELF_C_READ, (Elf *)NULL);

    if ((eheader = elf32_getehdr(elf)) == NULL) {
	fprintf(stderr, "%s: get header failed\n", argv[0] );
	return(1);
    }

    strings = eheader->e_shstrndx;

    section = NULL;
    scndx = 0;
    while ((section = elf_nextscn(elf, section)) != NULL) {
	char    *name = 0;

	++scndx;
	if ((sheader = elf32_getshdr(section)) != NULL)
	    name = elf_strptr(elf, strings, sheader->sh_name);
	if( name != NULL ) {
//	    printf("SECTION[%d]: <%s>\n",(int)section,name);
	    if( strcmp( name, THE_DATA_SECTION ) == 0 ) {
		pdata = (char *) (filep + sheader->sh_offset);
		data_index = scndx;
	    } else if( strcmp( name, SMALL_DATA_SECTION ) == 0 ) {
		psdata = (char *) (filep + sheader->sh_offset);
		sdata_index = scndx;
	    } else if( strcmp( name, ELF_SYMTAB ) == 0 ) {
		psyms = (Elf32_Sym *) (filep + sheader->sh_offset);
		nsyms = sheader->sh_size / sizeof(Elf32_Sym);
	    } else if( strcmp( name, ELF_STRTAB ) == 0 ) {
		pstr  = (char *) (filep + sheader->sh_offset);
	    }
	}
    }

    if( pdata == NULL && psdata == NULL ) {
	fprintf(stderr, "%s: no data segment found\n", argv[0] );
	return(1);
    }
    if( psyms == NULL ) {
	fprintf(stderr, "%s: no symbol table found\n", argv[0] );
	return(1);
    }
    if( pstr == NULL ) {
	fprintf(stderr, "%s: no string table found\n", argv[0] );
	return(1);
    }

    switch (what_to_do) {
    case 1:
	extract_virtual_index();
	break;

    case 2:
	extract_type_values();
	break;

    case 3:
	extract_virtual_table_size_indirect();
	break;
    }
    elf_end(elf);

    return(0);
}