Linux: DWARF2 only supports one section per compilation unit

Created on 27 Sep 2019  路  18Comments  路  Source: ClangBuiltLinux/linux

Same warnings as #607 when compiling ARM64 kernel using integrated assembler.

arch/arm64/kernel/vdso/vdso.S:14:2: warning: DWARF2 only supports one section per compilation unit
 .section .rodata
 ^

arch/arm64/kernel/head.S:62:2: warning: DWARF2 only supports one section per compilation unit
 .section ".head.text","ax"
 ^
/tmp/head-9725f8.s:1028:2: warning: DWARF2 only supports one section per compilation unit
 .section ".init.text","ax"
 ^
/tmp/head-9725f8.s:1275:2: warning: DWARF2 only supports one section per compilation unit
 .section ".idmap.text","awx"
 ^
<instantiation>:3:2: warning: DWARF2 only supports one section per compilation unit
 .section ___ksymtab+kimage_vaddr,"a"
 ^
/tmp/head-9725f8.s:1279:1: note: while in macro instantiation
___EXPORT_SYMBOL kimage_vaddr, kimage_vaddr,
^
<instantiation>:8:2: warning: DWARF2 only supports one section per compilation unit
 .section __ksymtab_strings,"a"
 ^
/tmp/head-9725f8.s:1279:1: note: while in macro instantiation
___EXPORT_SYMBOL kimage_vaddr, kimage_vaddr,
^
arch/arm64/kernel/head.S:662:2: warning: DWARF2 only supports one section per compilation unit
 .pushsection ".mmuoff.data.write", "aw"
 ^

<instantiation>:2:2: warning: DWARF2 only supports one section per compilation unit
 .pushsection .altinstructions, "a"
 ^
arch/arm64/mm/cache.S:42:1: note: while in macro instantiation
alternative_if 27
^
<instantiation>:5:2: warning: DWARF2 only supports one section per compilation unit
 .pushsection .altinstr_replacement, "ax"
 ^
arch/arm64/mm/cache.S:42:1: note: while in macro instantiation
alternative_if 27
^
<instantiation>:1:1: warning: DWARF2 only supports one section per compilation unit
.pushsection __ex_table, "a"
^
<instantiation>:5:20: note: while in macro instantiation
9999: ic ivau, x3; _asm_extable 9999b, 9f
                   ^
arch/arm64/mm/cache.S:61:2: note: while in macro instantiation
 invalidate_icache_by_line x0, x1, x2, x3, 9f
 ^
[BUG] linux [FIXED][LINUX] 5.10 [TOOL] integrated-as

Most helpful comment

All 18 comments

