2007-02-22 Paul Brook <paul@codesourcery.com>
authorPaul Brook <paul@codesourcery.com>
Thu, 22 Feb 2007 17:03:59 +0000 (17:03 +0000)
committerPaul Brook <paul@codesourcery.com>
Thu, 22 Feb 2007 17:03:59 +0000 (17:03 +0000)
bfd/
* elflink.c (gc_mark_hook_fn): Remove.
(_bfd_elf_gc_mark): Rename gc_mark_hook_fn to elf_gc_mark_hook_fn.
(bfd_elf_gc_sections): Ditto.  Call gc_mark_extra_sections.
* elf-bfd.h (elf_gc_mark_hook_fn): Define.
(elf_backend_data): Add gc_mark_extra_sections.
* elfxx-target.h (elf_backend_gc_mark_extra_sections): Provide default
definition.
(elfNN_bed): Add elf_backend_gc_mark_extra_sections.
* elf32-arm.c (elf32_arm_gc_mark_extra_sections): New function.
(elf_backend_gc_mark_extra_sections): Define.

ld/testsuite/
* ld-arm/arm-elf.exp (armelftests): Add gc-unwind.h.
* ld-arm/gc-unwind.s: New file.
* ld-arm/gc-unwind.d: New file.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf32-arm.c
bfd/elflink.c
bfd/elfxx-target.h
ld/testsuite/ChangeLog
ld/testsuite/ld-arm/arm-elf.exp
ld/testsuite/ld-arm/gc-unwind.d [new file with mode: 0644]
ld/testsuite/ld-arm/gc-unwind.s [new file with mode: 0644]

index 0bd67952294f42f0dc0947b15026155c984aaf41..0156a9c88ea5553b91b49e035931cebfa6de5ba9 100644 (file)
@@ -1,3 +1,16 @@
+2007-02-22  Paul Brook  <paul@codesourcery.com>
+
+       * elflink.c (gc_mark_hook_fn): Remove.
+       (_bfd_elf_gc_mark): Rename gc_mark_hook_fn to elf_gc_mark_hook_fn.
+       (bfd_elf_gc_sections): Ditto.  Call gc_mark_extra_sections.
+       * elf-bfd.h (elf_gc_mark_hook_fn): Define.
+       (elf_backend_data): Add gc_mark_extra_sections.
+       * elfxx-target.h (elf_backend_gc_mark_extra_sections): Provide default
+       definition.
+       (elfNN_bed): Add elf_backend_gc_mark_extra_sections.
+       * elf32-arm.c (elf32_arm_gc_mark_extra_sections): New function.
+       (elf_backend_gc_mark_extra_sections): Define.
+
 2007-02-21  Nick Clifton  <nickc@redhat.com>
 
        * elf.c (_bfd_elf_map_sections_to_segments): If the
index a0e6391a4f7d9ef80c406631e1217b9c19006728..303b823a77ca83fb3b5ce977420e801680d8c2ae 100644 (file)
@@ -538,6 +538,10 @@ enum action_discarded
     PRETEND = 2
   };
 
