Exemplo n.º 1
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
//---------------------------------------------------------------------
int getELFSymbolTableNdx(Elf* elf, char* symName)
{
  Elf_Scn *scn;
  Elf32_Shdr *shdr;
  Elf_Data *edata;
  Elf32_Sym *esym;


  scn = NULL;
  while ((scn = elf_nextscn(elf, scn)) != NULL){
    if ((shdr = elf32_getshdr(scn)) != NULL){
      if (SHT_SYMTAB == shdr->sh_type){
	edata = NULL;
	while ((edata = elf_getdata(scn, edata)) != NULL){
  	  if (ELF_T_SYM == edata->d_type){
	    int numSymbols, i;
	    char* symNameRead;
	    esym = (Elf32_Sym*)(edata->d_buf);
	    numSymbols = (int)(edata->d_size/shdr->sh_entsize);
	    for (i = 0; i < numSymbols; i++){
	      symNameRead = elf_strptr(elf, shdr->sh_link, esym[i].st_name);
	      if (strcmp(symNameRead, symName) == 0){
		return i;
	      }
	    }
	  }
	}
      }
    }
  }
  fprintf(stderr, "getElfSymbolTableNdx: Could not locate symbol in the symbol table.\n");
  return -1;
}
Exemplo n.º 4
0
Elf32_Shdr *xelf32_getshdr(Elf_Scn *scn)
{
  Elf32_Shdr *shdr = elf32_getshdr(scn);
  if (shdr == NULL)
	{
	  eprintf("elf_newshdr() failed: %s", elf_errmsg(-1));
	  exit(EXIT_FAILURE);
	}
  return shdr;
}
Exemplo n.º 5
0
/*
 * Load template of the function described by the given symbol.
 */
static struct code_template* function_template_load32(Elf* e, Elf32_Sym* func32)
{
    Elf_Scn* scn = elf_getscn(e, func32->st_shndx);
    assert(scn);
    
    Elf32_Shdr* shdr32 = elf32_getshdr(scn);
    assert(shdr32);
    
