/[gcl]/gcl/o/sfaslelf.c
ViewVC logotype

Diff of /gcl/o/sfaslelf.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by camm, Sat Dec 29 20:14:26 2001 UTC revision 1.5 by camm, Sun Feb 3 18:44:08 2002 UTC
# Line 15  License for more details. Line 15  License for more details.
15    
16  */  */
17    
18    /* for testing in standalone manner define STAND
19     You may then compile this file cc -g -DSTAND -DDEBUG -I../hn
20     a.out /tmp/foo.o /public/gcl/unixport/saved_kcl /public/gcl/unixport/
21     will write a /tmp/sfasltest file
22     which you can use comp to compare with one produced by ld.
23     */
24    
25    
26  #ifndef __linux__  #ifndef __linux__
27  #define ELF_TARGET_SPARC 1  #define ELF_TARGET_SPARC 1
28  #endif  #endif
# Line 29  License for more details. Line 37  License for more details.
37    
38  #include <elf.h>  #include <elf.h>
39    
40    #include "gclincl.h"
41    #ifdef HAVE_LIBBFD
42    #include <bfd.h>
43    #endif
44    
45    #ifdef STAND
46    #include "include.h"
47    
48    #define FEerror(a...) do {fprintf(stderr,##a);exit(1);} while (0)
49    #endif
50    
51  static void relocate_symbols(Elf32_Sym *sym,int nsyms,int nscns, int *init_address_ptr);  static void relocate_symbols(Elf32_Sym *sym,int nsyms,int nscns, int *init_address_ptr);
52  static void relocate(Elf32_Sym *symbol_table,Elf32_Rela  static void relocate(Elf32_Sym *symbol_table,Elf32_Rela
53  *reloc_info,Elf32_Word sh_type);  *reloc_info,Elf32_Word sh_type);
54    
55    
56  #ifdef STAND  #ifdef STAND
57  char *kcl_self;  char *kcl_self,*system_directory;
58  main(argc,argv)  main(argc,argv)
59       char *argv[];       char *argv[];
60  {char *file ;  {char *file ;
61   file = argv[1];   file = argv[1];
62   kcl_self = argv[2];   kcl_self = argv[2];
63     system_directory = argv[3];
64    /*   _fmode = O_BINARY; */
65   fasload(file);   fasload(file);
66     return 0;
67  }  }
68    
69    node_compare(node1,node2)
70    char *node1, *node2;
71    { return(strcmp( ((struct node *)node1)->string,
72                     ((struct node *)node2)->string));}
73    
74    
75    
76    read_special_symbols(symfile)
77    char *symfile;
78    {FILE *symin;
79     char *symbols;
80     int i,jj;
81     struct lsymbol_table tab;
82     if (!(symin=fopen(symfile,"r")))
83       {perror(symfile);exit(1);};
84     if(!fread((char *)&tab,sizeof(tab),1,symin))
85       FEerror("No header",0,0);
86     symbols=malloc(tab.tot_leng);
87     c_table.alloc_length=( (PTABLE_EXTRA+ tab.n_symbols));
88     (c_table.ptable) = (TABL *) malloc(sizeof(struct node) * c_table.alloc_length);
89     if (!(c_table.ptable)) {perror("could not allocate"); exit(1);};
90     i=0; c_table.length=tab.n_symbols;
91     while(i < tab.n_symbols)
92       { fread((char *)&jj,sizeof(int),1,symin);
93         (SYM_ADDRESS(c_table,i))=jj;
94         SYM_STRING(c_table,i)=symbols;
95    
96         while( *(symbols++) =   getc(symin))
97           {;}
98    /*     dprintf( name %s ,  SYM_STRING(c_table,i));
99         dprintf( addr %d , jj);
100    */
101         i++;
102       }
103    
104     /*
105       for(i=0;i< 5;i++)
106       {printf("Symbol: %d %s %d \n",i,SYM_STRINGN(c_table,i),
107       SYM_ADDRESS(*ptable,i));}
108       */
109    }
110    
111  #endif  #endif
112    
113  static Elf32_Ehdr *file_h;  static Elf32_Ehdr *file_h;
# Line 84  fasload(faslfile) Line 149  fasload(faslfile)
149     Elf32_Shdr *shp;     Elf32_Shdr *shp;
150     int file;     int file;
151     struct stat stat_buf;     struct stat stat_buf;
152    #ifndef STAND
153     object     * old_vs_base =   vs_base ;     object     * old_vs_base =   vs_base ;
154     object     * old_vs_top =   vs_top ;     object     * old_vs_top =   vs_top ;
155    #endif
156     int symtab_index,j;     int symtab_index,j;
157     int nsyms;     int nsyms;
158     int init_address=-1;     int init_address=-1;
# Line 100  fasload(faslfile) Line 167  fasload(faslfile)
167     section = section_org;     section = section_org;
168    
169  #ifdef STAND  #ifdef STAND
170     strcpy(filename,faslfile);     strcpy(filename,(char *)faslfile);
171     fp=fopen(filename,RDONLY);     fp=fopen(filename,RDONLY);
172  #else  #else
173     coerce_to_filename(faslfile, filename);     coerce_to_filename(faslfile, filename);
# Line 180  fasload(faslfile) Line 247  fasload(faslfile)
247     extra_bss = 0;     extra_bss = 0;
248    
249    
250    #ifndef STAND
251     memory = alloc_object(t_cfdata);     memory = alloc_object(t_cfdata);
252     memory->cfd.cfd_self = 0;     memory->cfd.cfd_self = 0;
253     memory->cfd.cfd_start = 0;     memory->cfd.cfd_start = 0;
254     memory->cfd.cfd_size = current + (max_align > sizeof(char *) ?     memory->cfd.cfd_size = current + (max_align > sizeof(char *) ?
255                                       max_align :0);                                       max_align :0);
256        
   
