Regenerate
[deliverable/binutils-gdb.git] / bfd / elfcode.h
index 0426da215e71ad13d09d1a5d124aaefcf09720d3..1a5f63a6b1a1808a11bc6241db210bdbdbd02c21 100644 (file)
@@ -1,5 +1,6 @@
 /* ELF executable support for BFD.
-   Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+   Copyright 1991, 92, 93, 94, 95, 96, 97, 98, 1999, 2000 Free
+   Software Foundation, Inc.
 
    Written by Fred Fish @ Cygnus Support, from information published
    in "UNIX System V Release 4, Programmers Guide: ANSI C and
@@ -117,6 +118,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define elf_add_dynamic_entry          NAME(bfd_elf,add_dynamic_entry)
 #define elf_write_shdrs_and_ehdr       NAME(bfd_elf,write_shdrs_and_ehdr)
 #define elf_write_out_phdrs            NAME(bfd_elf,write_out_phdrs)
+#define elf_write_relocs               NAME(bfd_elf,write_relocs)
+#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_link_record_dynamic_symbol  _bfd_elf_link_record_dynamic_symbol
@@ -129,6 +132,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #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)
 
 #if ARCH_SIZE == 64
 #define ELF_R_INFO(X,Y)        ELF64_R_INFO(X,Y)
@@ -162,10 +167,9 @@ static void elf_swap_shdr_out
 
 #define section_from_elf_index bfd_section_from_elf_index
 
-static boolean elf_slurp_reloc_table
-  PARAMS ((bfd *, asection *, asymbol **, boolean));
-
-static void write_relocs PARAMS ((bfd *, asection *, PTR));
+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 *));
 
@@ -193,7 +197,7 @@ static char *elf_symbol_flags PARAMS ((flagword));
 #endif
 
 /* Translate an ELF symbol in external format into an ELF symbol in internal
-   format. */
+   format.  */
 
 void
 elf_swap_symbol_in (abfd, src, dst)
@@ -201,8 +205,13 @@ elf_swap_symbol_in (abfd, src, dst)
      const Elf_External_Sym *src;
      Elf_Internal_Sym *dst;
 {
+  int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+
   dst->st_name = bfd_h_get_32 (abfd, (bfd_byte *) src->st_name);
-  dst->st_value = get_word (abfd, (bfd_byte *) src->st_value);
+  if (signed_vma)
+    dst->st_value = get_signed_word (abfd, (bfd_byte *) src->st_value);
+  else
+    dst->st_value = get_word (abfd, (bfd_byte *) src->st_value);
   dst->st_size = get_word (abfd, (bfd_byte *) src->st_size);
   dst->st_info = bfd_h_get_8 (abfd, (bfd_byte *) src->st_info);
   dst->st_other = bfd_h_get_8 (abfd, (bfd_byte *) src->st_other);
@@ -210,7 +219,7 @@ elf_swap_symbol_in (abfd, src, dst)
 }
 
 /* Translate an ELF symbol in internal format into an ELF symbol in external
-   format. */
+   format.  */
 
 void
 elf_swap_symbol_out (abfd, src, cdst)
@@ -227,9 +236,8 @@ elf_swap_symbol_out (abfd, src, cdst)
   bfd_h_put_16 (abfd, src->st_shndx, dst->st_shndx);
 }
 
-
 /* Translate an ELF file header in external format into an ELF file header in
-   internal format. */
+   internal format.  */
 
 static void
 elf_swap_ehdr_in (abfd, src, dst)
