* elflink.c (_bfd_elf_gc_mark): Mark sections referenced by

.eh_frame specially..
	(bfd_elf_gc_sections): ..rather than totally ignoring .eh_frame.
	Don't recheck sections we have already marked.
	(elf_gc_sweep): Keep non-code sections referenced from .eh_frame.
	* section.c (struct bfd_section): Add gc_mark_from_eh.
	(STD_SECTION): Adjust.
	* ecoff.c (bfd_debug_section): Adjust.
	* bfd-in2.h: Regenerate.
This commit is contained in:
Alan Modra 2005-06-29 14:05:21 +00:00
parent e8aaee2ad4
commit 39c2f51bd9
5 changed files with 73 additions and 29 deletions

View File

@ -1,3 +1,15 @@
2005-06-29 Alan Modra <amodra@bigpond.net.au>
* elflink.c (_bfd_elf_gc_mark): Mark sections referenced by
.eh_frame specially..
(bfd_elf_gc_sections): ..rather than totally ignoring .eh_frame.
Don't recheck sections we have already marked.
(elf_gc_sweep): Keep non-code sections referenced from .eh_frame.
* section.c (struct bfd_section): Add gc_mark_from_eh.
(STD_SECTION): Adjust.
* ecoff.c (bfd_debug_section): Adjust.
* bfd-in2.h: Regenerate.
2005-06-29 Alan Modra <amodra@bigpond.net.au>
* elflink.c (elf_gc_sweep): Do not refcount on sections that have

View File

@ -1262,8 +1262,9 @@ typedef struct bfd_section
output sections that have an input section. */
unsigned int linker_has_input : 1;
/* A mark flag used by some linker backends for garbage collection. */
/* Mark flags used by some linker backends for garbage collection. */
unsigned int gc_mark : 1;
unsigned int gc_mark_from_eh : 1;
/* The following flags are used by the ELF linker. */

View File

