]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
backends: Handle DW_TAG_unspecified_type in dwarf_peeled_die_type
authorMark Wielaard <mark@klomp.org>
Thu, 26 Jan 2023 17:19:15 +0000 (18:19 +0100)
committerMark Wielaard <mark@klomp.org>
Tue, 14 Feb 2023 15:30:24 +0000 (16:30 +0100)
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>
NEWS
backends/ChangeLog
backends/libebl_CPU.h
tests/ChangeLog
tests/funcretval.c

diff --git a/NEWS b/NEWS
index 71534b8c454b96d8d55cc0791efc250c031ee50c..80faca39b18c77f56ed57bcc2045141f3a1c2c7a 100644 (file)
--- 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.
index 40ec7c0c38db97ea79955334beb75ce3aed4dd32..81f08314249b21d20e7385b4c3918ea357a4e1a1 100644 (file)
@@ -1,3 +1,8 @@
+2023-02-07  Mark Wielaard  <mark@klomp.org>
+
+       * 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  <mark@klomp.org>
 
        * sparc_reloc.def (NONE): Add EXEC and DYN.
index 2abad76f5b063b47b9328d3479c501b970edc15c..3b2cc3e492fc79f9605480f957342b87ff54e59e 100644 (file)
@@ -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 <mark@klomp.org>
    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
index 974a3a4fc5a38e973150da75b7745b5360e073a5..89f1a9918e820e5c1136f2a89102bddfb4692ec5 100644 (file)
@@ -1,3 +1,8 @@
+2023-02-07  Mark Wielaard  <mark@klomp.org>
+
+       * tests/funcretval.c (handle_function): Check for
+       DW_TAG_unspecified_type.
+
 2023-02-03  Mark Wielaard  <mark@klomp.org>
 
        * run-addr2line-C-test.sh: Check ELFUTILS_DISABLE_DEMANGLE.
index 16cd1a444e8f1f9fe92f5ed3e1453e52664e9b02..41198ab7f5ee9aa6242cdd271b4798af6243afc1 100644 (file)
@@ -1,5 +1,6 @@
 /* Test program for dwfl_module_return_value_location.
    Copyright (C) 2005 Red Hat, Inc.
+   Copyright (C) 2023 Mark J. Wielaard <mark@klomp.org>
    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:");