@@ -237,11 +245,15 @@ elf_swap_ehdr_in (abfd, src, dst)
      const Elf_External_Ehdr *src;
      Elf_Internal_Ehdr *dst;
 {
+  int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
   memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
   dst->e_type = bfd_h_get_16 (abfd, (bfd_byte *) src->e_type);
   dst->e_machine = bfd_h_get_16 (abfd, (bfd_byte *) src->e_machine);
   dst->e_version = bfd_h_get_32 (abfd, (bfd_byte *) src->e_version);
-  dst->e_entry = get_word (abfd, (bfd_byte *) src->e_entry);
+  if (signed_vma)
+    dst->e_entry = get_signed_word (abfd, (bfd_byte *) src->e_entry);
+  else
+    dst->e_entry = get_word (abfd, (bfd_byte *) src->e_entry);
   dst->e_phoff = get_word (abfd, (bfd_byte *) src->e_phoff);
   dst->e_shoff = get_word (abfd, (bfd_byte *) src->e_shoff);
   dst->e_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->e_flags);
@@ -254,7 +266,7 @@ elf_swap_ehdr_in (abfd, src, dst)
 }
 
 /* Translate an ELF file header in internal format into an ELF file header in
-   external format. */
+   external format.  */
 
 static void
 elf_swap_ehdr_out (abfd, src, dst)
@@ -262,12 +274,16 @@ elf_swap_ehdr_out (abfd, src, dst)
      const Elf_Internal_Ehdr *src;
      Elf_External_Ehdr *dst;
 {
+  int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
   memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
-  /* note that all elements of dst are *arrays of unsigned char* already... */
+  /* note that all elements of dst are *arrays of unsigned char* already...  */
   bfd_h_put_16 (abfd, src->e_type, dst->e_type);
   bfd_h_put_16 (abfd, src->e_machine, dst->e_machine);
   bfd_h_put_32 (abfd, src->e_version, dst->e_version);
-  put_word (abfd, src->e_entry, dst->e_entry);
+  if (signed_vma)
+    put_signed_word (abfd, src->e_entry, dst->e_entry);
+  else
+    put_word (abfd, src->e_entry, dst->e_entry);
   put_word (abfd, src->e_phoff, dst->e_phoff);
   put_word (abfd, src->e_shoff, dst->e_shoff);
   bfd_h_put_32 (abfd, src->e_flags, dst->e_flags);
@@ -279,9 +295,8 @@ elf_swap_ehdr_out (abfd, src, dst)
   bfd_h_put_16 (abfd, src->e_shstrndx, dst->e_shstrndx);
 }
 
-
 /* Translate an ELF section header table entry in external format into an
-   ELF section header table entry in internal format. */
+   ELF section header table entry in internal format.  */
 
 static void
 elf_swap_shdr_in (abfd, src, dst)
@@ -289,10 +304,15 @@ elf_swap_shdr_in (abfd, src, dst)
      const Elf_External_Shdr *src;
      Elf_Internal_Shdr *dst;
 {
+  int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+
   dst->sh_name = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_name);
   dst->sh_type = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_type);
   dst->sh_flags = get_word (abfd, (bfd_byte *) src->sh_flags);
-  dst->sh_addr = get_word (abfd, (bfd_byte *) src->sh_addr);
+  if (signed_vma)
+    dst->sh_addr = get_signed_word (abfd, (bfd_byte *) src->sh_addr);
+  else
+    dst->sh_addr = get_word (abfd, (bfd_byte *) src->sh_addr);
   dst->sh_offset = get_word (abfd, (bfd_byte *) src->sh_offset);
   dst->sh_size = get_word (abfd, (bfd_byte *) src->sh_size);
   dst->sh_link = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_link);
@@ -304,7 +324,7 @@ elf_swap_shdr_in (abfd, src, dst)
 }
 
 /* Translate an ELF section header table entry in internal format into an
-   ELF section header table entry in external format. */
+   ELF section header table entry in external format.  */
 
 static void
 elf_swap_shdr_out (abfd, src, dst)
@@ -312,7 +332,7 @@ elf_swap_shdr_out (abfd, src, dst)
      const Elf_Internal_Shdr *src;
      Elf_External_Shdr *dst;
 {
-  /* note that all elements of dst are *arrays of unsigned char* already... */
+  /* note that all elements of dst are *arrays of unsigned char* already...  */
   bfd_h_put_32 (abfd, src->sh_name, dst->sh_name);
   bfd_h_put_32 (abfd, src->sh_type, dst->sh_type);
   put_word (abfd, src->sh_flags, dst->sh_flags);
@@ -325,9 +345,8 @@ elf_swap_shdr_out (abfd, src, dst)
   put_word (abfd, src->sh_entsize, dst->sh_entsize);
 }
 
