* gdb.arch/i386-sse.exp, gdb.arch/i386-sse.c: New tests.
[deliverable/binutils-gdb.git] / bfd / elf32-frv.c
index f00976f793ee28356dff995309edc6bf298be611..cf3195acd7b49c906db2a8d666039400a794c8c4 100644 (file)
@@ -939,8 +939,18 @@ _frvfdpic_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
                            sreloc->contents + reloc_offset);
   sreloc->reloc_count++;
 
-  BFD_ASSERT (entry->dynrelocs > 0);
-  entry->dynrelocs--;
+  /* If the entry's index is zero, this relocation was probably to a
+     linkonce section that got discarded.  We reserved a dynamic
+     relocation, but it was for another entry than the one we got at
+     the time of emitting the relocation.  Unfortunately there's no
+     simple way for us to catch this situation, since the relocation
+     is cleared right before calling relocate_section, at which point
+     we no longer know what the relocation used to point to.  */
+  if (entry->symndx)
+    {
+      BFD_ASSERT (entry->dynrelocs > 0);
+      entry->dynrelocs--;
+    }
 
   return reloc_offset;
 }
@@ -964,8 +974,10 @@ _frvfdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
     }
   rofixup->reloc_count++;
 
-  if (entry)
+  if (entry && entry->symndx)
     {
+      /* See discussion about symndx == 0 in _frvfdpic_add_dyn_reloc
+        above.  */
       BFD_ASSERT (entry->fixups > 0);
       entry->fixups--;
     }
@@ -3686,6 +3698,11 @@ elf32_frvfdpic_modify_segment_map (bfd *output_bfd,
 {
   struct elf_segment_map *m;
 
+  /* objcopy and strip preserve what's already there using
+     elf32_frvfdpic_copy_private_bfd_data ().  */
+  if (! info)
+    return TRUE;
+
   for (m = elf_tdata (output_bfd)->segment_map; m != NULL; m = m->next)
     if (m->p_type == PT_GNU_STACK)
       break;
@@ -4311,6 +4328,50 @@ frv_elf_arch_extension_p (flagword base, flagword extension)
   return FALSE;
 }
 
+static bfd_boolean
+elf32_frvfdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+  unsigned i;
+
+  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return TRUE;
+
+  if (! frv_elf_copy_private_bfd_data (ibfd, obfd))
+    return FALSE;
+
+  if (! elf_tdata (ibfd) || ! elf_tdata (ibfd)->phdr
+      || ! elf_tdata (obfd) || ! elf_tdata (obfd)->phdr)
+    return TRUE;
+
+  /* Copy the stack size.  */
+  for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++)
+    if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK)
+      {
+       Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i];
+
+       for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++)
+         if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK)
+           {
+             memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr));
+
+             /* Rewrite the phdrs, since we're only called after they
+                were first written.  */
+             if (bfd_seek (obfd, (bfd_signed_vma) get_elf_backend_data (obfd)
+                           ->s->sizeof_ehdr, SEEK_SET) != 0
+                 || get_elf_backend_data (obfd)->s
+                 ->write_out_phdrs (obfd, elf_tdata (obfd)->phdr,
+                                    elf_elfheader (obfd)->e_phnum) != 0)
+               return FALSE;
+             break;
+           }
+
+       break;
+      }
+
+  return TRUE;
+}
+
 /* Merge backend specific data from an object file to the output
    object file when linking.  */
 
@@ -4726,6 +4787,9 @@ frv_elf_print_private_bfd_data (abfd, ptr)
 #undef elf_backend_modify_segment_map
 #define elf_backend_modify_segment_map \
                elf32_frvfdpic_modify_segment_map
+#undef bfd_elf32_bfd_copy_private_bfd_data
+#define bfd_elf32_bfd_copy_private_bfd_data \
+               elf32_frvfdpic_copy_private_bfd_data
 
 #undef elf_backend_create_dynamic_sections
 #define elf_backend_create_dynamic_sections \
This page took 0.025612 seconds and 4 git commands to generate.