/[gcl]/gcl/binutils/bfd/elfcode.h
ViewVC logotype

Diff of /gcl/binutils/bfd/elfcode.h

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

revision 1.1.1.1 by camm, Fri Aug 9 05:35:27 2002 UTC revision 1.2 by camm, Fri Sep 9 23:32:13 2005 UTC
# Line 1  Line 1 
1  /* ELF executable support for BFD.  /* ELF executable support for BFD.
2     Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,     Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3     2001, 2002 Free Software Foundation, Inc.     2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4    
5     Written by Fred Fish @ Cygnus Support, from information published     Written by Fred Fish @ Cygnus Support, from information published
6     in "UNIX System V Release 4, Programmers Guide: ANSI C and     in "UNIX System V Release 4, Programmers Guide: ANSI C and
# Line 33  Foundation, Inc., 59 Temple Place - Suit Line 33  Foundation, Inc., 59 Temple Place - Suit
33  /* Problems and other issues to resolve.  /* Problems and other issues to resolve.
34    
35     (1)  BFD expects there to be some fixed number of "sections" in     (1)  BFD expects there to be some fixed number of "sections" in
36          the object file.  I.E. there is a "section_count" variable in the          the object file.  I.E. there is a "section_count" variable in the
37          bfd structure which contains the number of sections.  However, ELF          bfd structure which contains the number of sections.  However, ELF
38          supports multiple "views" of a file.  In particular, with current          supports multiple "views" of a file.  In particular, with current
39          implementations, executable files typically have two tables, a          implementations, executable files typically have two tables, a
# Line 102  Foundation, Inc., 59 Temple Place - Suit Line 102  Foundation, Inc., 59 Temple Place - Suit
102  #define elf_get_reloc_upper_bound       NAME(bfd_elf,get_reloc_upper_bound)  #define elf_get_reloc_upper_bound       NAME(bfd_elf,get_reloc_upper_bound)
103  #define elf_canonicalize_reloc          NAME(bfd_elf,canonicalize_reloc)  #define elf_canonicalize_reloc          NAME(bfd_elf,canonicalize_reloc)
104  #define elf_slurp_symbol_table          NAME(bfd_elf,slurp_symbol_table)  #define elf_slurp_symbol_table          NAME(bfd_elf,slurp_symbol_table)
105  #define elf_get_symtab                  NAME(bfd_elf,get_symtab)  #define elf_canonicalize_symtab         NAME(bfd_elf,canonicalize_symtab)
106  #define elf_canonicalize_dynamic_symtab \  #define elf_canonicalize_dynamic_symtab \
107    NAME(bfd_elf,canonicalize_dynamic_symtab)    NAME(bfd_elf,canonicalize_dynamic_symtab)
108    #define elf_get_synthetic_symtab \
109      NAME(bfd_elf,get_synthetic_symtab)
110  #define elf_make_empty_symbol           NAME(bfd_elf,make_empty_symbol)  #define elf_make_empty_symbol           NAME(bfd_elf,make_empty_symbol)
111  #define elf_get_symbol_info             NAME(bfd_elf,get_symbol_info)  #define elf_get_symbol_info             NAME(bfd_elf,get_symbol_info)
112  #define elf_get_lineno                  NAME(bfd_elf,get_lineno)  #define elf_get_lineno                  NAME(bfd_elf,get_lineno)
# Line 115  Foundation, Inc., 59 Temple Place - Suit Line 117  Foundation, Inc., 59 Temple Place - Suit
117  #define elf_no_info_to_howto            NAME(bfd_elf,no_info_to_howto)  #define elf_no_info_to_howto            NAME(bfd_elf,no_info_to_howto)
118  #define elf_no_info_to_howto_rel        NAME(bfd_elf,no_info_to_howto_rel)  #define elf_no_info_to_howto_rel        NAME(bfd_elf,no_info_to_howto_rel)
119  #define elf_find_section                NAME(bfd_elf,find_section)  #define elf_find_section                NAME(bfd_elf,find_section)
 #define elf_bfd_link_add_symbols        NAME(bfd_elf,bfd_link_add_symbols)  
 #define elf_add_dynamic_entry           NAME(bfd_elf,add_dynamic_entry)  
120  #define elf_write_shdrs_and_ehdr        NAME(bfd_elf,write_shdrs_and_ehdr)  #define elf_write_shdrs_and_ehdr        NAME(bfd_elf,write_shdrs_and_ehdr)
121  #define elf_write_out_phdrs             NAME(bfd_elf,write_out_phdrs)  #define elf_write_out_phdrs             NAME(bfd_elf,write_out_phdrs)
122  #define elf_write_relocs                NAME(bfd_elf,write_relocs)  #define elf_write_relocs                NAME(bfd_elf,write_relocs)
123  #define elf_slurp_reloc_table           NAME(bfd_elf,slurp_reloc_table)  #define elf_slurp_reloc_table           NAME(bfd_elf,slurp_reloc_table)
 #define elf_link_create_dynamic_sections \  
   NAME(bfd_elf,link_create_dynamic_sections)  
 #define elf_bfd_discard_info            NAME(bfd_elf,discard_info)  
 #define elf_reloc_symbol_deleted_p      NAME(_bfd_elf,reloc_symbol_deleted_p)  
 #define elf_link_record_dynamic_symbol  _bfd_elf_link_record_dynamic_symbol  
 #define elf_bfd_final_link              NAME(bfd_elf,bfd_final_link)  
 #define elf_create_pointer_linker_section NAME(bfd_elf,create_pointer_linker_section)  
 #define elf_finish_pointer_linker_section NAME(bfd_elf,finish_pointer_linker_section)  
 #define elf_gc_sections                 NAME(_bfd_elf,gc_sections)  
 #define elf_gc_common_finalize_got_offsets \  
   NAME(_bfd_elf,gc_common_finalize_got_offsets)  
 #define elf_gc_common_final_link        NAME(_bfd_elf,gc_common_final_link)  
 #define elf_gc_record_vtinherit         NAME(_bfd_elf,gc_record_vtinherit)  
 #define elf_gc_record_vtentry           NAME(_bfd_elf,gc_record_vtentry)  
 #define elf_link_record_local_dynamic_symbol \  
   NAME(_bfd_elf,link_record_local_dynamic_symbol)  
124    
125  #if ARCH_SIZE == 64  #if ARCH_SIZE == 64
126  #define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y)  #define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y)
# Line 155  Foundation, Inc., 59 Temple Place - Suit Line 139  Foundation, Inc., 59 Temple Place - Suit
139  #define LOG_FILE_ALIGN  2  #define LOG_FILE_ALIGN  2
140  #endif  #endif
141    
 /* Static functions */  
   
 static void elf_swap_ehdr_in  
   PARAMS ((bfd *, const Elf_External_Ehdr *, Elf_Internal_Ehdr *));  
 static void elf_swap_ehdr_out  
   PARAMS ((bfd *, const Elf_Internal_Ehdr *, Elf_External_Ehdr *));  
 static void elf_swap_shdr_in  
   PARAMS ((bfd *, const Elf_External_Shdr *, Elf_Internal_Shdr *));  
 static void elf_swap_shdr_out  
   PARAMS ((bfd *, const Elf_Internal_Shdr *, Elf_External_Shdr *));  
   
 #define elf_stringtab_init _bfd_elf_stringtab_init  
   
 #define section_from_elf_index bfd_section_from_elf_index  
   
 static boolean elf_slurp_reloc_table_from_section  
   PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type,  
            arelent *, asymbol **, boolean));  
   
 static boolean elf_file_p PARAMS ((Elf_External_Ehdr *));  
   
142  #ifdef DEBUG  #ifdef DEBUG
143  static void elf_debug_section PARAMS ((int, Elf_Internal_Shdr *));  static void elf_debug_section (int, Elf_Internal_Shdr *);
144  static void elf_debug_file PARAMS ((Elf_Internal_Ehdr *));  static void elf_debug_file (Elf_Internal_Ehdr *);
145  static char *elf_symbol_flags PARAMS ((flagword));  static char *elf_symbol_flags (flagword);
146  #endif  #endif
147    
148  /* Structure swapping routines */  /* Structure swapping routines */
# Line 203  static char *elf_symbol_flags PARAMS ((f Line 166  static char *elf_symbol_flags PARAMS ((f
166     format.  */     format.  */
167    
168  void  void
169  elf_swap_symbol_in (abfd, psrc, pshn, dst)  elf_swap_symbol_in (bfd *abfd,
170       bfd *abfd;                      const void *psrc,
171       const PTR psrc;                      const void *pshn,
172       const PTR pshn;                      Elf_Internal_Sym *dst)
      Elf_Internal_Sym *dst;  
