Bug 98708 - [11 Regression] cxx11-ios_failure-lt.s:36733: Error: file number less than one by r11-6755
Summary: [11 Regression] cxx11-ios_failure-lt.s:36733: Error: file number less than on...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 11.0
: P3 normal
Target Milestone: 11.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-01-17 01:07 UTC by H.J. Lu
Modified: 2021-01-19 13:39 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-01-17 00:00:00


Attachments
A patch (1.32 KB, patch)
2021-01-17 15:58 UTC, H.J. Lu
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2021-01-17 01:07:33 UTC
On Linux/x86-64, r11-6755 gave

cxx11-ios_failure-lt.s: Assembler messages:
cxx11-ios_failure-lt.s:36733: Error: file number less than one
make[9]: *** [Makefile:865: cxx11-ios_failure.lo] Error 1

  14         .file 1 "../../../../../src-master/libstdc++-v3/src/c++11/cxx11-io      s_failure.cc"
......

36733         .file 0 "/export/gnu/import/git/gcc-test-master-intel64-native/bld      /x86_64-pc-linux-gnu/libstdc++-v3/src/c++11" "../../../../../src-master/li      bstdc++-v3/src/c++11/cxx11-ios_failure.cc"
36734         .section        .debug_str,"MS",@progb

r6752 is OK.
Comment 1 H.J. Lu 2021-01-17 01:10:08 UTC
This is with binutils master.  I think 2.36 branch may have the same issue.
Comment 2 H.J. Lu 2021-01-17 03:51:21 UTC
/bin/sh ../../libtool --tag CXX --tag disable-shared   --mode=compile /export/gnu/import/git/gcc-test-master-intel64-native/bld/./gcc/xgcc -shared-libgcc -B/export/gnu/import/git/gcc-test-master-intel64-native/bld/./gcc -nostdinc++ -L/export/gnu/import/git/gcc-test-master-intel64-native/bld/x86_64-pc-linux-gnu/libstdc++-v3/src -L/export/gnu/import/git/gcc-test-master-intel64-native/bld/x86_64-pc-linux-gnu/libstdc++-v3/src/.libs -L/export/gnu/import/git/gcc-test-master-intel64-native/bld/x86_64-pc-linux-gnu/libstdc++-v3/libsupc++/.libs -B/usr/11.0.0/x86_64-pc-linux-gnu/bin/ -B/usr/11.0.0/x86_64-pc-linux-gnu/lib/ -isystem /usr/11.0.0/x86_64-pc-linux-gnu/include -isystem /usr/11.0.0/x86_64-pc-linux-gnu/sys-include   -fno-checking -I/export/gnu/import/git/gcc-test-master-intel64-native/src-master/libstdc++-v3/../libgcc -I/export/gnu/import/git/gcc-test-master-intel64-native/bld/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu -I/export/gnu/import/git/gcc-test-master-intel64-native/bld/x86_64-pc-linux-gnu/libstdc++-v3/include -I/export/gnu/import/git/gcc-test-master-intel64-native/src-master/libstdc++-v3/libsupc++   -std=gnu++11 -prefer-pic -D_GLIBCXX_SHARED -fno-implicit-templates  -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi=2  -fdiagnostics-show-location=once   -ffunction-sections -fdata-sections  -frandom-seed=cxx11-ios_failure.lo  -g -O2 -D_GNU_SOURCE -fcf-protection -mshstk -g0 -c cxx11-ios_failure-lt.s -o cxx11-ios_failure.lo

cxx11-ios_failure-lt.s contains DWARF5 debug info.  Since -g0 is used,
--gdwarf-5 isn't passed to assembler:

[hjl@gnu-clx-1 gcc]$ ./xgcc -B./ -c /tmp/cxx11-ios_failure-lt.s
/tmp/cxx11-ios_failure-lt.s: Assembler messages:
/tmp/cxx11-ios_failure-lt.s:36733: Error: file number less than one
[hjl@gnu-clx-1 gcc]$ ./xgcc -B./ -c /tmp/cxx11-ios_failure-lt.s -g
[hjl@gnu-clx-1 gcc]$ 

