Add option to nm to change the characters displayed for ifunc symbols. Add a configu...
authorNick Clifton <nickc@redhat.com>
Fri, 20 Nov 2020 13:04:56 +0000 (13:04 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 20 Nov 2020 13:04:56 +0000 (13:04 +0000)
PR 22967
* nm.c (ifunc_type_chars): New variable.
(long_options): Add --ifunc-chars.
(print_symbol): Use ifunc_type_chars for ifunc symbols.
(main): Handle the new option.
* doc/binutils.texi: Document the new option.
* configure.ac: Add --enable-f-for-ifunc-symbols option which
changes the default symbol displayed by nm.
* NEWS: Mention the new feature.
* testsuite/binutils-all/nm.exp: Test the new feature.
* config.in: Regenerate.
* configure: Regenerate.

binutils/ChangeLog
binutils/NEWS
binutils/config.in
binutils/configure
binutils/configure.ac
binutils/doc/binutils.texi
binutils/nm.c
binutils/testsuite/binutils-all/nm.exp

index d6af8dfe73d4cd041abc07c8b89615f678641535..946ce6c46b9a8a38734c6caeb2b7558f84e7b44a 100644 (file)
@@ -1,3 +1,18 @@
+2020-11-20  Nick Clifton  <nickc@redhat.com>
+
+       PR 22967
+       * nm.c (ifunc_type_chars): New variable.
+       (long_options): Add --ifunc-chars.
+       (print_symbol): Use ifunc_type_chars for ifunc symbols.
+       (main): Handle the new option.
+       * doc/binutils.texi: Document the new option.
+       * configure.ac: Add --enable-f-for-ifunc-symbols option which
+       changes the default symbol displayed by nm.
+       * NEWS: Mention the new feature.
+       * testsuite/binutils-all/nm.exp: Test the new feature.
+       * config.in: Regenerate.
+       * configure: Regenerate.
+
 2020-11-20  Linda Zhang  <lindasc@qq.com>
 
        PR 20979
index e74b6a2dbad4ec3a3a276b292ddde78baa1bdaa1..a5a31959ffecaa513033819a73cc02c96c3c6937 100644 (file)
@@ -1,5 +1,14 @@
 -*- text -*-
 
+* Nm has a new command line option: --ifunc-chars=CHARS.  This specifies a
+  string of one or two characters.  The first character is used as the type
+  character when displaying global ifunc symbols.  The second character, if
+  present is used when displaying local ifunc symbols.
+
+  In addition a new configure time option --enable-f-for-ifunc-symbols has been
+  created, which if used will change nm's default characters for ifunc symbols
+  from i (both local and global) to F (global) and f (local).
+
 * The ar tool's previously unused l modifier is now used for specifying
   dependencies of a static library. The arguments of this option
   (or --record-libdeps long form option) will be stored verbatim in the
index 3adc32bb1ffb55ea7dd1e69cdd7c92410bd4bf0f..4d6744737192c8ab6b8bf743495bd20898ebc8ca 100644 (file)
@@ -18,6 +18,9 @@
 /* Should ar and ranlib use -D behavior by default? */
 #undef DEFAULT_AR_DETERMINISTIC
 
+/* Have nm use F and f for global and local ifunc symbols */
+#undef DEFAULT_F_FOR_IFUNC_SYMBOLS
+
 /* Should strings use -a behavior by default? */
 #undef DEFAULT_STRINGS_ALL
 
index 6dde3053a35973fd7acca35a2d2fe68089f2daad..c000966308785c8d3e17f6ad9d1d4c162ca9a84d 100755 (executable)
@@ -821,6 +821,7 @@ enable_largefile
 enable_targets
 enable_deterministic_archives
 enable_default_strings_all
+enable_f_for_ifunc_symbols
 with_debuginfod
 enable_libctf
 enable_werror
@@ -1485,6 +1486,9 @@ Optional Features:
                           ar and ranlib default to -D behavior
   --disable-default-strings-all
                           strings defaults to --data behavior
+  --enable-f-for-ifunc-symbols
+                          Have nm use F and f for global and local ifunc
+                          symbols
   --enable-libctf         Handle .ctf type-info sections [default=yes]
   --enable-werror         treat compile warnings as errors
   --enable-build-warnings enable build-time compiler warnings
@@ -11552,7 +11556,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11555 "configure"
+#line 11559 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11658,7 +11662,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11661 "configure"
+#line 11665 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12273,6 +12277,7 @@ if test "${enable_targets+set}" = set; then :
 esac
 fi
 
+
 # Check whether --enable-deterministic-archives was given.
 if test "${enable_deterministic_archives+set}" = set; then :
   enableval=$enable_deterministic_archives;
@@ -12292,6 +12297,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+
 # Check whether --enable-default-strings-all was given.
 if test "${enable_default_strings_all+set}" = set; then :
   enableval=$enable_default_strings_all;
 
 
 
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_STRINGS_ALL $default_strings_all
+_ACEOF
+
+
+
+# Check whether --enable-f-for-ifunc-symbols was given.
+if test "${enable_f_for_ifunc_symbols+set}" = set; then :
+  enableval=$enable_f_for_ifunc_symbols;
+if test "${enableval}" = no; then
+  default_f_for_ifunc=0
+else
+  default_f_for_ifunc=1
+fi
+else
+  default_f_for_ifunc=0
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_F_FOR_IFUNC_SYMBOLS $default_f_for_ifunc
+_ACEOF
+
+
+
 
 
 
@@ -12554,12 +12586,6 @@ $as_echo "$as_me: WARNING: debuginfod support disabled; some features may be una
 fi
 
 
-
-cat >>confdefs.h <<_ACEOF
-#define DEFAULT_STRINGS_ALL $default_strings_all
-_ACEOF
-
-
  # Check whether --enable-libctf was given.
 if test "${enable_libctf+set}" = set; then :
   enableval=$enable_libctf;
index 883f3187e722ec7cf6bdf05b24c4f6f958f97e18..24bf102019d2f31a571330587564d643c91a4b57 100644 (file)
@@ -43,6 +43,7 @@ AC_ARG_ENABLE(targets,
   *)        enable_targets=$enableval ;;
 esac])dnl
 
