From 2bc16fa118ab4f519b21489539c048b4f3c475ec Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sat, 14 Mar 2009 09:35:06 +0000 Subject: bfd/ * xcofflink.c (xcoff_mark_symbol_by_name): New function. (bfd_xcoff_size_dynamic_sections): Use it to mark the entry, init and fini functions. Do garbage collection for objects without an entry point too. ld/testsuite/ * ld-powerpc/aix-gc-1.s, ld-powerpc/aix-gc-1.ex, ld-powerpc/aix-gc-1-32.dd, ld-powerpc/aix-gc-1-64.dd, ld-powerpc/aix-weak-1-gcdso.dnd, ld-powerpc/aix-weak-1-gcdso.hd, ld-powerpc/aix-weak-1-gcdso.nd: New tests. * ld-powerpc/aix52.exp: Run them. --- bfd/xcofflink.c | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) (limited to 'bfd/xcofflink.c') diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index d87940c395..3ca9b7287a 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -2482,6 +2482,30 @@ xcoff_mark_symbol (struct bfd_link_info *info, struct xcoff_link_hash_entry *h) return TRUE; } +/* Look for a symbol called NAME. If the symbol is defined, mark it. + If the symbol exists, set FLAGS. */ + +static bfd_boolean +xcoff_mark_symbol_by_name (struct bfd_link_info *info, + const char *name, unsigned int flags) +{ + struct xcoff_link_hash_entry *h; + + h = xcoff_link_hash_lookup (xcoff_hash_table (info), name, + FALSE, FALSE, TRUE); + if (h != NULL) + { + h->flags |= flags; + if (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + { + if (!xcoff_mark (info, h->root.u.def.section)) + return FALSE; + } + } + return TRUE; +} + /* The mark phase of garbage collection. For a given section, mark it, and all the sections which define symbols to which it refers. Because this function needs to look at the relocs, we also count @@ -3177,7 +3201,6 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd, asection **special_sections, bfd_boolean rtld) { - struct xcoff_link_hash_entry *hentry; asection *lsec; struct xcoff_loader_info ldinfo; int i; @@ -3216,15 +3239,6 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd, xcoff_hash_table (info)->textro = textro; xcoff_hash_table (info)->rtld = rtld; - hentry = NULL; - if (entry != NULL) - { - hentry = xcoff_link_hash_lookup (xcoff_hash_table (info), entry, - FALSE, FALSE, TRUE); - if (hentry != NULL) - hentry->flags |= XCOFF_ENTRY; - } - /* __rtinit */ if (info->init_function || info->fini_function || rtld) { @@ -3277,11 +3291,7 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd, } /* Garbage collect unused sections. */ - if (info->relocatable - || ! gc - || hentry == NULL - || (hentry->root.type != bfd_link_hash_defined - && hentry->root.type != bfd_link_hash_defweak)) + if (info->relocatable || !gc) { gc = FALSE; xcoff_hash_table (info)->gc = FALSE; @@ -3309,7 +3319,14 @@ bfd_xcoff_size_dynamic_sections (bfd *output_bfd, } else { - if (! xcoff_mark (info, hentry->root.u.def.section)) + if (entry != NULL + && !xcoff_mark_symbol_by_name (info, entry, XCOFF_ENTRY)) + goto error_return; + if (info->init_function != NULL + && !xcoff_mark_symbol_by_name (info, info->init_function, 0)) + goto error_return; + if (info->fini_function != NULL + && !xcoff_mark_symbol_by_name (info, info->fini_function, 0)) goto error_return; xcoff_sweep (info); xcoff_hash_table (info)->gc = TRUE; -- cgit v1.2.1