This means that "gcc -c" no longer works on assembly codes generated with
-g when DWARF5 is enabled.
Comment 3 H.J. Lu 2021-01-17 04:50:55 UTC
The assembler patch is posted at

https://sourceware.org/pipermail/binutils/2021-January/114978.html

GCC should emit ".dwarf_level 5" when generating DWARF5 info.
Comment 4 Jakub Jelinek 2021-01-17 08:07:41 UTC
I guess the primary question is why does it emit any .file directives or .debug_str when it is compiled with -g -O2 -g0.  That seems like the bug.
Comment 5 Jakub Jelinek 2021-01-17 10:41:38 UTC
Ah, no, the *.s file is generated with -g, but the assembler isn't able to cope with it.
I'd say that the assembler shouldn't require any directive or flag but just assemble it.
Anything else seems to be an assembler bug.
Comment 6 Jakub Jelinek 2021-01-17 10:42:47 UTC
The assembler has all the information in the assembly, .debug_info section contains version etc.
Comment 7 Jakub Jelinek 2021-01-17 10:51:35 UTC
I'd be for automatic bumping to dwarf5 level if .file 0 is seen, but remember that it happened and issue an error if .debug_info with version older than 5 is seen in the file.
Comment 8 Mark Wielaard 2021-01-17 11:22:43 UTC
I am not sure where the -g -O2 -g0 comes from. I must have missed this in my testing.

The issue is the .file 0 directive, which is special to gas (only valid with -gdwarf-5).

It is generated by dwarf2out_finish ():

  /* Output the source line correspondence table.  We must do this
     even if there is no line information.  Otherwise, on an empty
     translation unit, we will generate a present, but empty,
     .debug_info section.  IRIX 6.5 `nm' will then complain when
     examining the file.  This is done late so that any filenames
     used by the debug_info section are marked as 'used'.  */
  switch_to_section (debug_line_section);
  ASM_OUTPUT_LABEL (asm_out_file, debug_line_section_label);
  if (! output_asm_line_debug_info ())
    output_line_info (false);
  else if (asm_outputs_debug_line_str ())
    {
      /* When gas outputs DWARF5 .debug_line[_str] then we have to
         tell it the comp_dir and main file name for the zero entry
         line table.  */
      const char *comp_dir, *filename0;

      comp_dir = comp_dir_string ();
      if (comp_dir == NULL)
        comp_dir = "";

      filename0 = get_AT_string (comp_unit_die (), DW_AT_name);
      if (filename0 == NULL)
        filename0 = "";

      fprintf (asm_out_file, "\t.file 0 ");
      output_quoted_string (asm_out_file, remap_debug_filename (comp_dir));
      fputc (' ', asm_out_file);
      output_quoted_string (asm_out_file, remap_debug_filename (filename0));
      fputc ('\n', asm_out_file);
    }

So it looks like the asm_outputs_debug_line_str () is wrong:

/* Returns TRUE if we are outputting DWARF5 and the assembler supports
   DWARF5 .debug_line tables using .debug_line_str or we generate
   it ourselves, except for split-dwarf which doesn't have a
   .debug_line_str.  */
static bool
asm_outputs_debug_line_str (void)
{
  if (dwarf_version >= 5
      && ! output_asm_line_debug_info ()
      && DWARF5_USE_DEBUG_LINE_STR)
    return true;
  else
    {
#if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_N_FLAG)
      return !dwarf_split_debug_info && dwarf_version >= 5;
#else
      return false;
#endif
    }
}