+
 AC_ARG_ENABLE(deterministic-archives,
 [AS_HELP_STRING([--enable-deterministic-archives],
                [ar and ranlib default to -D behavior])], [
@@ -55,6 +56,7 @@ fi], [default_ar_deterministic=0])
 AC_DEFINE_UNQUOTED(DEFAULT_AR_DETERMINISTIC, $default_ar_deterministic,
                   [Should ar and ranlib use -D behavior by default?])
 
+
 AC_ARG_ENABLE(default-strings-all,
 [AS_HELP_STRING([--disable-default-strings-all],
                [strings defaults to --data behavior])], [
@@ -64,11 +66,24 @@ else
   default_strings_all=1
 fi], [default_strings_all=1])
 
-AC_DEBUGINFOD
-
 AC_DEFINE_UNQUOTED(DEFAULT_STRINGS_ALL, $default_strings_all,
                   [Should strings use -a behavior by default?])
 
+
+AC_ARG_ENABLE(f-for-ifunc-symbols,
+[AS_HELP_STRING([--enable-f-for-ifunc-symbols],
+       [Have nm use F and f for global and local ifunc symbols])], [
+if test "${enableval}" = no; then
+  default_f_for_ifunc=0
+else
+  default_f_for_ifunc=1
+fi], [default_f_for_ifunc=0])
+
+AC_DEFINE_UNQUOTED(DEFAULT_F_FOR_IFUNC_SYMBOLS, $default_f_for_ifunc,
+                  [Have nm use F and f for global and local ifunc symbols])
+
+AC_DEBUGINFOD
+
 GCC_ENABLE([libctf], [yes], [], [Handle .ctf type-info sections])
 if test "${enable_libctf}" = yes; then
     AC_DEFINE(ENABLE_LIBCTF, 1, [Handle .ctf type-info sections])