173  {  {
174    const Elf_External_Sym *src = (const Elf_External_Sym *) psrc;    const Elf_External_Sym *src = psrc;
175    const Elf_External_Sym_Shndx *shndx = (const Elf_External_Sym_Shndx *) pshn;    const Elf_External_Sym_Shndx *shndx = pshn;
176    int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;    int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
177    
178    dst->st_name = H_GET_32 (abfd, src->st_name);    dst->st_name = H_GET_32 (abfd, src->st_name);
# Line 234  elf_swap_symbol_in (abfd, psrc, pshn, ds Line 196  elf_swap_symbol_in (abfd, psrc, pshn, ds
196     format.  */     format.  */
197    
198  void  void
199  elf_swap_symbol_out (abfd, src, cdst, shndx)  elf_swap_symbol_out (bfd *abfd,
200       bfd *abfd;                       const Elf_Internal_Sym *src,
201       const Elf_Internal_Sym *src;                       void *cdst,
202       PTR cdst;                       void *shndx)
      PTR shndx;  
203  {  {
204    unsigned int tmp;    unsigned int tmp;
205    Elf_External_Sym *dst = (Elf_External_Sym *) cdst;    Elf_External_Sym *dst = cdst;
206    H_PUT_32 (abfd, src->st_name, dst->st_name);    H_PUT_32 (abfd, src->st_name, dst->st_name);
207    H_PUT_WORD (abfd, src->st_value, dst->st_value);    H_PUT_WORD (abfd, src->st_value, dst->st_value);
208    H_PUT_WORD (abfd, src->st_size, dst->st_size);    H_PUT_WORD (abfd, src->st_size, dst->st_size);
# Line 262  elf_swap_symbol_out (abfd, src, cdst, sh Line 223  elf_swap_symbol_out (abfd, src, cdst, sh
223     internal format.  */     internal format.  */
224    
225  static void  static void
226  elf_swap_ehdr_in (abfd, src, dst)  elf_swap_ehdr_in (bfd *abfd,
227       bfd *abfd;                    const Elf_External_Ehdr *src,
228       const Elf_External_Ehdr *src;                    Elf_Internal_Ehdr *dst)
      Elf_Internal_Ehdr *dst;  
229  {  {
230    int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;    int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
231    memcpy (dst->e_ident, src->e_ident, EI_NIDENT);    memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
# Line 291  elf_swap_ehdr_in (abfd, src, dst) Line 251  elf_swap_ehdr_in (abfd, src, dst)
251     external format.  */     external format.  */
252    
253  static void  static void
254  elf_swap_ehdr_out (abfd, src, dst)  elf_swap_ehdr_out (bfd *abfd,
255       bfd *abfd;                     const Elf_Internal_Ehdr *src,
256       const Elf_Internal_Ehdr *src;                     Elf_External_Ehdr *dst)
      Elf_External_Ehdr *dst;  
257  {  {
258    unsigned int tmp;    unsigned int tmp;
259    int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;    int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
# Line 328  elf_swap_ehdr_out (abfd, src, dst) Line 287  elf_swap_ehdr_out (abfd, src, dst)
287     ELF section header table entry in internal format.  */     ELF section header table entry in internal format.  */
288    
289  static void  static void
290  elf_swap_shdr_in (abfd, src, dst)  elf_swap_shdr_in (bfd *abfd,
291       bfd *abfd;                    const Elf_External_Shdr *src,
292       const Elf_External_Shdr *src;                    Elf_Internal_Shdr *dst)
      Elf_Internal_Shdr *dst;  
293  {  {
294    int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;    int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
295    
# Line 356  elf_swap_shdr_in (abfd, src, dst) Line 314  elf_swap_shdr_in (abfd, src, dst)
314     ELF section header table entry in external format.  */     ELF section header table entry in external format.  */
315    
316  static void  static void
317  elf_swap_shdr_out (abfd, src, dst)  elf_swap_shdr_out (bfd *abfd,
318       bfd *abfd;                     const Elf_Internal_Shdr *src,
319       const Elf_Internal_Shdr *src;                     Elf_External_Shdr *dst)
      Elf_External_Shdr *dst;  
320  {  {
321    /* note that all elements of dst are *arrays of unsigned char* already...  */    /* note that all elements of dst are *arrays of unsigned char* already...  */
322    H_PUT_32 (abfd, src->sh_name, dst->sh_name);    H_PUT_32 (abfd, src->sh_name, dst->sh_name);
# Line 378  elf_swap_shdr_out (abfd, src, dst) Line 335  elf_swap_shdr_out (abfd, src, dst)
335     ELF program header table entry in internal format.  */     ELF program header table entry in internal format.  */
336    
337  void  void
338  elf_swap_phdr_in (abfd, src, dst)  elf_swap_phdr_in (bfd *abfd,
339       bfd *abfd;                    const Elf_External_Phdr *src,
340       const Elf_External_Phdr *src;                    Elf_Internal_Phdr *dst)
      Elf_Internal_Phdr *dst;  
341  {  {
342    int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;    int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
343    
# Line 404  elf_swap_phdr_in (abfd, src, dst) Line 360  elf_swap_phdr_in (abfd, src, dst)
360  }  }
361    
362  void  void
363  elf_swap_phdr_out (abfd, src, dst)  elf_swap_phdr_out (bfd *abfd,
364       bfd *abfd;                     const Elf_Internal_Phdr *src,
365       const Elf_Internal_Phdr *src;                     Elf_External_Phdr *dst)
      Elf_External_Phdr *dst;  
366  {  {
367    /* note that all elements of dst are *arrays of unsigned char* already...  */    /* note that all elements of dst are *arrays of unsigned char* already...  */
368    H_PUT_32 (abfd, src->p_type, dst->p_type);    H_PUT_32 (abfd, src->p_type, dst->p_type);
# Line 421  elf_swap_phdr_out (abfd, src, dst) Line 376  elf_swap_phdr_out (abfd, src, dst)
376  }  }
377    
378  /* Translate an ELF reloc from external format to internal format.  */  /* Translate an ELF reloc from external format to internal format.  */
379  INLINE void  void
380  elf_swap_reloc_in (abfd, src, dst)  elf_swap_reloc_in (bfd *abfd,
381       bfd *abfd;                     const bfd_byte *s,
382       const Elf_External_Rel *src;                     Elf_Internal_Rela *dst)
      Elf_Internal_Rel *dst;  
383  {  {
384      const Elf_External_Rel *src = (const Elf_External_Rel *) s;
385    dst->r_offset = H_GET_WORD (abfd, src->r_offset);    dst->r_offset = H_GET_WORD (abfd, src->r_offset);
386    dst->r_info = H_GET_WORD (abfd, src->r_info);    dst->r_info = H_GET_WORD (abfd, src->r_info);
387      dst->r_addend = 0;
388  }  }
389    
390  INLINE void  void
391  elf_swap_reloca_in (abfd, src, dst)  elf_swap_reloca_in (bfd *abfd,
392       bfd *abfd;                      const bfd_byte *s,
393       const Elf_External_Rela *src;                      Elf_Internal_Rela *dst)
      Elf_Internal_Rela *dst;  
394  {  {
395      const Elf_External_Rela *src = (const Elf_External_Rela *) s;
396    dst->r_offset = H_GET_WORD (abfd, src->r_offset);    dst->r_offset = H_GET_WORD (abfd, src->r_offset);
397    dst->r_info = H_GET_WORD (abfd, src->r_info);    dst->r_info = H_GET_WORD (abfd, src->r_info);
398    dst->r_addend = H_GET_SIGNED_WORD (abfd, src->r_addend);    dst->r_addend = H_GET_SIGNED_WORD (abfd, src->r_addend);
399  }  }
400    
401  /* Translate an ELF reloc from internal format to external format.  */  /* Translate an ELF reloc from internal format to external format.  */
402  INLINE void  void
403  elf_swap_reloc_out (abfd, src, dst)  elf_swap_reloc_out (bfd *abfd,
404       bfd *abfd;                      const Elf_Internal_Rela *src,
405       const Elf_Internal_Rel *src;                      bfd_byte *d)
      Elf_External_Rel *dst;  
406  {  {
407      Elf_External_Rel *dst = (Elf_External_Rel *) d;
408    H_PUT_WORD (abfd, src->r_offset, dst->r_offset);    H_PUT_WORD (abfd, src->r_offset, dst->r_offset);
409    H_PUT_WORD (abfd, src->r_info, dst->r_info);    H_PUT_WORD (abfd, src->r_info, dst->r_info);
410  }  }
411    
412  INLINE void  void
413  elf_swap_reloca_out (abfd, src, dst)  elf_swap_reloca_out (bfd *abfd,
414       bfd *abfd;                       const Elf_Internal_Rela *src,
415       const Elf_Internal_Rela *src;                       bfd_byte *d)
      Elf_External_Rela *dst;  
416  {  {
417      Elf_External_Rela *dst = (Elf_External_Rela *) d;
418    H_PUT_WORD (abfd, src->r_offset, dst->r_offset);    H_PUT_WORD (abfd, src->r_offset, dst->r_offset);
419    H_PUT_WORD (abfd, src->r_info, dst->r_info);    H_PUT_WORD (abfd, src->r_info, dst->r_info);
420    H_PUT_SIGNED_WORD (abfd, src->r_addend, dst->r_addend);    H_PUT_SIGNED_WORD (abfd, src->r_addend, dst->r_addend);
421  }  }
422    
423  INLINE void  void
424  elf_swap_dyn_in (abfd, p, dst)  elf_swap_dyn_in (bfd *abfd,
425       bfd *abfd;                   const void *p,
426       const PTR p;                   Elf_Internal_Dyn *dst)
      Elf_Internal_Dyn *dst;  
427  {  {
428    const Elf_External_Dyn *src = (const Elf_External_Dyn *) p;    const Elf_External_Dyn *src = p;
429    
430    dst->d_tag = H_GET_WORD (abfd, src->d_tag);    dst->d_tag = H_GET_WORD (abfd, src->d_tag);
431    dst->d_un.d_val = H_GET_WORD (abfd, src->d_un.d_val);    dst->d_un.d_val = H_GET_WORD (abfd, src->d_un.d_val);
432  }  }
433    
434  INLINE void  void
435  elf_swap_dyn_out (abfd, src, p)  elf_swap_dyn_out (bfd *abfd,
436       bfd *abfd;                    const Elf_Internal_Dyn *src,
437       const Elf_Internal_Dyn *src;                    void *p)
      PTR p;  
438  {  {
439    Elf_External_Dyn *dst = (Elf_External_Dyn *) p;    Elf_External_Dyn *dst = p;
440    
441    H_PUT_WORD (abfd, src->d_tag, dst->d_tag);    H_PUT_WORD (abfd, src->d_tag, dst->d_tag);
442    H_PUT_WORD (abfd, src->d_un.d_val, dst->d_un.d_val);    H_PUT_WORD (abfd, src->d_un.d_val, dst->d_un.d_val);
# Line 495  elf_swap_dyn_out (abfd, src, p) Line 449  elf_swap_dyn_out (abfd, src, p)
449     First we validate the file by reading in the ELF header and checking     First we validate the file by reading in the ELF header and checking
450     the magic number.  */     the magic number.  */
451    
452  static INLINE boolean  static inline bfd_boolean
453  elf_file_p (x_ehdrp)  elf_file_p (Elf_External_Ehdr *x_ehdrp)
      Elf_External_Ehdr *x_ehdrp;  
454  {  {
455    return ((x_ehdrp->e_ident[EI_MAG0] == ELFMAG0)    return ((x_ehdrp->e_ident[EI_MAG0] == ELFMAG0)
456            && (x_ehdrp->e_ident[EI_MAG1] == ELFMAG1)            && (x_ehdrp->e_ident[EI_MAG1] == ELFMAG1)
# Line 505  elf_file_p (x_ehdrp) Line 458  elf_file_p (x_ehdrp)
458            && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3));            && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3));
459  }  }
460    
 struct bfd_preserve  
 {  
   const struct bfd_arch_info *arch_info;  
   struct elf_obj_tdata *tdata;  
   struct bfd_hash_table section_htab;  
   struct sec *sections;  
   struct sec **section_tail;  
   unsigned int section_count;  
 };  
   
461  /* Check to see if the file associated with ABFD matches the target vector  /* Check to see if the file associated with ABFD matches the target vector
462     that ABFD points to.     that ABFD points to.
463    
# Line 524  struct bfd_preserve Line 467  struct bfd_preserve
467     file does not match the target vector.  */     file does not match the target vector.  */
468    
469  const bfd_target *  const bfd_target *
470  elf_object_p (abfd)  elf_object_p (bfd *abfd)
      bfd *abfd;  
471  {  {
472    Elf_External_Ehdr x_ehdr;     /* Elf file header, external form */    Elf_External_Ehdr x_ehdr;     /* Elf file header, external form */
473    Elf_Internal_Ehdr *i_ehdrp;   /* Elf file header, internal form */    Elf_Internal_Ehdr *i_ehdrp;   /* Elf file header, internal form */
# Line 533  elf_object_p (abfd) Line 475  elf_object_p (abfd)
475    Elf_Internal_Shdr i_shdr;    Elf_Internal_Shdr i_shdr;
476    Elf_Internal_Shdr *i_shdrp;   /* Section header table, internal form */    Elf_Internal_Shdr *i_shdrp;   /* Section header table, internal form */
477    unsigned int shindex;    unsigned int shindex;
478    char *shstrtab;               /* Internal copy of section header stringtab */    const struct elf_backend_data *ebd;
   struct elf_backend_data *ebd;  
479    struct bfd_preserve preserve;    struct bfd_preserve preserve;
   struct elf_obj_tdata *new_tdata = NULL;  
480    asection *s;    asection *s;
481    bfd_size_type amt;    bfd_size_type amt;
482    
483    preserve.arch_info = abfd->arch_info;    preserve.marker = NULL;
484    
485    /* Read in the ELF header in external format.  */    /* Read in the ELF header in external format.  */
486    
487    if (bfd_bread ((PTR) & x_ehdr, (bfd_size_type) sizeof (x_ehdr), abfd)    if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
       != sizeof (x_ehdr))  
488      {      {
489        if (bfd_get_error () != bfd_error_system_call)        if (bfd_get_error () != bfd_error_system_call)
490          goto got_wrong_format_error;          goto got_wrong_format_error;
# Line 580  elf_object_p (abfd) Line 519  elf_object_p (abfd)
519        goto got_wrong_format_error;        goto got_wrong_format_error;
520      }      }
521    
522      if (!bfd_preserve_save (abfd, &preserve))
523        goto got_no_match;
524    
525    /* Allocate an instance of the elf_obj_tdata structure and hook it up to    /* Allocate an instance of the elf_obj_tdata structure and hook it up to
526       the tdata pointer in the bfd.  */       the tdata pointer in the bfd.  */
527    
528    amt = sizeof (struct elf_obj_tdata);    if (! (*abfd->xvec->_bfd_set_format[bfd_object]) (abfd))
   new_tdata = (struct elf_obj_tdata *) bfd_zalloc (abfd, amt);  
   if (new_tdata == NULL)  
     goto got_no_match;  
   preserve.tdata = elf_tdata (abfd);  
   elf_tdata (abfd) = new_tdata;  
   
   /* Clear section information, since there might be a recognized bfd that  
      we now check if we can replace, and we don't want to append to it.  */  
   preserve.sections = abfd->sections;  
   preserve.section_tail = abfd->section_tail;  
   preserve.section_count = abfd->section_count;  
   preserve.section_htab = abfd->section_htab;  
   abfd->sections = NULL;  
   abfd->section_tail = &abfd->sections;  
   abfd->section_count = 0;  
   if (!bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc))  
529      goto got_no_match;      goto got_no_match;
530      preserve.marker = elf_tdata (abfd);
531    
532    /* Now that we know the byte order, swap in the rest of the header */    /* Now that we know the byte order, swap in the rest of the header */
533    i_ehdrp = elf_elfheader (abfd);    i_ehdrp = elf_elfheader (abfd);
# Line 633  elf_object_p (abfd) Line 560  elf_object_p (abfd)
560    /* Check that the ELF e_machine field matches what this particular    /* Check that the ELF e_machine field matches what this particular
561       BFD format expects.  */       BFD format expects.  */
562    if (ebd->elf_machine_code != i_ehdrp->e_machine    if (ebd->elf_machine_code != i_ehdrp->e_machine
563        && (ebd->elf_machine_alt1 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt1)        && (ebd->elf_machine_alt1 == 0
564        && (ebd->elf_machine_alt2 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt2))            || i_ehdrp->e_machine != ebd->elf_machine_alt1)
565          && (ebd->elf_machine_alt2 == 0
566              || i_ehdrp->e_machine != ebd->elf_machine_alt2))
567      {      {
568        const bfd_target * const *target_ptr;        const bfd_target * const *target_ptr;
569    
# Line 645  elf_object_p (abfd) Line 574  elf_object_p (abfd)
574           for which we do not have a specific backend.  */           for which we do not have a specific backend.  */
575        for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)        for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
576          {          {
577            struct elf_backend_data *back;            const struct elf_backend_data *back;
578    
579            if ((*target_ptr)->flavour != bfd_target_elf_flavour)            if ((*target_ptr)->flavour != bfd_target_elf_flavour)
580              continue;              continue;
581            back = (struct elf_backend_data *) (*target_ptr)->backend_data;            back = (const struct elf_backend_data *) (*target_ptr)->backend_data;
582            if (back->elf_machine_code == i_ehdrp->e_machine            if (back->elf_machine_code == i_ehdrp->e_machine
583                || (back->elf_machine_alt1 != 0                || (back->elf_machine_alt1 != 0
584                    && back->elf_machine_alt1 == i_ehdrp->e_machine)                    && back->elf_machine_alt1 == i_ehdrp->e_machine)
# Line 683  elf_object_p (abfd) Line 612  elf_object_p (abfd)
612    
613    if (i_ehdrp->e_shoff != 0)    if (i_ehdrp->e_shoff != 0)
614      {      {
615          bfd_signed_vma where = i_ehdrp->e_shoff;
616    
617          if (where != (file_ptr) where)
618            goto got_wrong_format_error;
619    
620        /* Seek to the section header table in the file.  */        /* Seek to the section header table in the file.  */
621        if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0)        if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
622          goto got_no_match;          goto got_no_match;
623    
624        /* Read the first section header at index 0, and convert to internal        /* Read the first section header at index 0, and convert to internal
625           form.  */           form.  */
626        if (bfd_bread ((PTR) & x_shdr, (bfd_size_type) sizeof x_shdr, abfd)        if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
           != sizeof (x_shdr))  
627          goto got_no_match;          goto got_no_match;
628        elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);        elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);
629    
630        /* If the section count is zero, the actual count is in the first        /* If the section count is zero, the actual count is in the first
631           section header.  */           section header.  */
632        if (i_ehdrp->e_shnum == SHN_UNDEF)        if (i_ehdrp->e_shnum == SHN_UNDEF)
633          i_ehdrp->e_shnum = i_shdr.sh_size;          {
634              i_ehdrp->e_shnum = i_shdr.sh_size;
635              if (i_ehdrp->e_shnum != i_shdr.sh_size
636                  || i_ehdrp->e_shnum == 0)
637                goto got_wrong_format_error;
638            }
639    
640        /* And similarly for the string table index.  */        /* And similarly for the string table index.  */
641        if (i_ehdrp->e_shstrndx == SHN_XINDEX)        if (i_ehdrp->e_shstrndx == SHN_XINDEX)
642          i_ehdrp->e_shstrndx = i_shdr.sh_link;          {
643              i_ehdrp->e_shstrndx = i_shdr.sh_link;
644              if (i_ehdrp->e_shstrndx != i_shdr.sh_link)
645                goto got_wrong_format_error;
646            }
647    
648          /* Sanity check that we can read all of the section headers.
649             It ought to be good enough to just read the last one.  */
650          if (i_ehdrp->e_shnum != 1)
651            {
652              /* Check that we don't have a totally silly number of sections.  */
653              if (i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (x_shdr)
654                  || i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (i_shdr))
655                goto got_wrong_format_error;
656    
657              where += (i_ehdrp->e_shnum - 1) * sizeof (x_shdr);
658              if (where != (file_ptr) where)
659                goto got_wrong_format_error;
660              if ((bfd_size_type) where <= i_ehdrp->e_shoff)
661                goto got_wrong_format_error;
662    
663              if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
664                goto got_no_match;
665              if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
666                goto got_no_match;
667    
668              /* Back to where we were.  */
669              where = i_ehdrp->e_shoff + sizeof (x_shdr);
670              if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
671                goto got_no_match;
672            }
673      }      }
674    
675    /* Allocate space for a copy of the section header table in    /* Allocate space for a copy of the section header table in
# Line 712  elf_object_p (abfd) Line 680  elf_object_p (abfd)
680        unsigned int num_sec;        unsigned int num_sec;
681    
682        amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum;        amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum;
683        i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);        i_shdrp = bfd_alloc (abfd, amt);
684        if (!i_shdrp)        if (!i_shdrp)
685          goto got_no_match;          goto got_no_match;
686        num_sec = i_ehdrp->e_shnum;        num_sec = i_ehdrp->e_shnum;
# Line 720  elf_object_p (abfd) Line 688  elf_object_p (abfd)
688          num_sec += SHN_HIRESERVE + 1 - SHN_LORESERVE;          num_sec += SHN_HIRESERVE + 1 - SHN_LORESERVE;
689        elf_numsections (abfd) = num_sec;        elf_numsections (abfd) = num_sec;
690        amt = sizeof (i_shdrp) * num_sec;        amt = sizeof (i_shdrp) * num_sec;
691        elf_elfsections (abfd) = (Elf_Internal_Shdr **) bfd_alloc (abfd, amt);        elf_elfsections (abfd) = bfd_alloc (abfd, amt);
692        if (!elf_elfsections (abfd))        if (!elf_elfsections (abfd))
693          goto got_no_match;          goto got_no_match;
694    
# Line 741  elf_object_p (abfd) Line 709  elf_object_p (abfd)
709           to internal form.  */           to internal form.  */
710        for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++)        for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++)
711          {          {
712            if (bfd_bread ((PTR) & x_shdr, (bfd_size_type) sizeof x_shdr, abfd)            if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
               != sizeof (x_shdr))  
713              goto got_no_match;              goto got_no_match;
714            elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);            elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
715    
716              /* Sanity check sh_link and sh_info.  */
717              if (i_shdrp[shindex].sh_link >= num_sec
718                  || (i_shdrp[shindex].sh_link >= SHN_LORESERVE
719                      && i_shdrp[shindex].sh_link <= SHN_HIRESERVE))
720                goto got_wrong_format_error;
721    
722              if (((i_shdrp[shindex].sh_flags & SHF_INFO_LINK)
723                   || i_shdrp[shindex].sh_type == SHT_RELA
724                   || i_shdrp[shindex].sh_type == SHT_REL)
725                  && (i_shdrp[shindex].sh_info >= num_sec
726                      || (i_shdrp[shindex].sh_info >= SHN_LORESERVE
727                          && i_shdrp[shindex].sh_info <= SHN_HIRESERVE)))
728                goto got_wrong_format_error;
729    
730            /* If the section is loaded, but not page aligned, clear            /* If the section is loaded, but not page aligned, clear
731               D_PAGED.  */               D_PAGED.  */
732            if (i_shdrp[shindex].sh_size != 0            if (i_shdrp[shindex].sh_size != 0
733                && (i_shdrp[shindex].sh_flags & SHF_ALLOC) != 0                && (i_shdrp[shindex].sh_flags & SHF_ALLOC) != 0
734                && i_shdrp[shindex].sh_type != SHT_NOBITS                && i_shdrp[shindex].sh_type != SHT_NOBITS
735                && (((i_shdrp[shindex].sh_addr - i_shdrp[shindex].sh_offset)                && (((i_shdrp[shindex].sh_addr - i_shdrp[shindex].sh_offset)
736                     % ebd->maxpagesize)                     % ebd->minpagesize)
737                    != 0))                    != 0))
738              abfd->flags &= ~D_PAGED;              abfd->flags &= ~D_PAGED;
739          }          }
740      }      }
741    
742    if (i_ehdrp->e_shstrndx && i_ehdrp->e_shoff)    /* A further sanity check.  */
743      if (i_ehdrp->e_shnum != 0)
744      {      {
745        if (! bfd_section_from_shdr (abfd, i_ehdrp->e_shstrndx))        if (i_ehdrp->e_shstrndx >= elf_numsections (abfd)
746          goto got_no_match;            || (i_ehdrp->e_shstrndx >= SHN_LORESERVE
747                  && i_ehdrp->e_shstrndx <= SHN_HIRESERVE))
748            goto got_wrong_format_error;
749      }      }
750      else if (i_ehdrp->e_shstrndx != 0)
751        goto got_wrong_format_error;
752    
753    /* Read in the program headers.  */    /* Read in the program headers.  */
754    if (i_ehdrp->e_phnum == 0)    if (i_ehdrp->e_phnum == 0)
# Line 773  elf_object_p (abfd) Line 759  elf_object_p (abfd)
759        unsigned int i;        unsigned int i;
760    
761        amt = i_ehdrp->e_phnum * sizeof (Elf_Internal_Phdr);        amt = i_ehdrp->e_phnum * sizeof (Elf_Internal_Phdr);
762        elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);        elf_tdata (abfd)->phdr = bfd_alloc (abfd, amt);
763        if (elf_tdata (abfd)->phdr == NULL)        if (elf_tdata (abfd)->phdr == NULL)
764          goto got_no_match;          goto got_no_match;
765        if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)        if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
# Line 783  elf_object_p (abfd) Line 769  elf_object_p (abfd)
769          {          {
770            Elf_External_Phdr x_phdr;            Elf_External_Phdr x_phdr;
771    
772            if (bfd_bread ((PTR) &x_phdr, (bfd_size_type) sizeof x_phdr, abfd)            if (bfd_bread (&x_phdr, sizeof x_phdr, abfd) != sizeof x_phdr)
               != sizeof x_phdr)  
773              goto got_no_match;              goto got_no_match;
774            elf_swap_phdr_in (abfd, &x_phdr, i_phdr);            elf_swap_phdr_in (abfd, &x_phdr, i_phdr);
775          }          }
776      }      }
777    
778    /* Read in the string table containing the names of the sections.  We    if (i_ehdrp->e_shstrndx != 0 && i_ehdrp->e_shoff != 0)
      will need the base pointer to this table later.  */  
   /* We read this inline now, so that we don't have to go through  
      bfd_section_from_shdr with it (since this particular strtab is  
      used to find all of the ELF section names.) */  
   
   if (i_ehdrp->e_shstrndx != 0 && i_ehdrp->e_shoff)  
779      {      {
780        unsigned int num_sec;        unsigned int num_sec;
781    
       shstrtab = bfd_elf_get_str_section (abfd, i_ehdrp->e_shstrndx);  
       if (!shstrtab)  
         goto got_no_match;  
   
782        /* Once all of the section headers have been read and converted, we        /* Once all of the section headers have been read and converted, we
783           can start processing them.  Note that the first section header is           can start processing them.  Note that the first section header is
784           a dummy placeholder entry, so we ignore it.  */           a dummy placeholder entry, so we ignore it.  */
# Line 815  elf_object_p (abfd) Line 790  elf_object_p (abfd)
790            if (shindex == SHN_LORESERVE - 1)            if (shindex == SHN_LORESERVE - 1)
791              shindex += SHN_HIRESERVE + 1 - SHN_LORESERVE;              shindex += SHN_HIRESERVE + 1 - SHN_LORESERVE;
792          }          }
793    
794          /* Set up group pointers.  */
795          if (! _bfd_elf_setup_group_pointers (abfd))
796            goto got_wrong_format_error;
797      }      }
798    
799    /* Let the backend double check the format and override global    /* Let the backend double check the format and override global
# Line 844  elf_object_p (abfd) Line 823  elf_object_p (abfd)
823          }          }
824      }      }
825    
826    /* It would be nice to be able to free more memory here, eg. old    bfd_preserve_finish (abfd, &preserve);
827       elf_elfsections, old tdata, but that's not possible since these    return abfd->xvec;
      blocks are sitting inside obj_alloc'd memory.  */  
   bfd_hash_table_free (&preserve.section_htab);  
   return (abfd->xvec);  
828    
829   got_wrong_format_error:   got_wrong_format_error:
830    /* There is way too much undoing of half-known state here.  The caller,    /* There is way too much undoing of half-known state here.  The caller,
# Line 863  elf_object_p (abfd) Line 839  elf_object_p (abfd)
839    bfd_set_error (bfd_error_wrong_format);    bfd_set_error (bfd_error_wrong_format);
840    
841   got_no_match:   got_no_match:
842    abfd->arch_info = preserve.arch_info;    if (preserve.marker != NULL)
843    if (new_tdata != NULL)      bfd_preserve_restore (abfd, &preserve);
     {  
       /* bfd_release frees all memory more recently bfd_alloc'd than  
          its arg, as well as its arg.  */  
       bfd_release (abfd, new_tdata);  
       elf_tdata (abfd) = preserve.tdata;  
       abfd->section_htab = preserve.section_htab;  
       abfd->sections = preserve.sections;  
       abfd->section_tail = preserve.section_tail;  
       abfd->section_count = preserve.section_count;  
     }  
844    return NULL;    return NULL;
845  }  }
846    
# Line 883  elf_object_p (abfd) Line 849  elf_object_p (abfd)
849  /* Write out the relocs.  */  /* Write out the relocs.  */
850    
851  void  void
852  elf_write_relocs (abfd, sec, data)  elf_write_relocs (bfd *abfd, asection *sec, void *data)
      bfd *abfd;  
      asection *sec;  
      PTR data;  
853  {  {
854    boolean *failedp = (boolean *) data;    bfd_boolean *failedp = data;
855    Elf_Internal_Shdr *rela_hdr;    Elf_Internal_Shdr *rela_hdr;
856    Elf_External_Rela *outbound_relocas;    bfd_vma addr_offset;
857    Elf_External_Rel *outbound_relocs;    void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
858      size_t extsize;
859      bfd_byte *dst_rela;
860    unsigned int idx;    unsigned int idx;
861    int use_rela_p;    asymbol *last_sym;
862    asymbol *last_sym = 0;    int last_sym_idx;
   int last_sym_idx = 0;  
863    
864    /* If we have already failed, don't do anything.  */    /* If we have already failed, don't do anything.  */
865    if (*failedp)    if (*failedp)
# Line 914  elf_write_relocs (abfd, sec, data) Line 878  elf_write_relocs (abfd, sec, data)
878    rela_hdr = &elf_section_data (sec)->rel_hdr;    rela_hdr = &elf_section_data (sec)->rel_hdr;
879    
880    rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count;    rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count;
881    rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);    rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
882    if (rela_hdr->contents == NULL)    if (rela_hdr->contents == NULL)
883      {      {
884        *failedp = true;        *failedp = TRUE;
885        return;        return;
886      }      }
887    
888    /* Figure out whether the relocations are RELA or REL relocations.  */    /* Figure out whether the relocations are RELA or REL relocations.  */
889    if (rela_hdr->sh_type == SHT_RELA)    if (rela_hdr->sh_type == SHT_RELA)
890      use_rela_p = true;      {
891          swap_out = elf_swap_reloca_out;
892          extsize = sizeof (Elf_External_Rela);
893        }
894    else if (rela_hdr->sh_type == SHT_REL)    else if (rela_hdr->sh_type == SHT_REL)
895      use_rela_p = false;      {
896          swap_out = elf_swap_reloc_out;
897          extsize = sizeof (Elf_External_Rel);
898        }
899    else    else
900      /* Every relocation section should be either an SHT_RELA or an      /* Every relocation section should be either an SHT_RELA or an
901         SHT_REL section.  */         SHT_REL section.  */
902      abort ();      abort ();
903    
904    /* orelocation has the data, reloc_count has the count...  */    /* The address of an ELF reloc is section relative for an object
905    if (use_rela_p)       file, and absolute for an executable file or shared library.
906      {       The address of a BFD reloc is always section relative.  */
907        outbound_relocas = (Elf_External_Rela *) rela_hdr->contents;    addr_offset = 0;
908      if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
909        addr_offset = sec->vma;
910    
911        for (idx = 0; idx < sec->reloc_count; idx++)    /* orelocation has the data, reloc_count has the count...  */
912      last_sym = 0;
913      last_sym_idx = 0;
914      dst_rela = rela_hdr->contents;
915    
916      for (idx = 0; idx < sec->reloc_count; idx++, dst_rela += extsize)
917        {
918          Elf_Internal_Rela src_rela;
919          arelent *ptr;
920          asymbol *sym;
921          int n;
922    
923          ptr = sec->orelocation[idx];
924          sym = *ptr->sym_ptr_ptr;
925          if (sym == last_sym)
926            n = last_sym_idx;
927          else if (bfd_is_abs_section (sym->section) && sym->value == 0)
928            n = STN_UNDEF;
929          else
930          {          {
931            Elf_Internal_Rela dst_rela;            last_sym = sym;
932            Elf_External_Rela *src_rela;            n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
933            arelent *ptr;            if (n < 0)
           asymbol *sym;  
           int n;  
   
           ptr = sec->orelocation[idx];  
           src_rela = outbound_relocas + idx;  
   
           /* The address of an ELF reloc is section relative for an object  
              file, and absolute for an executable file or shared library.  
              The address of a BFD reloc is always section relative.  */  
           if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)  
             dst_rela.r_offset = ptr->address;  
           else  
             dst_rela.r_offset = ptr->address + sec->vma;  
   
           sym = *ptr->sym_ptr_ptr;  
           if (sym == last_sym)  
             n = last_sym_idx;  
           else if (bfd_is_abs_section (sym->section) && sym->value == 0)  
             n = STN_UNDEF;  
           else  
934              {              {
935                last_sym = sym;                *failedp = TRUE;
               n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);  
               if (n < 0)  
                 {  
                   *failedp = true;  
                   return;  
                 }  
               last_sym_idx = n;  
             }  
   
           if ((*ptr->sym_ptr_ptr)->the_bfd != NULL  
               && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec  
               && ! _bfd_elf_validate_reloc (abfd, ptr))  
             {  
               *failedp = true;  
936                return;                return;
937              }              }
938              last_sym_idx = n;
           dst_rela.r_info = ELF_R_INFO (n, ptr->howto->type);  
   
           dst_rela.r_addend = ptr->addend;  
           elf_swap_reloca_out (abfd, &dst_rela, src_rela);  
939          }          }
     }  
   else  
     /* REL relocations */  
     {  
       outbound_relocs = (Elf_External_Rel *) rela_hdr->contents;  
940    
941        for (idx = 0; idx < sec->reloc_count; idx++)        if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
942              && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
943              && ! _bfd_elf_validate_reloc (abfd, ptr))
944          {          {
945            Elf_Internal_Rel dst_rel;            *failedp = TRUE;
946            Elf_External_Rel *src_rel;            return;
           arelent *ptr;  
           int n;  
           asymbol *sym;  
   
           ptr = sec->orelocation[idx];  
           sym = *ptr->sym_ptr_ptr;  
           src_rel = outbound_relocs + idx;  
   
           /* The address of an ELF reloc is section relative for an object  
              file, and absolute for an executable file or shared library.  
              The address of a BFD reloc is always section relative.  */  
           if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)  
             dst_rel.r_offset = ptr->address;  
           else  
             dst_rel.r_offset = ptr->address + sec->vma;  
   
           if (sym == last_sym)  
             n = last_sym_idx;  
           else if (bfd_is_abs_section (sym->section) && sym->value == 0)  
             n = STN_UNDEF;  
           else  
             {  
               last_sym = sym;  
               n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);  
               if (n < 0)  
                 {  
                   *failedp = true;  
                   return;  
                 }  
               last_sym_idx = n;  
             }  
   
           if ((*ptr->sym_ptr_ptr)->the_bfd != NULL  
               && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec  
               && ! _bfd_elf_validate_reloc (abfd, ptr))  
             {  
               *failedp = true;  
               return;  
             }  
   
           dst_rel.r_info = ELF_R_INFO (n, ptr->howto->type);  
   
           elf_swap_reloc_out (abfd, &dst_rel, src_rel);  