-
 /* Translate an ELF program header table entry in external format into an
-   ELF program header table entry in internal format. */
+   ELF program header table entry in internal format.  */
 
 void
 elf_swap_phdr_in (abfd, src, dst)
@@ -335,11 +354,21 @@ elf_swap_phdr_in (abfd, src, dst)
      const Elf_External_Phdr *src;
      Elf_Internal_Phdr *dst;
 {
+  int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+
   dst->p_type = bfd_h_get_32 (abfd, (bfd_byte *) src->p_type);
   dst->p_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->p_flags);
   dst->p_offset = get_word (abfd, (bfd_byte *) src->p_offset);
-  dst->p_vaddr = get_word (abfd, (bfd_byte *) src->p_vaddr);
-  dst->p_paddr = get_word (abfd, (bfd_byte *) src->p_paddr);
+  if (signed_vma)
+    {
+      dst->p_vaddr = get_signed_word (abfd, (bfd_byte *) src->p_vaddr);
+      dst->p_paddr = get_signed_word (abfd, (bfd_byte *) src->p_paddr);
+    }
+  else
+    {
+      dst->p_vaddr = get_word (abfd, (bfd_byte *) src->p_vaddr);
+      dst->p_paddr = get_word (abfd, (bfd_byte *) src->p_paddr);
+    }
   dst->p_filesz = get_word (abfd, (bfd_byte *) src->p_filesz);
   dst->p_memsz = get_word (abfd, (bfd_byte *) src->p_memsz);
   dst->p_align = get_word (abfd, (bfd_byte *) src->p_align);
@@ -351,7 +380,7 @@ elf_swap_phdr_out (abfd, src, dst)
      const Elf_Internal_Phdr *src;
      Elf_External_Phdr *dst;
 {
-  /* note that all elements of dst are *arrays of unsigned char* already... */
+  /* note that all elements of dst are *arrays of unsigned char* already...  */
   bfd_h_put_32 (abfd, src->p_type, dst->p_type);
   put_word (abfd, src->p_offset, dst->p_offset);
   put_word (abfd, src->p_vaddr, dst->p_vaddr);
@@ -362,7 +391,7 @@ elf_swap_phdr_out (abfd, src, dst)
   put_word (abfd, src->p_align, dst->p_align);
 }
 
-/* Translate an ELF reloc from external format to internal format. */
+/* Translate an ELF reloc from external format to internal format.  */
 INLINE void
 elf_swap_reloc_in (abfd, src, dst)
      bfd *abfd;
@@ -384,7 +413,7 @@ elf_swap_reloca_in (abfd, src, dst)
   dst->r_addend = get_signed_word (abfd, (bfd_byte *) src->r_addend);
 }
 
-/* Translate an ELF reloc from internal format to external format. */
+/* Translate an ELF reloc from internal format to external format.  */
 INLINE void
 elf_swap_reloc_out (abfd, src, dst)
      bfd *abfd;
@@ -419,18 +448,19 @@ elf_swap_dyn_in (abfd, p, dst)
 }
 
 INLINE void
-elf_swap_dyn_out (abfd, src, dst)
+elf_swap_dyn_out (abfd, src, p)
      bfd *abfd;
      const Elf_Internal_Dyn *src;
-     Elf_External_Dyn *dst;
+     PTR p;
 {
+  Elf_External_Dyn *dst = (Elf_External_Dyn *) p;
+
   put_word (abfd, src->d_tag, dst->d_tag);
   put_word (abfd, src->d_un.d_val, dst->d_un.d_val);
 }
 \f
 /* ELF .o/exec file reading */
 
