From e6f6aa8d184c38230d9acd91a49aa0cbe3f37e42 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 20 Nov 2020 13:04:56 +0000 Subject: [PATCH] Add option to nm to change the characters displayed for ifunc symbols. Add a configure time option to change the default characters. 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 | 15 +++++++++ binutils/NEWS | 9 ++++++ binutils/config.in | 3 ++ binutils/configure | 42 ++++++++++++++++++++----- binutils/configure.ac | 19 ++++++++++-- binutils/doc/binutils.texi | 31 +++++++++++++++---- binutils/nm.c | 26 ++++++++++++++++ binutils/testsuite/binutils-all/nm.exp | 43 ++++++++++++++++++++++++++ 8 files changed, 172 insertions(+), 16 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index d6af8dfe73..946ce6c46b 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,18 @@ +2020-11-20 Nick Clifton + + 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 PR 20979 diff --git a/binutils/NEWS b/binutils/NEWS index e74b6a2dba..a5a31959ff 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -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 diff --git a/binutils/config.in b/binutils/config.in index 3adc32bb1f..4d67447371 100644 --- a/binutils/config.in +++ b/binutils/config.in @@ -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 diff --git a/binutils/configure b/binutils/configure index 6dde3053a3..c000966308 100755 --- a/binutils/configure +++ b/binutils/configure @@ -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; @@ -12306,6 +12312,32 @@ fi +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; diff --git a/binutils/configure.ac b/binutils/configure.ac index 883f3187e7..24bf102019 100644 --- a/binutils/configure.ac +++ b/binutils/configure.ac @@ -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]) diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 41fd92a908..671694f811 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -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 diff --git a/binutils/nm.c b/binutils/nm.c index cf2c02b129..2946bd6904 100644 --- a/binutils/nm.c +++ b/binutils/nm.c @@ -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; diff --git a/binutils/testsuite/binutils-all/nm.exp b/binutils/testsuite/binutils-all/nm.exp index 96cb50a300..c27a5aedaa 100644 --- a/binutils/testsuite/binutils-all/nm.exp +++ b/binutils/testsuite/binutils-all/nm.exp @@ -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. -- 2.34.1