This is rsym_elf.c in view mode; [Download] [Up]
/* Copyright William Schelter. All rights reserved. Use this to build an executable rsym, which will grab only the external symbols from an object file, and put them in a simple format: (cf ext_sym.h) This information will be used for relocation. to compile use cc rsym.c -o rsym -I../h */ #ifdef __linux__ /* Needed these to get it working with Linux. Bill Metzenthen 23 May 95 */ #define IN_RSYM 1 #include <stdio.h> #define SYMNMLEN 0 #ifndef NUM_AUX #define NUM_AUX(p) 0 #endif #endif #include "ext_sym.h" #include <elf.h> Elf32_Phdr pheader; Elf32_Ehdr eheader; Elf32_Sym *symbol_table; int text_index,data_index,bss_index; #undef SYM_NAME #undef EXT_and_TEXT_BSS_DAT int nsyms; char *my_string_table; char *start_address; int symbol_index; static void get_myself(); #ifdef RSYM_AUX #include RSYM_AUX #endif /* our defs */ #define TABLE_SIZE 3 #ifdef DEBUG int debug =1; #undef dprintf #define dprintf(s,ar) if(debug) { printf(" ( s )",ar) ; fflush(stdout);} #else int debug =0; #define dprintf(s,ar) #endif /* this program will get the external symbols from a file writing them out to a file together with their addresses */ static char *outfile; void main(argc,argv) int argc ; char *argv[]; { if (argc!=3) {perror("bad arg count"); fflush(stdout); exit(1);} #ifdef SET_BINARY_MODE SET_BINARY_MODE #endif get_myself(argv[1]); output_externals(outfile=argv[2]); exit(0); } #define SECTION_H(k) section_headers[k] char *section_names; Elf32_Shdr *section_headers; int get_section_number(name) char *name; {int k ; for (k = 1; k < eheader.e_shnum; k++) { if (!strcmp (section_names + SECTION_H(k).sh_name, name)) return k; } fprintf(stderr,"could not find section %s\n", name); return -1; } char * get_section(fp,name) FILE *fp; char *name; { int shndx; char *ans; if (strcmp(name,".shstrtab") == 0) shndx = eheader.e_shstrndx; else shndx = get_section_number(name); { fseek(fp,SECTION_H(shndx).sh_offset,SEEK_SET); ans = malloc(SECTION_H(shndx).sh_size); fread(ans,SECTION_H(shndx).sh_size,1,fp); return ans; } } static void get_myself(filename) char *filename; { unsigned int i; FILE *fp; int string_size=0; int symsize; extern char *malloc(); fp = fopen(filename, RDONLY); if (fp == NULL) { fprintf(stderr, "Can't open %s\n", filename); exit(1); } fread(&eheader,sizeof(eheader),1,fp); fseek(fp,eheader.e_ehsize,SEEK_SET); fread(&pheader,sizeof(pheader),1,fp); if(ELFMAG0 != eheader.e_ident[0]){ fprintf(stderr,"Bad magic %s",filename); exit(1);}; section_headers = (void *)malloc(sizeof(Elf32_Shdr)* (1+ eheader.e_shnum)); fseek(fp,eheader.e_shoff,0); for (i=0 ; i< eheader.e_shnum ; i++) fread(§ion_headers[i],eheader.e_shentsize,1,fp); section_names = get_section(fp,".shstrtab"); symbol_index = get_section_number(".symtab"); symsize = SECTION_H(symbol_index).sh_entsize; nsyms= SECTION_H(symbol_index).sh_size/symsize; symbol_table = (void *) malloc(sizeof(Elf32_Sym) * nsyms); /* sizeof(struct syment) and SYMESZ are not always the same. */ if(fseek(fp,(int)SECTION_H(symbol_index).sh_offset,0)) {fprintf(stderr,"seek error"); exit(1);} for (i = 0; i < nsyms; i++) fread((char *)&symbol_table[i], symsize, 1, fp); my_string_table = get_section(fp,".strtab"); text_index = get_section_number(".text"); bss_index = get_section_number(".bss"); data_index = get_section_number(".data"); fclose(fp); } struct lsymbol_table tab; #define EXT_and_TEXT_BSS_DAT(p) ((ELF32_ST_BIND(p->st_info) == STB_GLOBAL) \ && \ (p->st_shndx == text_index \ || p->st_shndx == data_index\ || p->st_shndx == bss_index \ || p->st_shndx == SHN_UNDEF \ )) #define SYM_NAME(p) my_string_table+(p->st_name) #define STRUCT_SYMENT Elf32_Sym #define n_value st_value int output_externals(out) char *out; {FILE *symout; char *name; char tem[SYMNMLEN+1]; STRUCT_SYMENT *p, *end; tem[SYMNMLEN]=0; tab.n_symbols=0; tab.tot_leng=0; symout=fopen(out,"wr"); if (!symout) {perror(out); exit(1);}; fseek(symout,sizeof(struct lsymbol_table),0); end = symbol_table + nsyms; for (p = symbol_table; p < end; p++) { /* Is the following check enough? */ if (EXT_and_TEXT_BSS_DAT(p)) { name= SYM_NAME(p); { dprintf(tab.n_symbols %d , tab.n_symbols); tab.n_symbols++; {int i = (p->n_value); #ifdef AIX3 if (p->n_scnum == TEXT_NSCN) i = i + 0x10000e00; else i += DBEGIN; /* leave space for the toc entry. */ #endif fwrite((char *)&i,sizeof(int),1,symout);} #ifdef AIX3 {short j=0; fwrite((char *)&j,sizeof(short),1,symout);} #endif dprintf( p->n_value %d , p->n_value); dprintf( name %s , name); while(tab.tot_leng++,*name) putc(*name++,symout); putc(0,symout); /* fprintf(symout,name); fprintf(symout," %d ", p->n_value); */ }; dprintf( NUM_AUX(p) %d , NUM_AUX(p)); dprintf( index , (int) (p - symbol_table) / sizeof(STRUCT_SYMENT)); p = p + NUM_AUX(p); } } fseek(symout,0,0); fwrite(&tab,sizeof(tab),1,symout); fclose(symout); #ifdef AIX3 add_tc_offsets(outfile); #endif return 0; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.