    return ct_load(e, scn, func32->st_value, func32->st_size,
        shdr32->sh_addralign);
}
Exemplo n.º 6
0
//---------------------------------------------------------------------
static int convElfHdr(Melf_Scn* mscn, Elf_Scn* escn)
{
  Elf32_Shdr *shdr; 
  if ((shdr = elf32_getshdr(escn)) == NULL){
    fprintf(stderr, "Error reading section header.\n");
    return -1;
  } 
  mscn->m_shdr.sh_id = (Melf_Half)elf_ndxscn(escn);
  mscn->m_shdr.sh_type = shdr->sh_type;
  mscn->m_shdr.sh_link = shdr->sh_link;
  mscn->m_shdr.sh_info = shdr->sh_info;
  return 0;
}
Exemplo n.º 7
0
/* if this function encounters an error it never returns */
static void exec_getsection(
    Elf *elf, size_t index,
    Elf32_Shdr **shdr,
    Elf_Data **data,
    int line
)
#define exec_getsection(a,b,c,d) \
    exec_getsection(a,b,c,d,__LINE__)
{
    Elf_Scn *section;
    char *location;

    location = NULL;
    section = elf_getscn( elf, index );
    if ( section )
    {
        if ( shdr )
        {
            *shdr = elf32_getshdr(section);
            if ( *shdr == NULL )
            {
                location = "elf32_getshdr";
            }
        }
        if ( location == NULL && data )
        {
            *data = elf_getdata(section, NULL);
            if ( *data == NULL )
            {
                location = "elf_getdata";
            }
            else if ( (*data)->d_buf == NULL )
            {
                location = "d_buf";
            }
        }
        if ( location == NULL )
        {
            return;
        }
    }
    else
    {
        location = "elf_getscn";
    }
    fprintf( stderr, "exec_getsection: %s@%d - %s\n", location, line,
             elf_errmsg( -1 ) );
    exit( 1 );
}
Exemplo n.º 8
0
//---------------------------------------------------------------------
static int initSymbolMap(symbol_map_t* symmap, Elf_Scn* symtabscn)
{
  Elf32_Shdr *shdr;
  Elf_Data *edata;

  if ((shdr = elf32_getshdr(symtabscn)) == NULL){
    fprintf(stderr, "Error reading symbol table section header.\n");
    return -1;
  }

  if (SHT_SYMTAB != shdr->sh_type){
    fprintf(stderr, "Not a symbol table section.\n");
    return -1;
  }

  edata = NULL;
  while ((edata = elf_getdata(symtabscn, edata)) != NULL){
    if (ELF_T_SYM == edata->d_type){
      int i;
      symmap->esym = (Elf32_Sym*)edata->d_buf;
	  //esym = (Elf32_Sym*)edata->d_buf;
      symmap->numE = (int)(edata->d_size/ shdr->sh_entsize);
      if ((symmap->msym = malloc(sizeof(Melf_Sym)* symmap->numE)) == NULL){
		fprintf(stderr, "Error allocating memory.\n");
		return -1;
      }
      if ((symmap->etommap = malloc(sizeof(int)* symmap->numE)) == NULL){
		fprintf(stderr, "Error allocating memory.\n");
		return -1;
      }
#ifdef DBGMODE
      if ((symmap->mtoemap = malloc(sizeof(int)* symmap->numE)) == NULL){
		fprintf(stderr, "Error allocating memory.\n");
		return -1;
      }
      for (i = 0; i < symmap->numE; i++)
		symmap->mtoemap[i] = -1;
#endif
      symmap->numM = 0;
      for (i = 0; i < symmap->numE; i++)
		symmap->etommap[i] = -1;
      return 0;
    }
  }
  fprintf(stderr, "Section does not contain any symbols.\n");
  return -1;
}
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;
}
Exemplo n.º 10
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);
}
Exemplo n.º 11
0
Arquivo: mcs.c Projeto: vocho/openqnx
void print(Elf *elf, Elf32_Ehdr *ehdr, struct list *sections, FILE *fp) {
	struct list			*list;
			
	for(list = sections; list; list = list->next) {
		int					section;

		for(section = 0; section < ehdr->e_shnum; section++) {
			Elf_Scn				*scn;
				
			if((scn = elf_getscn(elf, section))) {
				Elf32_Shdr			*shdr;
				
				if((shdr = elf32_getshdr(scn))) {
					char			*p;
				
					if((p = elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name))) {
						if(!strcmp(p, list->string)) {
							Elf_Data			*data;

							for(data = 0; (data = elf_getdata(scn, data));) {		// @@@ This should be elf_rawdata() but it doesn't seem to work!!
								if(data->d_buf && data->d_size > 0) {
									int					n;
									char				*str;

									for(n = 0, str = data->d_buf; n < data->d_size; str++, n++) {
										if(*str == '\0') {
											*str = '\n';
										}
									}
									fwrite(data->d_buf, 1, data->d_size, fp);
								}
							}
							break;
						}
					}
				}
			}
		}
	}
}
Exemplo n.º 12
0
int
write_shdr(elf_data_t *elf, Elf_Scn *scn, GElf_Shdr *shdr, size_t sidx, char **err)
{
  off_t off;
  size_t n, shdr_size;
  void *shdr_buf;

  if(!gelf_update_shdr(scn, shdr)) {
    (*err) = "failed to update section header";
    return -1;
  }

  if(elf->bits == 32) {
    shdr_buf = elf32_getshdr(scn);
    shdr_size = sizeof(Elf32_Shdr);
  } else {
    shdr_buf = elf64_getshdr(scn);
    shdr_size = sizeof(Elf64_Shdr);
  }

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

  off = lseek(elf->fd, elf->ehdr.e_shoff + sidx*elf->ehdr.e_shentsize, SEEK_SET);
  if(off < 0) {
    (*err) = "lseek failed";
    return -1;
  }
    
  n = write(elf->fd, shdr_buf, shdr_size);
  if(n != shdr_size) {
    (*err) = "write failed";
    return -1;
  }

  return 0;
}
Exemplo n.º 13
0
//---------------------------------------------------------------------
static Melf_Data* convProgbitsScn(Elf_Scn* progbitsscn)
{
  Elf32_Shdr *shdr;
  Elf_Data   *edata;
  Melf_Data  *mdata;

  if ((shdr = elf32_getshdr(progbitsscn)) == NULL){
    fprintf(stderr, "Error reading progbits section header.\n");
    return NULL;
  }

  if (SHT_PROGBITS != shdr->sh_type){
    fprintf(stderr, "Not a progbits section.\n");
    return NULL;
  }

  edata = NULL;
  // Get the RAW data from the ELF File for the Progbits section
  while ((edata = elf_rawdata(progbitsscn, edata)) != NULL){
    if (ELF_T_BYTE == edata->d_type){
      // Allocate memory for mdata
      if ((mdata = malloc(sizeof(Melf_Data))) == NULL){
	fprintf(stderr, "Could not allocte memory for Mini-ELF progbits mdata structure.\n");
	return NULL;
      }
      if ((mdata->d_buf = malloc(edata->d_size)) == NULL){
	fprintf(stderr, "Could not allocate memory for Mini-ELF progbits data.\n");
	return NULL;
      }
      mdata->d_type = ELF_T_BYTE;
      memcpy(mdata->d_buf, edata->d_buf, edata->d_size);
      mdata->d_size = edata->d_size;
      mdata->d_numData = edata->d_size;
      return mdata;
    }
  }
  fprintf(stderr, "No data in the progbits section.\n");
  return NULL;
}
Exemplo n.º 14
0
static Elf_Scn* extract_elf_section (Elf *elfP,
  				   Elf_Data *secHdr,
				   const SectionDesc* desc) {
    int cnt = 0;
    Elf_Scn* scn = NULL;
    Elf32_Shdr* shdr = NULL;
    char* sectionName = NULL;

    /* Iterate thru the elf sections */
    for (cnt = 1, scn = NULL; scn = elf_nextscn(elfP, scn); cnt++) {
        if (((shdr = elf32_getshdr(scn)) == NULL)) {
            return NULL;
        }
        sectionName = (char *)secHdr->d_buf + shdr->sh_name;
        if (sectionName &&
           ((strcmp(sectionName, desc->brigName) == 0) ||
           (strcmp(sectionName, desc->bifName) == 0))) {
            return scn;
        }
     }

     return NULL;
}
Exemplo n.º 15
0
//---------------------------------------------------------------------
Elf_Scn* getELFSymbolTableScn(Elf* elf)
{
  Elf_Scn *scn;
  Elf32_Shdr *shdr;
  Elf_Data *edata;
  
  scn = NULL;
  while ((scn = elf_nextscn(elf, scn)) != NULL){
    if ((shdr = elf32_getshdr(scn)) != NULL){
      if (SHT_SYMTAB == shdr->sh_type){
	edata = NULL;
	while ((edata = elf_getdata(scn, edata)) != NULL){
  	  if (ELF_T_SYM == edata->d_type){
	    DEBUG("No. of symbols: %d\n", (int)(edata->d_size/shdr->sh_entsize));
	    return scn;
	    //return (Elf32_Sym*)(edata->d_buf);
	  }
	}
      }
    }
  }
  return NULL;
}
Exemplo n.º 16
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); 
	}
}
Exemplo n.º 17
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;
}
Exemplo n.º 18
0
int add_object_sections(NAME_LIST *section_name_list)
{
    OBJECT_FILE **current;
    Elf_Scn *elf_section;
    Elf32_Shdr *shdr;
    NAME_LIST *section_name;
    Elf_Scn **array;
    int scns_available;
    int scns_added;
    array_index_t link_index;
    int page_links;
    const char *input_name;

    scns_added = scns_available = 0;
    array = NULL;
    array_index_init( &link_index, &link_array );
    current = (OBJECT_FILE **)array_index_next_page(
        &link_index, &page_links );
    while (current)
    {
        elf_section = NULL;
        while ((elf_section = elf_nextscn((*current)->elf, elf_section)) != 0)
        {
            shdr = elf32_getshdr(elf_section);
            elfcheck( shdr != NULL );
            if ( shdr->sh_type == SHT_PROGBITS ||
                 shdr->sh_type == SHT_NOBITS )
            {
                input_name = (*current)->strings+shdr->sh_name;
                for ( section_name = section_name_list ; section_name ;
                      section_name = section_name->next )
                {
                    if (strcmp( input_name, section_name->name) == 0)
                    {
                        if ((shdr->sh_flags & SHF_REFERENCED) == 0)
                        {
                            if ( scns_added >= scns_available )
                            {
                                array_update( &scn_array, scns_added );
                                scns_added = 0;
                                array = array_alloc( &scn_array,
                                                     &scns_available );
                            }
                            *array++ = elf_section;
                            ++scns_added;
//                            elf_flagshdr( elf_section, ELF_C_SET, SHF_REFERENCED );
                            shdr->sh_flags |= SHF_REFERENCED;
                        }
                        else
                        {
                            yyerror( "Input section is referenced twice" );
                        }
                        break;
                    }
                }
            }
        }
        ++current;
        if ( --page_links == 0 )
        {
            current = (OBJECT_FILE **)array_index_next_page(
                &link_index, &page_links );
        }
    }
    array_update( &scn_array, scns_added );
    return 1;
}
Exemplo n.º 19
0
static void fixup_symbols( void )
{
    bbtree_node_t *parent;
    OBJECT_FILE *file;
    Elf_Scn *section;
    Elf32_Shdr *shdr;
    Elf32_Sym *symbol;
    global_t *global_sym;
    int i;
    int compare;
    char *sym_name;

    file = objects;
    while (file)
    {
        section = NULL;
        while ((section = elf_nextscn(file->elf, section)) != 0)
        {
            shdr = elf32_getshdr(section);
            elfcheck( shdr != NULL );
            if ( (shdr->sh_type == SHT_PROGBITS ||
                  shdr->sh_type == SHT_NOBITS) &&
                 (shdr->sh_flags & SHF_REFERENCED) == 0)
            {
                yyerror( "Section %s in file %s is not referenced\n",
                         file->strings + shdr->sh_name, file->name );
            }
        }
        symbol = file->symbols + 1;
        for ( i = 1 ; i < file->symbol_count ; ++i )
        {
            sym_name = elf_strptr( file->elf, file->string_index,
                                   symbol->st_name);
            if (symbol->st_shndx != SHN_UNDEF)
            {
                exec_getsection( file->elf, symbol->st_shndx,
                                 &shdr, NULL );
                symbol->st_value += shdr->sh_addr;
                if (i >= file->first_global)
                {
                    parent = bbtree_preinsert( &globals, sym_name,
                                               &compare );
                    if (!parent || compare != 0)
                    {
                        global_sym = (global_t *)malloc(sizeof(*global_sym));
                        if (global_sym)
                        {
                            global_sym->file = file;
                            global_sym->name = sym_name;
                            global_sym->symbol = symbol;
                            bbtree_insert( &globals, parent, &global_sym->node,
                                           compare );
                        }
                        else
                        {
                            yyerror( "Failed to allocate memory\n" );
                        }

                    }
                    else
                    {
                        yyerror( "Global symbol \"%s\" multiply defined\n",
                                 sym_name );
                    }
                }
            }
            else if (i < file->first_global)
            {
                yyerror( "Symbol \"%s\" is undefined but local\n",
                         sym_name );
            }
            ++symbol;
        }
        file = file->next_object;
    }
}
Exemplo n.º 20
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;
}
Exemplo n.º 21
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;
}
Exemplo n.º 22
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);
	}
    }
}
Exemplo n.º 23
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);
}
Exemplo n.º 24
0
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;

}
Exemplo n.º 25
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;
}
Exemplo n.º 26
0
/* Given Elf header, Elf_Scn, and Elf32_Shdr 
 * print out the symbol table 
 */
