From: Petr Machata Date: Fri, 20 Jun 2014 20:59:43 +0000 (+0200) Subject: backends (*_return_value_location): call dwarf_peeled_die_type X-Git-Tag: elfutils-0.160~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ba9e5156207e3c2bb85adc747376e774af3c0df6;p=thirdparty%2Felfutils.git backends (*_return_value_location): call dwarf_peeled_die_type ... instead of inlining equivalent code. Signed-off-by: Petr Machata --- diff --git a/backends/ChangeLog b/backends/ChangeLog index bc5b8434f..7eda035c3 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,18 @@ +2014-06-20 Petr Machata + + * 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 * arm_init.c (arm_init): Hook check_reloc_target_type. diff --git a/backends/alpha_retval.c b/backends/alpha_retval.c index 6dfa69441..53dbfa454 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 222f75553..7aced742c 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 90678c325..9da797d5e 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 ac0d8c3d3..b5928c587 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 c5c3b6fef..a25198392 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 7ca0c1851..b14a99f11 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 b671ee86b..a927d46a0 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 116623184..d44f2601f 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 . @@ -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 dcd378598..e1b177538 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 e14cc5124..db81a20b3 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 f3e9f2be2..b3799ae07 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),