257     the_start=start_address=             the_start=start_address=        
258       memory->cfd.cfd_start =           memory->cfd.cfd_start =    
259         alloc_contblock(memory->cfd.cfd_size);         alloc_contblock(memory->cfd.cfd_size);
260    #else
261       memory=(object)malloc(sizeof(*memory));
262       memory->cfd.cfd_self = 0;
263       memory->cfd.cfd_start = 0;
264       memory->cfd.cfd_size = current + (max_align > sizeof(char *) ?
265                                         max_align :0);
266       the_start=start_address=memory->cfd.cfd_start=
267         malloc(memory->cfd.cfd_size + 0x80000);
268       the_start=start_address= (char *)(0x1000 *
269                                         ((((int)the_start + 0x70000) + 0x1000)/0x1000));
270    #endif
271    
272      /* make sure the memory is aligned */      /* make sure the memory is aligned */
273     start_address = ROUND_UP(start_address,max_align);     start_address = ROUND_UP(start_address,max_align);
# Line 216  fasload(faslfile) Line 294  fasload(faslfile)
294       for (j=1 ; j <  file_h->e_shnum ; j++)       for (j=1 ; j <  file_h->e_shnum ; j++)
295         {         {
296           shp = &SECTION_H(j);           shp = &SECTION_H(j);
297           if (shp->sh_type == SHT_RELA           if ((shp->sh_type == SHT_RELA || shp->sh_type == SHT_REL) &&
298               && (SECTION_H(shp->sh_info).sh_flags & SHF_ALLOC))               shp->sh_info<file_h->e_shnum &&
299             {               (SECTION_H(shp->sh_info).sh_flags & SHF_ALLOC))
              int index_to_relocate = shp->sh_info;  
              if (symtab_index != shp->sh_link)  
                FEerror("unexpected symbol table used");  
              the_start = start_address + section[index_to_relocate].start;  
            }  
          else if (shp->sh_type == SHT_REL  
              && (SECTION_H(shp->sh_info).sh_flags & SHF_ALLOC))  
300             {             {
301               int index_to_relocate = shp->sh_info;               int index_to_relocate = shp->sh_info;
302               if (symtab_index != shp->sh_link)               if (symtab_index != shp->sh_link)
303                 FEerror("unexpected symbol table used");                 FEerror("unexpected symbol table used");
304               the_start = start_address + section[index_to_relocate].start;               the_start = start_address + section[index_to_relocate].start;
305             }             }
306    /*       else if (shp->sh_type == SHT_REL */
307    /*           && (SECTION_H(shp->sh_info).sh_flags & SHF_ALLOC)) */
308    /*         { */
309    /*           int index_to_relocate = shp->sh_info; */
310    /*           if (symtab_index != shp->sh_link) */
311    /*             FEerror("unexpected symbol table used"); */
312    /*           the_start = start_address + section[index_to_relocate].start; */
313    /*         } */
314                    
315           else if ( (shp->sh_type == SHT_REL) || (shp->sh_type == SHT_RELA) )           else if ( (shp->sh_type == SHT_REL) || (shp->sh_type == SHT_RELA) )
316             {  if (get_section_number(".rel.stab") == j)             {  if (get_section_number(".rel.stab") == j)
# Line 243  fasload(faslfile) Line 322  fasload(faslfile)
322           {           {
323             int k=0;             int k=0;
324             char *rel = (char *) base +   shp->sh_offset;             char *rel = (char *) base +   shp->sh_offset;
325             for (k= 0; k< shp->sh_size ; k+= shp->sh_entsize)             for (k= 0; k< shp->sh_size ; k+= shp->sh_entsize)
326               relocate(symbol_table,(Elf32_Rela *)(rel + k),shp->sh_type);               relocate(symbol_table,(Elf32_Rela *)(rel + k),shp->sh_type);
327           }           }
328         }         }
329     }     }
330    
331    #ifdef STAND
332       {FILE *out;char pad=0;
333       out=fopen("/tmp/sfasltest","wb");
334       for (j=1 ; j <  file_h->e_shnum ; j++)
335         if ((SECTION_H(j).sh_flags & SHF_ALLOC) && (SECTION_H(j).sh_type == SHT_PROGBITS))
336           memcpy(base+SECTION_H(j).sh_offset,start_address+section[j].start,SECTION_H(j).sh_size);
337       fwrite((char *)base, stat_buf.st_size, 1, out);
338       fclose(out);}
339       printf("\n(start %x)\n",start_address);
340    #else  
341    
342     SEEK_TO_END_OFILE(fp);     SEEK_TO_END_OFILE(fp);
343    
344     /*   init_address += section[text_index].start ; */     /*   init_address += section[text_index].start ; */
# Line 265  fasload(faslfile) Line 355  fasload(faslfile)
355     else     else
356     free(base);     free(base);
357        
358      close_stream(faslfile);
    close_stream(faslfile);  
