home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / gcl-1.000 / gcl-1 / gcl-1.0 / unixport / rsym_elf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-24  |  4.9 KB  |  238 lines

  1. /*
  2. Copyright William Schelter. All rights reserved.
  3.  
  4.   Use this to build an executable rsym,
  5. which will grab only the external symbols from an object file,
  6. and put them in a simple format: (cf ext_sym.h) 
  7.  
  8. This information will be used for relocation. 
  9.  
  10. to compile use cc rsym.c -o rsym  -I../h
  11. */
  12.  
  13.  
  14. #include "ext_sym.h"
  15.  
  16.  
  17. #include <elf.h>
  18. Elf32_Phdr pheader;
  19. Elf32_Ehdr eheader;
  20. Elf32_Sym *symbol_table;
  21. int text_index,data_index,bss_index;
  22. #undef SYM_NAME
  23. #undef EXT_and_TEXT_BSS_DAT
  24.  
  25.  
  26. int nsyms;
  27. char *my_string_table;
  28. char *start_address;
  29. int symbol_index;
  30.  
  31. #ifdef RSYM_AUX
  32. #include RSYM_AUX
  33. #endif
  34.  
  35. /* our defs */
  36.  
  37. #define TABLE_SIZE 3
  38.  
  39.  
  40. #ifdef DEBUG
  41. int debug =1;
  42. #undef dprintf
  43. #define dprintf(s,ar) if(debug) { printf(" ( s )",ar) ; fflush(stdout);}
  44. #else
  45. int debug =0;
  46. #define dprintf(s,ar) 
  47. #endif
  48.  
  49.  
  50.  
  51.  
  52. /*  this program will get the external symbols from a file writing
  53. them out to a file together with their addresses */
  54. static char *outfile;
  55.  
  56. main(argc,argv)
  57. int argc ;
  58. char *argv[];
  59. {
  60.   if (argc!=3) {perror("bad arg count");
  61.         fflush(stdout);
  62.         exit(1);}
  63. #ifdef SET_BINARY_MODE
  64.   SET_BINARY_MODE
  65. #endif    
  66.   get_myself(argv[1]);
  67.   output_externals(outfile=argv[2]);
  68.   exit(0);
  69. }
  70. #define SECTION_H(k) section_headers[k]
  71. char *section_names;
  72. Elf32_Shdr *section_headers;
  73.  
  74. get_section_number(name)
  75.    char *name;
  76.      
  77. {int k ;
  78.  for (k = 1; k < eheader.e_shnum;
  79.       k++)
  80.    {
  81.      if (!strcmp (section_names + SECTION_H(k).sh_name,
  82.           name))
  83.        return k;
  84.    }
  85.  fprintf(stderr,"could not find section %s\n", name);
  86.  return -1;
  87. }
  88.  
  89.  
  90. char *
  91. get_section(fp,name)
  92.      FILE *fp;
  93.      char *name;
  94. { int shndx;
  95.   char *ans;
  96.   if (strcmp(name,".shstrtab") == 0)
  97.     shndx = eheader.e_shstrndx;
  98.   else
  99.     shndx = get_section_number(name);
  100.   { 
  101.       fseek(fp,SECTION_H(shndx).sh_offset,SEEK_SET);
  102.       ans = malloc(SECTION_H(shndx).sh_size);
  103.       fread(ans,SECTION_H(shndx).sh_size,1,fp);
  104.       return ans;
  105.     }
  106. }    
  107.         
  108.         
  109.  
  110. get_myself(filename)
  111. char *filename;
  112. {
  113.     unsigned int i;
  114.     FILE *fp;
  115.     int string_size=0;
  116.     int symsize;
  117.     extern char *malloc();
  118.     
  119.         
  120.     fp = fopen(filename, RDONLY);
  121.     
  122.     if (fp == NULL) {
  123.         fprintf(stderr, "Can't open %s\n", filename);
  124.         exit(1);
  125.     }
  126.  
  127.     fread(&eheader,sizeof(eheader),1,fp);
  128.     fseek(fp,eheader.e_ehsize,SEEK_SET);
  129.     fread(&pheader,sizeof(pheader),1,fp);
  130.  
  131.     if(ELFMAG0 != eheader.e_ident[0]){
  132.       fprintf(stderr,"Bad magic %s",filename);
  133.       exit(1);};
  134.  
  135.     section_headers = (void *)malloc(sizeof(Elf32_Shdr)*
  136.                  (1+ eheader.e_shnum));
  137.     fseek(fp,eheader.e_shoff,0);
  138.     for (i=0 ; i< eheader.e_shnum ; i++)
  139.       fread(§ion_headers[i],eheader.e_shentsize,1,fp);
  140.                  
  141.     section_names = get_section(fp,".shstrtab");
  142.     symbol_index = get_section_number(".symtab");
  143.     symsize = SECTION_H(symbol_index).sh_entsize;
  144.     nsyms= SECTION_H(symbol_index).sh_size/symsize;
  145.     symbol_table
  146.     = (void *) malloc(sizeof(Elf32_Sym) * nsyms);
  147.     /*
  148.     sizeof(struct syment) and SYMESZ are not always the same.
  149.     */
  150.  
  151.     if(fseek(fp,(int)SECTION_H(symbol_index).sh_offset,0))
  152.       {fprintf(stderr,"seek error");
  153.                            exit(1);}
  154.  
  155.     for (i = 0;  i < nsyms;  i++)
  156.         fread((char *)&symbol_table[i], symsize, 1, fp);
  157.  
  158.     my_string_table = get_section(fp,".strtab");
  159.     text_index = get_section_number(".text");
  160.     bss_index = get_section_number(".bss");
  161.     data_index = get_section_number(".data");
  162.     
  163.     fclose(fp);
  164. }
  165.  
  166. struct lsymbol_table tab;
  167.  
  168. #define EXT_and_TEXT_BSS_DAT(p) ((ELF32_ST_BIND(p->st_info) == STB_GLOBAL) \
  169.                  && \
  170.                  (p->st_shndx == text_index \
  171.                   || p->st_shndx == data_index\
  172.                   || p->st_shndx == bss_index))
  173. #define SYM_NAME(p) my_string_table+(p->st_name)
  174. #define STRUCT_SYMENT Elf32_Sym
  175. #define n_value st_value  
  176.                  
  177.                  
  178.  
  179. output_externals(out)
  180. char *out;
  181. {FILE *symout;
  182.  char *name;
  183.  char tem[SYMNMLEN+1];
  184.  STRUCT_SYMENT  *p, *end;
  185.  tem[SYMNMLEN]=0;
  186.  tab.n_symbols=0;
  187.  tab.tot_leng=0;
  188.  symout=fopen(out,"wr");
  189.  if (!symout)
  190.    {perror(out); exit(1);};
  191.  fseek(symout,sizeof(struct lsymbol_table),0);
  192.  end = symbol_table + nsyms;
  193.  for (p = symbol_table; p < end; p++)    {
  194.    /*
  195.      Is the following check enough?
  196.      */
  197.    if (EXT_and_TEXT_BSS_DAT(p))
  198.      { name= SYM_NAME(p);
  199.        { dprintf(tab.n_symbols %d , tab.n_symbols);
  200.      tab.n_symbols++;
  201.      {int i = (p->n_value);
  202. #ifdef AIX3
  203.       if (p->n_scnum == TEXT_NSCN)
  204.         i = i + 0x10000e00;
  205.       else
  206.         i += DBEGIN;
  207.         
  208.       /* leave space for the toc entry. */
  209.  
  210. #endif      
  211.       fwrite((char *)&i,sizeof(int),1,symout);}
  212. #ifdef AIX3     
  213.       {short j=0;   fwrite((char *)&j,sizeof(short),1,symout);}
  214. #endif       
  215.      dprintf( p->n_value %d , p->n_value);
  216.      dprintf( name %s , name);
  217.      while(tab.tot_leng++,*name)
  218.        putc(*name++,symout); 
  219.      putc(0,symout);
  220.      /*      fprintf(symout,name);
  221.          fprintf(symout," %d  ", p->n_value); 
  222.          */
  223.        };
  224.        dprintf(  NUM_AUX(p) %d ,  NUM_AUX(p));
  225.        dprintf( index , (int) (p - symbol_table)  / sizeof(STRUCT_SYMENT));
  226.        p = p + NUM_AUX(p); }
  227.  }
  228.  fseek(symout,0,0);
  229.  fwrite(&tab,sizeof(tab),1,symout);
  230.  fclose(symout);
  231. #ifdef AIX3
  232.  add_tc_offsets(outfile);
  233. #endif 
  234.  
  235.  return 0;
  236. }
  237.  
  238.