]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
nm: fix treating an ifunc symbol as a stab if '--ifunc-chars=--' is given
authorDmitry Klochkov <dmitry.klochkov@bell-sw.com>
Tue, 9 Sep 2025 10:06:25 +0000 (12:06 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 9 Sep 2025 10:06:25 +0000 (12:06 +0200)
If an ifunc symbol is processed in print_symbol(), a 'type' field of a
'syminfo' structure is set to any character specified by a user with an
'--ifunc-chars' option.  But afterwards the 'type' field is used to
check whether a symbol is a stab in print_symbol_info_{bsd,sysv}()
functions in order to print additional stab related data.  If the 'type'
field equals '-', a symbol is treated as a stab.  If '--ifunc-chars=--'
is given, all ifunc symbols will be treated as stab symbols and
uninitialized stab related fields of the 'syminfo' structure will be
printed which can lead to segmentation fault.

To fix this, check if a symbol is a stab before override the 'type'
field.  Also, add a test case for this fix.

PR binutils/32556
* nm.c (extended_symbol_info): Add is_stab.
(print_symbol): Check if a symbol is a stab.
(print_symbol_info_bsd): Use info->is_stab.
(print_symbol_info_sysv): Use info->is_stab.
* testsuite/binutils-all/nm.exp: Test nm --ifunc-chars=--.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32556
Fixes: e6f6aa8d184 ("Add option to nm to change the characters displayed for ifunc symbols")
Signed-off-by: Dmitry Klochkov <dmitry.klochkov@bell-sw.com>
binutils/nm.c
binutils/testsuite/binutils-all/nm.exp

index dce9207f44fac9d416e0206dc67c6e42d0f7f190..c3d118a93c3833bb4ebcae56be4508fc298250ec 100644 (file)
@@ -70,6 +70,7 @@ struct extended_symbol_info
   bfd_vma ssize;
   elf_symbol_type *elfinfo;
   coff_symbol_type *coffinfo;
+  bool is_stab;
   /* FIXME: We should add more fields for Type, Line, Section.  */
 };
 #define SYM_VALUE(sym)       (sym->sinfo->value)
@@ -1208,8 +1209,11 @@ print_symbol (bfd *        abfd,
 
   bfd_get_symbol_info (abfd, sym, &syminfo);
 
+  info.is_stab = false;
+  if (syminfo.type == '-')
+    info.is_stab = true;
   /* PR 22967 - Distinguish between local and global ifunc symbols.  */
-  if (syminfo.type == 'i'
+  else if (syminfo.type == 'i'
       && sym->flags & BSF_GNU_INDIRECT_FUNCTION)
     {
       if (ifunc_type_chars == NULL || ifunc_type_chars[0] == 0)
@@ -1873,7 +1877,7 @@ print_symbol_info_bsd (struct extended_symbol_info *info, bfd *abfd)
 
   printf (" %c", SYM_TYPE (info));
 
-  if (SYM_TYPE (info) == '-')
+  if (info->is_stab)
     {
       /* A stab.  */
       printf (" ");
@@ -1902,7 +1906,7 @@ print_symbol_info_sysv (struct extended_symbol_info *info, bfd *abfd)
 
   printf ("|   %c  |", SYM_TYPE (info));
 
-  if (SYM_TYPE (info) == '-')
+  if (info->is_stab)
     {
       /* A stab.  */
       printf ("%18s|  ", SYM_STAB_NAME (info));                /* (C) Type.  */
index fea68bf76bcc0c3bba36eabc1036426d6354ff4a..1feb8578fba429bb42cebf665962a1aceff6a12e 100644 (file)
@@ -329,6 +329,23 @@ if [is_elf_format] {
            fail "$testname (local ifunc)"
        }
 
+       # PR 32556
+       # Test nm --ifunc-chars=--
+
+       set got [binutils_run $NM "$NMFLAGS --ifunc-chars=-- $tmpfile"]
+
+       if [regexp -line "^\\S+ - global_foo$" $got] then {
+           pass "$testname=-- (global ifunc)"
+       } else {
+           fail "$testname=-- (global ifunc)"
+       }
+
+       if [regexp -line "^\\S+ - local_foo$" $got] then {
+           pass "$testname=-- (local ifunc)"
+       } else {
+           fail "$testname=-- (local ifunc)"
+       }
+
        if { $verbose < 1 } {
            remote_file host delete "tmpdir/ifunc.o"
        }