aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2007-02-22 17:03:59 +0000
committerPaul Brook <paul@codesourcery.com>2007-02-22 17:03:59 +0000
commit6a5bb8757e503d29dd2b0cc656a8747bca71362e (patch)
tree739be2901b553d31859250350c69dc13a3454070
parent115d86cfaa1c3ecbf7ce54222a7622a2adb994f9 (diff)
downloadgdb-6a5bb8757e503d29dd2b0cc656a8747bca71362e.zip
gdb-6a5bb8757e503d29dd2b0cc656a8747bca71362e.tar.gz
gdb-6a5bb8757e503d29dd2b0cc656a8747bca71362e.tar.bz2
2007-02-22 Paul Brook <paul@codesourcery.com>
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.
-rw-r--r--bfd/ChangeLog13
-rw-r--r--bfd/elf-bfd.h13
-rw-r--r--bfd/elf32-arm.c45
-rw-r--r--bfd/elflink.c14
-rw-r--r--bfd/elfxx-target.h4
-rw-r--r--ld/testsuite/ChangeLog6
-rw-r--r--ld/testsuite/ld-arm/arm-elf.exp3
-rw-r--r--ld/testsuite/ld-arm/gc-unwind.d5
-rw-r--r--ld/testsuite/ld-arm/gc-unwind.s38
9 files changed, 130 insertions, 11 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 0bd6795..0156a9c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index a0e6391..303b823 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -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
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 87d617f..78aa2a0 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -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
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 00dd2aa..f7de165 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -10088,10 +10088,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
/* 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)
{
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index c7be577..6615841 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -136,6 +136,9 @@
#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,
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 2f75a9e..17be551 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -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
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index 71d817a..9b7b369 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -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
index 0000000..fbb7911
--- /dev/null
+++ b/ld/testsuite/ld-arm/gc-unwind.d
@@ -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
index 0000000..c5326c2
--- /dev/null
+++ b/ld/testsuite/ld-arm/gc-unwind.s
@@ -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
+