I. A recent commit 5578fbf672e ("GAS: Add a return type tag to DWARF DIEs generated for function symbols") fixes a problem with gas-generated dwarf info. So, let's see if we can reproduce the problem and test the fix in gdb. Multi-source test-case: ... $ cat test.c extern int foo (void); int main (void) { int res = foo (); return res; } $ cat test2.c int foo (void) { return 0; } ... Test script: ... $ cat compile.sh #!/bin/sh as=/home/vries/binutils/install/bin/as gcc -c -g test.c gcc -S test2.c $as --64 -gdwarf-5 -o test2.o test2.s gcc test.o test2.o ./gdb.sh -batch a.out -ex start -ex "p foo" -ex "p (int) foo ()" ... II. 2.38 Using $as from 2.38: ... $ ./compile.sh Temporary breakpoint 1 at 0x40049f: file test.c, line 6. Temporary breakpoint 1, main () at test.c:6 6 int res = foo (); $1 = {<text variable, no debug info>} 0x4004ac <foo> $2 = 0 ... Looks as expected. III. 2.39 Using $as from 2.39: ... $ ./compile.sh Temporary breakpoint 1 at 0x40049f: file test.c, line 6. Temporary breakpoint 1, main () at test.c:6 6 int res = foo (); $1 = {void (void)} 0x4004ac <foo> Invalid cast. ... So, this is the bug the commit is trying to fix. III. current trunk Using $as from current trunk: ... $ ./compile.sh Dwarf Error: unexpected tag 'DW_TAG_unspecified_type' at offset 0xf4 Temporary breakpoint 1 at 0x40049f: file test.c, line 6. Temporary breakpoint 1, main () at test.c:6 6 int res = foo (); Dwarf Error: unexpected tag 'DW_TAG_unspecified_type' at offset 0xf4 Dwarf Error: unexpected tag 'DW_TAG_unspecified_type' at offset 0xf4 ... So, either the debug info is invalid, or gdb needs to learn how to handle this.
See also PR17271 - "unsupported tag: DW_TAG_unspecified_type"
Debug info looks like: ... Compilation Unit @ offset 0xf4: Length: 0x35 (32-bit) Version: 5 Unit Type: DW_UT_compile (1) Abbrev Offset: 0xa3 Pointer Size: 8 <0><100>: Abbrev Number: 3 (DW_TAG_unspecified_type) <0><101>: Abbrev Number: 1 (DW_TAG_compile_unit) <102> DW_AT_stmt_list : 0x123 <106> DW_AT_low_pc : 0x4004ac <10e> DW_AT_high_pc : 11 <10f> DW_AT_name : test2.s <113> DW_AT_comp_dir : /home/vries/gdb_versions/devel <117> DW_AT_producer : GNU AS 2.39.50 <11b> DW_AT_language : 32769 (MIPS assembler) <1><11d>: Abbrev Number: 2 (DW_TAG_subprogram) <11e> DW_AT_name : (indirect string, offset: 0x241): foo <122> DW_AT_external : 1 <122> DW_AT_type : <0x100> <123> DW_AT_low_pc : 0x4004ac <12b> DW_AT_high_pc : 11 ... OK, that looks highly unregular, the DW_TAG_unspecified_type die as a top-level DIE.
In the dwarf-5 standard I read: ... For each compilation unit compiled with a DWARF producer, a contribution is made to the .debug_info section of the object file. Each such contribution consists of a compilation unit header followed by a single DW_TAG_compile_unit or DW_TAG_partial_unit debugging information entry, together with its children. ... Ok, so this is in fact incorrect dwarf.
(In reply to Tom de Vries from comment #3) > Ok, so this is in fact incorrect dwarf. Filed gas PR29559 - "gas generated incorrect debug info (top-level DW_TAG_unspecified_type DIE)".
Created attachment 14326 [details] Dwarf assembly test-case Currently, this fails: ... (gdb) PASS: gdb.dwarf2/dw2-unspecified-type.exp: p ((int (*) ()) foo) () p (int) foo ()^M Invalid cast.^M (gdb) FAIL: gdb.dwarf2/dw2-unspecified-type.exp: p (int) foo () ... because DW_TAG_unspecified_type is translated as void.
(In reply to Tom de Vries from comment #1) > See also PR17271 - "unsupported tag: DW_TAG_unspecified_type" I've looked now at that one, and it looks unrelated, that's the case when a DW_TAG_unspecificed_type DIE has a name attribute.
https://sourceware.org/pipermail/gdb-patches/2022-September/191753.html
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=a34a90995ae7c2f0c0b79ad32d8087d507fe42db
Created attachment 14632 [details] tests: Handle DW_TAG_unspecified_type in funcretval test This patch just fixes the testcase to check for DW_TAG_unspecified_type as return type. With your test binary tests/funcretval now prints: () _start: returns unspecified type () main: return value location: {0x50, 0} But maybe a better fix is for dwfl_module_return_value_location to return zero (which technically means that the function doesn't have a return value). Opinions?
(In reply to Mark Wielaard from comment #9) > Created attachment 14632 [details] > tests: Handle DW_TAG_unspecified_type in funcretval test > > This patch just fixes the testcase to check for DW_TAG_unspecified_type as > return type. > With your test binary tests/funcretval now prints: > > () _start: returns unspecified type > () main: return value location: {0x50, 0} > > But maybe a better fix is for dwfl_module_return_value_location to return > zero (which technically means that the function doesn't have a return value). > > Opinions? Sorry, this patch was for elfutils, specifically https://sourceware.org/bugzilla/show_bug.cgi?id=30047 I was just looking how gdb handled this. Apologies.