359    
360  #ifdef CLEAR_CACHE  #ifdef CLEAR_CACHE
361     CLEAR_CACHE;     CLEAR_CACHE;
# Line 276  fasload(faslfile) Line 365  fasload(faslfile)
365                    
366     vs_base = old_vs_base;     vs_base = old_vs_base;
367     vs_top = old_vs_top;     vs_top = old_vs_top;
368    
369     if(symbol_value(sLAload_verboseA)!=Cnil)     if(symbol_value(sLAload_verboseA)!=Cnil)
370       printf("start address -T %x ",memory->cfd.cfd_start);       printf("start address -T %x ",memory->cfd.cfd_start);
371     return(memory->cfd.cfd_size);     return(memory->cfd.cfd_size);
372    
373    #endif /* STAND */
374    
375   }   }
376    
377    
# Line 353  relocate_symbols(sym,nsyms,nscns,init_ad Line 445  relocate_symbols(sym,nsyms,nscns,init_ad
445      }      }
446  }  }
447    
448    
449    #ifdef HAVE_LIBBFD
450    
451    typedef struct {
452      unsigned int type;
453      reloc_howto_type *h;
454    } mtbl;
455    
456    int in_bfd_init=0;
457    
458    static void
459    do_bfd_reloc(unsigned int oc,unsigned int val,
460                 unsigned int *where) {
461    
462      static bfd *dum;
463      static reloc_howto_type * m[BFD_RELOC_UNUSED];
464      reloc_howto_type *h;
465    
466      if (!m[0]) {
467    
468        bfd_reloc_code_real_type t;
469    
470        in_bfd_init=1;
471    
472        bfd_init();
473    
474        if (!(dum=bfd_openr("/dev/null",NULL)))
475          FEerror("Cannot open dummy bfd\n");
476    
477        for (t=BFD_RELOC_UNUSED;t>_dummy_first_bfd_reloc_code_real;t--)
478          if ((h=bfd_reloc_type_lookup(dum,t)))
479            m[h->type]=h;
480          
481        in_bfd_init=0;
482    
483      }
484    
485      if (oc>=BFD_RELOC_UNUSED || !m[oc])
486        FEerror("Cannot lookup type %u\n",oc);
487      h=m[oc];
488    
489      if (h->pc_relative)
490        val-=(unsigned int)where;
491    
492      val>>=h->rightshift;
493      val<<=h->bitpos;
494    /*    *where = ( (*where & ~h->dst_mask) |  */
495    /*           (((*where & h->src_mask) +  val) & h->dst_mask)); */
496    
497    #define DOIT(x) \
498      x = ( (x & ~h->dst_mask) | (((x & h->src_mask) +  val) & h->dst_mask))
499    
500      switch (h->size) {
501      case 0:
502        {
503          char x = bfd_get_8 (dum, (char *) where);
504          DOIT (x);
505          bfd_put_8 (dum, x, (unsigned char *) where);
506        }
507        break;
508    
509      case 1:
510        {
511          short x = bfd_get_16 (dum, (bfd_byte *) where);
512          DOIT (x);
513          bfd_put_16 (dum, (bfd_vma) x, (unsigned char *) where);
514        }
515        break;
516      case 2:
517        {
518          long x = bfd_get_32 (dum, (bfd_byte *) where);
519          DOIT (x);
520          bfd_put_32 (dum, (bfd_vma) x, (bfd_byte *) where);
521        }
522        break;
523      case -2:
524        {
525          long x = bfd_get_32 (dum, (bfd_byte *) where);
526          val = -val;
527          DOIT (x);
528          bfd_put_32 (dum, (bfd_vma) x, (bfd_byte *) where);
529        }
530        break;
531        
532      case -1:
533        {
534          long x = bfd_get_16 (dum, (bfd_byte *) where);
535          val = -val;
536          DOIT (x);
537          bfd_put_16 (dum, (bfd_vma) x, (bfd_byte *) where);
538        }
539        break;
540        
541      case 3:
542        /* Do nothing */
543        break;
544        
545      case 4:
546    #ifdef BFD64
547        {
548          bfd_vma x = bfd_get_64 (dum, (bfd_byte *) where);
549          DOIT (x);
550          bfd_put_64 (dum, x, (bfd_byte *) where);
551        }
552    #else
553        FEerror("Bad howto size %u\n",h->size);
554        /*        abort (); */
555    #endif
556        break;
557      default:
558        FEerror("Bad howto size %u\n",h->size);
559        break;
560      }
561      
562    }
563    
564    #endif /* HAVE_LIBBFD */
565    
566  static void  static void
567  relocate(symbol_table,reloc_info,sh_type)  relocate(symbol_table,reloc_info,sh_type)
568  Elf32_Rela *reloc_info;  Elf32_Rela *reloc_info;
# Line 372  Elf32_Word sh_type; Line 582  Elf32_Word sh_type;
582        FEerror("relocate() error: unknown sh_type in ELF object");        FEerror("relocate() error: unknown sh_type in ELF object");
583      b = (unsigned int) the_start;      b = (unsigned int) the_start;
584      s = symbol_table[ELF32_R_SYM(reloc_info->r_info)].st_value;      s = symbol_table[ELF32_R_SYM(reloc_info->r_info)].st_value;
585    /*      printf("Doing %s\n",string_table + symbol_table[ELF32_R_SYM(reloc_info->r_info)].st_name); */
586      where = the_start + reloc_info->r_offset;      where = the_start + reloc_info->r_offset;
587      p = (unsigned int) where;      p = (unsigned int) where;
588    
# Line 381  Elf32_Word sh_type; Line 592  Elf32_Word sh_type;
592      *(unsigned int *)where = ((val & mask) | ((*(unsigned int *)where) & ~mask))      *(unsigned int *)where = ((val & mask) | ((*(unsigned int *)where) & ~mask))
593  #define ADD_VAL(where, mask, val) \  #define ADD_VAL(where, mask, val) \
594      *(unsigned int *)where += ((val & mask) | ((*(unsigned int *)where) & ~mask))      *(unsigned int *)where += ((val & mask) | ((*(unsigned int *)where) & ~mask))
595        
596    #ifdef HAVE_LIBBFD
597        do_bfd_reloc(ELF32_R_TYPE(reloc_info->r_info),s+a,(unsigned int *)where);
598    #else
599      switch(ELF32_R_TYPE(reloc_info->r_info)){      switch(ELF32_R_TYPE(reloc_info->r_info)){
600  #if (defined(__svr4__) || defined(__linux__)) && defined(__i386__)  #if (defined(__svr4__) || defined(__linux__)) && defined(__i386__)
601      case     R_386_NONE:      case     R_386_NONE:
# Line 436  Elf32_Word sh_type; Line 650  Elf32_Word sh_type;
650        break;        break;
651  #endif  #endif
652    
653  #else  #else /*  (defined(__svr4__) || defined(__linux__)) && defined(__i386__) */
654      case     R_SPARC_WDISP30:      case     R_SPARC_WDISP30:
655        /* v-disp30*/        /* v-disp30*/
656        val=(s+a-p) >> 2;        val=(s+a-p) >> 2;
# Line 466  Elf32_Word sh_type; Line 680  Elf32_Word sh_type;
680        val = (s+a) & MASK(10);        val = (s+a) & MASK(10);
681        *(short *)(where +2) |= val;        *(short *)(where +2) |= val;
682        break;        break;
683  #endif  #endif /*  (defined(__svr4__) || defined(__linux__)) && defined(__i386__) */
684      default:      default:
685        printf("(non supported relocation type %d)\n",        printf("(non supported relocation type %d)\n",
686               ELF32_R_TYPE(reloc_info->r_info));               ELF32_R_TYPE(reloc_info->r_info));
687      }      }
688    #endif /* HAVE_LIBBFD */
689    }    }
690  }  }
691    

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26