summaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
authorPetr Machata <[email protected]>2014-06-20 22:59:43 +0200
committerPetr Machata <[email protected]>2014-06-20 22:59:43 +0200
commitba9e5156207e3c2bb85adc747376e774af3c0df6 (patch)
tree844f001f0e11201c301fb52a6561c0d7a5402bdd /backends
parent41362da47b7c570738c3fba55dae6fb42dd63b85 (diff)
backends (*_return_value_location): call dwarf_peeled_die_type
... instead of inlining equivalent code. Signed-off-by: Petr Machata <[email protected]>
Diffstat (limited to 'backends')
-rw-r--r--backends/ChangeLog15
-rw-r--r--backends/alpha_retval.c29
-rw-r--r--backends/arm_retval.c67
-rw-r--r--backends/i386_retval.c29
-rw-r--r--backends/ia64_retval.c49
-rw-r--r--backends/ppc64_retval.c49
-rw-r--r--backends/ppc_retval.c50
-rw-r--r--backends/s390_retval.c29
-rw-r--r--backends/sh_retval.c49
-rw-r--r--backends/sparc_retval.c55
-rw-r--r--backends/tilegx_retval.c63
-rw-r--r--backends/x86_64_retval.c49
12 files changed, 208 insertions, 325 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog
index bc5b8434..7eda035c 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,18 @@
+2014-06-20 Petr Machata <[email protected]>
+
+ * alpha_retval.c (alpha_return_value_location): Call
+ dwarf_peeled_die_type instead of inlining equivalent code.
+ * arm_retval.c (arm_return_value_location): Likewise.
+ * i386_retval.c (i386_return_value_location): Likewise.
+ * ia64_retval.c (ia64_return_value_location): Likewise.
+ * ppc64_retval.c (ppc64_return_value_location): Likewise.
+ * ppc_retval.c (ppc_return_value_location): Likewise.
+ * s390_retval.c (s390_return_value_location): Likewise.
+ * sh_retval.c (sh_return_value_location): Likewise.
+ * sparc_retval.c (sparc_return_value_location): Likewise.
+ * tilegx_retval.c (tilegx_return_value_location): Likewise.
+ * x86_64_retval.c (x86_64_return_value_location): Likewise.
+
2014-05-19 Mark Wielaard <[email protected]>
* arm_init.c (arm_init): Hook check_reloc_target_type.
diff --git a/backends/alpha_retval.c b/backends/alpha_retval.c
index 6dfa6944..53dbfa45 100644
--- a/backends/alpha_retval.c
+++ b/backends/alpha_retval.c
@@ -1,5 +1,5 @@
/* Function return value location for Alpha ELF ABI.
- Copyright (C) 2005, 2007 Red Hat, Inc.
+ Copyright (C) 2005, 2007, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -67,27 +67,10 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
/* Start with the function's type, and get the DW_AT_type attribute,
which is the type of the return value. */
-
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
- &attr_mem);
- if (attr == NULL)
- /* The function has no return value, like a `void' function in C. */
- return 0;
-
- Dwarf_Die die_mem;
- Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
- int tag = DWARF_TAG_OR_RETURN (typedie);
-
- /* Follow typedefs and qualifiers to get to the actual type. */
- while (tag == DW_TAG_typedef
- || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
- || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
- {
- attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
- typedie = dwarf_formref_die (attr, &die_mem);
- tag = DWARF_TAG_OR_RETURN (typedie);
- }
+ Dwarf_Die die_mem, *typedie = &die_mem;
+ int tag = dwarf_peeled_die_type (functypedie, typedie);
+ if (tag <= 0)
+ return tag;
switch (tag)
{
@@ -97,6 +80,7 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_subrange_type:
if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
{
+ Dwarf_Attribute attr_mem, *attr;
attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
tag = DWARF_TAG_OR_RETURN (typedie);
@@ -108,6 +92,7 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_pointer_type:
case DW_TAG_ptr_to_member_type:
{
+ Dwarf_Attribute attr_mem;
Dwarf_Word size;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
diff --git a/backends/arm_retval.c b/backends/arm_retval.c
index 222f7555..7aced742 100644
--- a/backends/arm_retval.c
+++ b/backends/arm_retval.c
@@ -1,5 +1,5 @@
/* Function return value location for ARM EABI.
- Copyright (C) 2009-2010 Red Hat, Inc.
+ Copyright (C) 2009-2010, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -63,27 +63,10 @@ arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
/* Start with the function's type, and get the DW_AT_type attribute,
which is the type of the return value. */
-
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
- &attr_mem);
- if (attr == NULL)
- /* The function has no return value, like a `void' function in C. */
- return 0;
-
- Dwarf_Die die_mem;
- Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
- int tag = DWARF_TAG_OR_RETURN (typedie);
-
- /* Follow typedefs and qualifiers to get to the actual type. */
- while (tag == DW_TAG_typedef
- || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
- || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
- {
- attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
- typedie = dwarf_formref_die (attr, &die_mem);
- tag = DWARF_TAG_OR_RETURN (typedie);
- }
+ Dwarf_Die die_mem, *typedie = &die_mem;
+ int tag = dwarf_peeled_die_type (functypedie, typedie);
+ if (tag <= 0)
+ return tag;
Dwarf_Word size;
switch (tag)
@@ -94,6 +77,7 @@ arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_subrange_type:
if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
{
+ Dwarf_Attribute attr_mem, *attr;
attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
tag = DWARF_TAG_OR_RETURN (typedie);
@@ -104,24 +88,27 @@ arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_enumeration_type:
case DW_TAG_pointer_type:
case DW_TAG_ptr_to_member_type:
- if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
- &attr_mem), &size) != 0)
- {
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
- size = 4;
- else
- return -1;
- }
- if (size <= 16)
- {
- intreg:
- *locp = loc_intreg;
- return size <= 4 ? nloc_intreg : nloc_intregs ((size + 3) / 4);
- }
-
- aggregate:
- *locp = loc_aggregate;
- return nloc_aggregate;
+ {
+ Dwarf_Attribute attr_mem;
+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+ &attr_mem), &size) != 0)
+ {
+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ size = 4;
+ else
+ return -1;
+ }
+ if (size <= 16)
+ {
+ intreg:
+ *locp = loc_intreg;
+ return size <= 4 ? nloc_intreg : nloc_intregs ((size + 3) / 4);
+ }
+
+ aggregate:
+ *locp = loc_aggregate;
+ return nloc_aggregate;
+ }
case DW_TAG_structure_type:
case DW_TAG_class_type:
diff --git a/backends/i386_retval.c b/backends/i386_retval.c
index 90678c32..9da797d5 100644
--- a/backends/i386_retval.c
+++ b/backends/i386_retval.c
@@ -1,5 +1,5 @@
/* Function return value location for Linux/i386 ABI.
- Copyright (C) 2005-2010 Red Hat, Inc.
+ Copyright (C) 2005-2010, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -67,27 +67,10 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
/* Start with the function's type, and get the DW_AT_type attribute,
which is the type of the return value. */
-
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
- &attr_mem);
- if (attr == NULL)
- /* The function has no return value, like a `void' function in C. */
- return 0;
-
- Dwarf_Die die_mem;
- Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
- int tag = DWARF_TAG_OR_RETURN (typedie);
-
- /* Follow typedefs and qualifiers to get to the actual type. */
- while (tag == DW_TAG_typedef
- || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
- || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
- {
- attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
- typedie = dwarf_formref_die (attr, &die_mem);
- tag = DWARF_TAG_OR_RETURN (typedie);
- }
+ Dwarf_Die die_mem, *typedie = &die_mem;
+ int tag = dwarf_peeled_die_type (functypedie, typedie);
+ if (tag <= 0)
+ return tag;
switch (tag)
{
@@ -97,6 +80,7 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_subrange_type:
if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
{
+ Dwarf_Attribute attr_mem, *attr;
attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
tag = DWARF_TAG_OR_RETURN (typedie);
@@ -109,6 +93,7 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_ptr_to_member_type:
{
Dwarf_Word size;
+ Dwarf_Attribute attr_mem;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
{
diff --git a/backends/ia64_retval.c b/backends/ia64_retval.c
index ac0d8c3d..b5928c58 100644
--- a/backends/ia64_retval.c
+++ b/backends/ia64_retval.c
@@ -1,5 +1,5 @@
/* Function return value location for IA64 ABI.
- Copyright (C) 2006-2010 Red Hat, Inc.
+ Copyright (C) 2006-2010, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -238,27 +238,10 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
/* Start with the function's type, and get the DW_AT_type attribute,
which is the type of the return value. */
-
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
- &attr_mem);
- if (attr == NULL)
- /* The function has no return value, like a `void' function in C. */
- return 0;
-
- Dwarf_Die die_mem;
- Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
- int tag = DWARF_TAG_OR_RETURN (typedie);
-
- /* Follow typedefs and qualifiers to get to the actual type. */
- while (tag == DW_TAG_typedef
- || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
- || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
- {
- attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
- typedie = dwarf_formref_die (attr, &die_mem);
- tag = DWARF_TAG_OR_RETURN (typedie);
- }
+ Dwarf_Die die_mem, *typedie = &die_mem;
+ int tag = dwarf_peeled_die_type (functypedie, typedie);
+ if (tag <= 0)
+ return tag;
Dwarf_Word size;
switch (tag)
@@ -269,6 +252,7 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_subrange_type:
if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
{
+ Dwarf_Attribute attr_mem, *attr;
attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
tag = DWARF_TAG_OR_RETURN (typedie);
@@ -279,16 +263,21 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_enumeration_type:
case DW_TAG_pointer_type:
case DW_TAG_ptr_to_member_type:
- if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
- &attr_mem), &size) != 0)
- {
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
- size = 8;
- else
- return -1;
- }
+ {
+ Dwarf_Attribute attr_mem;
+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+ &attr_mem), &size) != 0)
+ {
+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ size = 8;
+ else
+ return -1;
+ }
+ }
+
if (tag == DW_TAG_base_type)
{
+ Dwarf_Attribute attr_mem;
Dwarf_Word encoding;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
&attr_mem),
diff --git a/backends/ppc64_retval.c b/backends/ppc64_retval.c
index c5c3b6fe..a2519839 100644
--- a/backends/ppc64_retval.c
+++ b/backends/ppc64_retval.c
@@ -1,5 +1,5 @@
/* Function return value location for Linux/PPC64 ABI.
- Copyright (C) 2005-2010 Red Hat, Inc.
+ Copyright (C) 2005-2010, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -77,27 +77,10 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
/* Start with the function's type, and get the DW_AT_type attribute,
which is the type of the return value. */
-
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
- &attr_mem);
- if (attr == NULL)
- /* The function has no return value, like a `void' function in C. */
- return 0;
-
- Dwarf_Die die_mem;
- Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
- int tag = DWARF_TAG_OR_RETURN (typedie);
-
- /* Follow typedefs and qualifiers to get to the actual type. */
- while (tag == DW_TAG_typedef
- || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
- || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
- {
- attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
- typedie = dwarf_formref_die (attr, &die_mem);
- tag = DWARF_TAG_OR_RETURN (typedie);
- }
+ Dwarf_Die die_mem, *typedie = &die_mem;
+ int tag = dwarf_peeled_die_type (functypedie, typedie);
+ if (tag <= 0)
+ return tag;
Dwarf_Word size;
switch (tag)
@@ -108,6 +91,7 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_subrange_type:
if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
{
+ Dwarf_Attribute attr_mem, *attr;
attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
tag = DWARF_TAG_OR_RETURN (typedie);
@@ -118,16 +102,21 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_enumeration_type:
case DW_TAG_pointer_type:
case DW_TAG_ptr_to_member_type:
- if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
- &attr_mem), &size) != 0)
- {
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
- size = 8;
- else
- return -1;
+ {
+ Dwarf_Attribute attr_mem;
+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+ &attr_mem), &size) != 0)
+ {
+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ size = 8;
+ else
+ return -1;
}
+ }
+
if (tag == DW_TAG_base_type)
{
+ Dwarf_Attribute attr_mem;
Dwarf_Word encoding;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
&attr_mem),
@@ -162,6 +151,7 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_array_type:
{
+ Dwarf_Attribute attr_mem;
bool is_vector;
if (dwarf_formflag (dwarf_attr_integrate (typedie, DW_AT_GNU_vector,
&attr_mem), &is_vector) == 0
@@ -179,6 +169,7 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
if (tag == DW_TAG_array_type)
{
/* Check if it's a character array. */
+ Dwarf_Attribute attr_mem, *attr;
attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
tag = DWARF_TAG_OR_RETURN (typedie);
diff --git a/backends/ppc_retval.c b/backends/ppc_retval.c
index 7ca0c185..b14a99f1 100644
--- a/backends/ppc_retval.c
+++ b/backends/ppc_retval.c
@@ -1,5 +1,5 @@
/* Function return value location for Linux/PPC ABI.
- Copyright (C) 2005, 2006, 2007, 2010 Red Hat, Inc.
+ Copyright (C) 2005, 2006, 2007, 2010, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -89,27 +89,10 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
/* Start with the function's type, and get the DW_AT_type attribute,
which is the type of the return value. */
-
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
- &attr_mem);
- if (attr == NULL)
- /* The function has no return value, like a `void' function in C. */
- return 0;
-
- Dwarf_Die die_mem;
- Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
- int tag = DWARF_TAG_OR_RETURN (typedie);
-
- /* Follow typedefs and qualifiers to get to the actual type. */
- while (tag == DW_TAG_typedef
- || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
- || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
- {
- attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
- typedie = dwarf_formref_die (attr, &die_mem);
- tag = DWARF_TAG_OR_RETURN (typedie);
- }
+ Dwarf_Die die_mem, *typedie = &die_mem;
+ int tag = dwarf_peeled_die_type (functypedie, typedie);
+ if (tag <= 0)
+ return tag;
Dwarf_Word size;
switch (tag)
@@ -120,6 +103,7 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_subrange_type:
if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
{
+ Dwarf_Attribute attr_mem, *attr;
attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
tag = DWARF_TAG_OR_RETURN (typedie);
@@ -130,18 +114,23 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_enumeration_type:
case DW_TAG_pointer_type:
case DW_TAG_ptr_to_member_type:
- if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
- &attr_mem), &size) != 0)
- {
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
- size = 4;
- else
- return -1;
- }
+ {
+ Dwarf_Attribute attr_mem;
+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+ &attr_mem), &size) != 0)
+ {
+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ size = 4;
+ else
+ return -1;
+ }
+ }
+
if (size <= 8)
{
if (tag == DW_TAG_base_type)
{
+ Dwarf_Attribute attr_mem;
Dwarf_Word encoding;
if (dwarf_formudata (dwarf_attr_integrate (typedie,
DW_AT_encoding,
@@ -165,6 +154,7 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_array_type:
{
+ Dwarf_Attribute attr_mem;
bool is_vector;
if (dwarf_formflag (dwarf_attr_integrate (typedie, DW_AT_GNU_vector,
&attr_mem), &is_vector) == 0
diff --git a/backends/s390_retval.c b/backends/s390_retval.c
index b671ee86..a927d46a 100644
--- a/backends/s390_retval.c
+++ b/backends/s390_retval.c
@@ -1,5 +1,5 @@
/* Function return value location for S/390 ABI.
- Copyright (C) 2006, 2007 Red Hat, Inc.
+ Copyright (C) 2006, 2007, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -68,27 +68,10 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
/* Start with the function's type, and get the DW_AT_type attribute,
which is the type of the return value. */
-
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
- &attr_mem);
- if (attr == NULL)
- /* The function has no return value, like a `void' function in C. */
- return 0;
-
- Dwarf_Die die_mem;
- Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
- int tag = DWARF_TAG_OR_RETURN (typedie);
-
- /* Follow typedefs and qualifiers to get to the actual type. */
- while (tag == DW_TAG_typedef
- || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
- || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
- {
- attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
- typedie = dwarf_formref_die (attr, &die_mem);
- tag = DWARF_TAG_OR_RETURN (typedie);
- }
+ Dwarf_Die die_mem, *typedie = &die_mem;
+ int tag = dwarf_peeled_die_type (functypedie, typedie);
+ if (tag <= 0)
+ return tag;
Dwarf_Word size;
switch (tag)
@@ -99,6 +82,7 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_subrange_type:
if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
{
+ Dwarf_Attribute attr_mem, *attr;
attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
tag = DWARF_TAG_OR_RETURN (typedie);
@@ -115,6 +99,7 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
if (dwarf_diecu (typedie, &cudie, &asize, NULL) == NULL)
return -1;
+ Dwarf_Attribute attr_mem;
if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
{
diff --git a/backends/sh_retval.c b/backends/sh_retval.c
index 11662318..d44f2601 100644
--- a/backends/sh_retval.c
+++ b/backends/sh_retval.c
@@ -1,5 +1,5 @@
/* Function return value location for Linux/SH ABI.
- Copyright (C) 2010 Red Hat, Inc.
+ Copyright (C) 2010, 2014 Red Hat, Inc.
This file is part of elfutils.
Contributed by Matt Fleming <[email protected]>.
@@ -65,27 +65,10 @@ sh_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
/* Start with the function's type, and get the DW_AT_type attribute,
which is the type of the return value. */
-
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
- &attr_mem);
- if (attr == NULL)
- /* The function has no return value, like a `void' function in C. */
- return 0;
-
- Dwarf_Die die_mem;
- Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
- int tag = DWARF_TAG_OR_RETURN (typedie);
-
- /* Follow typedefs and qualifiers to get to the actual type. */
- while (tag == DW_TAG_typedef
- || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
- || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
- {
- attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
- typedie = dwarf_formref_die (attr, &die_mem);
- tag = DWARF_TAG_OR_RETURN (typedie);
- }
+ Dwarf_Die die_mem, *typedie = &die_mem;
+ int tag = dwarf_peeled_die_type (functypedie, typedie);
+ if (tag <= 0)
+ return tag;
Dwarf_Word size;
switch (tag)
@@ -96,6 +79,7 @@ sh_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_subrange_type:
if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
{
+ Dwarf_Attribute attr_mem, *attr;
attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
tag = DWARF_TAG_OR_RETURN (typedie);
@@ -106,18 +90,23 @@ sh_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_enumeration_type:
case DW_TAG_pointer_type:
case DW_TAG_ptr_to_member_type:
- if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
- &attr_mem), &size) != 0)
- {
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
- size = 4;
- else
- return -1;
- }
+ {
+ Dwarf_Attribute attr_mem;
+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+ &attr_mem), &size) != 0)
+ {
+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ size = 4;
+ else
+ return -1;
+ }
+ }
+
if (size <= 8)
{
if (tag == DW_TAG_base_type)
{
+ Dwarf_Attribute attr_mem;
Dwarf_Word encoding;
if (dwarf_formudata (dwarf_attr_integrate (typedie,
DW_AT_encoding,
diff --git a/backends/sparc_retval.c b/backends/sparc_retval.c
index dcd37859..e1b17753 100644
--- a/backends/sparc_retval.c
+++ b/backends/sparc_retval.c
@@ -1,5 +1,5 @@
/* Function return value location for SPARC.
- Copyright (C) 2006-2010 Red Hat, Inc.
+ Copyright (C) 2006-2010, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -72,27 +72,10 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
/* Start with the function's type, and get the DW_AT_type attribute,
which is the type of the return value. */
-
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
- &attr_mem);
- if (attr == NULL)
- /* The function has no return value, like a `void' function in C. */
- return 0;
-
- Dwarf_Die die_mem;
- Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
- int tag = DWARF_TAG_OR_RETURN (typedie);
-
- /* Follow typedefs and qualifiers to get to the actual type. */
- while (tag == DW_TAG_typedef
- || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
- || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
- {
- attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
- typedie = dwarf_formref_die (attr, &die_mem);
- tag = DWARF_TAG_OR_RETURN (typedie);
- }
+ Dwarf_Die die_mem, *typedie = &die_mem;
+ int tag = dwarf_peeled_die_type (functypedie, typedie);
+ if (tag <= 0)
+ return tag;
Dwarf_Word size;
switch (tag)
@@ -103,6 +86,7 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_subrange_type:
if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
{
+ Dwarf_Attribute attr_mem, *attr;
attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
tag = DWARF_TAG_OR_RETURN (typedie);
@@ -113,19 +97,24 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_enumeration_type:
case DW_TAG_pointer_type:
case DW_TAG_ptr_to_member_type:
- if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
- &attr_mem), &size) != 0)
- {
- uint8_t asize;
- Dwarf_Die cudie;
- if ((tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
- && dwarf_diecu (typedie, &cudie, &asize, NULL) != NULL)
- size = asize;
- else
- return -1;
- }
+ {
+ Dwarf_Attribute attr_mem;
+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+ &attr_mem), &size) != 0)
+ {
+ uint8_t asize;
+ Dwarf_Die cudie;
+ if ((tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ && dwarf_diecu (typedie, &cudie, &asize, NULL) != NULL)
+ size = asize;
+ else
+ return -1;
+ }
+ }
+
if (tag == DW_TAG_base_type)
{
+ Dwarf_Attribute attr_mem;
Dwarf_Word encoding;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
&attr_mem),
diff --git a/backends/tilegx_retval.c b/backends/tilegx_retval.c
index e14cc512..db81a20b 100644
--- a/backends/tilegx_retval.c
+++ b/backends/tilegx_retval.c
@@ -1,5 +1,6 @@
/* Function return value location for Linux/TILE-Gx ABI.
Copyright (C) 2012 Tilera Corporation
+ Copyright (C) 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -59,27 +60,10 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
/* Start with the function's type, and get the DW_AT_type attribute,
which is the type of the return value. */
-
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
- &attr_mem);
- if (attr == NULL)
- /* The function has no return value, like a `void' function in C. */
- return 0;
-
- Dwarf_Die die_mem;
- Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
- int tag = DWARF_TAG_OR_RETURN (typedie);
-
- /* Follow typedefs and qualifiers to get to the actual type. */
- while (tag == DW_TAG_typedef
- || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
- || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
- {
- attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
- typedie = dwarf_formref_die (attr, &die_mem);
- tag = DWARF_TAG_OR_RETURN (typedie);
- }
+ Dwarf_Die die_mem, *typedie = &die_mem;
+ int tag = dwarf_peeled_die_type (functypedie, typedie);
+ if (tag <= 0)
+ return tag;
Dwarf_Word size;
switch (tag)
@@ -90,6 +74,7 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_subrange_type:
if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
{
+ Dwarf_Attribute attr_mem, *attr;
attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
tag = DWARF_TAG_OR_RETURN (typedie);
@@ -100,22 +85,25 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_enumeration_type:
case DW_TAG_pointer_type:
case DW_TAG_ptr_to_member_type:
- if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
- &attr_mem), &size) != 0)
- {
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
- size = 8;
- else
- return -1;
- }
- if (tag == DW_TAG_base_type)
- {
- Dwarf_Word encoding;
- if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
- &attr_mem),
- &encoding) != 0)
- return -1;
- }
+ {
+ Dwarf_Attribute attr_mem;
+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+ &attr_mem), &size) != 0)
+ {
+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ size = 8;
+ else
+ return -1;
+ }
+ if (tag == DW_TAG_base_type)
+ {
+ Dwarf_Word encoding;
+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+ &attr_mem),
+ &encoding) != 0)
+ return -1;
+ }
+ }
/* Small enough structs are passed directly in registers R0 ... R7. */
if (size <= 8)
@@ -139,6 +127,7 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
if (tag == DW_TAG_array_type)
{
+ Dwarf_Attribute attr_mem, *attr;
/* Check if it's a character array. */
attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
diff --git a/backends/x86_64_retval.c b/backends/x86_64_retval.c
index f3e9f2be..b3799ae0 100644
--- a/backends/x86_64_retval.c
+++ b/backends/x86_64_retval.c
@@ -1,5 +1,5 @@
/* Function return value location for Linux/x86-64 ABI.
- Copyright (C) 2005-2010 Red Hat, Inc.
+ Copyright (C) 2005-2010, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -81,27 +81,10 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
/* Start with the function's type, and get the DW_AT_type attribute,
which is the type of the return value. */
-
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
- &attr_mem);
- if (attr == NULL)
- /* The function has no return value, like a `void' function in C. */
- return 0;
-
- Dwarf_Die die_mem;
- Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
- int tag = DWARF_TAG_OR_RETURN (typedie);
-
- /* Follow typedefs and qualifiers to get to the actual type. */
- while (tag == DW_TAG_typedef
- || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
- || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
- {
- attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
- typedie = dwarf_formref_die (attr, &die_mem);
- tag = DWARF_TAG_OR_RETURN (typedie);
- }
+ Dwarf_Die die_mem, *typedie = &die_mem;
+ int tag = dwarf_peeled_die_type (functypedie, typedie);
+ if (tag <= 0)
+ return tag;
Dwarf_Word size;
switch (tag)
@@ -112,6 +95,7 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_subrange_type:
if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
{
+ Dwarf_Attribute attr_mem, *attr;
attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
typedie = dwarf_formref_die (attr, &die_mem);
tag = DWARF_TAG_OR_RETURN (typedie);
@@ -122,16 +106,21 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_enumeration_type:
case DW_TAG_pointer_type:
case DW_TAG_ptr_to_member_type:
- if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
- &attr_mem), &size) != 0)
- {
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
- size = 8;
- else
- return -1;
- }
+ {
+ Dwarf_Attribute attr_mem;
+ if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+ &attr_mem), &size) != 0)
+ {
+ if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ size = 8;
+ else
+ return -1;
+ }
+ }
+
if (tag == DW_TAG_base_type)
{
+ Dwarf_Attribute attr_mem;
Dwarf_Word encoding;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
&attr_mem),