void *GetSymbolAdress(const char *filename, const char *symbol) {

#ifdef PLATFORM_POSIX

	int fd;
	Elf *elf;
	GElf_Ehdr elfhdr;

	if (elf_version(EV_CURRENT) == EV_NONE) {
		META_CONPRINTF("ELF library is out of date, Quitting\n");
	}

	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		META_CONPRINTF("[Masterhook] Unable to open \"%s\"\n", filename);
	}

	elf = elf_begin(fd, ELF_C_READ, NULL);
	if (gelf_getehdr(elf, &elfhdr) == 0)	{
		META_CONPRINTF("Cannot read elf header. This usually means that %s is not a valid elf file\n", filename);
	}

	Elf_Scn* section = 0;
	Elf32_Shdr *shdr = NULL;
	bool symtabFound = false;
	while ((section = elf_nextscn(elf, section)) != 0) {
		if ((shdr = elf32_getshdr (section)) != 0) {
			if (shdr->sh_type == SHT_SYMTAB) {
				symtabFound = true;
				break;
			}
		}
	}

	if (shdr == NULL || !symtabFound) {
		return NULL;
	}

	Elf_Scn *scn = section;

	Elf_Data *data;
	char *name;
	data = 0;
	int number = 0;
	if ((data = elf_getdata(scn, data)) == 0 || data->d_size == 0){
		META_CONPRINTF("Section had no data!\n");
		return NULL;
	}

	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 ((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;
		}

		name = elf_strptr(elf, shdr->sh_link , (size_t)esym->st_name);
		if(!name){
			META_CONPRINTF("%s\n", elf_errmsg(elf_errno()));
			return NULL;
		}

		char *name_demangled = 0;
		int* status;
		name_demangled = abi::__cxa_demangle(name, 0, 0, status);

		#ifdef DEBUG
		META_CONPRINTF("%d: Name: %s == %s Address: 0x%x\n", number++, name_demangled, symbol, esym->st_value);
#endif

		if (name_demangled != NULL) {
			if (strstr(name_demangled, symbol)) {
				return (void*)esym->st_value;
			}
		}

		//free(name_demangled);
	}
