Hello, We are looking at DWARF data for the kernel ABI verification in RHEL-7. This is what we're seeing in kernel-debuginfo-3.10.0-229.el7.x86_64, the DW_AT_decl_line and DW_AT_decl_file for enum blk_eh_timer_return don't seem correct. $ readelf --debug=info /usr/lib/debug/lib/modules/3.10.0-229.el7.x86_64/kernel/drivers/ata/libata.ko.debug | less ... Compilation Unit @ offset 0x985a5: Length: 0x148fa (32-bit) Version: 4 Abbrev Offset: 0x2ecd Pointer Size: 8 <0><985b0>: Abbrev Number: 1 (DW_TAG_compile_unit) ... <985b5> DW_AT_language : 1 (ANSI C) <985b6> DW_AT_name : (indirect string, offset: 0x63c38): drivers/ata/libata-acpi.c ### ^^^ This is the name of the CU we'll be looking at ### <985ba> DW_AT_comp_dir : (indirect string, offset: 0x5f70a): /usr/src/debug/kernel-3.10.0-229.el7/linux-3.10.0-229.el7.x86_64 <985be> DW_AT_low_pc : 0x19ba0 <985c6> DW_AT_high_pc : 0x1591 <985ce> DW_AT_stmt_list : 0xab78 ### ^^^ Note the stmt offset here ### ... <1><a72f7>: Abbrev Number: 50 (DW_TAG_enumeration_type) <a72f8> DW_AT_name : (indirect string, offset: 0x5b7af): blk_eh_timer_return <a72fc> DW_AT_byte_size : 4 <a72fd> DW_AT_decl_file : 133 <a72fe> DW_AT_decl_line : 361 ### ^^^ Note the file and line here ### <a7300> DW_AT_sibling : <0xa7317> <2><a7304>: Abbrev Number: 11 (DW_TAG_enumerator) <a7305> DW_AT_name : (indirect string, offset: 0x60e5d): BLK_EH_NOT_HANDLED <a7309> DW_AT_const_value : 0 <2><a730a>: Abbrev Number: 11 (DW_TAG_enumerator) <a730b> DW_AT_name : (indirect string, offset: 0x5bfe6): BLK_EH_HANDLED <a730f> DW_AT_const_value : 1 <2><a7310>: Abbrev Number: 11 (DW_TAG_enumerator) <a7311> DW_AT_name : (indirect string, offset: 0x5ac40): BLK_EH_RESET_TIMER <a7315> DW_AT_const_value : 2 ### ^^^ This is correct definition of the enum blk_eh_timer_return ### So, we see that the line of the blk_eh_timer return is defined as 361. If we then look at the .debug_line section for the file information: $ readelf --debug=line /usr/lib/debug/lib/modules/3.10.0-229.el7.x86_64/kernel/drivers/ata/libata.ko.debug | less ... Offset: 0xab78 ... The Directory Table (offset 0xab93): ### ^^^ This is our stmt offset ### 1 drivers/ata 2 include/linux 3 include/uapi/asm-generic 4 include/asm-generic 5 /usr/src/debug/kernel-3.10.0-229.el7/linux-3.10.0-229.el7.x86_64/include/uapi/asm-generic 6 include/uapi/linux 7 /usr/src/debug/kernel-3.10.0-229.el7/linux-3.10.0-229.el7.x86_64/arch/x86/include/asm 8 include/acpi 9 /usr/src/debug/kernel-3.10.0-229.el7/linux-3.10.0-229.el7.x86_64/include/uapi/linux 10 include/scsi 11 XXXXXXXXXXXXXXXXXXXX The File Name Table (offset 0xad21): Entry Dir Time Size Name ... 133 10 0 0 scsi_host.h So the DW_AT_decl_file corresponds to include/scsi/scsi_host.h. In that file we see: $ nl -ba /usr/src/debug/kernel-3.10.0-229.el7/linux-3.10.0-229.el7.x86_64/include/scsi/scsi_host.h | grep 361 361 enum blk_eh_timer_return (*eh_timed_out)(struct scsi_cmnd *); This is one of the fields in the struct scsi_host_template, and it does not define the enum blk_eh_timer. So are the DW_AT_decl_line and DW_AT_decl_file incorrectly generated by the gcc?
Can you please attach preprocessed source for the CU that you see this on and mention the full gcc command line used to compile it? Thanks.
Created attachment 1260928 [details] Preprocessed file
A bit better gcc command: /var/lib/mock/epel-7-x86_64/root/bin/gcc -Wp,-MD,drivers/ata/.libata-acpi.o.d -nostdinc -isystem /var/lib/mock/epel-7-x86_64/root/usr/bin/../lib/gcc/x86_64-redhat-linux/4.8.5/include -I/kernel_compile_dir/arch/x86/include -Iarch/x86/include/generated -Iinclude -I/kernel_compile_dir/arch/x86/include/uapi -Iarch/x86/include/generated/uapi -I/kernel_compile_dir/include/uapi -Iinclude/generated/uapi -include /kernel_compile_dir/include/linux/kconfig.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -Werror -O2 -m64 -mno-sse -mpreferred-stack-boundary=3 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -Wframe-larger-than=2048 -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -Wframe-larger-than=2048 -fstack-protector-strong -Wno-unused-but-set-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -pg -mfentry -DCC_USING_FENTRY -fno-inline-functions-called-once -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -DCC_HAVE_ASM_GOTO -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(libata_acpi)" -D"KBUILD_MODNAME=KBUILD_STR(libata)" -c -o drivers/ata/.tmp_libata-acpi.o drivers/ata/libata-acpi.c
So this boils down to enum A foo (void); enum A { B = 1, C = 2 }; void bar (void) { enum A a = C; } in C and enum A : int; enum A : int { B = 1, C = 2 }; void bar (void) { enum A a = C; } in C++, with -g -dA gcc gives DW_AT_line 1 for the enum while g++ gives DW_AT_line 3 for the enum. C picks the location from the forward declaration, C++ from the definition, even with latest gcc trunk. I'll have a look.
Thanks Jakub! And thanks Yauheni for providing the requested information faster than me;-)
The related test passes on all architectures with gcc-4.8.5-14.el7. VERIFIED.
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2017:2094