packaging: Enable testing infrastructure
[external/binutils.git] / binutils / nm.c
index 39083c3..f987fae 100644 (file)
@@ -1,5 +1,5 @@
 /* nm.c -- Describe symbol table of a rel file.
-   Copyright (C) 1991-2018 Free Software Foundation, Inc.
+   Copyright (C) 1991-2019 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
@@ -77,15 +77,15 @@ struct extended_symbol_info
   (sym->elfinfo ? sym->elfinfo->internal_elf_sym.st_size: sym->ssize)
 
 /* The output formatting functions.  */
-static void print_object_filename_bsd (char *);
-static void print_object_filename_sysv (char *);
-static void print_object_filename_posix (char *);
-static void print_archive_filename_bsd (char *);
-static void print_archive_filename_sysv (char *);
-static void print_archive_filename_posix (char *);
-static void print_archive_member_bsd (char *, const char *);
-static void print_archive_member_sysv (char *, const char *);
-static void print_archive_member_posix (char *, const char *);
+static void print_object_filename_bsd (const char *);
+static void print_object_filename_sysv (const char *);
+static void print_object_filename_posix (const char *);
+static void print_archive_filename_bsd (const char *);
+static void print_archive_filename_sysv (const char *);
+static void print_archive_filename_posix (const char *);
+static void print_archive_member_bsd (const char *, const char *);
+static void print_archive_member_sysv (const char *, const char *);
+static void print_archive_member_posix (const char *, const char *);
 static void print_symbol_filename_bsd (bfd *, bfd *);
 static void print_symbol_filename_sysv (bfd *, bfd *);
 static void print_symbol_filename_posix (bfd *, bfd *);
@@ -98,13 +98,13 @@ static void print_symbol_info_posix (struct extended_symbol_info *, bfd *);
 struct output_fns
   {
     /* Print the name of an object file given on the command line.  */
-    void (*print_object_filename) (char *);
+    void (*print_object_filename) (const char *);
 
     /* Print the name of an archive file given on the command line.  */
-    void (*print_archive_filename) (char *);
+    void (*print_archive_filename) (const char *);
 
     /* Print the name of an archive member file.  */
-    void (*print_archive_member) (char *, const char *);
+    void (*print_archive_member) (const char *, const char *);
 
     /* Print the name of the file (and archive, if there is one)
        containing a symbol.  */
@@ -141,6 +141,8 @@ static struct output_fns formats[] =
 
 /* The output format to use.  */
 static struct output_fns *format = &formats[FORMAT_DEFAULT];
+static unsigned int print_format = FORMAT_DEFAULT;
+static const char *print_format_string = NULL;
 
 /* Command options.  */
 
@@ -168,17 +170,6 @@ static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
 static int filename_per_file = 0;      /* Once per file, on its own line.  */
 static int filename_per_symbol = 0;    /* Once per symbol, at start of line.  */
 
-/* Print formats for printing a symbol value.  */
-static char value_format_32bit[] = "%08lx";
-#if BFD_HOST_64BIT_LONG
-static char value_format_64bit[] = "%016lx";
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
-static char value_format_64bit[] = "%016llx";
-#else
-static char value_format_64bit[] = "%016I64x";
-#endif
-#endif
 static int print_width = 0;
 static int print_radix = 16;
 /* Print formats for printing stab info.  */
@@ -303,29 +294,15 @@ set_print_radix (char *radix)
 {
   switch (*radix)
     {
-    case 'x':
-      break;
-    case 'd':
-    case 'o':
-      if (*radix == 'd')
-       print_radix = 10;
-      else
-       print_radix = 8;
-      value_format_32bit[4] = *radix;
-#if BFD_HOST_64BIT_LONG
-      value_format_64bit[5] = *radix;
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
-      value_format_64bit[6] = *radix;
-#else
-      value_format_64bit[7] = *radix;
-#endif
-#endif
-      other_format[3] = desc_format[3] = *radix;
-      break;
+    case 'x': print_radix = 16; break;
+    case 'd': print_radix = 10; break;
+    case 'o': print_radix =  8; break;
+
     default:
       fatal (_("%s: invalid radix"), radix);
     }
+
+  other_format[3] = desc_format[3] = *radix;
 }
 
 static void
@@ -351,6 +328,7 @@ set_output_format (char *f)
       fatal (_("%s: invalid output format"), f);
     }
   format = &formats[i];
+  print_format = i;
 }
 \f
 static const char *
@@ -461,6 +439,10 @@ print_symdef_entry (bfd *abfd)
     }
 }
 \f
+
+/* True when we can report missing plugin error.  */
+bfd_boolean report_plugin_err = TRUE;
+
 /* Choose which symbol entries to print;
    compact them downward to get rid of the rest.
    Return the number of symbols to be printed.  */
@@ -493,9 +475,13 @@ filter_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms,
 
       if (sym->name[0] == '_'
          && sym->name[1] == '_'
-         && strcmp (sym->name + (sym->name[2] == '_'), "__gnu_lto_slim") == 0)
-       non_fatal (_("%s: plugin needed to handle lto object"),
-                  bfd_get_filename (abfd));
+         && strcmp (sym->name + (sym->name[2] == '_'), "__gnu_lto_slim") == 0
+         && report_plugin_err)
+       {
+         report_plugin_err = FALSE;
+         non_fatal (_("%s: plugin needed to handle lto object"),
+                    bfd_get_filename (abfd));
+       }
 
       if (undefined_only)
        keep = bfd_is_und_section (sym->section);