947          }          }
948    
949          src_rela.r_offset = ptr->address + addr_offset;
950          src_rela.r_info = ELF_R_INFO (n, ptr->howto->type);
951          src_rela.r_addend = ptr->addend;
952          (*swap_out) (abfd, &src_rela, dst_rela);
953      }      }
954  }  }
955    
956  /* Write out the program headers.  */  /* Write out the program headers.  */
957    
958  int  int
959  elf_write_out_phdrs (abfd, phdr, count)  elf_write_out_phdrs (bfd *abfd,
960       bfd *abfd;                       const Elf_Internal_Phdr *phdr,
961       const Elf_Internal_Phdr *phdr;                       unsigned int count)
      unsigned int count;  
962  {  {
963    while (count--)    while (count--)
964      {      {
965        Elf_External_Phdr extphdr;        Elf_External_Phdr extphdr;
966        elf_swap_phdr_out (abfd, phdr, &extphdr);        elf_swap_phdr_out (abfd, phdr, &extphdr);
967        if (bfd_bwrite (&extphdr, (bfd_size_type) sizeof (Elf_External_Phdr),        if (bfd_bwrite (&extphdr, sizeof (Elf_External_Phdr), abfd)
968                       abfd) != sizeof (Elf_External_Phdr))            != sizeof (Elf_External_Phdr))
969          return -1;          return -1;
970        phdr++;        phdr++;
971      }      }
# Line 1064  elf_write_out_phdrs (abfd, phdr, count) Line 974  elf_write_out_phdrs (abfd, phdr, count)
974    
975  /* Write out the section headers and the ELF file header.  */  /* Write out the section headers and the ELF file header.  */
976    
977  boolean  bfd_boolean
978  elf_write_shdrs_and_ehdr (abfd)  elf_write_shdrs_and_ehdr (bfd *abfd)
      bfd *abfd;  
979  {  {
980    Elf_External_Ehdr x_ehdr;     /* Elf file header, external form */    Elf_External_Ehdr x_ehdr;     /* Elf file header, external form */
981    Elf_Internal_Ehdr *i_ehdrp;   /* Elf file header, internal form */    Elf_Internal_Ehdr *i_ehdrp;   /* Elf file header, internal form */
# Line 1086  elf_write_shdrs_and_ehdr (abfd) Line 995  elf_write_shdrs_and_ehdr (abfd)
995    elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr);    elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr);
996    amt = sizeof (x_ehdr);    amt = sizeof (x_ehdr);
997    if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0    if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
998        || bfd_bwrite ((PTR) & x_ehdr, amt, abfd) != amt)        || bfd_bwrite (&x_ehdr, amt, abfd) != amt)
999      return false;      return FALSE;
1000    
1001    /* Some fields in the first section header handle overflow of ehdr    /* Some fields in the first section header handle overflow of ehdr
1002       fields.  */       fields.  */
# Line 1099  elf_write_shdrs_and_ehdr (abfd) Line 1008  elf_write_shdrs_and_ehdr (abfd)
1008    /* at this point we've concocted all the ELF sections...  */    /* at this point we've concocted all the ELF sections...  */
1009    amt = i_ehdrp->e_shnum;    amt = i_ehdrp->e_shnum;
1010    amt *= sizeof (*x_shdrp);    amt *= sizeof (*x_shdrp);
1011    x_shdrp = (Elf_External_Shdr *) bfd_alloc (abfd, amt);    x_shdrp = bfd_alloc (abfd, amt);
1012    if (!x_shdrp)    if (!x_shdrp)
1013      return false;      return FALSE;
1014    
1015    for (count = 0; count < i_ehdrp->e_shnum; i_shdrp++, count++)    for (count = 0; count < i_ehdrp->e_shnum; i_shdrp++, count++)
1016      {      {
# Line 1109  elf_write_shdrs_and_ehdr (abfd) Line 1018  elf_write_shdrs_and_ehdr (abfd)
1018        elf_debug_section (count, *i_shdrp);        elf_debug_section (count, *i_shdrp);
1019  #endif  #endif
1020        elf_swap_shdr_out (abfd, *i_shdrp, x_shdrp + count);        elf_swap_shdr_out (abfd, *i_shdrp, x_shdrp + count);
1021          
1022        if (count == SHN_LORESERVE - 1)        if (count == SHN_LORESERVE - 1)
1023          i_shdrp += SHN_HIRESERVE + 1 - SHN_LORESERVE;          i_shdrp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
1024      }      }
1025    if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0    if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0
1026        || bfd_bwrite ((PTR) x_shdrp, amt, abfd) != amt)        || bfd_bwrite (x_shdrp, amt, abfd) != amt)
1027      return false;      return FALSE;
1028    
1029    /* need to dump the string table too...  */    /* need to dump the string table too...  */
1030    
1031    return true;    return TRUE;
1032  }  }
1033    
1034  long  long
1035  elf_slurp_symbol_table (abfd, symptrs, dynamic)  elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
      bfd *abfd;  
      asymbol **symptrs;         /* Buffer for generated bfd symbols */  
      boolean dynamic;  
