Esempio n. 1
0
int
elfsyms_main(int argc, char **argv)
{
int			fd,nsyms;
CexpSymTbl	t;
CexpSym		symp;

	if (argc<2) {
		fprintf(stderr,"Need a file name\n");
		return 1;
	}

	t=cexpSlurpElf(argv[1]);

	if (!t) {
		return 1;
	}

	fprintf(stderr,"%i symbols found\n",t->nentries);
	symp=t->syms;
	for (nsyms=0; nsyms<t->nentries;  nsyms++) {
		symp=t->aindex[nsyms];
		fprintf(stderr,
			"%02i 0x%08xx (%2i) %s\n",
			symp->value.type,
			symp->value.ptv,
			symp->size,
			symp->name);	
		symp++;
	}
	cexpFreeSymTbl(&t);
	return 0;
}
Esempio n. 2
0
CexpSymTbl
cexpAddSymTbl(CexpSymTbl stbl, void *syms, int symSize, int nsyms, CexpSymFilterProc filter, CexpSymAssignProc assign, void *closure, unsigned flags)
{
char		*sp,*dst;
const char	*symname;
CexpSymTbl	rval;
CexpSym		cesp;
int			n,nDstSyms,nDstChars;
CexpStrTbl  strtbl = 0;

	if ( stbl ) {
		rval = stbl;
	} else {
		if (! (rval=(CexpSymTbl)calloc(1, sizeof(*rval))))
			return 0;
	}

	if ( filter && assign ) {

		if ( rval->syms && 0 == rval->size ) {
			/* cannot add to a table that we didn't create */
			return 0;
		}

		/* count the number of valid symbols */
		if ( (flags & CEXP_SYMTBL_FLAG_NO_STRCPY) ) {
			for (sp=syms,n=0,nDstSyms=0; n<nsyms; sp+=symSize,n++) {
				if ((symname=filter(sp,closure))) {
					nDstSyms++;
				}
			}
			nDstChars = 0;
		} else {
			for (sp=syms,n=0,nDstSyms=0,nDstChars=0; n<nsyms; sp+=symSize,n++) {
				if ((symname=filter(sp,closure))) {
					nDstChars+=strlen(symname)+1;
					nDstSyms++;
				}
			}
		}

		/* create our copy of the symbol table - the object format contains
		 * many things we're not interested in and also, it's not
		 * sorted...
		 */

		if ( nDstSyms > rval->size - rval->nentries ) {
			/* allocate all the table space */
			if ( ! (rval->syms=(CexpSym)realloc(rval->syms, sizeof(rval->syms[0])*(rval->nentries + nDstSyms + 1))) )
				goto cleanup;

			rval->size = rval->nentries + nDstSyms;
		}

		if ( nDstChars ) {
			if ( !(strtbl = malloc(sizeof(*strtbl))) )
				goto cleanup;
			if ( !(strtbl->chars = malloc(nDstChars)) ) {
				free( strtbl );
				strtbl = 0;
				goto cleanup;
			}
			strtbl->next = rval->strtbl;
			rval->strtbl = strtbl;
		}
	
		/* now copy the relevant stuff */
		dst = strtbl ? strtbl->chars : 0;
		for (sp=syms,n=0,cesp=rval->syms + rval->nentries; n<nsyms; sp+=symSize,n++) {
			if ((symname=filter(sp,closure))) {
					memset(cesp,0,sizeof(*cesp));
					if ( (flags & CEXP_SYMTBL_FLAG_NO_STRCPY) ) {
						cesp->name=symname;
					} else {
						/* copy the name to the string table and put a pointer
						 * into the symbol table.
						 */
						cesp->name=dst;
						while ((*(dst++)=*(symname++)))
							/* do nothing else */;
					}
					cesp->flags = 0;
	
					assign(sp,cesp,closure);
	
				
					cesp++;
			}
		}
		/* mark the last table entry */
		cesp->name=0;
	} else { /* no filter or assign callback -- they pass us a list of symbols in already */
		if ( rval->syms ) {
			/* cannot add an existing list of symbols to another */
			return 0;
		}
		nDstSyms   = nsyms;
		rval->syms = syms;
	}

	rval->nentries += nDstSyms;

	return rval;

cleanup:
	if ( stbl ) {
		/* leave old table alone */
	} else {
		cexpFreeSymTbl(&rval);
	}
	return 0;
}
Esempio n. 3
0
/* read an ELF file, extract the relevant information and
 * build our internal version of the symbol table.
 * All libelf resources are released upon return from this
 * routine.
 */