@@ -1187,6 +1173,15 @@ display_rel_file (bfd *abfd, bfd *archive_bfd)
        }
     }
 
+  /* lto_slim_object is set to false when a bfd is loaded with a compiler
+     LTO plugin.  */
+  if (abfd->lto_slim_object)
+    {
+      report_plugin_err = FALSE;
+      non_fatal (_("%s: plugin needed to handle lto object"),
+                bfd_get_filename (abfd));
+    }
+
   /* Discard the symbols we don't want to print.
      It's OK to do this in place; we'll free the storage anyway
      (after printing).  */
@@ -1222,6 +1217,51 @@ display_rel_file (bfd *abfd, bfd *archive_bfd)
   free (symsizes);
 }
 
+/* Construct a formatting string for printing symbol values.  */
+
+static const char *
+get_print_format (void)
+{
+  const char * padding;
+  if (print_format == FORMAT_POSIX)
+    {
+      /* POSIX compatible output does not have any padding.  */
+      padding = "";
+    }
+  else if (print_width == 32)
+    {
+      padding ="08";
+    }
+  else /* print_width == 64 */
+    {
+      padding = "016";
+    }
+
+  const char * length = "l";
+  if (print_width == 64)
+    {
+#if BFD_HOST_64BIT_LONG
+      ;
+#elif BFD_HOST_64BIT_LONG_LONG
+#ifndef __MSVCRT__
+      length = "ll";
+#else
+      length = "I64";
+#endif
+#endif
+    }
+
+  const char * radix = NULL;
+  switch (print_radix)
+    {
+    case 8:  radix = "o"; break;
+    case 10: radix = "d"; break;
+    case 16: radix = "x"; break;
+    }
+
+  return concat ("%", padding, length, radix, NULL);
+}
+
 static void
 set_print_width (bfd *file)
 {
@@ -1240,6 +1280,8 @@ set_print_width (bfd *file)
       else
        print_width = 32;
     }
+  free ((char *) print_format_string);
+  print_format_string = get_print_format ();
 }
 
 static void
@@ -1363,14 +1405,14 @@ display_file (char *filename)
 /* Print the name of an object file given on the command line.  */
 
 static void
-print_object_filename_bsd (char *filename)
+print_object_filename_bsd (const char *filename)
 {
   if (filename_per_file && !filename_per_symbol)
     printf ("\n%s:\n", filename);
 }
 
 static void
-print_object_filename_sysv (char *filename)
+print_object_filename_sysv (const char *filename)
 {
   if (undefined_only)
     printf (_("\n\nUndefined symbols from %s:\n\n"), filename);
@@ -1385,7 +1427,7 @@ Name                  Value           Class        Type         Size
 }
 
 static void
-print_object_filename_posix (char *filename)
+print_object_filename_posix (const char *filename)
 {
   if (filename_per_file && !filename_per_symbol)
     printf ("%s:\n", filename);
@@ -1394,26 +1436,26 @@ print_object_filename_posix (char *filename)
 /* Print the name of an archive file given on the command line.  */
 
 static void
-print_archive_filename_bsd (char *filename)
+print_archive_filename_bsd (const char *filename)
 {
   if (filename_per_file)
     printf ("\n%s:\n", filename);
 }
 
 static void
-print_archive_filename_sysv (char *filename ATTRIBUTE_UNUSED)
+print_archive_filename_sysv (const char *filename ATTRIBUTE_UNUSED)
 {
 }
 
 static void
-print_archive_filename_posix (char *filename ATTRIBUTE_UNUSED)
+print_archive_filename_posix (const char *filename ATTRIBUTE_UNUSED)
 {
 }
 \f
 /* Print the name of an archive member file.  */
 
 static void
-print_archive_member_bsd (char *archive ATTRIBUTE_UNUSED,
+print_archive_member_bsd (const char *archive ATTRIBUTE_UNUSED,
                          const char *filename)
 {
   if (!filename_per_symbol)
@@ -1421,7 +1463,7 @@ print_archive_member_bsd (char *archive ATTRIBUTE_UNUSED,
 }
 
 static void
-print_archive_member_sysv (char *archive, const char *filename)
+print_archive_member_sysv (const char *archive, const char *filename)
 {
   if (undefined_only)
     printf (_("\n\nUndefined symbols from %s[%s]:\n\n"), archive, filename);
@@ -1436,7 +1478,7 @@ Name                  Value           Class        Type         Size
 }
 
 static void
-print_archive_member_posix (char *archive, const char *filename)
+print_archive_member_posix (const char *archive, const char *filename)
 {
   if (!filename_per_symbol)
     printf ("%s[%s]:\n", archive, filename);
@@ -1488,12 +1530,12 @@ print_value (bfd *abfd ATTRIBUTE_UNUSED, bfd_vma val)
   switch (print_width)
     {
     case 32:
-      printf (value_format_32bit, (unsigned long) val);
+      printf (print_format_string, (unsigned long) val);
       break;
 
     case 64:
 #if BFD_HOST_64BIT_LONG || BFD_HOST_64BIT_LONG_LONG
-      printf (value_format_64bit, val);
+      printf (print_format_string, val);
 #else
       /* We have a 64 bit value to print, but the host is only 32 bit.  */
       if (print_radix == 16)