From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30251 invoked by alias); 7 Jan 2009 23:23:43 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 30209 invoked by uid 9674); 7 Jan 2009 23:23:42 -0000 Date: Wed, 07 Jan 2009 23:23:00 -0000 Message-ID: <20090107232342.30192.qmail@sourceware.org> From: jkratoch@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-jankratochvil-vla: Fix DW_AT_data_location&co. for access through typedefs. X-Git-Refname: refs/heads/archer-jankratochvil-vla X-Git-Reftype: branch X-Git-Oldrev: 10215662672716867cba70dac7d5882c1542c4cc X-Git-Newrev: 497dece94a7d853e2e0a09c265f5b3a425d309d2 X-SW-Source: 2009-q1/txt/msg00013.txt.bz2 List-Id: The branch, archer-jankratochvil-vla has been updated via 497dece94a7d853e2e0a09c265f5b3a425d309d2 (commit) from 10215662672716867cba70dac7d5882c1542c4cc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 497dece94a7d853e2e0a09c265f5b3a425d309d2 Author: Jan Kratochvil Date: Thu Jan 8 00:18:12 2009 +0100 Fix DW_AT_data_location&co. for access through typedefs. Fix copy_type_recursive_1 for DATA_LOCATION/DATA_ALLOCATED/DATA_ASSOCIATED. ----------------------------------------------------------------------- Summary of changes: gdb/dwarf2read.c | 11 ++++- gdb/eval.c | 6 +- gdb/gdbtypes.c | 38 ++++++++++++++++- gdb/gdbtypes.h | 53 +++++++++++++++++++---- gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S | 8 ++-- gdb/valops.c | 27 +++++++++--- 6 files changed, 118 insertions(+), 25 deletions(-) First 500 lines of diff: diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 750498f..6b226be 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -4494,9 +4494,12 @@ create_single_array_dimension (struct type *type, struct type *range_type, /* These generic type attributes need to be fetched by evaluate_subexp_standard 's call of value_subscripted_rvalue only for the innermost array type. */ - fetch_die_type_attrs (die, type, cu); + /* These generic type attributes are checked for allocated/associated + validity while accessing FIELD_LOC_KIND_DWARF_BLOCK. */ + fetch_die_type_attrs (die, range_type, cu); + return type; } @@ -10602,15 +10605,19 @@ fetch_die_type_attrs (struct die_info *die, struct type *type, attr = dwarf2_attr (die, DW_AT_data_location, cu); if (attr_form_is_block (attr)) - TYPE_DATA_LOCATION (type) = dwarf2_attr_to_locexpr_baton (attr, cu); + TYPE_DATA_LOCATION_DWARF_BLOCK (type) = dwarf2_attr_to_locexpr_baton (attr, + cu); + gdb_assert (!TYPE_DATA_LOCATION_IS_ADDR (type)); attr = dwarf2_attr (die, DW_AT_allocated, cu); if (attr_form_is_block (attr)) TYPE_ALLOCATED (type) = dwarf2_attr_to_locexpr_baton (attr, cu); + gdb_assert (!TYPE_NOT_ALLOCATED (type)); attr = dwarf2_attr (die, DW_AT_associated, cu); if (attr_form_is_block (attr)) TYPE_ASSOCIATED (type) = dwarf2_attr_to_locexpr_baton (attr, cu); + gdb_assert (!TYPE_NOT_ASSOCIATED (type)); } /* Set the type associated with DIE to TYPE. Save it in CU's hash diff --git a/gdb/eval.c b/gdb/eval.c index d7851cd..e1f6856 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -2650,13 +2650,13 @@ evaluate_subexp_with_coercion (struct expression *exp, { case OP_VAR_VALUE: var = exp->elts[pc + 2].symbol; + /* locate_var_value will call object_address_set for check_typedef. */ + val = locate_var_value (var, + block_innermost_frame (exp->elts[pc + 1].block)); if (TYPE_CODE (check_typedef (SYMBOL_TYPE (var))) == TYPE_CODE_ARRAY && CAST_IS_CONVERSION) { (*pos) += 4; - val = - locate_var_value - (var, block_innermost_frame (exp->elts[pc + 1].block)); return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (check_typedef (SYMBOL_TYPE (var)))), val); } diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index ebd51b3..727a351 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -3152,6 +3152,38 @@ copy_type_recursive_1 (struct objfile *objfile, TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type); TYPE_LENGTH (new_type) = TYPE_LENGTH (type); + if (TYPE_ALLOCATED (new_type)) + { + gdb_assert (!TYPE_NOT_ALLOCATED (new_type)); + + if (!dwarf_locexpr_baton_eval (TYPE_ALLOCATED (new_type))) + TYPE_NOT_ALLOCATED (new_type) = 1; + TYPE_ALLOCATED (new_type) = NULL; + } + + if (TYPE_ASSOCIATED (new_type)) + { + gdb_assert (!TYPE_NOT_ASSOCIATED (new_type)); + + if (!dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (new_type))) + TYPE_NOT_ASSOCIATED (new_type) = 1; + TYPE_ASSOCIATED (new_type) = NULL; + } + + if (!TYPE_DATA_LOCATION_IS_ADDR (new_type) + && TYPE_DATA_LOCATION_DWARF_BLOCK (new_type)) + { + if (TYPE_NOT_ALLOCATED (new_type) + || TYPE_NOT_ASSOCIATED (new_type)) + TYPE_DATA_LOCATION_DWARF_BLOCK (new_type) = NULL; + else + { + TYPE_DATA_LOCATION_IS_ADDR (new_type) = 1; + TYPE_DATA_LOCATION_ADDR (new_type) = dwarf_locexpr_baton_eval + (TYPE_DATA_LOCATION_DWARF_BLOCK (new_type)); + } + } + /* Copy the fields. */ if (TYPE_NFIELDS (type)) { @@ -3190,7 +3222,11 @@ copy_type_recursive_1 (struct objfile *objfile, case FIELD_LOC_KIND_DWARF_BLOCK: /* `struct dwarf2_locexpr_baton' is too bound to its objfile so it is expected to be made constant by CHECK_TYPEDEF. */ - SET_FIELD_BITPOS (TYPE_FIELD (new_type, i), + if (TYPE_NOT_ALLOCATED (new_type) + || TYPE_NOT_ASSOCIATED (new_type)) + SET_FIELD_DWARF_BLOCK (TYPE_FIELD (new_type, i), NULL); + else + SET_FIELD_BITPOS (TYPE_FIELD (new_type, i), dwarf_locexpr_baton_eval (TYPE_FIELD_DWARF_BLOCK (type, i))); break; default: diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 69b70ef..a33fbb8 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -271,6 +271,36 @@ enum type_instance_flag_value #define TYPE_NOTTEXT(t) (TYPE_MAIN_TYPE (t)->flag_nottext) +/* Is HIGH_BOUND a low-bound relative count (1) or the high bound itself (0)? */ + +#define TYPE_RANGE_HIGH_BOUND_IS_COUNT(range_type) \ + (TYPE_MAIN_TYPE (range_type)->flag_range_high_bound_is_count) + +/* Not allocated. TYPE_ALLOCATED(t) must be NULL in such case. If this flag + is unset and TYPE_ALLOCATED(t) is NULL then the type is allocated. If this + flag is unset and TYPE_ALLOCATED(t) is not NULL then its DWARF block + determines the actual allocation state. */ + +#define TYPE_NOT_ALLOCATED(t) (TYPE_MAIN_TYPE (t)->flag_not_allocated) + +/* Not associated. TYPE_ASSOCIATED(t) must be NULL in such case. If this flag + is unset and TYPE_ASSOCIATED(t) is NULL then the type is associated. If + this flag is unset and TYPE_ASSOCIATED(t) is not NULL then its DWARF block + determines the actual association state. */ + +#define TYPE_NOT_ASSOCIATED(t) (TYPE_MAIN_TYPE (t)->flag_not_associated) + +/* Address of the actual data as for DW_AT_data_location. Its dwarf block must + not be evaluated unless both TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are + false. If TYPE_DATA_LOCATION_IS_ADDR set then TYPE_DATA_LOCATION_ADDR value + is the actual data address value. If unset and + TYPE_DATA_LOCATION_DWARF_BLOCK is NULL then the value is the normal + VALUE_ADDRESS copy. If unset and TYPE_DATA_LOCATION_DWARF_BLOCK is not NULL + then its DWARF block determines the actual data address. */ + +#define TYPE_DATA_LOCATION_IS_ADDR(t) \ + (TYPE_MAIN_TYPE (t)->flag_data_location_is_addr) + /* Constant type. If this is set, the corresponding type has a * const modifier. */ @@ -359,6 +389,9 @@ struct main_type unsigned int flag_fixed_instance : 1; unsigned int flag_dynamic : 1; unsigned int flag_range_high_bound_is_count : 1; + unsigned int flag_not_allocated : 1; + unsigned int flag_not_associated : 1; + unsigned int flag_data_location_is_addr : 1; /* Number of fields described for this type. This field appears at this location because it packs nicely here. */ @@ -421,13 +454,18 @@ struct main_type struct type *target_type; - /* For DW_AT_data_location. FIXME: Support also its constant form. */ - struct dwarf2_locexpr_baton *data_location; + /* For DW_AT_data_location. */ + union + { + struct dwarf2_locexpr_baton *dwarf_block; + CORE_ADDR addr; + } + data_location; - /* For DW_AT_allocated. FIXME: Support also its constant form. */ + /* For DW_AT_allocated. */ struct dwarf2_locexpr_baton *allocated; - /* For DW_AT_associated. FIXME: Support also its constant form. */ + /* For DW_AT_associated. */ struct dwarf2_locexpr_baton *associated; /* For structure and union types, a description of each field. @@ -823,7 +861,8 @@ extern void allocate_cplus_struct_type (struct type *); #define TYPE_NFIELDS(thistype) TYPE_MAIN_TYPE(thistype)->nfields #define TYPE_FIELDS(thistype) TYPE_MAIN_TYPE(thistype)->fields #define TYPE_TEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->template_args -#define TYPE_DATA_LOCATION(thistype) TYPE_MAIN_TYPE (thistype)->data_location +#define TYPE_DATA_LOCATION_DWARF_BLOCK(thistype) TYPE_MAIN_TYPE (thistype)->data_location.dwarf_block +#define TYPE_DATA_LOCATION_ADDR(thistype) TYPE_MAIN_TYPE (thistype)->data_location.addr #define TYPE_ALLOCATED(thistype) TYPE_MAIN_TYPE (thistype)->allocated #define TYPE_ASSOCIATED(thistype) TYPE_MAIN_TYPE (thistype)->associated @@ -840,10 +879,6 @@ extern void allocate_cplus_struct_type (struct type *); #define TYPE_ARRAY_BOUND_IS_DWARF_BLOCK(array_type, fieldno) \ TYPE_RANGE_BOUND_IS_DWARF_BLOCK (TYPE_INDEX_TYPE (array_type), fieldno) -/* Is HIGH_BOUND a low-bound relative count (1) or the high bound itself (0)? */ -#define TYPE_RANGE_HIGH_BOUND_IS_COUNT(range_type) \ - (TYPE_MAIN_TYPE (range_type)->flag_range_high_bound_is_count) - /* Unbound arrays, such as GCC array[]; at end of struct. */ #define TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED(rangetype) \ TYPE_FIELD_ARTIFICIAL((rangetype),0) diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S index 630422a..66f7a39 100644 --- a/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S @@ -1,4 +1,4 @@ - .file "vla-typedef.c" + .file "x86_64-vla-typedef.c" .section .debug_abbrev,"",@progbits .Ldebug_abbrev0: .section .debug_info,"",@progbits @@ -11,7 +11,7 @@ .type foo, @function foo: .LFB2: - .file 1 "vla-typedef.c" + .file 1 "x86_64-vla-typedef.c" .loc 1 22 0 pushq %rbp .LCFI0: @@ -442,13 +442,13 @@ break_here: .LASF5: .string "size" .LASF3: - .string "vla-typedef.c" + .string "x86_64-vla-typedef.c" .LASF6: .string "array_t" .LASF1: .string "char" .LASF4: - .string "/home/jkratoch/redhat/archer-jankratochvil-vla/gdb/testsuite/gdb.base" + .string "gdb.arch" .LASF2: .string "GNU C 4.3.2 20081105 (Red Hat 4.3.2-7)" .ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)" diff --git a/gdb/valops.c b/gdb/valops.c index 7b5bc89..ddbf10e 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -572,13 +572,20 @@ value_one (struct type *type, enum lval_type lv) const char * object_address_data_not_valid (struct type *type) { + /* Attributes are present only at the target type of a typedef. Make the + call conditional as it would otherwise loop through type_length_get. */ + if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) + CHECK_TYPEDEF (type); + /* DW_AT_associated has a preference over DW_AT_allocated. */ - if (TYPE_ASSOCIATED (type) != NULL - && 0 == dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (type))) + if (TYPE_NOT_ASSOCIATED (type) + || (TYPE_ASSOCIATED (type) != NULL + && 0 == dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (type)))) return N_("object is not associated"); - if (TYPE_ALLOCATED (type) != NULL - && 0 == dwarf_locexpr_baton_eval (TYPE_ALLOCATED (type))) + if (TYPE_NOT_ALLOCATED (type) + || (TYPE_ALLOCATED (type) != NULL + && 0 == dwarf_locexpr_baton_eval (TYPE_ALLOCATED (type)))) return N_("object is not allocated"); return NULL; @@ -597,6 +604,11 @@ object_address_get_data (struct type *type, CORE_ADDR *address_return) gdb_assert (address_return != NULL); object_address_set (*address_return); + + /* TYPE_DATA_LOCATION_DWARF_BLOCK / TYPE_DATA_LOCATION_ADDR are present only + at the target type of a typedef. */ + CHECK_TYPEDEF (type); + if (object_address_data_not_valid (type) != NULL) { /* Do not try to evaluate DW_AT_data_location as it may even crash @@ -604,8 +616,11 @@ object_address_get_data (struct type *type, CORE_ADDR *address_return) return 0; } - if (TYPE_DATA_LOCATION (type) != NULL) - *address_return = dwarf_locexpr_baton_eval (TYPE_DATA_LOCATION (type)); + if (TYPE_DATA_LOCATION_IS_ADDR (type)) + *address_return = TYPE_DATA_LOCATION_ADDR (type); + else if (TYPE_DATA_LOCATION_DWARF_BLOCK (type) != NULL) + *address_return + = dwarf_locexpr_baton_eval (TYPE_DATA_LOCATION_DWARF_BLOCK (type)); return 1; } hooks/post-receive -- Repository for Project Archer.