index 41fd92a908aa7e4471daa4ecfc0e50ed0c39c3f0..671694f8111e68f394e40a2d9a81c368c85fb089 100644 (file)
@@ -797,6 +797,7 @@ nm [@option{-A}|@option{-o}|@option{--print-file-name}] [@option{-a}|@option{--d
    [@option{-B}|@option{--format=bsd}] [@option{-C}|@option{--demangle}[=@var{style}]]
    [@option{-D}|@option{--dynamic}] [@option{-f}@var{format}|@option{--format=}@var{format}]
    [@option{-g}|@option{--extern-only}] [@option{-h}|@option{--help}]
+   [@option{--ifunc-chars=@var{CHARS}}]
    [@option{-l}|@option{--line-numbers}] [@option{--inlines}]
    [@option{-n}|@option{-v}|@option{--numeric-sort}]
    [@option{-P}|@option{--portability}] [@option{-p}|@option{--no-sort}]
@@ -869,12 +870,21 @@ such as a global int variable as opposed to a large global array.
 
 @item i
 For PE format files this indicates that the symbol is in a section
-specific to the implementation of DLLs.  For ELF format files this
-indicates that the symbol is an indirect function.  This is a GNU
-extension to the standard set of ELF symbol types.  It indicates a
-symbol which if referenced by a relocation does not evaluate to its
-address, but instead must be invoked at runtime.  The runtime
-execution will then return the value to be used in the relocation.
+specific to the implementation of DLLs.
+
+For ELF format files this indicates that the symbol is an indirect
+function.  This is a GNU extension to the standard set of ELF symbol
+types.  It indicates a symbol which if referenced by a relocation does
+not evaluate to its address, but instead must be invoked at runtime.
+The runtime execution will then return the value to be used in the
+relocation.
+
+Note - the actual symbols display for GNU indirect symbols is
+controlled by the @option{--ifunc-chars} command line option.  If this
+option has been provided then the first character in the string will
+be used for global indirect function symbols.  If the string contains
+a second character then that will be used for local indirect function
+symbols.
 
 @item I
 The symbol is an indirect reference to another symbol.
@@ -1029,6 +1039,15 @@ Display only external symbols.
 @itemx --help
 Show a summary of the options to @command{nm} and exit.
 
+@item --ifunc-chars=@var{CHARS}
+When display GNU indirect function symbols @command{nm} will default
+to using the @code{i} character for both local indirect functions and
+global indirect functions.  The @option{--ifunc-chars} option allows
+the user to specify a string containing one or two characters. The
+first character will be used for global indirect function symbols and
+the second character, if present, will be used for local indirect
+function symbols.
+
 @item -l
 @itemx --line-numbers
 @cindex symbol line numbers
index cf2c02b1296412b06974a6668a09c91816e18651..2946bd6904646b90085b4d1138b4299e7aac4381 100644 (file)
@@ -162,6 +162,13 @@ static int show_synthetic = 0;     /* Display synthesized symbols too.  */
 static int line_numbers = 0;   /* Print line numbers for symbols.  */
 static int allow_special_symbols = 0;  /* Allow special symbols.  */
 
+/* The characters to use for global and local ifunc symbols.  */
+#if DEFAULT_F_FOR_IFUNC_SYMBOLS
+static const char * ifunc_type_chars = "Ff";
+#else
+static const char * ifunc_type_chars = NULL;
+#endif
+
 static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
 
 /* When to print the names of files.  Not mutually exclusive in SYSV format.  */
@@ -192,6 +199,7 @@ enum long_option_values
   OPTION_SIZE_SORT,
   OPTION_RECURSE_LIMIT,
   OPTION_NO_RECURSE_LIMIT,
+  OPTION_IFUNC_CHARS,
   OPTION_WITH_SYMBOL_VERSIONS
 };
 
@@ -203,6 +211,7 @@ static struct option long_options[] =
   {"extern-only", no_argument, &external_only, 1},
   {"format", required_argument, 0, 'f'},
   {"help", no_argument, 0, 'h'},
+  {"ifunc-chars", required_argument, 0, OPTION_IFUNC_CHARS},
   {"line-numbers", no_argument, 0, 'l'},
   {"no-cplus", no_argument, &do_demangle, 0},  /* Linux compatibility.  */
   {"no-demangle", no_argument, &do_demangle, 0},
@@ -255,6 +264,7 @@ usage (FILE *stream, int status)
   -f, --format=FORMAT    Use the output format FORMAT.  FORMAT can be `bsd',\n\
                            `sysv' or `posix'.  The default is `bsd'\n\
   -g, --extern-only      Display only external symbols\n\
+    --ifunc-chars=CHARS  Characters to use when displaying ifunc symbols\n\
   -l, --line-numbers     Use debugging information to find a filename and\n\
                            line number for each symbol\n\
   -n, --numeric-sort     Sort symbols numerically by address\n\
@@ -888,6 +898,18 @@ print_symbol (bfd *        abfd,
 
   bfd_get_symbol_info (abfd, sym, &syminfo);
 
+  /* PR 22967 - Distinguish between local and global ifunc symbols.  */
+  if (syminfo.type == 'i'
+      && sym->flags & BSF_GNU_INDIRECT_FUNCTION)
+    {
+      if (ifunc_type_chars == NULL || ifunc_type_chars[0] == 0)
+       ; /* Change nothing.  */
+      else if (sym->flags & BSF_GLOBAL) 
+       syminfo.type = ifunc_type_chars[0];
+      else if (ifunc_type_chars[1] != 0)
+       syminfo.type = ifunc_type_chars[1];
+    }
+
   info.sinfo = &syminfo;
   info.ssize = ssize;
   /* Synthetic symbols do not have a full symbol type set of data available.
@@ -1831,6 +1853,10 @@ main (int argc, char **argv)
 #endif
          break;
 
+       case OPTION_IFUNC_CHARS:
+         ifunc_type_chars = optarg;
+         break;
+
        case 0:         /* A long option that just sets a flag.  */
          break;
 
index 96cb50a300ac7919d22f5cf937802d772764017e..c27a5aedaab4d633401fc1f42268cd531f5094d2 100644 (file)
@@ -298,6 +298,49 @@ if [is_elf_format] {
            remote_file host delete $tmpfile
        }
     }
+
+    # PR 22967
+    # Test nm --ifunc-chars on a indirect symbols.
+    
+    # The following targets are known to not support ifuncs.
+    setup_xfail "alpha*-*-*"
+    setup_xfail "arm*-*-nto*"
+    setup_xfail "arm*-*-netbsdelf*"
+    setup_xfail "mips*-*-*"
+    setup_xfail "msp430*-*-*"
+    setup_xfail "tx39*-*-*"
+    setup_xfail "visium*-*-*"
+
+    set testname "nm --ifunc-chars"
+    if {![binutils_assemble $srcdir/$subdir/ifunc.s tmpdir/ifunc.o]} then {
+       fail "$testname (assembly)"
+    } else {
+       if [is_remote host] {
+           set tmpfile [remote_download host tmpdir/ifunc.o]
+       } else {
+           set tmpfile tmpdir/ifunc.o
+       }
+
+       set got [binutils_run $NM "$NMFLAGS --ifunc-chars=Ff $tmpfile"]
+
+       if [regexp "F global_foo" $got] then {
+           pass "$testname (global ifunc)"
+       } else {
+           fail "$testname (global ifunc)"
+       }
+
+       if [regexp "f local_foo" $got] then {
+           pass "$testname (local ifunc)"
+       } else {
+           fail "$testname (local ifunc)"
+       }
+
+       if { $verbose < 1 } {
+           remote_file host delete "tmpdir/ifunc.o"
+       }
+    }
+
+    
 }
 
 # There are certainly other tests that could be run.