summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/elfutils/files/handle_DW_TAG_unspecified_type.patch
blob: 8cab01c29a059aa6c7354571ff85e356d6e08984 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
From: Mark Wielaard <mark@klomp.org>
Date: Thu, 26 Jan 2023 17:19:15 +0000 (+0100)
Subject: backends: Handle DW_TAG_unspecified_type in dwarf_peeled_die_type
X-Git-Url: https://sourceware.org/git/?p=elfutils.git;a=commitdiff_plain;h=f2c522567ad63ac293535fba9704895e685ab5bc;hp=3fa98a6f29b0f370e32549ead7eb897c839af980

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

Upstream-Status: Backport [https://sourceware.org/git/?p=elfutils.git;a=commitdiff;h=f2c522567ad63ac293535fba9704895e685ab5bc;hp=3fa98a6f29b0f370e32549ead7eb897c839af980]
Signed-off-by: Mark Wielaard <mark@klomp.org>
---

--- 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 <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
      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, D
   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;
 }
 
 #endif	/* libebl_CPU.h */
--- 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 <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, voi
     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:");