Bug 30047 - libdw unable to handle DW_TAG_unspecified_type
Summary: libdw unable to handle DW_TAG_unspecified_type
Status: RESOLVED FIXED
Alias: None
Product: elfutils
Classification: Unclassified
Component: libdw (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Mark Wielaard
URL:
Keywords:
: 30192 (view as bug list)
Depends on:
Blocks:
 
Reported: 2023-01-25 01:21 UTC by Khem Raj
Modified: 2023-03-02 13:27 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2023-01-26 00:00:00


Attachments
sample binary linked with glibc built with binutils 2.40 (4.44 KB, application/x-sharedlib)
2023-01-25 01:30 UTC, Khem Raj
Details
tests: Handle DW_TAG_unspecified_type in funcretval test (1.12 KB, patch)
2023-01-26 17:30 UTC, Mark Wielaard
Details | Diff
backends: Handle DW_TAG_unspecified_type in dwarf_peeled_die_type (1.81 KB, patch)
2023-02-07 15:47 UTC, Mark Wielaard
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Khem Raj 2023-01-25 01:21:46 UTC
GNU assembler starting with 2.40 release is generating DW_TAG_unspecified_type for assembly files [1] this is fixed in gdb [2], however, it shows up as one of test failures in elfutils 


% ./funcretval
() _start: ./funcretval: dwfl_module_return_value_location: cannot handle DWARF type description

The reason is that glibc startup files e.g. (/usr/lib/Scrt1.o) is built from assembly routines and when compiled with toolchain using binutils 2.40 gets these DW_TAG_unspecified_type entries emitted into its debug segments which inturn get into the testcases when they are built in elfutils testsuites

native.c
=========
#include <unistd.h>
int main () { while (1) pause (); return 0;}

gcc -g native.c

./funcretval

then results in this error and failure in elfutils testcases

/usr/lib/elfutils/ptest/tests/funcretval: dwfl_module_return_value_location: cannot handle DWARF type description
FAIL: run-native-test.sh

I think libdw has to implement handling DW_TAG_unspecified_type, since it will start showing up everywhere soon as 2.40 binutils trickle into downstream distributions and they do mass-rebuilds.

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=29559
[2] https://sourceware.org/bugzilla/show_bug.cgi?id=29558
Comment 1 Khem Raj 2023-01-25 01:30:31 UTC
Created attachment 14620 [details]
sample binary linked with glibc built with binutils 2.40
Comment 2 Mark Wielaard 2023-01-26 16:39:01 UTC
This is slightly tricky, because I think we technically do the right thing here.

dwfl_module_return_value_location returns that cannot handle DWARF type description error, which is technically correct, since it is an unspecified_type.

dwfl_module_return_value_location can return an error (< 0) which means either bad DWARF or unknown/unhandled type, it can return zero, which means the function has no return value, or it return the number of DWARF expression operations (> 0) that describe how to get the value returned by the function.

Sadly we don't have an easy way to distinguish between bad DWARF/type and cannot handle type.

I think we can change the testcase though, to check for the special case of DW_TAG_unspecified_type.
Comment 3 Mark Wielaard 2023-01-26 17:30:33 UTC
Created attachment 14633 [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?
Comment 4 Khem Raj 2023-01-26 17:41:38 UTC
lgtm, I did something similar by changing return value locally.
Comment 5 Martin Liska 2023-02-06 13:11:43 UTC
May I please ping this issue as one needs it with the latest binutils release (2.40).
Comment 6 Mark Wielaard 2023-02-07 15:47:52 UTC
Created attachment 14657 [details]
backends: Handle DW_TAG_unspecified_type in dwarf_peeled_die_type

(In reply to Martin Liska from comment #5)
> May I please ping this issue as one needs it with the latest binutils
> release (2.40).

Yes, thanks. I didn't forget, but I changed my mind how to best handle this issue.
See the new patch. This changes the code so that an DW_TAG_unspecified_type is treated just as if the function doesn't have a return type. I think that is a better fix because there might be more code out there that uses dwfl_module_return_value_location and might not handle an error in this case. And there isn't actually much that can be done with an unspecified type, for normal cases it is as if there is no return type.

I did adjust the testcase to show how you can see whether it is a missing return type or an unspecified return type in case you program does care.
Comment 7 Martin Liska 2023-02-14 08:25:25 UTC
Thank you, Mark. Can you please commit the patch so that very can cherry-pick it?
Comment 8 Mark Wielaard 2023-02-14 15:34:23 UTC
commit f2c522567ad63ac293535fba9704895e685ab5bc
Author: Mark Wielaard <mark@klomp.org>
Date:   Thu Jan 26 18:19:15 2023 +0100

    backends: Handle DW_TAG_unspecified_type in dwarf_peeled_die_type
    
    binutils 2.40 introduces DW_TAG_unspecified_type for assembly
    functions with an unknown return type. This breaks the
    run-funcretval.sh testcase because dwfl_module_return_value_location
    returns an error for such functions because it cannot determine the
    return value location. Fix that by treating DW_TAG_unspecified_type
    as if the DIE doesn't have a DW_AT_type.
    
    Also update the testcase to explicitly checking for
    DW_TAG_unspecified_type and printing "returns unspecified type".
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=30047
    
    Signed-off-by: Mark Wielaard <mark@klomp.org>
Comment 9 Martin Liska 2023-03-02 13:27:56 UTC
*** Bug 30192 has been marked as a duplicate of this bug. ***