-
 /* Begin processing a given object.
 
    First we validate the file by reading in the ELF header and checking
@@ -466,9 +496,18 @@ elf_object_p (abfd)
   char *shstrtab;              /* Internal copy of section header stringtab */
   struct elf_backend_data *ebd;
   struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd);
+  struct sec *preserved_sections = abfd->sections;
+  unsigned int preserved_section_count = abfd->section_count;
+  enum bfd_architecture previous_arch = bfd_get_arch (abfd);
+  unsigned long previous_mach = bfd_get_mach (abfd);
   struct elf_obj_tdata *new_tdata = NULL;
   asection *s;
 
+  /* 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.  */
+  abfd->sections = NULL;
+  abfd->section_count = 0;
+
   /* Read in the ELF header in external format.  */
 
   if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
@@ -483,7 +522,7 @@ elf_object_p (abfd)
      make use of.  The magic number must match, the address size ('class')
      and byte-swapping must match our XVEC entry, and it must have a
      section header table (FIXME: See comments re sections at top of this
-     file). */
+     file).  */
 
   if ((elf_file_p (&x_ehdr) == false) ||
       (x_ehdr.e_ident[EI_VERSION] != EV_CURRENT) ||
@@ -526,13 +565,13 @@ elf_object_p (abfd)
   if (i_ehdrp->e_type == ET_CORE)
     goto got_wrong_format_error;
 
-  /* If there is no section header table, we're hosed. */
+  /* If there is no section header table, we're hosed.  */
   if (i_ehdrp->e_shoff == 0)
     goto got_wrong_format_error;
 
   /* As a simple sanity check, verify that the what BFD thinks is the
      size of each section header table entry actually matches the size
-     recorded in the file. */
+     recorded in the file.  */
   if (i_ehdrp->e_shentsize != sizeof (x_shdr))
     goto got_wrong_format_error;
 
@@ -586,8 +625,8 @@ elf_object_p (abfd)
        goto got_no_match;
     }
 
-  /* Remember the entry point specified in the ELF file header. */
-  bfd_get_start_address (abfd) = i_ehdrp->e_entry;
+  /* Remember the entry point specified in the ELF file header.  */
+  bfd_set_start_address (abfd, i_ehdrp->e_entry);
 
   /* Allocate space for a copy of the section header table in
      internal form, seek to the section header table in the file,
@@ -652,7 +691,7 @@ elf_object_p (abfd)
     }
 
   /* Read in the string table containing the names of the sections.  We
-     will need the base pointer to this table later. */
+     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.) */
@@ -701,6 +740,16 @@ elf_object_p (abfd)
   return (abfd->xvec);
 
  got_wrong_format_error:
+  /* There is way too much undoing of half-known state here.  The caller,
+     bfd_check_format_matches, really shouldn't iterate on live bfd's to
+     check match/no-match like it does.  We have to rely on that a call to
+     bfd_default_set_arch_mach with the previously known mach, undoes what
+     was done by the first bfd_default_set_arch_mach (with mach 0) here.
+     For this to work, only elf-data and the mach may be changed by the
+     target-specific elf_backend_object_p function.  Note that saving the
+     whole bfd here and restoring it would be even worse; the first thing
+     you notice is that the cached bfd file position gets out of sync.  */
+  bfd_default_set_arch_mach (abfd, previous_arch, previous_mach);
   bfd_set_error (bfd_error_wrong_format);
  got_no_match:
   if (new_tdata != NULL
@@ -711,6 +760,8 @@ elf_object_p (abfd)
   if (new_tdata != NULL)
     bfd_release (abfd, new_tdata);
   elf_tdata (abfd) = preserved_tdata;
+  abfd->sections = preserved_sections;
+  abfd->section_count = preserved_section_count;
   return (NULL);
 }
 \f
@@ -718,8 +769,8 @@ elf_object_p (abfd)
 
 /* Write out the relocs.  */
 
-static void
-write_relocs (abfd, sec, data)
+void
+elf_write_relocs (abfd, sec, data)
      bfd *abfd;
      asection *sec;
      PTR data;
