+2009-04-01 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c (xcoff_archive_info): Add contains_shared_object_p
+ and know_contains_shared_object_p.
+ (xcoff_archive_contains_shared_object_p): Add an "info" parameter.
+ Cache the result in the archive_info table.
+ (xcoff_auto_export_p): Add an "info" parameter and update the
+ call to xcoff_archive_contains_shared_object_p.
+ (xcoff_mark_auto_exports): Update accordingly.
+ (xcoff_post_gc_symbol): Likewise.
+
2009-04-01 Richard Sandiford <r.sandiford@uk.ibm.com>
* xcofflink.c (bfd_link_input_bfd): Treat __rtinit as C_HIDEXT
this archive in the .loader section. */
const char *imppath;
const char *impfile;
+
+ /* True if the archive contains a dynamic object. */
+ unsigned int contains_shared_object_p : 1;
+
+ /* True if the previous field is valid. */
+ unsigned int know_contains_shared_object_p : 1;
};
struct xcoff_link_hash_table
/* Return true if the given bfd contains at least one shared object. */
static bfd_boolean
-xcoff_archive_contains_shared_object_p (bfd *archive)
+xcoff_archive_contains_shared_object_p (struct bfd_link_info *info,
+ bfd *archive)
{
+ struct xcoff_archive_info *archive_info;
bfd *member;
- member = bfd_openr_next_archived_file (archive, NULL);
- while (member != NULL && (member->flags & DYNAMIC) == 0)
- member = bfd_openr_next_archived_file (archive, member);
- return member != NULL;
+ archive_info = xcoff_get_archive_info (info, archive);
+ if (!archive_info->know_contains_shared_object_p)
+ {
+ member = bfd_openr_next_archived_file (archive, NULL);
+ while (member != NULL && (member->flags & DYNAMIC) == 0)
+ member = bfd_openr_next_archived_file (archive, member);
+
+ archive_info->contains_shared_object_p = (member != NULL);
+ archive_info->know_contains_shared_object_p = 1;
+ }
+ return archive_info->contains_shared_object_p;
}
/* Symbol H qualifies for export by -bexpfull. Return true if it also
specified by AUTO_EXPORT_FLAGS. */
static bfd_boolean
-xcoff_auto_export_p (struct xcoff_link_hash_entry *h,
+xcoff_auto_export_p (struct bfd_link_info *info,
+ struct xcoff_link_hash_entry *h,
unsigned int auto_export_flags)
{
/* Don't automatically export things that were explicitly exported. */
owner = h->root.u.def.section->owner;
if (owner != NULL
&& owner->my_archive != NULL
- && xcoff_archive_contains_shared_object_p (owner->my_archive))
+ && xcoff_archive_contains_shared_object_p (info, owner->my_archive))
return FALSE;
}
struct xcoff_loader_info *ldinfo;
ldinfo = (struct xcoff_loader_info *) data;
- if (xcoff_auto_export_p (h, ldinfo->auto_export_flags))
+ if (xcoff_auto_export_p (ldinfo->info, h, ldinfo->auto_export_flags))
{
if (!xcoff_mark_symbol (ldinfo->info, h))
ldinfo->failed = TRUE;
if (xcoff_hash_table (ldinfo->info)->loader_section)
{
- if (xcoff_auto_export_p (h, ldinfo->auto_export_flags))
+ if (xcoff_auto_export_p (ldinfo->info, h, ldinfo->auto_export_flags))
h->flags |= XCOFF_EXPORT;
if (!xcoff_build_ldsym (ldinfo, h))