Bug 26389

Summary: nm print "c" for a common symbol with -flto and -fcommon
Product: binutils Reporter: Martin Liska <mliska>
Component: binutilsAssignee: Alan Modra <amodra>
Status: RESOLVED FIXED    
Severity: normal CC: laurent.stacul, nickc
Priority: P2    
Version: 2.34   
Target Milestone: 2.35   
Host: Target:
Build: Last reconfirmed: 2020-08-15 00:00:00

Description Martin Liska 2020-08-14 10:23:06 UTC
Starting from Alan's 49d9fd42acefc1c0ee282b5808874a1074bf1ecd, the following changed:

$ cat conf.c
char nm_test_var;

$ gcc -flto -fcommon -c conf.c
$ ./binutils/nm-new conf.o
00000000 c nm_test_var

while before the revision the following is printed:
$ nm conf.o
00000000 C nm_test_var

Note that the "c" value is not supported by libtool and so a configure detection fails for various packages.

I think we want to print "C" for a common symbol from LTO plugin. So one needs something like:

 bfd/syms.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/bfd/syms.c b/bfd/syms.c
index c1de8ebab1..baa22cfcd9 100644
--- a/bfd/syms.c
+++ b/bfd/syms.c
@@ -653,7 +653,9 @@ bfd_decode_symclass (asymbol *symbol)
 
   if (symbol->section && bfd_is_com_section (symbol->section))
     {
-      if (symbol->section == bfd_com_section_ptr)
+      if (symbol->section == bfd_com_section_ptr
+	  || (symbol->section->name
+	      && strcmp (symbol->section->name, "plug") == 0))
 	return 'C';
       else
 	return 'c';

And, can you please document the "c" in manual page?
Comment 1 Alan Modra 2020-08-15 00:34:38 UTC
Yes, I jumped the wrong way in handling .scommon and other small data common sections.  I'll commit the following after some testing.

diff --git a/bfd/syms.c b/bfd/syms.c
index b9f73361e6..cb25af17fa 100644
--- a/bfd/syms.c
+++ b/bfd/syms.c
@@ -653,10 +653,10 @@ bfd_decode_symclass (asymbol *symbol)
 
   if (symbol->section && bfd_is_com_section (symbol->section))
     {
-      if (symbol->section == bfd_com_section_ptr)
-	return 'C';
-      else
+      if (symbol->section->flags & SEC_SMALL_DATA)
 	return 'c';
+      else
+	return 'C';
     }
   if (bfd_is_und_section (symbol->section))
     {
Comment 2 Sourceware Commits 2020-08-15 05:50:29 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4d1823674eedf267c7cafac2b923256db0b10ac8

commit 4d1823674eedf267c7cafac2b923256db0b10ac8
Author: Alan Modra <amodra@gmail.com>
Date:   Sat Aug 15 09:42:44 2020 +0930

    PR26389, nm prints "c" for a common symbol with -flto and -fcommon
    
    git commit 49d9fd42acef chose to make nm print 'C' for the normal
    common section, and 'c' for other commons.  This was an attempt to
    make common symbols in .scommon and other small common sections show
    a 'c' type without a section name comparison, but it failed for
    nm --plugin on lto objects where normal common symbols are stashed in
    a "plug" section.  It's also wrong for large common symbols.  So
    instead set SEC_SMALL_DATA on sections created for small commons, and
    key off that flag to show 'c' type.  If your ELF target doesn't have
    an elf_backend_symbol_processing function, then you won't see 'c' for
    symbols in .scommon.
    
    Note that due to bfd_decode_symclass decoding common symbols without
    a chance for coff_section_type to treat .scommon specially, then
    having .scommon in the array of special sections handled by
    coff_section_type prior to 49d9fd42acef was entirely ineffective.
    That fact escaped me when writing 49d9fd42acef.  Unless .scommon
    didn't have SEC_IS_COMMON set, which would be a little weird.
    
            PR 26389
            * syms.c (bfd_decode_symclass): Choose 'c' for commons only when
            SEC_SMALL_DATA.
            * elf32-m32r.c (_bfd_m32r_elf_symbol_processing): Set SEC_SMALL_DATA
            on small common section.
            * elf32-score.c (s3_bfd_score_elf_symbol_processing): Likewise.
            * elf32-score7.c (s7_bfd_score_elf_symbol_processing): Likewise.
            * elf32-tic6x.c (elf32_tic6x_symbol_processing): Likewise.
            * elf32-v850.c (v850_elf_symbol_processing): Likewise.
            * elfxx-mips.c (_bfd_mips_elf_symbol_processing): Likewise.
            * ecoff.c (ecoff_set_symbol_info, ecoff_link_add_externals): Likewise.
Comment 3 Sourceware Commits 2020-08-15 13:39:43 UTC
The binutils-2_35-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6183270ab45614eef9f33f58a3e01fdd0b525c6b

commit 6183270ab45614eef9f33f58a3e01fdd0b525c6b
Author: Alan Modra <amodra@gmail.com>
Date:   Sat Aug 15 09:42:44 2020 +0930

    PR26389, nm prints "c" for a common symbol with -flto and -fcommon
    
    git commit 49d9fd42acef chose to make nm print 'C' for the normal
    common section, and 'c' for other commons.  This was an attempt to
    make common symbols in .scommon and other small common sections show
    a 'c' type without a section name comparison, but it failed for
    nm --plugin on lto objects where normal common symbols are stashed in
    a "plug" section.  It's also wrong for large common symbols.  So
    instead set SEC_SMALL_DATA on sections created for small commons, and
    key off that flag to show 'c' type.  If your ELF target doesn't have
    an elf_backend_symbol_processing function, then you won't see 'c' for
    symbols in .scommon.
    
    Note that due to bfd_decode_symclass decoding common symbols without
    a chance for coff_section_type to treat .scommon specially, then
    having .scommon in the array of special sections handled by
    coff_section_type prior to 49d9fd42acef was entirely ineffective.
    That fact escaped me when writing 49d9fd42acef.  Unless .scommon
    didn't have SEC_IS_COMMON set, which would be a little weird.
    
            PR 26389
            * syms.c (bfd_decode_symclass): Choose 'c' for commons only when
            SEC_SMALL_DATA.
            * elf32-m32r.c (_bfd_m32r_elf_symbol_processing): Set SEC_SMALL_DATA
            on small common section.
            * elf32-score.c (s3_bfd_score_elf_symbol_processing): Likewise.
            * elf32-score7.c (s7_bfd_score_elf_symbol_processing): Likewise.
            * elf32-tic6x.c (elf32_tic6x_symbol_processing): Likewise.
            * elf32-v850.c (v850_elf_symbol_processing): Likewise.
            * elfxx-mips.c (_bfd_mips_elf_symbol_processing): Likewise.
            * ecoff.c (ecoff_set_symbol_info, ecoff_link_add_externals): Likewise.
    
    (cherry picked from commit 4d1823674eedf267c7cafac2b923256db0b10ac8)
Comment 4 Alan Modra 2020-08-15 13:40:40 UTC
Fixed
Comment 5 Sourceware Commits 2020-08-16 12:47:04 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=246b9ea1983d59c8b0070746a904a6b3f8d62187

commit 246b9ea1983d59c8b0070746a904a6b3f8d62187
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sun Aug 16 05:45:02 2020 -0700

    ld: Add a PR binutils/26389 test
    
            PR binutils/26389
            * testsuite/ld-plugin/lto.exp: Run PR binutils/26389 test.
            * testsuite/ld-plugin/pr26389.c: New file.
            * testsuite/ld-plugin/pr26389.d: Likewise.
Comment 6 Sourceware Commits 2020-08-16 12:51:41 UTC
The binutils-2_35-branch branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d79b7acb00900e23fdb58d535039ad2e9d026843

commit d79b7acb00900e23fdb58d535039ad2e9d026843
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sun Aug 16 05:45:02 2020 -0700

    ld: Add a PR binutils/26389 test
    
            PR binutils/26389
            * testsuite/ld-plugin/lto.exp: Run PR binutils/26389 test.
            * testsuite/ld-plugin/pr26389.c: New file.
            * testsuite/ld-plugin/pr26389.d: Likewise.
    
    (cherry picked from commit 246b9ea1983d59c8b0070746a904a6b3f8d62187)
Comment 7 Nick Clifton 2020-09-24 13:27:48 UTC
Quick note - this PR was duplicated in 26662, where it was also noted that the 'c' type in nm's output is not documented.  So I have checked in a small patch to update the documentation:

https://sourceware.org/bugzilla/show_bug.cgi?id=26662

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a2ab58313a248e4848c69c8d11ff547539a3c46f
Comment 8 H.J. Lu 2020-09-24 17:36:20 UTC
*** Bug 26662 has been marked as a duplicate of this bug. ***