1036  {  {
1037    Elf_Internal_Shdr *hdr;    Elf_Internal_Shdr *hdr;
1038    Elf_Internal_Shdr *verhdr;    Elf_Internal_Shdr *verhdr;
# Line 1138  elf_slurp_symbol_table (abfd, symptrs, d Line 1044  elf_slurp_symbol_table (abfd, symptrs, d
1044    Elf_Internal_Sym *isymbuf = NULL;    Elf_Internal_Sym *isymbuf = NULL;
1045    Elf_External_Versym *xver;    Elf_External_Versym *xver;
1046    Elf_External_Versym *xverbuf = NULL;    Elf_External_Versym *xverbuf = NULL;
1047    struct elf_backend_data *ebd;    const struct elf_backend_data *ebd;
1048    bfd_size_type amt;    bfd_size_type amt;
1049    
1050    /* Read each raw ELF symbol, converting from external ELF form to    /* Read each raw ELF symbol, converting from external ELF form to
# Line 1168  elf_slurp_symbol_table (abfd, symptrs, d Line 1074  elf_slurp_symbol_table (abfd, symptrs, d
1074            || (elf_tdata (abfd)->dynverref_section != 0            || (elf_tdata (abfd)->dynverref_section != 0
1075                && elf_tdata (abfd)->verref == NULL))                && elf_tdata (abfd)->verref == NULL))
1076          {          {
1077            if (! _bfd_elf_slurp_version_tables (abfd))            if (!_bfd_elf_slurp_version_tables (abfd, FALSE))
1078              return -1;              return -1;
1079          }          }
1080      }      }
# Line 1186  elf_slurp_symbol_table (abfd, symptrs, d Line 1092  elf_slurp_symbol_table (abfd, symptrs, d
1092    
1093        amt = symcount;        amt = symcount;
1094        amt *= sizeof (elf_symbol_type);        amt *= sizeof (elf_symbol_type);
1095        symbase = (elf_symbol_type *) bfd_zalloc (abfd, amt);        symbase = bfd_zalloc (abfd, amt);
1096        if (symbase == (elf_symbol_type *) NULL)        if (symbase == (elf_symbol_type *) NULL)
1097          goto error_return;          goto error_return;
1098    
# Line 1201  elf_slurp_symbol_table (abfd, symptrs, d Line 1107  elf_slurp_symbol_table (abfd, symptrs, d
1107               symcount);               symcount);
1108    
1109            /* Slurp in the symbols without the version information,            /* Slurp in the symbols without the version information,
1110               since that is more helpful than just quitting.  */               since that is more helpful than just quitting.  */
1111            verhdr = NULL;            verhdr = NULL;
1112          }          }
1113    
# Line 1210  elf_slurp_symbol_table (abfd, symptrs, d Line 1116  elf_slurp_symbol_table (abfd, symptrs, d
1116            if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0)            if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0)
1117              goto error_return;              goto error_return;
1118    
1119            xverbuf = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);            xverbuf = bfd_malloc (verhdr->sh_size);
1120            if (xverbuf == NULL && verhdr->sh_size != 0)            if (xverbuf == NULL && verhdr->sh_size != 0)
1121              goto error_return;              goto error_return;
1122    
1123            if (bfd_bread ((PTR) xverbuf, verhdr->sh_size, abfd)            if (bfd_bread (xverbuf, verhdr->sh_size, abfd) != verhdr->sh_size)
               != verhdr->sh_size)  