@@ -767,7 +818,7 @@ write_relocs (abfd, sec, data)
        SHT_REL section.  */
     abort ();
 
-  /* orelocation has the data, reloc_count has the count... */
+  /* orelocation has the data, reloc_count has the count...  */
   if (use_rela_p)
     {
       outbound_relocas = (Elf_External_Rela *) rela_hdr->contents;
@@ -849,6 +900,8 @@ write_relocs (abfd, sec, data)
 
          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;
@@ -861,7 +914,8 @@ write_relocs (abfd, sec, data)
              last_sym_idx = n;
            }
 
-         if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
+         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;
@@ -910,7 +964,7 @@ elf_write_shdrs_and_ehdr (abfd)
   i_ehdrp = elf_elfheader (abfd);
   i_shdrp = elf_elfsections (abfd);
 
-  /* swap the header before spitting it out... */
+  /* swap the header before spitting it out...  */
 
 #if DEBUG & 1
   elf_debug_file (i_ehdrp);
@@ -921,7 +975,7 @@ elf_write_shdrs_and_ehdr (abfd)
          != sizeof (x_ehdr)))
     return false;
 
-  /* at this point we've concocted all the ELF sections... */
+  /* at this point we've concocted all the ELF sections...  */
   x_shdrp = (Elf_External_Shdr *)
     bfd_alloc (abfd, sizeof (*x_shdrp) * (i_ehdrp->e_shnum));
   if (!x_shdrp)
@@ -939,7 +993,7 @@ elf_write_shdrs_and_ehdr (abfd)
          != sizeof (*x_shdrp) * i_ehdrp->e_shnum))
     return false;
 
-  /* need to dump the string table too... */
+  /* need to dump the string table too...  */
 
   return true;
 }
@@ -967,7 +1021,7 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
      based on a one-to-one mapping of the ELF symbols to canonical
      symbols.  We actually use all the ELF symbols, so there will be no
      space left over at the end.  When we have all the symbols, we
-     build the caller's pointer vector. */
+     build the caller's pointer vector.  */
 
   if (! dynamic)
     {
@@ -1195,50 +1249,27 @@ error_return:
   return -1;
 }
 
-/* Read in and swap the external relocs.  */
+/* Read  relocations for ASECT from REL_HDR.  There are RELOC_COUNT of
+   them.  */
 
 static boolean
-elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
+elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr, reloc_count,
+                                   relents, symbols, dynamic)
      bfd *abfd;
      asection *asect;
+     Elf_Internal_Shdr *rel_hdr;
+     bfd_size_type reloc_count;
+     arelent *relents;
      asymbol **symbols;
      boolean dynamic;
 {
   struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
-  struct bfd_elf_section_data * const d = elf_section_data (asect);
-  Elf_Internal_Shdr *rel_hdr;
-  bfd_size_type reloc_count;
   PTR allocated = NULL;
   bfd_byte *native_relocs;
-  arelent *relents;
   arelent *relent;
   unsigned int i;
   int entsize;
 
-  if (asect->relocation != NULL)
-    return true;
-
-  if (! dynamic)
-    {
-      if ((asect->flags & SEC_RELOC) == 0
-         || asect->reloc_count == 0)
-       return true;
-
-      rel_hdr = &d->rel_hdr;
-      reloc_count = asect->reloc_count;
-
-      BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
-                 && reloc_count == rel_hdr->sh_size / rel_hdr->sh_entsize);
-    }
-  else
-    {
-      if (asect->_raw_size == 0)
-       return true;
-
-      rel_hdr = &d->this_hdr;
-      reloc_count = rel_hdr->sh_size / rel_hdr->sh_entsize;
-    }
-
   allocated = (PTR) bfd_malloc ((size_t) rel_hdr->sh_size);
   if (allocated == NULL)
     goto error_return;
@@ -1250,10 +1281,6 @@ elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
 
   native_relocs = (bfd_byte *) allocated;
 