static CexpSymTbl
cexpSlurpElf(char *filename)
{
Elf_Stream	elf=0;
Elf_Shdr	*shdr=0;
Elf_Ehdr    ehdr;
Pmelf_Shtab  shtab  = 0;
Pmelf_Symtab symtab = 0;
CexpSymTbl	rval=0,csymt=0;
CexpSym		sane;
#ifdef USE_ELF_MEMORY
char		*buf=0,*ptr=0;
long		size=0,avail=0,got;
#ifdef		__rtems__
extern		struct in_addr rtems_bsdnet_bootp_server_address;
char		HOST[30];
#else
#define		HOST "localhost"
#endif
#endif
int			fd=-1;
unsigned    symsz;

	pmelf_set_errstrm(stderr);

#ifdef USE_ELF_MEMORY
#ifdef HAVE_RCMD
	if ('~'==filename[0]) {
		char *cmd=malloc(strlen(filename)+40);
		strcpy(cmd,filename);
		ptr=strchr(cmd,'/');
		if (!ptr) {
			fprintf(stderr,"Illegal filename for rshLoad %s\n",filename);
			free(cmd);
			goto cleanup;
		}
		*(ptr++)=0;
		memmove(ptr+4,ptr,strlen(ptr));
		memcpy(ptr,"cat ",4);
#ifdef __rtems__
		inet_ntop(AF_INET, &rtems_bsdnet_bootp_server_address, HOST, sizeof(HOST));
#endif
		/* try to load via rsh */
		if (!(buf=rshLoad(HOST,cmd+1,ptr)))
			goto cleanup;
	}
	else
#endif
	{
		if ((fd=open(filename,O_RDONLY,0))<0)
			goto cleanup;

		do {
			if (avail<LOAD_CHUNK) {
				size+=LOAD_CHUNK; avail+=LOAD_CHUNK;
				if (!(buf=realloc(buf,size)))
					goto cleanup;
				ptr=buf+(size-avail);
			}
			got=read(fd,ptr,avail);
			if (got<0)
				goto cleanup;
			avail-=got;
			ptr+=got;
		} while (got);
			got = ptr-buf;
	}
	if (!(elf = pmelf_memstrm(buf,got)))
		goto cleanup;
#else
	if ( ! (elf =  pmelf_newstrm(filename,0)) )
		goto cleanup;
#endif

	/* we need the section header string table */
	if (      pmelf_getehdr(elf, &ehdr)
	     || ! (shtab  = pmelf_getshtab(elf, &ehdr))
	     || ! (symtab = pmelf_getsymtab(elf, shtab)) )
		goto cleanup;
	
	/* convert the symbol table */
	

	if ( ELFCLASS64 == ehdr.e_ident[EI_CLASS] ) {
		csymt=cexpCreateSymTbl(
				(void*)symtab->syms.p_t64,
				sizeof(Elf64_Sym), symtab->nsyms,
				filter64,assign64,
				(void*)symtab->strtab);
	} else {
		csymt=cexpCreateSymTbl(
				(void*)symtab->syms.p_t32,
				sizeof(Elf32_Sym), symtab->nsyms,
				filter32,assign32,
				(void*)symtab->strtab);
	}
	if ( ! csymt )
		goto cleanup;


#ifndef ELFSYMS_TEST_MAIN
	/* do a couple of sanity checks */
	if ((sane=cexpSymTblLookup("cexpSlurpElf",csymt))) {
		extern void *_edata, *_etext;
		/* it must be the main symbol table */
		if (    sane->value.ptv!=(CexpVal)cexpSlurpElf
		     || !(sane=cexpSymTblLookup("_etext",csymt)) || sane->value.ptv!=(CexpVal)&_etext
		     || !(sane=cexpSymTblLookup("_edata",csymt)) || sane->value.ptv!=(CexpVal)&_edata ) {
			fprintf(stderr,"ELFSYMS SANITY CHECK FAILED: you possibly loaded the wrong symbol table\n");
			goto cleanup;
		}
		/* OK, sanity test passed */
	}
#endif

	rval  = csymt;
	csymt = 0;

cleanup:
	pmelf_delsymtab(symtab);
	pmelf_delshtab(shtab);
	pmelf_delstrm(elf,0);
#ifdef USE_ELF_MEMORY
	if (buf)
		free(buf);
#endif
	if (csymt)
		cexpFreeSymTbl(&csymt);
	if (fd>=0)
		close(fd);
	return rval;
}
Esempio n. 4
0
CexpSymTbl
cexpCreateSymTbl(void *syms, int symSize, int nsyms, CexpSymFilterProc filter, CexpSymAssignProc assign, void *closure)
{
char		*sp,*dst;
const char	*symname;
CexpSymTbl	rval;
CexpSym		cesp;
int			n,nDstSyms,nDstChars;

	if (!(rval=(CexpSymTbl)malloc(sizeof(*rval))))
			return 0;

	memset(rval,0,sizeof(*rval));
	
	if ( filter && assign ) {
		/* count the number of valid symbols */
		for (sp=syms,n=0,nDstSyms=0,nDstChars=0; n<nsyms; sp+=symSize,n++) {
				if ((symname=filter(sp,closure))) {
					nDstChars+=strlen(symname)+1;
					nDstSyms++;
				}
		}


		/* create our copy of the symbol table - the object format contains
		 * many things we're not interested in and also, it's not
		 * sorted...
		 */
		
		/* allocate all the table space */
		if (!(rval->syms=(CexpSym)malloc(sizeof(CexpSymRec)*(nDstSyms+1))))
			goto cleanup;
	
		if (!(rval->strtbl=(char*)malloc(nDstChars)) ||
   	     !(rval->aindex=(CexpSym*)malloc(nDstSyms*sizeof(*rval->aindex))))
			goto cleanup;
	
		/* now copy the relevant stuff */
		for (sp=syms,n=0,cesp=rval->syms,dst=rval->strtbl; n<nsyms; sp+=symSize,n++) {
			if ((symname=filter(sp,closure))) {
					memset(cesp,0,sizeof(*cesp));
					/* copy the name to the string table and put a pointer
					 * into the symbol table.
					 */
					cesp->name=dst;
					while ((*(dst++)=*(symname++)))
							/* do nothing else */;
					cesp->flags = 0;
					rval->aindex[cesp-rval->syms]=cesp;
	
					assign(sp,cesp,closure);
	
				
					cesp++;
			}
		}
		/* mark the last table entry */
		cesp->name=0;
	} else { /* no filter or assign callback -- they pass us a list of symbols in already */
		nDstSyms   = nsyms;
		if ( !(rval->aindex=(CexpSym*)malloc(nDstSyms*sizeof(*rval->aindex))) )
			goto cleanup;
		rval->syms = syms;
		for ( cesp = rval->syms; cesp->name; cesp++ ) {
			rval->aindex[cesp-rval->syms] = cesp;
		}
	}

	rval->nentries=nDstSyms;

	/* sort the tables */
	qsort((void*)rval->syms,
		rval->nentries,
		sizeof(*rval->syms),
		_cexp_namecomp);
	qsort((void*)rval->aindex,
		rval->nentries,
		sizeof(*rval->aindex),
		_cexp_addrcomp);

	return rval;

cleanup:
	cexpFreeSymTbl(&rval);
	return 0;
}