1124              goto error_return;              goto error_return;
1125          }          }
1126    
# Line 1229  elf_slurp_symbol_table (abfd, symptrs, d Line 1134  elf_slurp_symbol_table (abfd, symptrs, d
1134            memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));            memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
1135            sym->symbol.the_bfd = abfd;            sym->symbol.the_bfd = abfd;
1136    
1137            sym->symbol.name = bfd_elf_string_from_elf_section (abfd,            sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym);
                                                               hdr->sh_link,  
                                                               isym->st_name);  
1138    
1139            sym->symbol.value = isym->st_value;            sym->symbol.value = isym->st_value;
1140    
# Line 1242  elf_slurp_symbol_table (abfd, symptrs, d Line 1145  elf_slurp_symbol_table (abfd, symptrs, d
1145            else if (isym->st_shndx < SHN_LORESERVE            else if (isym->st_shndx < SHN_LORESERVE
1146                     || isym->st_shndx > SHN_HIRESERVE)                     || isym->st_shndx > SHN_HIRESERVE)
1147              {              {
1148                sym->symbol.section = section_from_elf_index (abfd,                sym->symbol.section = bfd_section_from_elf_index (abfd,
1149                                                              isym->st_shndx);                                                                  isym->st_shndx);
1150                if (sym->symbol.section == NULL)                if (sym->symbol.section == NULL)
1151                  {                  {
1152                    /* This symbol is in a section for which we did not                    /* This symbol is in a section for which we did not
# Line 1268  elf_slurp_symbol_table (abfd, symptrs, d Line 1171  elf_slurp_symbol_table (abfd, symptrs, d
1171            else            else
1172              sym->symbol.section = bfd_abs_section_ptr;              sym->symbol.section = bfd_abs_section_ptr;
1173    
1174            /* If this is a relocateable file, then the symbol value is            /* If this is a relocatable file, then the symbol value is
1175               already section relative.  */               already section relative.  */
1176            if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)            if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
1177              sym->symbol.value -= sym->symbol.section->vma;              sym->symbol.value -= sym->symbol.section->vma;
1178    
# Line 1301  elf_slurp_symbol_table (abfd, symptrs, d Line 1204  elf_slurp_symbol_table (abfd, symptrs, d
1204              case STT_OBJECT:              case STT_OBJECT:
1205                sym->symbol.flags |= BSF_OBJECT;                sym->symbol.flags |= BSF_OBJECT;
1206                break;                break;
1207                case STT_TLS:
1208                  sym->symbol.flags |= BSF_THREAD_LOCAL;
1209                  break;
1210              }              }
1211    
1212            if (dynamic)            if (dynamic)
# Line 1357  error_return: Line 1263  error_return:
1263    return -1;    return -1;
1264  }  }
1265    
1266  /* Read  relocations for ASECT from REL_HDR.  There are RELOC_COUNT of  /* Read relocations for ASECT from REL_HDR.  There are RELOC_COUNT of
1267     them.  */     them.  */
1268    
1269  static boolean  static bfd_boolean
1270  elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr, reloc_count,  elf_slurp_reloc_table_from_section (bfd *abfd,
1271                                      relents, symbols, dynamic)                                      asection *asect,
1272       bfd *abfd;                                      Elf_Internal_Shdr *rel_hdr,
1273       asection *asect;                                      bfd_size_type reloc_count,
1274       Elf_Internal_Shdr *rel_hdr;                                      arelent *relents,
1275       bfd_size_type reloc_count;                                      asymbol **symbols,
1276       arelent *relents;                                      bfd_boolean dynamic)
      asymbol **symbols;  
      boolean dynamic;  
