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.
This is with binutils master. I think 2.36 branch may have the same issue.
/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.
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.
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.
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.
The assembler has all the information in the assembly, .debug_info section contains version etc.
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.
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.
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.
(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.
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?
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'
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.
Created attachment 49986 [details] A patch How about this assembler patch?
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.
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-$@
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.
Worked around on the gcc side and fixed on the binutils side.