From 16e4ecc0dbe114cfc97fe2cd32a035ae4c37f22b Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 22 Jan 2014 16:05:12 +1030 Subject: [PATCH] Display the reference causing a shared library to be needed Adds a section for --as-needed libraries to a linker map file, similar to what we do for archive libraries. bfd/ * elflink.c (elf_link_add_object_symbols): Call minfo for --as-needed. ld/ * ldlang.c (asneeded_list_head, asneeded_list_tail): New vars. (lang_init): Initialise them. (lang_print_asneeded): New function. (lang_process): Call lang_print_asneeded. * ldlang.h (struct asneeded_minfo): New. (asneeded_list_tail): Declare. * ldmain.c (add_archive_element): Improve archive map heading. * ldmisc.c (minfo): Stash --as-needed info. --- bfd/ChangeLog | 4 ++++ bfd/elflink.c | 3 +++ ld/ChangeLog | 11 +++++++++++ ld/ldlang.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ ld/ldlang.h | 9 +++++++++ ld/ldmain.c | 3 ++- ld/ldmisc.c | 17 ++++++++++++++++- 7 files changed, 89 insertions(+), 2 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 332bb56dec..3996dfcb2d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,7 @@ +2014-01-22 Alan Modra + + * elflink.c (elf_link_add_object_symbols): Call minfo for --as-needed. + 2014-01-22 Alan Modra * elf64-ppc.c (STK_LINKER): Comment typo fix. diff --git a/bfd/elflink.c b/bfd/elflink.c index 792e14e526..88967c835f 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -4437,6 +4437,9 @@ error_free_dyn: int ret; const char *soname = elf_dt_name (abfd); + info->callbacks->minfo ("%!", soname, old_bfd, + h->root.root.string); + /* A symbol from a library loaded via DT_NEEDED of some other library is referenced by a regular object. Add a DT_NEEDED entry for it. Issue an error if diff --git a/ld/ChangeLog b/ld/ChangeLog index 0645c2d07a..59e9d36e0b 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,14 @@ +2014-01-22 Alan Modra + + * ldlang.c (asneeded_list_head, asneeded_list_tail): New vars. + (lang_init): Initialise them. + (lang_print_asneeded): New function. + (lang_process): Call lang_print_asneeded. + * ldlang.h (struct asneeded_minfo): New. + (asneeded_list_tail): Declare. + * ldmain.c (add_archive_element): Improve archive map heading. + * ldmisc.c (minfo): Stash --as-needed info. + 2014-01-22 Alan Modra * ld.h (struct map_symbol_def): Move to.. diff --git a/ld/ldlang.c b/ld/ldlang.c index 62f85bcbcf..1a0d48f0bc 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -67,6 +67,7 @@ static struct bfd_hash_table lang_definedness_table; static lang_statement_list_type *stat_save[10]; static lang_statement_list_type **stat_save_ptr = &stat_save[0]; static struct unique_sections *unique_section_list; +static struct asneeded_minfo *asneeded_list_head; /* Forward declarations. */ static void exp_init_os (etree_type *); @@ -105,6 +106,7 @@ bfd_boolean lang_float_flag = FALSE; bfd_boolean delete_output_file_on_failure = FALSE; struct lang_phdr *lang_phdr_list; struct lang_nocrossrefs *nocrossref_list; +struct asneeded_minfo **asneeded_list_tail; /* Functions that traverse the linker script and might evaluate DEFINED() need to increment this at the start of the traversal. */ @@ -1228,6 +1230,9 @@ lang_init (void) sizeof (struct lang_definedness_hash_entry), 13)) einfo (_("%P%F: can not create hash table: %E\n")); + + asneeded_list_head = NULL; + asneeded_list_tail = &asneeded_list_head; } void @@ -1953,6 +1958,43 @@ lang_insert_orphan (asection *s, return os; } +static void +lang_print_asneeded (void) +{ + struct asneeded_minfo *m; + char buf[100]; + + if (asneeded_list_head == NULL) + return; + + sprintf (buf, _("\nAs-needed library included " + "to satisfy reference by file (symbol)\n\n")); + minfo ("%s", buf); + + for (m = asneeded_list_head; m != NULL; m = m->next) + { + size_t len; + + minfo ("%s", m->soname); + len = strlen (m->soname); + + if (len >= 29) + { + print_nl (); + len = 0; + } + while (len < 30) + { + print_space (); + ++len; + } + + if (m->ref != NULL) + minfo ("%B ", m->ref); + minfo ("(%T)\n", m->name); + } +} + static void lang_map_flags (flagword flag) { @@ -6629,6 +6671,8 @@ lang_process (void) link_info.gc_sym_list = ldlang_undef_chain_list_head; ldemul_after_open (); + if (config.map_file != NULL) + lang_print_asneeded (); bfd_section_already_linked_table_free (); diff --git a/ld/ldlang.h b/ld/ldlang.h index c64ded0445..7236c1cc20 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -487,6 +487,14 @@ struct orphan_save lang_output_section_statement_type **os_tail; }; +struct asneeded_minfo +{ + struct asneeded_minfo *next; + const char *soname; + bfd *ref; + const char *name; +}; + extern struct lang_phdr *lang_phdr_list; extern struct lang_nocrossrefs *nocrossref_list; extern const char *output_target; @@ -505,6 +513,7 @@ extern lang_statement_list_type file_chain; extern lang_statement_list_type input_file_chain; extern int lang_statement_iteration; +extern struct asneeded_minfo **asneeded_list_tail; extern void lang_init (void); diff --git a/ld/ldmain.c b/ld/ldmain.c index 019df71a2c..00f79ecad9 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -841,7 +841,8 @@ add_archive_element (struct bfd_link_info *info, { char buf[100]; - sprintf (buf, _("Archive member included because of file (symbol)\n\n")); + sprintf (buf, _("Archive member included " + "to satisfy reference by file (symbol)\n\n")); minfo ("%s", buf); header_printed = TRUE; } diff --git a/ld/ldmisc.c b/ld/ldmisc.c index 1b69ab1da4..cddcb185ae 100644 --- a/ld/ldmisc.c +++ b/ld/ldmisc.c @@ -484,7 +484,22 @@ minfo (const char *fmt, ...) va_list arg; va_start (arg, fmt); - vfinfo (config.map_file, fmt, arg, FALSE); + if (fmt[0] == '%' && fmt[1] == '!' && fmt[2] == 0) + { + /* Stash info about --as-needed shared libraries. Print + later so they don't appear intermingled with archive + library info. */ + struct asneeded_minfo *m = xmalloc (sizeof *m); + + m->next = NULL; + m->soname = va_arg (arg, const char *); + m->ref = va_arg (arg, bfd *); + m->name = va_arg (arg, const char *); + *asneeded_list_tail = m; + asneeded_list_tail = &m->next; + } + else + vfinfo (config.map_file, fmt, arg, FALSE); va_end (arg); } }