1277  {  {
1278    struct elf_backend_data * const ebd = get_elf_backend_data (abfd);    const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
1279    PTR allocated = NULL;    void *allocated = NULL;
1280    bfd_byte *native_relocs;    bfd_byte *native_relocs;
1281    arelent *relent;    arelent *relent;
1282    unsigned int i;    unsigned int i;
1283    int entsize;    int entsize;
1284      unsigned int symcount;
1285    
1286    allocated = (PTR) bfd_malloc (rel_hdr->sh_size);    allocated = bfd_malloc (rel_hdr->sh_size);
1287    if (allocated == NULL)    if (allocated == NULL)
1288      goto error_return;      goto error_return;
1289    
# Line 1387  elf_slurp_reloc_table_from_section (abfd Line 1292  elf_slurp_reloc_table_from_section (abfd
1292            != rel_hdr->sh_size))            != rel_hdr->sh_size))
1293      goto error_return;      goto error_return;
1294    
1295    native_relocs = (bfd_byte *) allocated;    native_relocs = allocated;
1296    
1297    entsize = rel_hdr->sh_entsize;    entsize = rel_hdr->sh_entsize;
1298    BFD_ASSERT (entsize == sizeof (Elf_External_Rel)    BFD_ASSERT (entsize == sizeof (Elf_External_Rel)
1299                || entsize == sizeof (Elf_External_Rela));                || entsize == sizeof (Elf_External_Rela));
1300    
1301      if (dynamic)
1302        symcount = bfd_get_dynamic_symcount (abfd);
1303      else
1304        symcount = bfd_get_symcount (abfd);
1305    
1306    for (i = 0, relent = relents;    for (i = 0, relent = relents;
1307         i < reloc_count;         i < reloc_count;
1308         i++, relent++, native_relocs += entsize)         i++, relent++, native_relocs += entsize)
1309      {      {
1310        Elf_Internal_Rela rela;        Elf_Internal_Rela rela;
       Elf_Internal_Rel rel;  
1311    
1312        if (entsize == sizeof (Elf_External_Rela))        if (entsize == sizeof (Elf_External_Rela))
1313          elf_swap_reloca_in (abfd, (Elf_External_Rela *) native_relocs, &rela);          elf_swap_reloca_in (abfd, native_relocs, &rela);
1314        else        else
1315          {          elf_swap_reloc_in (abfd, native_relocs, &rela);
           elf_swap_reloc_in (abfd, (Elf_External_Rel *) native_relocs, &rel);  
           rela.r_offset = rel.r_offset;  
           rela.r_info = rel.r_info;  
           rela.r_addend = 0;  
         }  
1316    
1317        /* The address of an ELF reloc is section relative for an object        /* The address of an ELF reloc is section relative for an object
1318           file, and absolute for an executable file or shared library.           file, and absolute for an executable file or shared library.
# Line 1421  elf_slurp_reloc_table_from_section (abfd Line 1325  elf_slurp_reloc_table_from_section (abfd
1325    
1326        if (ELF_R_SYM (rela.r_info) == 0)        if (ELF_R_SYM (rela.r_info) == 0)
1327          relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;          relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1328          else if (ELF_R_SYM (rela.r_info) > symcount)
1329            {
1330              (*_bfd_error_handler)
1331                (_("%s(%s): relocation %d has invalid symbol index %ld"),
1332                 abfd->filename, asect->name, i, ELF_R_SYM (rela.r_info));
1333              relent->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
1334            }
1335        else        else
1336          {          {
1337            asymbol **ps, *s;            asymbol **ps, *s;
# Line 1428  elf_slurp_reloc_table_from_section (abfd Line 1339  elf_slurp_reloc_table_from_section (abfd
1339            ps = symbols + ELF_R_SYM (rela.r_info) - 1;            ps = symbols + ELF_R_SYM (rela.r_info) - 1;
1340            s = *ps;            s = *ps;
1341    
1342            /* Canonicalize ELF section symbols.  FIXME: Why?  */            relent->sym_ptr_ptr = ps;
           if ((s->flags & BSF_SECTION_SYM) == 0)  
             relent->sym_ptr_ptr = ps;  
           else  
             relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;  
1343          }          }
1344    
1345        relent->addend = rela.r_addend;        relent->addend = rela.r_addend;
1346    
1347        if (entsize == sizeof (Elf_External_Rela))        if ((entsize == sizeof (Elf_External_Rela)
1348               && ebd->elf_info_to_howto != NULL)
1349              || ebd->elf_info_to_howto_rel == NULL)
1350          (*ebd->elf_info_to_howto) (abfd, relent, &rela);          (*ebd->elf_info_to_howto) (abfd, relent, &rela);
1351        else        else
1352          (*ebd->elf_info_to_howto_rel) (abfd, relent, &rel);          (*ebd->elf_info_to_howto_rel) (abfd, relent, &rela);
1353      }      }
1354    
1355    if (allocated != NULL)    if (allocated != NULL)
1356      free (allocated);      free (allocated);
1357    
1358    return true;    return TRUE;
1359    
1360   error_return:   error_return:
1361    if (allocated != NULL)    if (allocated != NULL)
1362      free (allocated);      free (allocated);
1363    return false;    return FALSE;
1364  }  }
1365    
1366  /* Read in and swap the external relocs.  */  /* Read in and swap the external relocs.  */
1367    
1368  boolean  bfd_boolean
1369  elf_slurp_reloc_table (abfd, asect, symbols, dynamic)  elf_slurp_reloc_table (bfd *abfd,
1370       bfd *abfd;                         asection *asect,
1371       asection *asect;                         asymbol **symbols,
1372       asymbol **symbols;                         bfd_boolean dynamic)
      boolean dynamic;  
