aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2005-06-29 14:05:21 +0000
committerAlan Modra <amodra@gmail.com>2005-06-29 14:05:21 +0000
commit39c2f51bd9f82438706973c4b92597a945d9c4df (patch)
tree44152730391ea82957bcbc22e60bce18565e60f4 /bfd
parente8aaee2ad47c086c1c64639df152489eb283b342 (diff)
downloadfsf-binutils-gdb-39c2f51bd9f82438706973c4b92597a945d9c4df.zip
fsf-binutils-gdb-39c2f51bd9f82438706973c4b92597a945d9c4df.tar.gz
fsf-binutils-gdb-39c2f51bd9f82438706973c4b92597a945d9c4df.tar.bz2
* 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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/bfd-in2.h3
-rw-r--r--bfd/ecoff.c14
-rw-r--r--bfd/elflink.c54
-rw-r--r--bfd/section.c19
5 files changed, 73 insertions, 29 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 769534b..f4e4944 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,17 @@
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
not been processed by check_relocs.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index a1ca958..7d16049 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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. */
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
index 74098ed..832b22f 100644
--- a/bfd/ecoff.c
+++ b/bfd/ecoff.c
@@ -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,
diff --git a/bfd/elflink.c b/bfd/elflink.c
index b561b1f..8870857 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -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. */
diff --git a/bfd/section.c b/bfd/section.c
index 75acad7..aeb63a6 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -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, \