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.
This commit is contained in:
Paul Brook 2007-02-22 17:03:59 +00:00
parent 115d86cfaa
commit 6a5bb8757e
9 changed files with 130 additions and 11 deletions

View 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

View 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

View 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

View file

@ -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)
{

View file

@ -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,

View 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

View 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"}
}

View file

@ -0,0 +1,5 @@
.*: file format.*
Contents of section .data:
[^ ]* 22222222 .*

View file

@ -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