It probably should check debug_info_level > DINFO_LEVEL_NONE.
Comment 9 Jakub Jelinek 2021-01-17 12:25:47 UTC
Bootstrap is fine if one uses older binutils.
The thing is that cxx11-ios_failure* is built by hand first with -g -O2 -S,
then the assembly is modified by a script and then it is assembled, and as older assemblers would fail miserably on assembling .s file containing .debug_info etc. with -g (-gdwarf-2 passed to assembler), the assembly is invoked with -g -O2 -c -g0.
I really think this should be fixed solely on the assembler side, and
if needed, we can add a temporary workaround, I guess compiling cxx11-ios_failure* with -gno-as-loc-support could fix that.
Comment 10 H.J. Lu 2021-01-17 12:40:09 UTC
(In reply to Jakub Jelinek from comment #9)
> Bootstrap is fine if one uses older binutils.
> The thing is that cxx11-ios_failure* is built by hand first with -g -O2 -S,
> then the assembly is modified by a script and then it is assembled, and as
> older assemblers would fail miserably on assembling .s file containing
> .debug_info etc. with -g (-gdwarf-2 passed to assembler), the assembly is
> invoked with -g -O2 -c -g0.
> I really think this should be fixed solely on the assembler side, and
> if needed, we can add a temporary workaround, I guess compiling
> cxx11-ios_failure* with -gno-as-loc-support could fix that.

Assembler option:

 --gdwarf-<N>            generate DWARF<N> debugging information. 2 <= <N> <= 5

both accepts and generates DWARF<N> info.  This decision is made very early.
Comment 11 Mark Wielaard 2021-01-17 12:59:22 UTC
Aha, now I see in libstdc++-v3/src/c++11/Makefile.am:

if ENABLE_DUAL_ABI
# Rewrite the type info for __ios_failure.
rewrite_ios_failure_typeinfo = sed -e '/^_*_ZTISt13__ios_failure:/,/_ZTVN10__cxxabiv120__si_class_type_infoE/s/_ZTVN10__cxxabiv120__si_class_type_infoE/_ZTVSt19__iosfail_type_info/'

cxx11-ios_failure-lt.s: cxx11-ios_failure.cc
        $(LTCXXCOMPILE) -S $< -o tmp-cxx11-ios_failure-lt.s
        -test -f tmp-cxx11-ios_failure-lt.o && mv -f tmp-cxx11-ios_failure-lt.o tmp-cxx11-ios_failure-lt.s
        $(rewrite_ios_failure_typeinfo) tmp-$@ > $@
        -rm -f tmp-$@
cxx11-ios_failure.s: cxx11-ios_failure.cc
        $(CXXCOMPILE) -S $< -o tmp-$@
        $(rewrite_ios_failure_typeinfo) tmp-$@ > $@
        -rm -f tmp-$@

cxx11-ios_failure.lo: cxx11-ios_failure-lt.s
        $(LTCXXCOMPILE) -g0 -c $< -o $@
cxx11-ios_failure.o: cxx11-ios_failure.s
        $(CXXCOMPILE) -g0 -c $<
endif

Then my workaround of checking for debug_info_level > DINFO_LEVEL_NONE indeed wouldn't work. It is explicitly generating debuginfo for the assembly file and then adding -g0 when turning the assembly file into an object file. So that is too late.

I don't think adding -gno-as-loc-support to the -S invocation will work because of the definition of asm_outputs_debug_line_str () which is true if dwarf_version >= 5 && ! output_asm_line_debug_info () && DWARF5_USE_DEBUG_LINE_STR. So then it will still generate the .file 0 directive.

Ideally gas wouldn't error on .file 0, but simply ignore it when not generating DWARF5.

Maybe the simplest workaround for now would be also adding -g0 to the -S invocations?
Comment 12 Mark Wielaard 2021-01-17 13:31:40 UTC
On the binutils gas side it could be as simple as turning the error into a warning:

diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index a428370ecca..a216bfd6b28 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -1044,7 +1044,7 @@ dwarf2_directive_filename (void)
 
   if ((offsetT) num < 1 && DWARF2_LINE_VERSION < 5)
     {
-      as_bad (_("file number less than one"));
+      as_warn (_("file number less than one, ignored"));
       ignore_rest_of_line ();
       return NULL;
     }
@@ -1143,7 +1143,8 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
     {
       if (filenum != 0 || DWARF2_LINE_VERSION < 5)
        {
-         as_bad (_("file number less than one"));
+         as_warn (_("file number less than one, ignored"));
+         ignore_rest_of_line ();
          return;
        }
     }
diff --git a/gas/testsuite/gas/lns/lns-diag-1.l b/gas/testsuite/gas/lns/lns-diag-1.l
index 1256e85cfcb..d8aa84d9d1a 100644
--- a/gas/testsuite/gas/lns/lns-diag-1.l
+++ b/gas/testsuite/gas/lns/lns-diag-1.l
@@ -1,5 +1,5 @@
 .*: Assembler messages:
-.*:2: Error: file number less than one
+.*:2: Warning: file number less than one, ignored
 .*:3: Error: missing string
 .*:4: Error: file table slot 1 is already occupied.*
 .*:8: Error: unassigned file number 3
@@ -9,7 +9,7 @@
 .*:19: Error: bad or irreducible absolute expression
 .*:23: Error: isa number less than zero
 .*:26: Error: bad or irreducible absolute expression
-.*:26: Error: file number less than one
+.*:26: Warning: file number less than one, ignored
 .*:27: Error: bad or irreducible absolute expression
 .*:28: Error: unknown .loc sub-directive `frobnitz'
 .*:29: Error: unknown .loc sub-directive `frobnitz'
Comment 13 Jakub Jelinek 2021-01-17 15:57:04 UTC
But then it will warn and not do what it was expected to do.

Anyway, I've rebuilt cc1plus (on a box without new binutils) with hacking up auto-host.h so that it normally emits .file 0 "..." directive, and with -gno-as-loc-support it doesn't emit it.  Will try it soon in a koji build where it failed.
Comment 14 H.J. Lu 2021-01-17 15:58:12 UTC
Created attachment 49986 [details]
A patch

How about this assembler patch?
Comment 15 Jakub Jelinek 2021-01-17 16:02:07 UTC
Comment on attachment 49986 [details]
A patch

If that works, that would be great.
I can't easily test it right away, but perhaps you could.
Just compile some other libstdc++ source with -g -O2 -c
on gcc configured against latest binutils, save the *.o file and repeat
with -g -O2 -S + assembly by hand without -g* and compare if the readelf -wl
between the two is identical.
Comment 16 Jakub Jelinek 2021-01-17 16:22:15 UTC
And the temporary workaround could be
--- libstdc++-v3/src/c++11/Makefile.am.jj	2021-01-04 10:26:02.067970728 +0100
+++ libstdc++-v3/src/c++11/Makefile.am	2021-01-17 17:20:58.580262364 +0100
@@ -141,12 +141,12 @@ if ENABLE_DUAL_ABI
 rewrite_ios_failure_typeinfo = sed -e '/^_*_ZTISt13__ios_failure:/,/_ZTVN10__cxxabiv120__si_class_type_infoE/s/_ZTVN10__cxxabiv120__si_class_type_infoE/_ZTVSt19__iosfail_type_info/'
 
 cxx11-ios_failure-lt.s: cxx11-ios_failure.cc
-	$(LTCXXCOMPILE) -S $< -o tmp-cxx11-ios_failure-lt.s
+	$(LTCXXCOMPILE) -gno-as-loc-support -S $< -o tmp-cxx11-ios_failure-lt.s
 	-test -f tmp-cxx11-ios_failure-lt.o && mv -f tmp-cxx11-ios_failure-lt.o tmp-cxx11-ios_failure-lt.s
 	$(rewrite_ios_failure_typeinfo) tmp-$@ > $@
 	-rm -f tmp-$@
 cxx11-ios_failure.s: cxx11-ios_failure.cc
-	$(CXXCOMPILE) -S $< -o tmp-$@
+	$(CXXCOMPILE) -gno-as-loc-support -S $< -o tmp-$@
 	$(rewrite_ios_failure_typeinfo) tmp-$@ > $@
 	-rm -f tmp-$@
 
--- libstdc++-v3/src/c++11/Makefile.in.jj	2020-12-17 02:29:28.734557483 +0100
+++ libstdc++-v3/src/c++11/Makefile.in	2021-01-17 17:21:27.510931383 +0100
@@ -852,12 +852,12 @@ limits.o: limits.cc
 	$(CXXCOMPILE) -fchar8_t -c $<
 
 @ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure-lt.s: cxx11-ios_failure.cc
-@ENABLE_DUAL_ABI_TRUE@	$(LTCXXCOMPILE) -S $< -o tmp-cxx11-ios_failure-lt.s
+@ENABLE_DUAL_ABI_TRUE@	$(LTCXXCOMPILE) -gno-as-loc-support -S $< -o tmp-cxx11-ios_failure-lt.s
 @ENABLE_DUAL_ABI_TRUE@	-test -f tmp-cxx11-ios_failure-lt.o && mv -f tmp-cxx11-ios_failure-lt.o tmp-cxx11-ios_failure-lt.s
 @ENABLE_DUAL_ABI_TRUE@	$(rewrite_ios_failure_typeinfo) tmp-$@ > $@
 @ENABLE_DUAL_ABI_TRUE@	-rm -f tmp-$@
 @ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure.s: cxx11-ios_failure.cc
-@ENABLE_DUAL_ABI_TRUE@	$(CXXCOMPILE) -S $< -o tmp-$@
+@ENABLE_DUAL_ABI_TRUE@	$(CXXCOMPILE) -gno-as-loc-support -S $< -o tmp-$@
 @ENABLE_DUAL_ABI_TRUE@	$(rewrite_ios_failure_typeinfo) tmp-$@ > $@
 @ENABLE_DUAL_ABI_TRUE@	-rm -f tmp-$@
Comment 17 GCC Commits 2021-01-18 10:29:34 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:2e43880dbd4cb9722ae99708c01c399f985dc7c3

commit r11-6765-g2e43880dbd4cb9722ae99708c01c399f985dc7c3
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Mon Jan 18 11:28:17 2021 +0100

    libstd++: : Add workaround for as Error: file number less than one error [PR98708]
    
    As mentioned in the PR, since the switch to DWARF5 by default instead of
    DWARF4, gcc fails to build when configured against recent binutils.
    
    The problem is that cxx11-ios_failure* is built in separate steps,
    -S compilation (with -g -O2) followed by some sed and followed by
    -c -g -O2 -g0 assembly.  When gcc is configured against recent binutils
    and DWARF5 is the default, we emit .file 0 "..." directive on which the
    assembler then fails (unless --gdwarf-5 is passed to it, but we don't want
    that generally because on the other side older assemblers don't like -g*
    passed to it when invoked on *.s file with compiler generated debug info.
    
    I hope the bug will be fixed soon on the binutils side, but it would be nice
    to have a workaround.
    
    The following patch is one of the possibilities, another one is to do that
    but add configure check for whether it is needed,
    essentially
    echo 'int main () { return 0; }' > conftest.c
    ${CXX} ${CXXFLAGS} -g -O2 -S conftest.c -o conftest.s
    ${CXX} ${CXXFLAGS} -g -O2 -g0 -c conftest.s -o conftest.o
    and if the last command fails, we need that -gno-as-loc-support.
    Or yet another option would be I think do a different check, whether
    ${CXX} ${CXXFLAGS} -g -O2 -S conftest.c -o conftest.s
    ${CXX} ${CXXFLAGS} -g -O2 -c conftest.s -o conftest.o
    works and if yes, don't add the -g0 to cxx11-ios_failure*.s assembly.
    
    2021-01-18  Jakub Jelinek  <jakub@redhat.com>
    
            PR debug/98708
            * src/c++11/Makefile.am (cxx11-ios_failure-lt.s, cxx11-ios_failure.s):
            Compile with -gno-as-loc-support.
            * src/c++11/Makefile.in: Regenerated.
Comment 18 Jakub Jelinek 2021-01-19 13:39:09 UTC
Worked around on the gcc side and fixed on the binutils side.