From: Mark Wielaard Date: Thu, 26 Jan 2023 17:19:15 +0000 (+0100) Subject: backends: Handle DW_TAG_unspecified_type in dwarf_peeled_die_type X-Git-Tag: elfutils-0.189~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f2c522567ad63ac293535fba9704895e685ab5bc;p=thirdparty%2Felfutils.git 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 --- diff --git a/NEWS b/NEWS index 71534b8c4..80faca39b 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +Version 0.189 + +libdwfl: dwfl_module_return_value_location now returns 0 (no return type) + for DIEs that point to a DW_TAG_unspecified_type. + Version 0.188 readelf: Add -D, --use-dynamic option. diff --git a/backends/ChangeLog b/backends/ChangeLog index 40ec7c0c3..81f083142 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,8 @@ +2023-02-07 Mark Wielaard + + * libebl_CPU.h (dwarf_peeled_die_type): Explicitly handle + DW_TAG_unspecified_type as if there was no DW_AT_type. + 2023-01-19 Mark Wielaard * sparc_reloc.def (NONE): Add EXEC and DYN. diff --git a/backends/libebl_CPU.h b/backends/libebl_CPU.h index 2abad76f5..3b2cc3e49 100644 --- a/backends/libebl_CPU.h +++ b/backends/libebl_CPU.h @@ -1,5 +1,6 @@ /* Common interface for libebl modules. Copyright (C) 2000, 2001, 2002, 2003, 2005, 2013, 2014 Red Hat, Inc. + Copyright (C) 2023 Mark J. Wielaard This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -53,7 +54,9 @@ extern bool (*generic_debugscn_p) (const char *) attribute_hidden; dwarf_tag (_die); }) /* Get a type die corresponding to DIE. Peel CV qualifiers off - it. */ + it. Returns zero if the DIE doesn't have a type, or the type + is DW_TAG_unspecified_type. Returns -1 on error. Otherwise + returns the result tag DW_AT value. */ static inline int dwarf_peeled_die_type (Dwarf_Die *die, Dwarf_Die *result) { @@ -69,7 +72,14 @@ dwarf_peeled_die_type (Dwarf_Die *die, Dwarf_Die *result) if (dwarf_peel_type (result, result) != 0) return -1; - return DWARF_TAG_OR_RETURN (result); + if (result == NULL) + return -1; + + int tag = dwarf_tag (result); + if (tag == DW_TAG_unspecified_type) + return 0; /* Treat an unspecified type as if there was no type. */ + + return tag; } static inline bool diff --git a/tests/ChangeLog b/tests/ChangeLog index 974a3a4fc..89f1a9918 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2023-02-07 Mark Wielaard + + * tests/funcretval.c (handle_function): Check for + DW_TAG_unspecified_type. + 2023-02-03 Mark Wielaard * run-addr2line-C-test.sh: Check ELFUTILS_DISABLE_DEMANGLE. diff --git a/tests/funcretval.c b/tests/funcretval.c index 16cd1a444..41198ab7f 100644 --- a/tests/funcretval.c +++ b/tests/funcretval.c @@ -1,5 +1,6 @@ /* Test program for dwfl_module_return_value_location. Copyright (C) 2005 Red Hat, Inc. + Copyright (C) 2023 Mark J. Wielaard This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -67,7 +68,18 @@ handle_function (Dwarf_Die *funcdie, void *arg) error (EXIT_FAILURE, 0, "dwfl_module_return_value_location: %s", dwfl_errmsg (-1)); else if (nlocops == 0) - puts ("returns no value"); + { + // Check if this is the special unspecified type + // https://sourceware.org/bugzilla/show_bug.cgi?id=30047 + Dwarf_Die die_mem, *typedie = &die_mem; + Dwarf_Attribute attr_mem, *attr; + attr = dwarf_attr_integrate (funcdie, DW_AT_type, &attr_mem); + if (dwarf_formref_die (attr, typedie) != NULL + && dwarf_tag (typedie) == DW_TAG_unspecified_type) + puts ("returns unspecified type"); + else + puts ("returns no value"); + } else { printf ("return value location:");