コード例 #1
0
ファイル: debug.c プロジェクト: kejiewei/eresi
/**
 * Debug : print the section list 
 * @param obj
 * @param label
 * @return
 */
int		elfsh_print_sectlist(elfshobj_t *obj, char *label)
{
	elfshsect_t	*actual;
	u_int		index;
	u_char	*data;
	char		*sctname;

	PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

	printf(" [SCTLIST][%s]\n", label);
	for (index = 0, actual = obj->sectlist;
			actual != NULL;
			index++, actual = actual->next)
	{
		sctname = elfsh_get_section_name(obj, actual);
		if (sctname == NULL)
			sctname = "UNK";
		data = elfsh_readmem(actual);
		if (data == (u_char *)NULL)
			data = (u_char *)"\xFF\xFF\xFF";
		printf(" [%03u:%03u] %-15s HDRNAM: %-15s BYTES[%02X %02X %02X] P(%8p) "
				"A(%8p) N(%8p) SCTIDX(%03u) HDRFOFF:%010u SZ:%010u VADDR:%08X \n",
				index, actual->index, 
				(actual->name != NULL ? actual->name : "UNK"),
				sctname,
				(u_int) data[0],
				(u_int) data[1],
				(u_int) data[2],
				actual->prev,
				actual,
				actual->next,
				actual->index,
				(u_int) actual->shdr->sh_offset,
				(u_int) actual->shdr->sh_size,
				(u_int) actual->shdr->sh_addr);
	}
	puts(" [EOL]\n");
	fflush(stdout);
	PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
コード例 #2
0
ファイル: rel.c プロジェクト: LucaBongiorni/poly-engine
/** 
 * @brief Display relocation entries 
 */
int		cmd_rel()
{
  elfshsect_t	*sect;
  elfsh_Rel	*rel;
  regex_t	*tmp;
  char		*type;
  char		*typeshort;
  char		*name;
  u_int		index;
  u_int		index2;
  u_int		typenum;
  char		buff[256];
  u_int         size;
  revmconst_t  *types;
  char		addstr[32];
  char		logbuf[BUFSIZ];
  void		*data;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Sanity checks */
  sect = elfsh_get_reloc(world.curjob->curfile, 0, &size);
  if (sect == NULL)
    RET(-1);

  /* Choose between global or local regx */
  FIRSTREGX(tmp);
  snprintf(logbuf, BUFSIZ - 1, " [RELOCATION TABLES]\n [Object %s]\n\n", 
	   world.curjob->curfile->name);
  revm_output(logbuf);

  /* We need to iterate as much as there is .rel* sections */
  for (index2 = 0; sect; index2++)
    {

      snprintf(logbuf, BUFSIZ - 1,
	       " {Section %s} \n", elfsh_get_section_name(world.curjob->curfile, sect));
      revm_output(logbuf);

      /* Iterate on the .rel entries array for each .rel section */
      data = elfsh_readmem(sect);
      for (index = 0; index < size; index++)
	{

	  /* Get the current relocation entry */
	  if (sect->shdr->sh_type == SHT_RELA)
	    {

	      rel = (void *) ((elfsh_Rela *) data + index);
	      snprintf(addstr, sizeof(addstr), "add[%s]",
		       revm_colornumber("%08u", (unsigned int) ((elfsh_Rela *) rel)->r_addend));
	    }
	  else
	    {
	      rel = (elfsh_Rel *) data + index;
	      addstr[0] = 0x00;
	    }


	  /* Get linked symbol name */
	  name = elfsh_get_symname_from_reloc(world.curjob->curfile, rel);
	  typenum  = elfsh_get_reltype(rel);
	  types = revm_getrelascii(world.curjob->curfile);

	  type      = (char *) (typenum > ELFSH_RELOC_MAX(world.curjob->curfile) ? NULL :
				types[typenum].desc);
	  typeshort = (char *) (typenum > ELFSH_RELOC_MAX(world.curjob->curfile) ? NULL :
				types[typenum].name);

	  /* Output is different depending on the quiet flag */
	  if (!world.state.revm_quiet)
	    snprintf(buff, sizeof(buff),
		     " [%s] %s %s %s%s%s : %s %s => %s\n",
		     revm_colornumber("%03u", index), 
		     revm_colortypestr_fmt("%-15s", typeshort),
		     revm_coloraddress(XFMT, elfsh_get_reloffset(rel)),
		     revm_colorfieldstr("sym["),
		     revm_colornumber("%03u", elfsh_get_relsym(rel)),
		     revm_colorfieldstr("]"),
		     (name != NULL ? revm_colorstr_fmt("%-30s", name) : revm_colorwarn_fmt("%-30s", "<?>")), addstr, 
		     revm_colortypestr(type));
	  else
	    snprintf(buff, sizeof(buff),
		     " [%s] %s %s %s%s%s : %s %s\n",
		     revm_colornumber("%03u", index), 
		     revm_colortypestr_fmt("%-15s", typeshort),
		     revm_coloraddress(XFMT, elfsh_get_reloffset(rel)),
		     revm_colorfieldstr("sym["),
		     revm_colornumber("%03u", elfsh_get_relsym(rel)),
		     revm_colorfieldstr("]"),
		     (name != NULL ? revm_colorstr_fmt("%-22s", name) : revm_colorwarn_fmt("%-22s", "<?>")),
		     addstr);

	  /* Print it if it matchs the regex */
	  if (NULL == tmp || (tmp != NULL && name != NULL &&
			      0 == regexec(tmp, buff, 0, 0, 0)))
	    switch (revm_output(buff))
	      {
	      case -1:
		revm_endline();
		revm_output("\n");
		PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
	      case -2:
		revm_endline();
		goto next;
	      }
	  
	  revm_endline();
	}

    next:
       sect = elfsh_get_reloc(world.curjob->curfile, index2 + 1, &size);
       revm_output("\n");
    }

  revm_output("\n");
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
コード例 #3
0
ファイル: pht.c プロジェクト: kejiewei/eresi
/** 
 * @brief Display a PHT 
 * @param phdr
 * @param num
 * @param base
 */
void	        revm_pht_print(elfsh_Phdr *phdr, uint16_t num, eresi_Addr base)
{
  elfsh_Shdr	*shdr;
  int		shtnum;
  int		index;
  int		index2;
  char		*type;
  u_int		typenum;
  elfshsect_t	*list;
  regex_t	*tmp;
  char		buff[512];
  char		warnmsg[256];
  char		logbuf[BUFSIZ];
  int		check;
  
  eresi_Addr	addr;
  eresi_Addr	addr_end;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  FIRSTREGX(tmp);
  
  /* Primary view (2 modes, depending on the quiet flag) */
  for (index = 0; index < num; index++)
    {
      
      typenum = elfsh_get_segment_type(phdr + index);
      type    = (char *) (typenum >= ELFSH_SEGTYPE_MAX ? 
			  revm_display_pdesc(typenum) : 
			  elfsh_seg_type[typenum].desc);

      addr = phdr[index].p_vaddr;
      addr_end = phdr[index].p_vaddr + phdr[index].p_memsz;
      if (elfsh_is_runtime_mode())
	{
	  addr_end += base;
	  addr += base;
	}

      /* We check if we have a correct alignment */
      check = (addr - phdr[index].p_offset) & (phdr[index].p_align - 1);

      if (check != 0)
	snprintf(warnmsg, 255, "Wrong alignment (%d)", check);

      if (!world.state.revm_quiet)
	snprintf(buff, sizeof(buff), 
		 " %s %s -> %s %c%c%c %s%s%s "
		 "%s%s%s %s%s%s %s%s%s => %s %s\n",
		 revm_colornumber("[%02u]", index), 
		 revm_coloraddress(XFMT, addr), 
		 revm_coloraddress(XFMT, addr_end),
		 (elfsh_segment_is_readable(&phdr[index])   ? 'r' : '-'),
		 (elfsh_segment_is_writable(&phdr[index])   ? 'w' : '-'),
		 (elfsh_segment_is_executable(&phdr[index]) ? 'x' : '-'),
		 revm_colorfieldstr("memsz("),
		 revm_colornumber(UFMT, phdr[index].p_memsz),
		 revm_colorfieldstr(")"),
		 revm_colorfieldstr("foffset("),
		 revm_colornumber(UFMT, phdr[index].p_offset),
		 revm_colorfieldstr(")"),
		 revm_colorfieldstr("filesz("),
		 revm_colornumber(UFMT, phdr[index].p_filesz),
		 revm_colorfieldstr(")"),
		 revm_colorfieldstr("align("),
		 revm_colornumber(UFMT, phdr[index].p_align),
		 revm_colorfieldstr(")"),
		 revm_colortypestr(type),
		 check != 0 ? revm_colorwarn(warnmsg) : ""
		 );

      else
	snprintf(buff, sizeof(buff), 
		 " %s %s -> %s %c%c%c %s%s%s "
		 "%s%s%s %s%s%s\n",
		 revm_colornumber("[%02u]", index), 
		 revm_coloraddress(XFMT, addr), 
		 revm_coloraddress(XFMT, addr_end),
		 (elfsh_segment_is_readable(&phdr[index])   ? 'r' : '-'),
		 (elfsh_segment_is_writable(&phdr[index])   ? 'w' : '-'),
		 (elfsh_segment_is_executable(&phdr[index]) ? 'x' : '-'),
		 revm_colorfieldstr("memsz("),
		 revm_colornumber(UFMT, phdr[index].p_memsz),
		 revm_colorfieldstr(")"),
		 revm_colorfieldstr("foffset("),
		 revm_colornumber(UFMT, phdr[index].p_offset),
		 revm_colorfieldstr(")"),
		 revm_colorfieldstr("filesz("),
		 revm_colornumber(UFMT, phdr[index].p_filesz),
		 revm_colorfieldstr(")"));

      if (!tmp || (tmp && !regexec(tmp, buff, 0, 0, 0)))
	revm_output(buff);

      revm_endline();

    }

  snprintf(logbuf, BUFSIZ - 1, 
	   "\n [SHT correlation]"
	   "\n [Object %s]\n\n", world.curjob->curfile->name);
  revm_output(logbuf);

  /* Retreive the sht */
  if ((shdr = elfsh_get_sht(world.curjob->curfile, &shtnum)) == 0)
    PROFILER_OUT(__FILE__, __FUNCTION__, __LINE__);

  snprintf(logbuf, BUFSIZ - 1, " [*] SHT %s \n", 
	   (world.curjob->curfile->shtrb ? 
	    "has been rebuilt \n" :
	    "is not stripped \n"));
  revm_output(logbuf);
   
  /* Alternate View */
  for (index = 0; index < num; index++, index2 = 0)
    {
      typenum = elfsh_get_segment_type(phdr + index);
      type    = (char *) (typenum >= ELFSH_SEGTYPE_MAX ? 
			  revm_display_pname(typenum)    : 
			  elfsh_seg_type[typenum].name);

      snprintf(logbuf, BUFSIZ - 1, " %s %s \t", 
	       revm_colornumber("[%02u]", index), 
	       revm_colortypestr_fmt("%-10s", type));
      revm_output(logbuf);

      revm_endline();
      
      /* In SHT */
      for (index2 = 0, list = world.curjob->curfile->sectlist; 
	   list; list = list->next)
	if (elfsh_segment_is_parent(list, phdr + index))
	  {
	    index2++;
	    snprintf(logbuf, BUFSIZ - 1, "%s%s ", 
		     (list->shdr->sh_offset + list->shdr->sh_size > 
		      phdr[index].p_offset + phdr[index].p_filesz ? "|" : ""),
		     revm_colorstr(elfsh_get_section_name(world.curjob->curfile, list)));
	    revm_output(logbuf);

	    revm_endline();
	  }

      /* In RSHT */
      for (index2 = 0, list = world.curjob->curfile->rsectlist; 
	   list; list = list->next)
	if (elfsh_segment_is_parent(list, phdr + index))
	  {
	    index2++;
	    snprintf(logbuf, BUFSIZ - 1, "%s%s ", 
		     (list->shdr->sh_addr + list->shdr->sh_size > 
		      phdr[index].p_vaddr + phdr[index].p_memsz ? "|" : ""),
		     revm_colorstr(elfsh_get_section_name(world.curjob->curfile, list)));
	    revm_output(logbuf);

	    revm_endline();
	  }

      revm_output("\n");
    }
  
  PROFILER_OUT(__FILE__, __FUNCTION__, __LINE__);
}
コード例 #4
0
ファイル: sym.c プロジェクト: LucaBongiorni/poly-engine
/** 
 * Print the chosen symbol table 
 * @param file
 * @param sect
 * @param tab
 * @param num
 * @param regx
 * @param get_symname
 * @return
 */
int		ds(elfshobj_t	*file,
		   elfshsect_t	*sect,
		   u_int        num,
		   regex_t	*regx,
		   char		*(*get_symname)(elfshobj_t *f, elfsh_Sym *s))
{
  elfsh_Sym	*table;
  char		*name;
  char		*type;
  char		*bind;
  u_int		typenum;
  u_int		bindnum;
  u_int		foff;
  u_int		index;
  char		*sect_name;
  char		buff[512];
  char		off[50];
  char		type_unk[ERESI_MEANING + 1];
  char		bind_unk[ERESI_MEANING + 1];

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Sort the table if necessary */
  if (world.state.sort != NULL)
    switch (*world.state.sort)
      {
      case ELFSH_SORT_BY_ADDR:
	table = sect->altdata;
	break;
      case ELFSH_SORT_BY_SIZE:
	table = sect->terdata;
	break;
      default:
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Unknown sort mode", -1);
      }

  /* Avoid reading inexistant memory in the process for .symtab */
  else
    table = (elfsh_Sym *) (sect->shdr->sh_addr ? elfsh_readmem(sect) : sect->data);

  /* Browse symtab */
  for (index = 0; index < num; index++)
    {

      /* Retreive names */
      typenum = elfsh_get_symbol_type(table + index);
      bindnum = elfsh_get_symbol_bind(table + index);
      type = (char *) (typenum > ELFSH_SYMTYPE_MAX ? 
		       revm_build_unknown(type_unk, "type", typenum) : 
		       elfsh_sym_type[typenum].desc);
      bind = (char *) (bindnum >= ELFSH_SYMBIND_MAX ?
		       revm_build_unknown(bind_unk, "type", bindnum) : 
		       elfsh_sym_bind[bindnum].desc);
      name = get_symname(world.curjob->curfile, table + index);
      sect_name = NULL;
      sect = elfsh_get_parent_section(world.curjob->curfile, 
				      table[index].st_value, 
				      NULL);
      if (sect == NULL && table[index].st_shndx)
	sect = elfsh_get_section_by_index(world.curjob->curfile, 
					  table[index].st_shndx,
					  NULL, NULL);
      if (sect != NULL)
	sect_name = elfsh_get_section_name(world.curjob->curfile, sect);

      /* Fixup names */
      if (name == NULL || *name == 0)
	name = ELFSH_NULL_STRING;
      if (type == NULL || *type == 0)
	type = ELFSH_NULL_STRING;
      if (bind == NULL || *bind == 0)
	bind = ELFSH_NULL_STRING;
      if (sect_name == NULL)
	sect_name = ELFSH_NULL_STRING;
      foff = (!table[index].st_value ? 0 : 
	      elfsh_get_foffset_from_vaddr(world.curjob->curfile, 
					   table[index].st_value));
					
      if (sect && sect->shdr->sh_addr != table[index].st_value)
	snprintf(off, sizeof(off), " + %s", 
		 revm_colornumber("%u", (u_int) (table[index].st_value - sect->shdr->sh_addr)));
      else
	*off = '\0';



      /* Different output depending on the quiet flag */
      if (!world.state.revm_quiet)
	{
	  snprintf(buff, sizeof(buff), 
		   " %s %s %s %s %s%s "
		   "%s%s %s%s %s%s => %s%s\n",
		   revm_colornumber("[%03u]", index), 
		   revm_coloraddress(XFMT, (eresi_Addr) elfsh_get_symbol_value(table + index) + file->rhdr.base), 
		   revm_colortypestr_fmt("%-8s", type), 
		   revm_colorstr_fmt("%-40s", name),
		   revm_colorfieldstr("size:"),
		   revm_colornumber("%010u", elfsh_get_symbol_size(table + index)), 				  
		   revm_colorfieldstr("foffset:"),
		   revm_colornumber("%06u", foff),
		   revm_colorfieldstr("scope:"),
		   revm_colortypestr_fmt("%-6s", bind), 
		   revm_colorfieldstr("sctndx:"),
		   revm_colornumber("%02u", elfsh_get_symbol_link(table + index)),
		   revm_colorstr(sect_name), off);
	}

      else
	{
	  snprintf(buff, sizeof(buff), 
		   " %s %s %s %s %s%s %s%s %s%-6s\n",
		   revm_colornumber("[%03u]", index), 
		   revm_coloraddress(XFMT, (eresi_Addr) elfsh_get_symbol_value(table + index) + file->rhdr.base),
		   revm_colortypestr_fmt("%-8s", type), revm_colorstr_fmt("%-15s", name), 
		   revm_colorfieldstr("sz:"),
		   revm_colornumber("%06u", elfsh_get_symbol_size(table + index)),
		   revm_colorfieldstr("foff:"),
		   revm_colornumber("%06u", foff),
		   revm_colorfieldstr("scop:"),
		   revm_colortypestr_fmt("%-6s", bind));
	}
      
      if (regx == NULL || 
	  (regx != NULL && regexec(regx, buff, 0, 0, 0) == 0))
	{
	  /* If the user ask quit, we just break */
	  if (revm_output(buff) == -1)
	    break;
	}

      revm_endline();
    }

  revm_endline();
  revm_output("\n");
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
コード例 #5
0
ファイル: map.c プロジェクト: kejiewei/eresi
/**
 * Load all the part of the binary.
 * This function should not be used by e2dbg 
 * @param file
 * @return
 */
int		        elfsh_read_obj(elfshobj_t *file)
{
  elfshsect_t		*actual;
  int			index;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  if (file->read)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
  if (file->sht == NULL && NULL == elfsh_get_sht(file, NULL))
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
                 "Unable to grab SHT", -1);
  if (NULL == elfsh_get_pht(file, NULL) && file->hdr->e_type != ET_REL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
                 "Unable to grab PHT", -1);

#if __DEBUG_MAP__
  puts("[DEBUG:read_obj] Loading all known typed sections\n");
#endif

  /* Fill multiple relocation sections */
  for (index = 0; NULL != 
       (actual = elfsh_get_reloc(file, index, NULL)); 
       index++);

  /*
  ** Load sections placed after symtab
  ** Added for Solaris
  */
  elfsh_get_comments(file);
  elfsh_get_dwarf(file);
  elfsh_get_stab(file, NULL);
  
  if (file->hdr->e_type == ET_CORE) 
    {
      elfsh_get_core_notes(file);
      goto out;
    }


  /*
   ** We cannot use simply elfsh_get_anonymous_section() here
   ** because the object's section hash ptrs would not be filled.
   */
  elfsh_get_symtab(file, NULL);

  /* Fixup stuffs in the SHT */
  elfsh_fixup(file);

  elfsh_get_dynsymtab(file, NULL);
  elfsh_get_stab(file, NULL);
  elfsh_get_dynamic(file, NULL);
  elfsh_get_ctors(file, NULL);
  elfsh_get_dtors(file, NULL);
  elfsh_get_got(file, NULL);
  elfsh_get_interp(file);

  elfsh_get_versymtab(file, NULL);
  elfsh_get_verneedtab(file, NULL);
  elfsh_get_verdeftab(file, NULL);
  elfsh_get_hashtable(file, NULL);

  //elfsh_get_comments(file);
  elfsh_get_plt(file, NULL);

  /* Fill the multiple notes sections */
  for (index = 0; NULL != elfsh_get_notes(file, index); index++);

  /* Loop on the section header table and load all unknown-typed sections */
  for (actual = file->sectlist; actual; actual = actual->next)
  {
    /* Fix first section size */
    if (actual->shdr->sh_size == 0 && actual->next &&
        actual->next->shdr->sh_offset != actual->shdr->sh_offset &&
	actual->next->shdr->sh_addr   != actual->shdr->sh_addr)
      actual->shdr->sh_size =
        actual->next->shdr->sh_offset - actual->shdr->sh_offset;

    /* If the section data has to be loaded, load it */
    /* In case of bss, only load if BSS data is inserted in the file */
    if (actual->data == NULL && actual->shdr->sh_size)
    {
      if ((actual->shdr->sh_type == SHT_NOBITS && 
           actual->shdr->sh_offset == actual->next->shdr->sh_offset) ||
          (actual->next != NULL && actual->next->shdr->sh_offset == actual->shdr->sh_offset))
        continue;

#if __DEBUG_MAP__
      printf("[LIBELFSH] Loading anonymous  section %15s \n",
             elfsh_get_section_name(file, actual));
#endif
      elfsh_get_anonymous_section(file, actual);
    }
  }

  /* Fixup various symbols like dynamic ones that are NULL */
  /* Non fatal error */
  if (file->secthash[ELFSH_SECTION_DYNSYM])
    elfsh_fixup_dynsymtab(file->secthash[ELFSH_SECTION_DYNSYM]);

out:
  /* We close the file descriptor after file mapping so we can open more files */
  if (file->fd >= 0) {
#if __DEBUG_MAP__
    printf("[LIBELFSH] Closing descriptor %d \n",
           file->fd);
#endif

    XCLOSE(file->fd, -1);
    /* neutralize file descriptor */
    file->fd = -1;
  }
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
コード例 #6
0
ファイル: symbol.c プロジェクト: LucaBongiorni/poly-engine
/**
 * Return the dynamic symbol name giving its value,
 * Fill 'offset' with the difference between sym->st_value and 'value'
 * @param file
 * @param value
 * @param offset
 * @return
 */
char		*elfsh_reverse_symbol(elfshobj_t	*file,
				      eresi_Addr       	value,
				      elfsh_SAddr      	*offset)
{
  elfshsect_t	*sect;
  elfsh_Sym	*sorted;
  int		num;
  int		index;
  char		*str;
  int		best;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Sanity checks */
  if (!value || value == 0xFFFFFFFF)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid parameter", NULL);
  if (file == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid NULL parameter", NULL);

  /* handle dynamic case */
  if (elfsh_is_runtime_mode())
    value -= file->rhdr.base;

  /* If there is no symtab, resolve using SHT */
  if (elfsh_get_symtab(file, &num) == NULL)
    {
      sect = elfsh_get_parent_section(file, value, offset);
      if (sect == NULL)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "No parent section", NULL);

      *offset = (elfsh_SAddr) (sect->shdr->sh_addr - value);
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (elfsh_get_section_name(file, sect)));
    }

  /* Else use the sorted-by-address symbol table to match what we want */
  if (file->secthash[ELFSH_SECTION_SYMTAB]->altdata == NULL)
    elfsh_sync_sorted_symtab(file->secthash[ELFSH_SECTION_SYMTAB]);
  sorted = file->secthash[ELFSH_SECTION_SYMTAB]->altdata;

  /* Now find the best symbol -- type is more important than offset */
  for (str = NULL, best = index = 0; index < num; index++)
    if (sorted[index].st_value <= value && DUMPABLE(sorted + index))
      {
	if (best && !BESTYPE(sorted + index, sorted + best))
	  continue;

	*offset = (elfsh_SAddr) (value - sorted[index].st_value);
	best = index;
	str = elfsh_get_symbol_name(file, sorted + index);
	if (!*str)
	  str = NULL;
      }

  if (str)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, str);
  PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		    "No valid symbol interval", NULL);
}