+typedef asection * (*elf_gc_mark_hook_fn)
+  (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+   struct elf_link_hash_entry *, Elf_Internal_Sym *);
+
 struct elf_backend_data
 {
   /* The architecture for this backend.  */
@@ -843,9 +847,12 @@ struct elf_backend_data
 
   /* This function is called during section gc to discover the section a
      particular relocation refers to.  */
-  asection * (*gc_mark_hook)
-    (asection *sec, struct bfd_link_info *, Elf_Internal_Rela *,
-     struct elf_link_hash_entry *h, Elf_Internal_Sym *);
+  elf_gc_mark_hook_fn gc_mark_hook;
+
+  /* This function, if defined, is called after the first gc marking pass
+     to allow the backend to mark additional sections.  */
+  bfd_boolean (*gc_mark_extra_sections)
+    (struct bfd_link_info *info, elf_gc_mark_hook_fn gc_mark_hook);
 
   /* This function, if defined, is called during the sweep phase of gc
      in order that a backend might update any data structures it might
index 87d617f7e4585d2df7de81eca1e064ac08adc193..78aa2a0aad8d3f6e41a72e32ed2993f29ff388de 100644 (file)
@@ -8150,6 +8150,50 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
   return TRUE;
 }
 
+/* Unwinding tables are not referenced directly.  This pass marks them as
+   required if the corresponding code section is marked.  */
+
+static bfd_boolean
+elf32_arm_gc_mark_extra_sections(struct bfd_link_info *info,
+                                elf_gc_mark_hook_fn gc_mark_hook)
+{
+  bfd *sub;
+  Elf_Internal_Shdr **elf_shdrp;
+  bfd_boolean again;
+
+  /* Marking EH data may cause additional code sections to be marked,
+     requiring multiple passes.  */
+  again = TRUE;
+  while (again)
+    {
+      again = FALSE;
+      for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+       {
+         asection *o;
+
+         if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
+           continue;
+
+         elf_shdrp = elf_elfsections (sub);
+         for (o = sub->sections; o != NULL; o = o->next)
+           {
+             Elf_Internal_Shdr *hdr;
+             hdr = &elf_section_data (o)->this_hdr;
+             if (hdr->sh_type == SHT_ARM_EXIDX && hdr->sh_link
+                 && !o->gc_mark
+                 && elf_shdrp[hdr->sh_link]->bfd_section->gc_mark)
+               {
+                 again = TRUE;
+                 if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+                   return FALSE;
+               }
+           }
+       }
+    }
+
+  return TRUE;
+}
+
 /* Treat mapping symbols as special target symbols.  */
 
 static bfd_boolean
@@ -10532,6 +10576,7 @@ const struct elf_size_info elf32_arm_size_info = {
 
 #define elf_backend_get_symbol_type             elf32_arm_get_symbol_type
 #define elf_backend_gc_mark_hook                elf32_arm_gc_mark_hook
+#define elf_backend_gc_mark_extra_sections     elf32_arm_gc_mark_extra_sections
 #define elf_backend_gc_sweep_hook               elf32_arm_gc_sweep_hook
 #define elf_backend_check_relocs                elf32_arm_check_relocs
 #define elf_backend_relocate_section           elf32_arm_relocate_section
index 00dd2aafe7ce1e33aab678e55f22c6e0fbaf21f5..f7de165e2f6a687ca7bec7bb104ffb7dbcf01670 100644 (file)
@@ -10088,10 +10088,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 \f
 /* Garbage collect unused sections.  */
 
-typedef asection * (*gc_mark_hook_fn)
-  (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
-   struct elf_link_hash_entry *, Elf_Internal_Sym *);
-
 /* Default gc_mark_hook.  */
 
 asection *
@@ -10129,7 +10125,7 @@ _bfd_elf_gc_mark_hook (asection *sec,
 bfd_boolean
 _bfd_elf_gc_mark (struct bfd_link_info *info,
                  asection *sec,
-                 gc_mark_hook_fn gc_mark_hook)
+                 elf_gc_mark_hook_fn gc_mark_hook)
 {
   bfd_boolean ret;
   bfd_boolean is_eh;
@@ -10498,9 +10494,7 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
 {
   bfd_boolean ok = TRUE;
   bfd *sub;
-  asection * (*gc_mark_hook)
-    (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
-     struct elf_link_hash_entry *h, Elf_Internal_Sym *);
+  elf_gc_mark_hook_fn gc_mark_hook;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if (!bed->can_gc_sections
@@ -10547,6 +10541,10 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
            return FALSE;
     }
 
+  /* Allow the backend to mark additional target specific sections.  */
+  if (bed->gc_mark_extra_sections)
+    bed->gc_mark_extra_sections(info, gc_mark_hook);
+
   /* ... again for sections marked from eh_frame.  */
   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
     {
index c7be5771c0b21f52b7f7b7b1e7e31664fb8d8ee6..661584115b7c2df4ada79caf077a5aa86e64a2fe 100644 (file)
 #ifndef elf_backend_gc_mark_hook
 #define elf_backend_gc_mark_hook       _bfd_elf_gc_mark_hook
 #endif
+#ifndef elf_backend_gc_mark_extra_sections
+#define elf_backend_gc_mark_extra_sections     NULL
+#endif
 #ifndef elf_backend_gc_sweep_hook
 #define elf_backend_gc_sweep_hook      NULL
 #endif
@@ -627,6 +630,7 @@ static struct elf_backend_data elfNN_bed =
   elf_backend_modify_program_headers,
   elf_backend_gc_mark_dynamic_ref,
   elf_backend_gc_mark_hook,
+  elf_backend_gc_mark_extra_sections,
   elf_backend_gc_sweep_hook,
   elf_backend_post_process_headers,
   elf_backend_print_symbol_all,
index 2f75a9e54f599e71fe8f83b6174f299893b12905..17be55150e3b4f5dd1d40ea940360c4e897a78b3 100644 (file)
@@ -1,3 +1,9 @@
+2007-02-22  Paul Brook  <paul@codesourcery.com>
+
+       * ld-arm/arm-elf.exp (armelftests): Add gc-unwind.h.
+       * ld-arm/gc-unwind.s: New file.
+       * ld-arm/gc-unwind.d: New file.
+
 2007-02-14  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/3953
index 71d817a71dee521a3a98ed83d8f8d5c6387698e6..9b7b36965870650be177cf466c840daf7e6df09e 100644 (file)
@@ -156,6 +156,9 @@ set armelftests {
      "-EL --vfp11-denorm-fix=scalar" "-EL" {vfp11-fix-none.s}
      {{objdump -dr vfp11-fix-none.d}}
      "vfp11-fix-none"}
+    {"Unwinding and -gc-sections" "-gc-sections" "" {gc-unwind.s}
+     {{objdump -sj.data gc-unwind.d}}
+     "gc-unwind"}
 
 }
 
diff --git a/ld/testsuite/ld-arm/gc-unwind.d b/ld/testsuite/ld-arm/gc-unwind.d
new file mode 100644 (file)
index 0000000..fbb7911
--- /dev/null
@@ -0,0 +1,5 @@
+
+.*:     file format.*
+
+Contents of section .data:
+ [^ ]* 22222222                            .*
diff --git a/ld/testsuite/ld-arm/gc-unwind.s b/ld/testsuite/ld-arm/gc-unwind.s
new file mode 100644 (file)
index 0000000..c5326c2
--- /dev/null
@@ -0,0 +1,38 @@
+@ Test -gc-sections and unwinding tables.  .data.eh should be pulled in
+@ via the EH tables, .data.foo should not.
+.text
+.global _start
+.fnstart
+_start:
+bx lr
+.personality my_pr
+.handlerdata
+.word 0
+.fnend
+
+.section .data.foo
+my_foo:
+.word 0x11111111
+
+.section .text.foo
+.fnstart
+foo:
+bx lr
+.personality my_pr
+.handlerdata
+.word my_foo
+.fnend
+
+.section .data.eh
+my_eh:
+.word 0x22222222
+
+.section .text.eh
+.fnstart
+my_pr:
+bx lr
+.personality my_pr
+.handlerdata
+.word my_eh
+.fnend
+