aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2010-01-08 01:43:23 +0000
committerH.J. Lu <hjl.tools@gmail.com>2010-01-08 01:43:23 +0000
commitbde6f3eb6dff94cea1d471e15c6154d55d49820f (patch)
tree33ff2b586001fc671d83306de7968fdaab523c67 /bfd/elflink.c
parentb903363e43c8ea7d9b37b599bc15591036d03690 (diff)
downloadgdb-bde6f3eb6dff94cea1d471e15c6154d55d49820f.zip
gdb-bde6f3eb6dff94cea1d471e15c6154d55d49820f.tar.gz
gdb-bde6f3eb6dff94cea1d471e15c6154d55d49820f.tar.bz2
Set SEC_KEEP on section XXX for undefined __start_XXX/__stop_XXX
bfd/ 2010-01-07 H.J. Lu <hongjiu.lu@intel.com> PR ld/11133 * elflink.c (_bfd_elf_gc_mark_hook): Check section XXX for undefined __start_XXX/__stop_XXX in all input files and set SEC_KEEP. ld/testsuite/ 2010-01-07 H.J. Lu <hongjiu.lu@intel.com> PR ld/11133 * ld-gc/gc.exp: Run start. * ld-gc/start.d: New. * ld-gc/start.s: Likewise.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 284bff1..f9f804d 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11331,6 +11331,8 @@ _bfd_elf_gc_mark_hook (asection *sec,
struct elf_link_hash_entry *h,
Elf_Internal_Sym *sym)
{
+ const char *sec_name;
+
if (h != NULL)
{
switch (h->root.type)
@@ -11342,6 +11344,33 @@ _bfd_elf_gc_mark_hook (asection *sec,
case bfd_link_hash_common:
return h->root.u.c.p->section;
+ case bfd_link_hash_undefined:
+ case bfd_link_hash_undefweak:
+ /* To work around a glibc bug, keep all XXX input sections
+ when there is an as yet undefined reference to __start_XXX
+ or __stop_XXX symbols. The linker will later define such
+ symbols for orphan input sections that have a name
+ representable as a C identifier. */
+ if (strncmp (h->root.root.string, "__start_", 8) == 0)
+ sec_name = h->root.root.string + 8;
+ else if (strncmp (h->root.root.string, "__stop_", 7) == 0)
+ sec_name = h->root.root.string + 7;
+ else
+ sec_name = NULL;
+
+ if (sec_name && *sec_name != '\0')
+ {
+ bfd *i;
+
+ for (i = info->input_bfds; i; i = i->link_next)
+ {
+ sec = bfd_get_section_by_name (i, sec_name);
+ if (sec)
+ sec->flags |= SEC_KEEP;
+ }
+ }
+ break;
+
default:
break;
}