1373  {  {
1374    struct bfd_elf_section_data * const d = elf_section_data (asect);    struct bfd_elf_section_data * const d = elf_section_data (asect);
1375    Elf_Internal_Shdr *rel_hdr;    Elf_Internal_Shdr *rel_hdr;
# Line 1472  elf_slurp_reloc_table (abfd, asect, symb Line 1380  elf_slurp_reloc_table (abfd, asect, symb
1380    bfd_size_type amt;    bfd_size_type amt;
1381    
1382    if (asect->relocation != NULL)    if (asect->relocation != NULL)
1383      return true;      return TRUE;
1384    
1385    if (! dynamic)    if (! dynamic)
1386      {      {
1387        if ((asect->flags & SEC_RELOC) == 0        if ((asect->flags & SEC_RELOC) == 0
1388            || asect->reloc_count == 0)            || asect->reloc_count == 0)
1389          return true;          return TRUE;
1390    
1391        rel_hdr = &d->rel_hdr;        rel_hdr = &d->rel_hdr;
1392        reloc_count = NUM_SHDR_ENTRIES (rel_hdr);        reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
# Line 1496  elf_slurp_reloc_table (abfd, asect, symb Line 1404  elf_slurp_reloc_table (abfd, asect, symb
1404           case because relocations against this section may use the           case because relocations against this section may use the
1405           dynamic symbol table, and in that case bfd_section_from_shdr           dynamic symbol table, and in that case bfd_section_from_shdr
1406           in elf.c does not update the RELOC_COUNT.  */           in elf.c does not update the RELOC_COUNT.  */
1407        if (asect->_raw_size == 0)        if (asect->size == 0)
1408          return true;          return TRUE;
1409    
1410        rel_hdr = &d->this_hdr;        rel_hdr = &d->this_hdr;
1411        reloc_count = NUM_SHDR_ENTRIES (rel_hdr);        reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
# Line 1506  elf_slurp_reloc_table (abfd, asect, symb Line 1414  elf_slurp_reloc_table (abfd, asect, symb
1414      }      }
1415    
1416    amt = (reloc_count + reloc_count2) * sizeof (arelent);    amt = (reloc_count + reloc_count2) * sizeof (arelent);
1417    relents = (arelent *) bfd_alloc (abfd, amt);    relents = bfd_alloc (abfd, amt);
1418    if (relents == NULL)    if (relents == NULL)
1419      return false;      return FALSE;
1420    
1421    if (!elf_slurp_reloc_table_from_section (abfd, asect,    if (!elf_slurp_reloc_table_from_section (abfd, asect,
1422                                             rel_hdr, reloc_count,                                             rel_hdr, reloc_count,
1423                                             relents,                                             relents,
1424                                             symbols, dynamic))                                             symbols, dynamic))
1425      return false;      return FALSE;
1426    
1427    if (rel_hdr2    if (rel_hdr2
1428        && !elf_slurp_reloc_table_from_section (abfd, asect,        && !elf_slurp_reloc_table_from_section (abfd, asect,
1429                                                rel_hdr2, reloc_count2,                                                rel_hdr2, reloc_count2,
1430                                                relents + reloc_count,                                                relents + reloc_count,
1431                                                symbols, dynamic))                                                symbols, dynamic))
1432      return false;      return FALSE;
1433    
1434    asect->relocation = relents;    asect->relocation = relents;
1435    return true;    return TRUE;
1436  }  }
1437    
1438  #ifdef DEBUG  #ifdef DEBUG
1439  static void  static void
1440  elf_debug_section (num, hdr)  elf_debug_section (int num, Elf_Internal_Shdr *hdr)
      int num;  
      Elf_Internal_Shdr *hdr;  
1441  {  {
1442    fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num,    fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num,
1443             hdr->bfd_section != NULL ? hdr->bfd_section->name : "",             hdr->bfd_section != NULL ? hdr->bfd_section->name : "",
# Line 1557  elf_debug_section (num, hdr) Line 1463  elf_debug_section (num, hdr)
1463  }  }
1464    
1465  static void  static void
1466  elf_debug_file (ehdrp)  elf_debug_file (Elf_Internal_Ehdr *ehdrp)
      Elf_Internal_Ehdr *ehdrp;  
1467  {  {
1468    fprintf (stderr, "e_entry      = 0x%.8lx\n", (long) ehdrp->e_entry);    fprintf (stderr, "e_entry      = 0x%.8lx\n", (long) ehdrp->e_entry);
1469    fprintf (stderr, "e_phoff      = %ld\n", (long) ehdrp->e_phoff);    fprintf (stderr, "e_phoff      = %ld\n", (long) ehdrp->e_phoff);
# Line 1570  elf_debug_file (ehdrp) Line 1475  elf_debug_file (ehdrp)
1475  }  }
1476    
1477  static char *  static char *
1478  elf_symbol_flags (flags)  elf_symbol_flags (flagword flags)
      flagword flags;  
