Display the reference causing a shared library to be needed
authorAlan Modra <amodra@gmail.com>
Wed, 22 Jan 2014 05:35:12 +0000 (16:05 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 22 Jan 2014 05:51:34 +0000 (16:21 +1030)
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
bfd/elflink.c
ld/ChangeLog
ld/ldlang.c
ld/ldlang.h
ld/ldmain.c
ld/ldmisc.c

index 332bb56dec16febe17729e069217319bb8c2024a..3996dfcb2db6700d9ee25535ca25e474c326fcb0 100644 (file)
@@ -1,3 +1,7 @@
+2014-01-22  Alan Modra  <amodra@gmail.com>
+
+       * elflink.c (elf_link_add_object_symbols): Call minfo for --as-needed.
+
 2014-01-22  Alan Modra  <amodra@gmail.com>
 
        * elf64-ppc.c (STK_LINKER): Comment typo fix.
index 792e14e526fd6821805ed1a53d3bbb3532894fda..88967c835fa7dc7d164e70ade4093c6c079a7bb1 100644 (file)
@@ -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
index 0645c2d07a91c09fa7714f3b1e737a28512d8466..59e9d36e0bd03d23c3500f62a783e8cfc6b8b98d 100644 (file)
@@ -1,3 +1,14 @@
+2014-01-22  Alan Modra  <amodra@gmail.com>
+
+       * 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  <amodra@gmail.com>
 
        * ld.h (struct map_symbol_def): Move to..
index 62f85bcbcf44271998031898566fc95a1ad09b01..1a0d48f0bcb446f03aa25cfc9c8cf82466d9d55c 100644 (file)
@@ -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 ();
 
index c64ded0445bd0478edd78e3e7249dc35895d141c..7236c1cc20179611684401ef8da5b14fa3687e5f 100644 (file)
@@ -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);
index 019df71a2c40c734bec59de7bd442f83a7f1073f..00f79ecad9fd7e6892fb77e5854bcf47a5e990bb 100644 (file)
@@ -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;
        }
index 1b69ab1da46a969cee4999e11abe05faf1d1adf9..cddcb185aee60ee0b2669709d4d5186b902156ba 100644 (file)
@@ -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);
     }
 }