@ -54,12 +54,12 @@ static asection bfd_debug_section =
{
/* name, id, index, next, prev, flags, user_set_vma, */
"*DEBUG*", 0, 0, NULL, NULL, 0, 0,
/* linker_mark, linker_has_input, gc_mark, segment_mark, */
0, 0, 0, 0,
/* sec_info_type, use_rela_p, has_tls_reloc, has_gp_reloc, */
0, 0, 0, 0,
/* need_finalize_relax, reloc_done, */
0, 0,
/* linker_mark, linker_has_input, gc_mark, gc_mark_from_eh, */
0, 0, 1, 0,
/* segment_mark, sec_info_type, use_rela_p, has_tls_reloc, */
0, 0, 0, 0,
/* has_gp_reloc, need_finalize_relax, reloc_done, */
0, 0, 0,
/* vma, lma, size, rawsize, */
0, 0, 0, 0,
/* output_offset, output_section, alignment_power, */
@ -68,7 +68,7 @@ static asection bfd_debug_section =
NULL, NULL, 0, 0, 0,
/* line_filepos, userdata, contents, lineno, lineno_count, */
0, NULL, NULL, NULL, 0,
/* entsize, kept_section, moving_line_filepos, */
/* entsize, kept_section, moving_line_filepos, */
0, NULL, 0,
/* target_index, used_by_bfd, constructor_chain, owner, */
0, NULL, NULL, NULL,

View File

@ -8733,6 +8733,7 @@ _bfd_elf_gc_mark (struct bfd_link_info *info,
gc_mark_hook_fn gc_mark_hook)
{
bfd_boolean ret;
bfd_boolean is_eh;
asection *group_sec;
sec->gc_mark = 1;
@ -8745,6 +8746,7 @@ _bfd_elf_gc_mark (struct bfd_link_info *info,
/* Look through the section relocs. */
ret = TRUE;
is_eh = strcmp (sec->name, ".eh_frame") == 0;
if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0)
{
Elf_Internal_Rela *relstart, *rel, *relend;
@ -8821,6 +8823,8 @@ _bfd_elf_gc_mark (struct bfd_link_info *info,
{
if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour)
rsec->gc_mark = 1;
else if (is_eh)
rsec->gc_mark_from_eh = 1;
else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook))
{
ret = FALSE;
@ -8891,6 +8895,41 @@ elf_gc_sweep (struct bfd_link_info *info, gc_sweep_hook_fn gc_sweep_hook)
if (o->gc_mark)
continue;
/* Keep .gcc_except_table.* if the associated .text.* is
marked. This isn't very nice, but the proper solution,
splitting .eh_frame up and using comdat doesn't pan out
easily due to needing special relocs to handle the
difference of two symbols in separate sections.
Don't keep code sections referenced by .eh_frame. */
if (o->gc_mark_from_eh && (o->flags & SEC_CODE) == 0)
{
if (strncmp (o->name, ".gcc_except_table.", 18) == 0)
{
unsigned long len;
char *fn_name;
asection *fn_text;
len = strlen (o->name + 18) + 1;
fn_name = bfd_malloc (len + 6);
if (fn_name == NULL)
return FALSE;
memcpy (fn_name, ".text.", 6);
memcpy (fn_name + 6, o->name + 18, len);
fn_text = bfd_get_section_by_name (sub, fn_name);
free (fn_name);
if (fn_text != NULL && fn_text->gc_mark)
o->gc_mark = 1;
}
/* If not using specially named exception table section,
then keep whatever we are using. */
else
o->gc_mark = 1;
if (o->gc_mark)
continue;
}
/* Skip sweeping sections already excluded. */
if (o->flags & SEC_EXCLUDE)
continue;
@ -9125,18 +9164,9 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
continue;
for (o = sub->sections; o != NULL; o = o->next)
{
if (o->flags & SEC_KEEP)
{
/* _bfd_elf_discard_section_eh_frame knows how to discard
orphaned FDEs so don't mark sections referenced by the
EH frame section. */
if (strcmp (o->name, ".eh_frame") == 0)
o->gc_mark = 1;
else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
return FALSE;
}
}
if ((o->flags & SEC_KEEP) != 0 && !o->gc_mark)
if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
return FALSE;
}
/* ... and mark SEC_EXCLUDE for those that go. */

View File

@ -354,8 +354,9 @@ CODE_FRAGMENT
. output sections that have an input section. *}
. unsigned int linker_has_input : 1;
.
. {* A mark flag used by some linker backends for garbage collection. *}
. {* Mark flags used by some linker backends for garbage collection. *}
. unsigned int gc_mark : 1;
. unsigned int gc_mark_from_eh : 1;
.
. {* The following flags are used by the ELF linker. *}
.
@ -661,18 +662,18 @@ static const asymbol global_syms[] =
#define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX) \
const asymbol * const SYM = (asymbol *) &global_syms[IDX]; \
asection SEC = \
asection SEC = \
/* name, id, index, next, prev, flags, user_set_vma, */ \
{ NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
\
/* linker_mark, linker_has_input, gc_mark, segment_mark, */ \
/* linker_mark, linker_has_input, gc_mark, gc_mark_from_eh, */ \
0, 0, 1, 0, \
\
/* sec_info_type, use_rela_p, has_tls_reloc, has_gp_reloc, */ \
0, 0, 0, 0, \
/* segment_mark, sec_info_type, use_rela_p, has_tls_reloc, */ \
0, 0, 0, 0, \
\
/* need_finalize_relax, reloc_done, */ \
0, 0, \
/* has_gp_reloc, need_finalize_relax, reloc_done, */ \
0, 0, 0, \
\
/* vma, lma, size, rawsize */ \
0, 0, 0, 0, \
@ -686,8 +687,8 @@ static const asymbol global_syms[] =
/* line_filepos, userdata, contents, lineno, lineno_count, */ \
0, NULL, NULL, NULL, 0, \
\
/* entsize, kept_section, moving_line_filepos, */ \
0, NULL, 0, \
/* entsize, kept_section, moving_line_filepos, */ \
0, NULL, 0, \
\
/* target_index, used_by_bfd, constructor_chain, owner, */ \
0, NULL, NULL, NULL, \