#endif

	return NULL;
}
int
elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags)
{
  if (scn == NULL)
    return -1;

  if ((flags & ~ELF_CHF_FORCE) != 0)
    {
      __libelf_seterrno (ELF_E_INVALID_OPERAND);
      return -1;
    }

  bool force = (flags & ELF_CHF_FORCE) != 0;

  Elf *elf = scn->elf;
  GElf_Ehdr ehdr;
  if (gelf_getehdr (elf, &ehdr) == NULL)
    return -1;

  int elfclass = elf->class;
  int elfdata = ehdr.e_ident[EI_DATA];

  Elf64_Xword sh_flags;
  Elf64_Word sh_type;
  Elf64_Xword sh_addralign;
  if (elfclass == ELFCLASS32)
    {
      Elf32_Shdr *shdr = elf32_getshdr (scn);
      if (shdr == NULL)
	return -1;

      sh_flags = shdr->sh_flags;
      sh_type = shdr->sh_type;
      sh_addralign = shdr->sh_addralign;
    }
  else
    {
      Elf64_Shdr *shdr = elf64_getshdr (scn);
      if (shdr == NULL)
	return -1;

      sh_flags = shdr->sh_flags;
      sh_type = shdr->sh_type;
      sh_addralign = shdr->sh_addralign;
    }

  if ((sh_flags & SHF_ALLOC) != 0)
    {
      __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS);
      return -1;
    }

  if (sh_type == SHT_NULL || sh_type == SHT_NOBITS)
    {
      __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE);
      return -1;
    }

  /* For GNU compression we cannot really know whether the section is
     already compressed or not.  Just try and see what happens...  */
  // int compressed = (sh_flags & SHF_COMPRESSED);
  if (inflate == 1)
    {
      size_t hsize = 4 + 8; /* GNU "ZLIB" + 8 byte size.  */
      size_t orig_size, new_size, orig_addralign;
      void *out_buf = __libelf_compress (scn, hsize, elfdata,
					 &orig_size, &orig_addralign,
					 &new_size, force);

      /* Compression would make section larger, don't change anything.  */
      if (out_buf == (void *) -1)
	return 0;

      /* Compression failed, return error.  */
      if (out_buf == NULL)
	return -1;

      uint64_t be64_size = htobe64 (orig_size);
      memmove (out_buf, "ZLIB", 4);
      memmove (out_buf + 4, &be64_size, sizeof (be64_size));

      /* We don't know anything about sh_entsize, sh_addralign and
	 sh_flags won't have a SHF_COMPRESSED hint in the GNU format.
	 Just adjust the sh_size.  */
      if (elfclass == ELFCLASS32)
	{
	  Elf32_Shdr *shdr = elf32_getshdr (scn);
	  shdr->sh_size = new_size;
	}
      else
	{
	  Elf64_Shdr *shdr = elf64_getshdr (scn);
	  shdr->sh_size = new_size;
	}

      __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_BYTE);

      /* The section is now compressed, we could keep the uncompressed
	 data around, but since that might have been multiple Elf_Data
	 buffers let the user uncompress it explicitly again if they
	 want it to simplify bookkeeping.  */
      scn->zdata_base = NULL;

      return 1;
    }
  else if (inflate == 0)
    {
      /* In theory the user could have constucted a compressed section
	 by hand.  But we always just take the rawdata directly and
	 decompress that.  */
      Elf_Data *data = elf_rawdata (scn, NULL);
      if (data == NULL)
	return -1;

      size_t hsize = 4 + 8; /* GNU "ZLIB" + 8 byte size.  */
      if (data->d_size < hsize || memcmp (data->d_buf, "ZLIB", 4) != 0)
	{
          __libelf_seterrno (ELF_E_NOT_COMPRESSED);
	  return -1;
	}

      /* There is a 12-byte header of "ZLIB" followed by
	 an 8-byte big-endian size.  There is only one type and
	 Alignment isn't preserved separately.  */
      uint64_t gsize;
      memcpy (&gsize, data->d_buf + 4, sizeof gsize);
      gsize = be64toh (gsize);

      /* One more sanity check, size should be bigger than original
	 data size plus some overhead (4 chars ZLIB + 8 bytes size + 6
	 bytes zlib stream overhead + 5 bytes overhead max for one 16K
	 block) and should fit into a size_t.  */
      if (gsize + 4 + 8 + 6 + 5 < data->d_size || gsize > SIZE_MAX)
	{
	  __libelf_seterrno (ELF_E_NOT_COMPRESSED);
	  return -1;
	}

      size_t size = gsize;
      size_t size_in = data->d_size - hsize;
      void *buf_in = data->d_buf + hsize;
      void *buf_out = __libelf_decompress (buf_in, size_in, size);
      if (buf_out == NULL)
	return -1;

      /* We don't know anything about sh_entsize, sh_addralign and
	 sh_flags won't have a SHF_COMPRESSED hint in the GNU format.
	 Just adjust the sh_size.  */
      if (elfclass == ELFCLASS32)
	{
	  Elf32_Shdr *shdr = elf32_getshdr (scn);
	  shdr->sh_size = size;
	}
      else
	{
	  Elf64_Shdr *shdr = elf64_getshdr (scn);
	  shdr->sh_size = size;
	}

      __libelf_reset_rawdata (scn, buf_out, size, sh_addralign,
			      __libelf_data_type (elf, sh_type));

      scn->zdata_base = buf_out;

      return 1;
    }
  else
    {
      __libelf_seterrno (ELF_E_UNKNOWN_COMPRESSION_TYPE);
      return -1;
    }
}
Exemplo n.º 28
0
Arquivo: ext_elf.c Projeto: jimix/k42
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);
}
Exemplo n.º 29
0
//---------------------------------------------------------------------
static Melf_Data* convRelaScn(Elf_Scn* relascn, symbol_map_t* symmap)
{
  Elf32_Shdr *shdr;
  Elf_Data *edata;
  Elf32_Rela *erela;
  Melf_Rela  *mrela;
  int numRecs, i;
  Melf_Data* mreladata;

  // Get the ELF Rela Section Header
  if ((shdr = elf32_getshdr(relascn)) == NULL){
    fprintf(stderr, "Error reading rela section header.\n");
    return NULL;
  }
  // Verify the ELF RELA section type
  if (SHT_RELA != shdr->sh_type){
    fprintf(stderr, "Not a relocation section. \n");
    return NULL;
  }
  // Get the ELF rela table
  edata = NULL;
  while ((edata = elf_getdata(relascn, edata)) != NULL){
    if (ELF_T_RELA == edata->d_type){
      erela = (Elf32_Rela*)edata->d_buf;
      numRecs = edata->d_size/shdr->sh_entsize;
      // Allocating memory for MELF rela table
      if ((mreladata = malloc(sizeof(Melf_Data))) == NULL){
		fprintf(stderr, "Error allocating memory.");
		return NULL;
      }
      if ((mreladata->d_buf = malloc(sizeof(Melf_Rela) * numRecs)) == NULL){
		fprintf(stderr, "Error allocating memory.");
		return NULL;
      }
      // Init the MELF rela table
      mreladata->d_numData = 0;      
      mreladata->d_type = ELF_T_RELA;
      mrela = (Melf_Rela*)mreladata->d_buf;
      for (i = 0; i < numRecs; i++){
		int esymndx;
		int msymndx;
		esymndx = ELF32_R_SYM(erela[i].r_info);

		/*
		//
		// Check whether we can patch the symbol right now 
		// (i.e. known sys-calls)
		//
		if( patchSymbol( symmap, erela + i ) != 0 ) {
			continue;
		}
		*/
		
		// Get MELF Symbol Index
		if ((msymndx = addMelfSymbol(symmap, esymndx)) == -1){
			fprintf(stderr, "Invalid symbol index in rela.\n");
			return NULL;
		}
		// Convert ELF Rela record to MELF Rela	record
		mrela[mreladata->d_numData].r_offset = (Melf_Addr)erela[i].r_offset;
		mrela[mreladata->d_numData].r_symbol = msymndx;
		mrela[mreladata->d_numData].r_type = (unsigned char)ELF32_R_TYPE(erela[i].r_info);
		mrela[mreladata->d_numData].r_addend = (Melf_Sword) erela[i].r_addend;
		//
		mreladata->d_numData++;
      }
      mreladata->d_size = mreladata->d_numData * sizeof(Melf_Rela);
      return mreladata;
    }
  }
  fprintf(stderr, "Section does not contain any rela records.\n");
  return NULL;
}
Exemplo n.º 30
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;
}