1479  {  {
1480    static char buffer[1024];    static char buffer[1024];
1481    
# Line 1642  elf_symbol_flags (flags) Line 1546  elf_symbol_flags (flags)
1546  }  }
1547  #endif  #endif
1548    
1549    /* Create a new BFD as if by bfd_openr.  Rather than opening a file,
1550       reconstruct an ELF file by reading the segments out of remote memory
1551       based on the ELF file header at EHDR_VMA and the ELF program headers it
1552       points to.  If not null, *LOADBASEP is filled in with the difference
1553       between the VMAs from which the segments were read, and the VMAs the
1554       file headers (and hence BFD's idea of each section's VMA) put them at.
1555    
1556       The function TARGET_READ_MEMORY is called to copy LEN bytes from the
1557       remote memory at target address VMA into the local buffer at MYADDR; it
1558       should return zero on success or an `errno' code on failure.  TEMPL must
1559       be a BFD for a target with the word size and byte order found in the
1560       remote memory.  */
1561    
1562    bfd *
1563    NAME(_bfd_elf,bfd_from_remote_memory)
1564      (bfd *templ,
1565       bfd_vma ehdr_vma,
1566       bfd_vma *loadbasep,
1567       int (*target_read_memory) (bfd_vma, bfd_byte *, int))
1568    {
1569      Elf_External_Ehdr x_ehdr;     /* Elf file header, external form */
1570      Elf_Internal_Ehdr i_ehdr;     /* Elf file header, internal form */
1571      Elf_External_Phdr *x_phdrs;
1572      Elf_Internal_Phdr *i_phdrs, *last_phdr;
1573      bfd *nbfd;
1574      struct bfd_in_memory *bim;
1575      int contents_size;
1576      bfd_byte *contents;
1577      int err;
1578      unsigned int i;
1579      bfd_vma loadbase;
1580    
1581      /* Read in the ELF header in external format.  */
1582      err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr);
1583      if (err)
1584        {
1585          bfd_set_error (bfd_error_system_call);
1586          errno = err;
1587          return NULL;
1588        }
1589    
1590      /* Now check to see if we have a valid ELF file, and one that BFD can
1591         make use of.  The magic number must match, the address size ('class')
1592         and byte-swapping must match our XVEC entry.  */
1593    
1594      if (! elf_file_p (&x_ehdr)
1595          || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT
1596          || x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
1597        {
1598          bfd_set_error (bfd_error_wrong_format);
1599          return NULL;
1600        }
1601    
1602      /* Check that file's byte order matches xvec's */
1603      switch (x_ehdr.e_ident[EI_DATA])
1604        {
1605        case ELFDATA2MSB:           /* Big-endian */
1606          if (! bfd_header_big_endian (templ))
1607            {
1608              bfd_set_error (bfd_error_wrong_format);
1609              return NULL;
1610            }
1611          break;
1612        case ELFDATA2LSB:           /* Little-endian */
1613          if (! bfd_header_little_endian (templ))
1614            {
1615              bfd_set_error (bfd_error_wrong_format);
1616              return NULL;
1617            }
1618          break;
1619        case ELFDATANONE:           /* No data encoding specified */
1620        default:                    /* Unknown data encoding specified */
1621          bfd_set_error (bfd_error_wrong_format);
1622          return NULL;
1623        }
1624    
1625      elf_swap_ehdr_in (templ, &x_ehdr, &i_ehdr);
1626    
1627      /* The file header tells where to find the program headers.
1628         These are what we use to actually choose what to read.  */
1629    
1630      if (i_ehdr.e_phentsize != sizeof (Elf_External_Phdr) || i_ehdr.e_phnum == 0)
1631        {
1632          bfd_set_error (bfd_error_wrong_format);
1633          return NULL;
1634        }
1635    
1636      x_phdrs = bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs));
1637      if (x_phdrs == NULL)
1638        {
1639          bfd_set_error (bfd_error_no_memory);
1640          return NULL;
1641        }
1642      err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs,
1643                                i_ehdr.e_phnum * sizeof x_phdrs[0]);
1644      if (err)
1645        {
1646          free (x_phdrs);
1647          bfd_set_error (bfd_error_system_call);
1648          errno = err;
1649          return NULL;
1650        }
1651      i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum];
1652    
1653      contents_size = 0;
1654      last_phdr = NULL;
1655      loadbase = ehdr_vma;
1656      for (i = 0; i < i_ehdr.e_phnum; ++i)
1657        {
1658          elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]);
1659          if (i_phdrs[i].p_type == PT_LOAD)
1660            {
1661              bfd_vma segment_end;
1662              segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
1663                             + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
1664              if (segment_end > (bfd_vma) contents_size)
1665                contents_size = segment_end;
1666    
1667              if ((i_phdrs[i].p_offset & -i_phdrs[i].p_align) == 0)
1668                loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align);
1669    
1670              last_phdr = &i_phdrs[i];
1671            }
1672        }
1673      if (last_phdr == NULL)
1674        {
1675          /* There were no PT_LOAD segments, so we don't have anything to read.  */
1676          free (x_phdrs);
1677          bfd_set_error (bfd_error_wrong_format);
1678          return NULL;
1679        }
1680    
1681      /* Trim the last segment so we don't bother with zeros in the last page
1682         that are off the end of the file.  However, if the extra bit in that
1683         page includes the section headers, keep them.  */
1684      if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz
1685          && (bfd_vma) contents_size >= (i_ehdr.e_shoff
1686                                         + i_ehdr.e_shnum * i_ehdr.e_shentsize))
1687        {
1688          contents_size = last_phdr->p_offset + last_phdr->p_filesz;
1689          if ((bfd_vma) contents_size < (i_ehdr.e_shoff
1690                                         + i_ehdr.e_shnum * i_ehdr.e_shentsize))
1691            contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize;
1692        }
1693      else
1694        contents_size = last_phdr->p_offset + last_phdr->p_filesz;
1695    
1696      /* Now we know the size of the whole image we want read in.  */
1697      contents = bfd_zmalloc (contents_size);
1698      if (contents == NULL)
1699        {
1700          free (x_phdrs);
1701          bfd_set_error (bfd_error_no_memory);
1702          return NULL;
1703        }
1704    
1705      for (i = 0; i < i_ehdr.e_phnum; ++i)
1706        if (i_phdrs[i].p_type == PT_LOAD)
1707          {
1708            bfd_vma start = i_phdrs[i].p_offset & -i_phdrs[i].p_align;
1709            bfd_vma end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
1710                           + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
1711            if (end > (bfd_vma) contents_size)
1712              end = contents_size;
1713            err = target_read_memory ((loadbase + i_phdrs[i].p_vaddr)
1714                                      & -i_phdrs[i].p_align,
1715                                      contents + start, end - start);
1716            if (err)
1717              {
1718                free (x_phdrs);
1719                free (contents);
1720                bfd_set_error (bfd_error_system_call);
1721                errno = err;
1722                return NULL;
1723              }
1724          }
1725      free (x_phdrs);
1726    
1727      /* If the segments visible in memory didn't include the section headers,
1728         then clear them from the file header.  */
1729      if ((bfd_vma) contents_size < (i_ehdr.e_shoff
1730                                     + i_ehdr.e_shnum * i_ehdr.e_shentsize))
1731        {
1732          memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff);
1733          memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum);
1734          memset (&x_ehdr.e_shstrndx, 0, sizeof x_ehdr.e_shstrndx);
1735        }
1736    
1737      /* This will normally have been in the first PT_LOAD segment.  But it
1738         conceivably could be missing, and we might have just changed it.  */
1739      memcpy (contents, &x_ehdr, sizeof x_ehdr);
1740    
1741      /* Now we have a memory image of the ELF file contents.  Make a BFD.  */
1742      bim = bfd_malloc (sizeof (struct bfd_in_memory));
1743      if (bim == NULL)
1744        {
1745          free (contents);
1746          bfd_set_error (bfd_error_no_memory);
1747          return NULL;
1748        }
1749      nbfd = _bfd_new_bfd ();
1750      if (nbfd == NULL)
1751        {
1752          free (bim);
1753          free (contents);
1754          bfd_set_error (bfd_error_no_memory);
1755          return NULL;
1756        }
1757      nbfd->filename = "<in-memory>";
1758      nbfd->xvec = templ->xvec;
1759      bim->size = contents_size;
1760      bim->buffer = contents;
1761      nbfd->iostream = bim;
1762      nbfd->flags = BFD_IN_MEMORY;
1763      nbfd->direction = read_direction;
1764      nbfd->mtime = time (NULL);
1765      nbfd->mtime_set = TRUE;
1766    
1767      if (loadbasep)
1768        *loadbasep = loadbase;
1769      return nbfd;
1770    }
1771    
1772  #include "elfcore.h"  #include "elfcore.h"
 #include "elflink.h"  
1773    
1774  /* Size-dependent data and functions.  */  /* Size-dependent data and functions.  */
1775  const struct elf_size_info NAME(_bfd_elf,size_info) = {  const struct elf_size_info NAME(_bfd_elf,size_info) = {
# Line 1657  const struct elf_size_info NAME(_bfd_elf Line 1783  const struct elf_size_info NAME(_bfd_elf
1783    sizeof (Elf_External_Note),    sizeof (Elf_External_Note),
1784    4,    4,
1785    1,    1,
1786    ARCH_SIZE, FILE_ALIGN,    ARCH_SIZE, LOG_FILE_ALIGN,
1787    ELFCLASS, EV_CURRENT,    ELFCLASS, EV_CURRENT,
1788    elf_write_out_phdrs,    elf_write_out_phdrs,
1789    elf_write_shdrs_and_ehdr,    elf_write_shdrs_and_ehdr,
# Line 1668  const struct elf_size_info NAME(_bfd_elf Line 1794  const struct elf_size_info NAME(_bfd_elf
1794    elf_slurp_symbol_table,    elf_slurp_symbol_table,
1795    elf_swap_dyn_in,    elf_swap_dyn_in,
1796    elf_swap_dyn_out,    elf_swap_dyn_out,
1797    NULL,    elf_swap_reloc_in,
1798    NULL,    elf_swap_reloc_out,
1799    NULL,    elf_swap_reloca_in,
1800    NULL    elf_swap_reloca_out
1801  };  };

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.2

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