@jcai19 so for this, the warning is not wrong but:

  1. it's not named, so we can't turn it off explicitly.
  2. without .cfi_* directives, I'm not sure that debug sections get created, so who cares about dwarf if we're not emitting debug info? (Maybe we are somehow, and I'm wrong).

Old proposed fix: https://reviews.llvm.org/D6379

Great find! Maybe I can "commandeer" that revision.

Jotting down some notes:

  1. the top level Makefile sets KBUILD_AFLAGS += -Wa,-gdwarf-2, so all assembly files are assembled in dwarf2 mode.
  2. most .s/.S files don't use any assembler directives that would produce dwarf debug sections:

    1. for f in $(find arch/ -name \*.S); do grep -l "cfi" $f; done produces 23 files that have any .cfi related directives. I'm not sure if there's other assembler directives other than the many .cfi ones that produce debug info. (More info on cfi directives.

    2. the presence of these directives produces .debug_line, .debug_info, .debug_abbrev, .debug_aranges, .debug_str, and .eh_frame (and their .rela equivalents) in .o binaries.

    3. without cfi directives, it seems the .debug_line is still produced.

  3. these can be dumped with objdump -W foo.o. It seems that llvm-objdump doesn't implement -W :( Also, aarch64-linux-gnu-readelf --debug-dump=line for non cfi assembler files.

Chrome OS has moved to dwarf-4 (CONFIG_DEBUG_INFO_DWARF4=y). Does these warnings also trigger for dwarf4 ?

No

It turns out that pahole has issue with this:

die__process_unit: DW_TAG_label (0xa) @ <0x7689bf6> not handled!

When I experimented and later switched to CONFIG_DEBUG_INFO_DWARF4=y I have seen this, too.

One result was the simplification of DEBUG_INFO Kconfig handling (see [1] which is now in Linux v5.10-rc1).

The commit in [1] also points to my introduction of CONFIG_DEBUG_INFO_AS_DWARF2 and CONFIG_DEBUG_INFO_AS_DWARF4 (see [2]).
Unfortunately on kbuild ML I got no reply how to go further with this.

We have more places where KBUILD_AFLAGS += -Wa,-gdwarf-2 is used.

Please, let me know what you think.

[1] https://git.kernel.org/linus/695afd3d7d58ec3044d25c9d2fe384ab8627fd20
[2] https://patchwork.kernel.org/project/linux-kbuild/patch/CA+icZUV85LS08Y2qJ-mheecCrzZmCTV4B5x9kh=BGCUzQVOKaA@mail.gmail.com/

Adding @jcai19

Some notes:

[ include/asm/dwarf2.h ]

We have arch/x86/include/asm/dwarf2.h included in some .S files - do we need something similiar like dwarf4.h for x86 arch?

$ git grep dwarf2.h arch/
arch/x86/entry/vdso/vdso32/system_call.S:#include <asm/dwarf2.h>
arch/x86/include/asm/dwarf2.h:#warning "asm/dwarf2.h should be only included in pure assembly files"
arch/x86/lib/retpoline.S:#include <asm/dwarf2.h>

Do we need such an include also for other archs like arm/arm64?

[ -fno-dwarf2-cfi-asm ]

We have places in arm/arm64 arch where we pass -fno-dwarf2-cfi-asm - is that in the CONFIG_DEBUG_INFO=y case or in general?

[ Makefile ]

Passing DWARF-2 assembler option KBUILD_AFLAGS += -Wa,-gdwarf-2 in top-level Makefile is IMHO not correct when using CONFIG_DEBUG_INFO=y and especially together with CONFIG_DEBUG_INFO_DWARF4=y.

My approach looks like this (here: on top of Linux v5.10-rc1):

diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -828,7 +828,11 @@ else
 DEBUG_CFLAGS   += -g
 endif

+ifdef CONFIG_DEBUG_INFO_AS_DWARF2
 KBUILD_AFLAGS  += -Wa,-gdwarf-2
+else ifdef CONFIG_DEBUG_INFO_AS_DWARF4
+KBUILD_AFLAGS  += -Wa,-gdwarf-4
+endif

 ifdef CONFIG_DEBUG_INFO_DWARF4
 DEBUG_CFLAGS   += -gdwarf-4
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -256,9 +256,22 @@ config DEBUG_INFO_SPLIT
          to know about the .dwo files and include them.
          Incompatible with older versions of ccache.

+config DEBUG_INFO_AS_DWARF2
+       bool "Use DWARF-2 assembler option with debuginfo"
+       depends on $(cc-option,-Wa$(comma)-gdwarf-2)
+       help
+         Set DWARF-2 assembler option with debuginfo
+
+config DEBUG_INFO_AS_DWARF4
+       bool "Use DWARF-4 assembler option with debuginfo"
+       depends on $(cc-option,-Wa$(comma)-gdwarf-4)
+       help
+         Set DWARF-4 assembler option with debuginfo
+
 config DEBUG_INFO_DWARF4
        bool "Generate dwarf4 debuginfo"
        depends on $(cc-option,-gdwarf-4)
+       select DEBUG_INFO_AS_DWARF4
        help
          Generate dwarf4 debug info. This requires recent versions
          of gcc and gdb. It makes the debug information larger.

Tested on all my Linux 5.9 rcX and final builds for x86 64bit.

Sidenote:
My experiences with DWARF-4 was LLVM with ld.lld version 11.0.0 was reducing debug-info (binary) size better that GCC version 10.2 with GNU/ld.bfd v2.35.1.

My approach looks like this

I'd rather keep the assembler's DWARF version in sync with the compilers. There's no real need to mix and match versions.

Also, by not explicitly specifying -gdwarf-2 when CONFIG_DEBUG_INFO_DWARF4 is not set, clang still defaults to DWARF4, so upstream is currently broken in that regard.

Sent upstream (https://lore.kernel.org/lkml/[email protected]/T/#u) as part of my series on DWARF v5 (https://lore.kernel.org/lkml/[email protected]/T/#u).

Was this page helpful?
0 / 5 - 0 ratings