Author: Petr Machata Description: Move get_hfa_type from IA64 backend to type.c, name it type_get_hfa_type Applied-Upstream: http://anonscm.debian.org/gitweb/?p=collab-maint/ltrace.git;a=commit;h=982cbca34b2b49a158086ff5f43eb9bba89edead Last-Update: 2014-03-13 Index: ltrace/sysdeps/linux-gnu/ia64/fetch.c =================================================================== --- ltrace.orig/sysdeps/linux-gnu/ia64/fetch.c 2014-03-12 16:13:44.075726000 -0600 +++ ltrace/sysdeps/linux-gnu/ia64/fetch.c 2014-03-13 09:32:30.504762084 -0600 @@ -1,6 +1,6 @@ /* * This file is part of ltrace. - * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc. * Copyright (C) 2008,2009 Juan Cespedes * Copyright (C) 2006 Steve Fink * Copyright (C) 2006 Ian Wienand @@ -249,37 +249,6 @@ return 0; } -static enum arg_type -get_hfa_type(struct arg_type_info *info, size_t *countp) -{ - size_t n = type_aggregate_size(info); - if (n == (size_t)-1) - return ARGTYPE_VOID; - - enum arg_type type = ARGTYPE_VOID; - *countp = 0; - - while (n-- > 0) { - struct arg_type_info *emt = type_element(info, n); - - enum arg_type emt_type = emt->type; - size_t emt_count = 1; - if (emt_type == ARGTYPE_STRUCT || emt_type == ARGTYPE_ARRAY) - emt_type = get_hfa_type(emt, &emt_count); - - if (type == ARGTYPE_VOID) { - if (emt_type != ARGTYPE_FLOAT - && emt_type != ARGTYPE_DOUBLE) - return ARGTYPE_VOID; - type = emt_type; - } - if (emt_type != type) - return ARGTYPE_VOID; - *countp += emt_count; - } - return type; -} - static int allocate_hfa(struct fetch_context *ctx, struct Process *proc, struct arg_type_info *info, struct value *valuep, @@ -380,10 +349,11 @@ * floating-point registers, beginning with f8. */ if (info->type == ARGTYPE_STRUCT || info->type == ARGTYPE_ARRAY) { size_t hfa_size; - enum arg_type hfa_type = get_hfa_type(info, &hfa_size); - if (hfa_type != ARGTYPE_VOID && hfa_size <= 8) + struct arg_type_info *hfa_info + = type_get_hfa_type(info, &hfa_size); + if (hfa_info != NULL && hfa_size <= 8) return allocate_hfa(ctx, proc, info, valuep, - hfa_type, hfa_size); + hfa_info->type, hfa_size); } /* Integers and pointers are passed in r8. 128-bit integers @@ -409,7 +379,7 @@ struct arg_type_info *info, struct value *valuep) { switch (info->type) { - enum arg_type hfa_type; + struct arg_type_info *hfa_info; size_t hfa_size; case ARGTYPE_VOID: @@ -421,10 +391,10 @@ return allocate_float(ctx, proc, info, valuep, 1); case ARGTYPE_STRUCT: - hfa_type = get_hfa_type(info, &hfa_size); - if (hfa_type != ARGTYPE_VOID) + hfa_info = type_get_hfa_type(info, &hfa_size); + if (hfa_info != NULL) return allocate_hfa(ctx, proc, info, valuep, - hfa_type, hfa_size); + hfa_info->type, hfa_size); /* Fall through. */ case ARGTYPE_CHAR: case ARGTYPE_SHORT: Index: ltrace/type.c =================================================================== --- ltrace.orig/type.c 2014-03-12 16:13:44.075726000 -0600 +++ ltrace/type.c 2014-03-13 09:32:30.504762084 -0600 @@ -568,3 +568,39 @@ } abort(); } + +struct arg_type_info * +type_get_hfa_type(struct arg_type_info *info, size_t *countp) +{ + assert(info != NULL); + if (info->type != ARGTYPE_STRUCT + && info->type != ARGTYPE_ARRAY) + return NULL; + + size_t n = type_aggregate_size(info); + if (n == (size_t)-1) + return NULL; + + struct arg_type_info *ret = NULL; + *countp = 0; + + while (n-- > 0) { + struct arg_type_info *emt = type_element(info, n); + + size_t emt_count = 1; + if (emt->type == ARGTYPE_STRUCT || emt->type == ARGTYPE_ARRAY) + emt = type_get_hfa_type(emt, &emt_count); + if (emt == NULL) + return NULL; + if (ret == NULL) { + if (emt->type != ARGTYPE_FLOAT + && emt->type != ARGTYPE_DOUBLE) + return NULL; + ret = emt; + } + if (emt->type != ret->type) + return NULL; + *countp += emt_count; + } + return ret; +} Index: ltrace/type.h =================================================================== --- ltrace.orig/type.h 2014-03-12 16:13:44.075726000 -0600 +++ ltrace/type.h 2014-03-13 09:32:30.504762084 -0600 @@ -1,6 +1,6 @@ /* * This file is part of ltrace. - * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc. * Copyright (C) 1997-2009 Juan Cespedes * * This program is free software; you can redistribute it and/or @@ -142,4 +142,13 @@ * type. */ struct arg_type_info *type_get_fp_equivalent(struct arg_type_info *info); +/* If INFO is homogeneous floating-point aggregate, return the + * corresponding floating point type, and set *COUNTP to number of + * fields of the structure. Otherwise return NULL. INFO is a HFA if + * it's an aggregate whose each field is either a HFA, or a + * floating-point type. */ +struct arg_type_info *type_get_hfa_type(struct arg_type_info *info, + size_t *countp); + + #endif /* TYPE_H */