From 0c16c58610276858702c0db8b3bc8d332fb85656 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 5 Jan 2010 22:59:32 -0800 Subject: [PATCH] Use dwarf_aggregate_size in backend return_value functions. Observe DW_AT_GNU_vector on powerpc return_value type. --- backends/ChangeLog | 12 +++++++++++ backends/arm_retval.c | 5 ++--- backends/ia64_retval.c | 36 +++++++++++++++---------------- backends/ppc64_retval.c | 27 ++++++++++++++++++----- backends/ppc_retval.c | 46 +++++++++++++++++++++++++++++++++++----- backends/sparc_retval.c | 5 ++--- backends/x86_64_retval.c | 7 +++--- 7 files changed, 100 insertions(+), 38 deletions(-) diff --git a/backends/ChangeLog b/backends/ChangeLog index 69351b323..b52d75dd7 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,15 @@ +2010-01-05 Roland McGrath + + * arm_retval.c (arm_return_value_location): Use dwarf_aggregate_size. + * ia64_retval.c (ia64_return_value_location): Likewise. + * ppc_retval.c (ppc_return_value_location): Likewise. + * ppc64_retval.c (ppc64_return_value_location): Likewise. + * sparc_retval.c (sparc_return_value_location): Likewise. + + * ppc64_retval.c (ppc64_return_value_location): + Use vr2 for DW_TAG_array_type with DW_AT_GNU_vector. + * ppc_retval.c (ppc_return_value_location): Likewise. + 2010-01-04 Roland McGrath * linux-core-note.c (vmcoreinfo_items): New static const variable. diff --git a/backends/arm_retval.c b/backends/arm_retval.c index 4ffc6e7c5..191cb1746 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 Red Hat, Inc. + Copyright (C) 2009-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -124,8 +124,7 @@ arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) case DW_TAG_class_type: case DW_TAG_union_type: case DW_TAG_array_type: - if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, - &attr_mem), &size) == 0 + if (dwarf_aggregate_size (typedie, &size) == 0 && size > 0 && size <= 4) goto intreg; goto aggregate; diff --git a/backends/ia64_retval.c b/backends/ia64_retval.c index 238cd9efe..7645c3c89 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, 2007 Red Hat, Inc. + Copyright (C) 2006-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -89,7 +89,8 @@ static const Dwarf_Op loc_aggregate[] = /* If this type is an HFA small enough to be returned in FP registers, return the number of registers to use. Otherwise 9, or -1 for errors. */ static int -hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used) +hfa_type (Dwarf_Die *typedie, Dwarf_Word size, + const Dwarf_Op **locp, int fpregs_used) { /* Descend the type structure, counting elements and finding their types. If we find a datum that's not an FP type (and not quad FP), punt. @@ -114,10 +115,6 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used) return -1; case DW_TAG_base_type:; - int size = dwarf_bytesize (typedie); - if (size < 0) - return -1; - Dwarf_Word encoding; if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, &attr_mem), &encoding) != 0) @@ -178,9 +175,13 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used) DW_AT_type, &attr_mem), &child_type_mem); + Dwarf_Word child_size; + if (dwarf_aggregate_size (child_typedie, &child_size) != 0) + return -1; if (tag == DW_TAG_union_type) { - int used = hfa_type (child_typedie, locp, fpregs_used); + int used = hfa_type (child_typedie, child_size, + locp, fpregs_used); if (used < 0 || used > 8) return used; if (used > max_used) @@ -188,7 +189,8 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used) } else { - fpregs_used = hfa_type (child_typedie, locp, fpregs_used); + fpregs_used = hfa_type (child_typedie, child_size, + locp, fpregs_used); if (fpregs_used < 0 || fpregs_used > 8) return fpregs_used; } @@ -200,10 +202,7 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used) } break; - case DW_TAG_array_type:; - size = dwarf_bytesize (typedie); - if (size < 0) - return 9; + case DW_TAG_array_type: if (size == 0) break; @@ -212,14 +211,16 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used) = dwarf_formref_die (dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem), &base_type_mem); + Dwarf_Word base_size; + if (dwarf_aggregate_size (base_typedie, &base_size) != 0) + return -1; - int used = hfa_type (base_typedie, locp, 0); + int used = hfa_type (base_typedie, base_size, locp, 0); if (used < 0 || used > 8) return used; if (size % (*locp)[1].number != 0) return 0; - size /= (*locp)[1].number; - fpregs_used += used * size; + fpregs_used += used * (size / (*locp)[1].number); break; default: @@ -346,13 +347,12 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) case DW_TAG_class_type: case DW_TAG_union_type: case DW_TAG_array_type: - if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, - &attr_mem), &size) != 0) + if (dwarf_aggregate_size (typedie, &size) != 0) return -1; /* If this qualifies as an homogeneous floating-point aggregate (HFA), then it should be returned in FP regs. */ - int nfpreg = hfa_type (typedie, locp, 0); + int nfpreg = hfa_type (typedie, size, locp, 0); if (nfpreg < 0) return nfpreg; else if (nfpreg > 0 && nfpreg <= 8) diff --git a/backends/ppc64_retval.c b/backends/ppc64_retval.c index 454897ccc..a5fc0dc80 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, 2006, 2007 Red Hat, Inc. + Copyright (C) 2005-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -53,6 +53,13 @@ static const Dwarf_Op loc_fpreg[] = #define nloc_fp2regs 4 #define nloc_fp4regs 8 +/* vr2. */ +static const Dwarf_Op loc_vmxreg[] = + { + { .atom = DW_OP_regx, .number = 1124 + 2 } + }; +#define nloc_vmxreg 1 + /* The return value is a structure and is actually stored in stack space passed in a hidden argument by the caller. But, the compiler helpfully returns the address of that space in r3. */ @@ -150,11 +157,21 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) *locp = loc_aggregate; return nloc_aggregate; - case DW_TAG_string_type: case DW_TAG_array_type: - if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, - &attr_mem), &size) == 0 - && size <= 8) + { + bool is_vector; + if (dwarf_formflag (dwarf_attr_integrate (typedie, DW_AT_GNU_vector, + &attr_mem), &is_vector) == 0 + && is_vector) + { + *locp = loc_vmxreg; + return nloc_vmxreg; + } + } + /* Fall through. */ + + case DW_TAG_string_type: + if (dwarf_aggregate_size (typedie, &size) == 0 && size <= 8) { if (tag == DW_TAG_array_type) { diff --git a/backends/ppc_retval.c b/backends/ppc_retval.c index fa0e303cb..15a0dba80 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 Red Hat, Inc. + Copyright (C) 2005, 2006, 2007, 2010 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -38,14 +38,17 @@ #define SVR4_STRUCT_RETURN 0 -/* r3, or pair r3, r4. */ +/* r3, or pair r3, r4, or quad r3-r6. */ static const Dwarf_Op loc_intreg[] = { { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 }, { .atom = DW_OP_reg4 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg5 }, { .atom = DW_OP_piece, .number = 4 }, + { .atom = DW_OP_reg6 }, { .atom = DW_OP_piece, .number = 4 }, }; #define nloc_intreg 1 #define nloc_intregpair 4 +#define nloc_intregquad 8 /* f1. */ static const Dwarf_Op loc_fpreg[] = @@ -54,6 +57,13 @@ static const Dwarf_Op loc_fpreg[] = }; #define nloc_fpreg 1 +/* vr2. */ +static const Dwarf_Op loc_vmxreg[] = + { + { .atom = DW_OP_regx, .number = 1124 + 2 } + }; +#define nloc_vmxreg 1 + /* The return value is a structure and is actually stored in stack space passed in a hidden argument by the caller. But, the compiler helpfully returns the address of that space in r3. */ @@ -64,6 +74,13 @@ static const Dwarf_Op loc_aggregate[] = #define nloc_aggregate 1 +/* XXX We should check the SHT_GNU_ATTRIBUTES bits here (or in ppc_init). */ +static bool +ppc_altivec_abi (void) +{ + return true; +} + int ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) { @@ -143,13 +160,32 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) *locp = loc_aggregate; return nloc_aggregate; + case DW_TAG_array_type: + { + bool is_vector; + if (dwarf_formflag (dwarf_attr_integrate (typedie, DW_AT_GNU_vector, + &attr_mem), &is_vector) == 0 + && is_vector + && dwarf_aggregate_size (typedie, &size) == 0) + switch (size) + { + case 16: + if (ppc_altivec_abi ()) + { + *locp = loc_vmxreg; + return nloc_vmxreg; + } + *locp = loc_intreg; + return nloc_intregquad; + } + } + /* Fall through. */ + case DW_TAG_structure_type: case DW_TAG_class_type: case DW_TAG_union_type: - case DW_TAG_array_type: if (SVR4_STRUCT_RETURN - && dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, - &attr_mem), &size) == 0 + && dwarf_aggregate_size (typedie, &size) == 0 && size > 0 && size <= 8) goto intreg; goto aggregate; diff --git a/backends/sparc_retval.c b/backends/sparc_retval.c index 7d7cbf2ce..dcff67a2c 100644 --- a/backends/sparc_retval.c +++ b/backends/sparc_retval.c @@ -1,5 +1,5 @@ /* Function return value location for SPARC. - Copyright (C) 2006, 2007 Red Hat, Inc. + Copyright (C) 2006-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -154,8 +154,7 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) case DW_TAG_class_type: case DW_TAG_union_type: case DW_TAG_array_type: - if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, - &attr_mem), &size) == 0 + if (dwarf_aggregate_size (typedie, &size) == 0 && size > 0 && size <= 8) goto intreg; goto aggregate; diff --git a/backends/x86_64_retval.c b/backends/x86_64_retval.c index 3109431e0..ba772bb92 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, 2007 Red Hat, Inc. + Copyright (C) 2005-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -181,9 +181,8 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp) case DW_TAG_class_type: case DW_TAG_union_type: case DW_TAG_array_type: - if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size, - &attr_mem), &size) != 0) - return -1; + if (dwarf_aggregate_size (typedie, &size) != 0) + goto large; if (size > 16) goto large; -- 2.47.2