* elf32-ppc.c (ppc_elf_info_to_howto): Check for invalid relocation
[deliverable/binutils-gdb.git] / bfd / elflink.c
index b58cfa6485c069ca5f675cc73fedcc82cdd43dc1..dfdbade6353c337bf2459d07f52550cfd6ca7acc 100644 (file)
@@ -2609,6 +2609,52 @@ _bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data)
   return TRUE;
 }
 
+/* Adjust the dynamic symbol, H, for copy in the dynamic bss section,
+   DYNBSS.  */
+
+bfd_boolean
+_bfd_elf_adjust_dynamic_copy (struct elf_link_hash_entry *h,
+                             asection *dynbss)
+{
+  unsigned int power_of_two;
+  bfd_vma mask;
+  asection *sec = h->root.u.def.section;
+
+  /* The section aligment of definition is the maximum alignment
+     requirement of symbols defined in the section.  Since we don't
+     know the symbol alignment requirement, we start with the
+     maximum alignment and check low bits of the symbol address
+     for the minimum alignment.  */
+  power_of_two = bfd_get_section_alignment (sec->owner, sec);
+  mask = ((bfd_vma) 1 << power_of_two) - 1;
+  while ((h->root.u.def.value & mask) != 0)
+    {
+       mask >>= 1;
+       --power_of_two;
+    }
+
+  if (power_of_two > bfd_get_section_alignment (dynbss->owner,
+                                               dynbss))
+    {
+      /* Adjust the section alignment if needed.  */
+      if (! bfd_set_section_alignment (dynbss->owner, dynbss,
+                                      power_of_two))
+       return FALSE;
+    }
+
+  /* We make sure that the symbol will be aligned properly.  */
+  dynbss->size = BFD_ALIGN (dynbss->size, mask + 1);
+
+  /* Define the symbol as being at this point in DYNBSS.  */
+  h->root.u.def.section = dynbss;
+  h->root.u.def.value = dynbss->size;
+
+  /* Increment the size of DYNBSS to make room for the symbol.  */
+  dynbss->size += h->size;
+
+  return TRUE;
+}
+
 /* Adjust all external symbols pointing into SEC_MERGE sections
    to reflect the object merging within the sections.  */
 
@@ -8198,7 +8244,7 @@ _bfd_elf_check_kept_section (asection *sec, struct bfd_link_info *info)
 static bfd_boolean
 elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
 {
-  bfd_boolean (*relocate_section)
+  int (*relocate_section)
     (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
      Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
   bfd *output_bfd;
@@ -8212,7 +8258,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
   asection **ppsection;
   asection *o;
   const struct elf_backend_data *bed;
-  bfd_boolean emit_relocs;
   struct elf_link_hash_entry **sym_hashes;
 
   output_bfd = finfo->output_bfd;
@@ -8225,9 +8270,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
   if ((input_bfd->flags & DYNAMIC) != 0)
     return TRUE;
 
-  emit_relocs = (finfo->info->relocatable
-                || finfo->info->emitrelocations);
-
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   if (elf_bad_symtab (input_bfd))
     {
@@ -8443,6 +8485,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
          Elf_Internal_Rela *internal_relocs;
          bfd_vma r_type_mask;
          int r_sym_shift;
+         int ret;
 
          /* Get the swapped relocs.  */
          internal_relocs
@@ -8580,14 +8623,17 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
             corresponding to the output section, which will require
             the addend to be adjusted.  */
 
-         if (! (*relocate_section) (output_bfd, finfo->info,
+         ret = (*relocate_section) (output_bfd, finfo->info,
                                     input_bfd, o, contents,
                                     internal_relocs,
                                     isymbuf,
-                                    finfo->sections))
+                                    finfo->sections);
+         if (!ret)
            return FALSE;
 
-         if (emit_relocs)
+         if (ret == 2
+             || finfo->info->relocatable
+             || finfo->info->emitrelocations)
            {
              Elf_Internal_Rela *irela;
              Elf_Internal_Rela *irelaend;
@@ -9312,13 +9358,18 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
                {
                  Elf_Internal_Rela * relocs;
 
-                 relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+                 relocs = _bfd_elf_link_read_relocs (sec->owner, sec,
+                                                     NULL, NULL,
                                                      info->keep_memory);
 
-                 reloc_count = (*bed->elf_backend_count_relocs) (sec, relocs);
+                 if (relocs != NULL)
+                   {
+                     reloc_count
+                       = (*bed->elf_backend_count_relocs) (sec, relocs);
 
-                 if (elf_section_data (o)->relocs != relocs)
-                   free (relocs);
+                     if (elf_section_data (sec)->relocs != relocs)
+                       free (relocs);
+                   }
                }
 
              if (sec->rawsize > max_contents_size)
@@ -11147,7 +11198,10 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
                                                 cookie.locsymcount, 0,
                                                 NULL, NULL, NULL);
          if (cookie.locsyms == NULL)
-           return FALSE;
+           {
+             info->callbacks->einfo (_("%P%X: can not read symbols: %E\n"));
+             return FALSE;
+           }
        }
 
       if (stab != NULL)
This page took 0.02796 seconds and 4 git commands to generate.