-  relents = (arelent *) bfd_alloc (abfd, reloc_count * sizeof (arelent));
-  if (relents == NULL)
-    goto error_return;
-
   entsize = rel_hdr->sh_entsize;
   BFD_ASSERT (entsize == sizeof (Elf_External_Rel)
              || entsize == sizeof (Elf_External_Rela));
@@ -1308,8 +1335,6 @@ elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
        (*ebd->elf_info_to_howto_rel) (abfd, relent, &rel);
     }
 
-  asect->relocation = relents;
-
   if (allocated != NULL)
     free (allocated);
 
@@ -1321,6 +1346,81 @@ elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
   return false;
 }
 
+/* Read in and swap the external relocs.  */
+
+boolean
+elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
+     bfd *abfd;
+     asection *asect;
+     asymbol **symbols;
+     boolean dynamic;
+{
+  struct bfd_elf_section_data * const d = elf_section_data (asect);
+  Elf_Internal_Shdr *rel_hdr;
+  Elf_Internal_Shdr *rel_hdr2;
+  bfd_size_type reloc_count;
+  bfd_size_type reloc_count2;
+  arelent *relents;
+
+  if (asect->relocation != NULL)
+    return true;
+
+  if (! dynamic)
+    {
+      if ((asect->flags & SEC_RELOC) == 0
+         || asect->reloc_count == 0)
+       return true;
+
+      rel_hdr = &d->rel_hdr;
+      reloc_count = rel_hdr->sh_size / rel_hdr->sh_entsize;
+      rel_hdr2 = d->rel_hdr2;
+      reloc_count2 = (rel_hdr2
+                     ? (rel_hdr2->sh_size / rel_hdr2->sh_entsize)
+                     : 0);
+
+      BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
+      BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
+                 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
+
+    }
+  else
+    {
+      /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
+        case because relocations against this section may use the
+        dynamic symbol table, and in that case bfd_section_from_shdr
+        in elf.c does not update the RELOC_COUNT.  */
+      if (asect->_raw_size == 0)
+       return true;
+
+      rel_hdr = &d->this_hdr;
+      reloc_count = rel_hdr->sh_size / rel_hdr->sh_entsize;
+      rel_hdr2 = NULL;
+      reloc_count2 = 0;
+    }
+
+  relents = ((arelent *)
+            bfd_alloc (abfd,
+                       (reloc_count + reloc_count2) * sizeof (arelent)));
+  if (relents == NULL)
+    return false;
+
+  if (!elf_slurp_reloc_table_from_section (abfd, asect,
+                                          rel_hdr, reloc_count,
+                                          relents,
+                                          symbols, dynamic))
+    return false;
+
+  if (rel_hdr2
+      && !elf_slurp_reloc_table_from_section (abfd, asect,
+                                             rel_hdr2, reloc_count2,
+                                             relents + reloc_count,
+                                             symbols, dynamic))
+    return false;
+
+  asect->relocation = relents;
+  return true;
+}
+
 #ifdef DEBUG
 static void
 elf_debug_section (num, hdr)
@@ -1449,14 +1549,20 @@ const struct elf_size_info NAME(_bfd_elf,size_info) = {
   sizeof (Elf_External_Sym),
   sizeof (Elf_External_Dyn),
   sizeof (Elf_External_Note),
-
+  4,
+  1,
   ARCH_SIZE, FILE_ALIGN,
   ELFCLASS, EV_CURRENT,
   elf_write_out_phdrs,
   elf_write_shdrs_and_ehdr,
-  write_relocs,
+  elf_write_relocs,
   elf_swap_symbol_out,
   elf_slurp_reloc_table,
   elf_slurp_symbol_table,
-  elf_swap_dyn_in
+  elf_swap_dyn_in,
+  elf_swap_dyn_out,
+  NULL,
+  NULL,
+  NULL,
+  NULL
 };
This page took 0.032393 seconds and 4 git commands to generate.