diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 19902a9..4c56107 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -107,8 +107,8 @@ struct dwarf_expr_baton
{
struct frame_info *frame;
struct objfile *objfile;
- /* From DW_TAG_variable's DW_AT_location (not DW_TAG_type's
- DW_AT_data_location) for DW_OP_push_object_address. */
+
+ /* Address to set by object_address_set. */
CORE_ADDR object_address;
};
@@ -217,9 +217,12 @@ dwarf_expr_object_address (void *baton)
return debaton->object_address;
}
-/* Address of the variable we are currently referring to. It is set from
- DW_TAG_variable's DW_AT_location (not DW_TAG_type's DW_AT_data_location) for
- DW_OP_push_object_address. */
+/* Address of the variable we are currently referring to. It is initially set
+ from DW_TAG_variable's DW_AT_location. It is used for
+ DW_OP_push_object_address. It is never the address derived by
+ DW_AT_data_location (nor completely unrelated DW_AT_data_member_location).
+ Expresses the address of the closes DW_AT_type, such as an element of an
+ array, not the base address of an array. */
static CORE_ADDR object_address;
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index e559d86..8ce4884 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -4655,6 +4655,8 @@ create_single_array_dimension (struct type *type, struct type *range_type,
validity while accessing FIELD_LOC_KIND_DWARF_BLOCK. */
fetch_die_type_attrs (die, range_type, cu);
+ finalize_type (type);
+
return type;
}
@@ -5095,6 +5097,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
struct type *type, *range_type, *index_type, *char_type;
struct attribute *attr;
int length;
+ char *name;
index_type = builtin_type_int32;
/* RANGE_TYPE is allocated from OBJFILE, not as a permanent type. */
@@ -5185,6 +5188,10 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
type = create_string_type (NULL, range_type);
+ name = dwarf2_name (die, cu);
+ if (name)
+ TYPE_NAME (type) = name;
+
return set_die_type (die, type, cu);
}
diff --git a/gdb/eval.c b/gdb/eval.c
index 83ae2cd..6ae3cfa 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -2696,6 +2696,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
int pc;
struct type *type;
struct value *val;
+ struct cleanup *back_to;
pc = (*pos);
op = exp->elts[pc].opcode;
@@ -2709,7 +2710,14 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
case UNOP_IND:
(*pos)++;
val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+
+ back_to = make_cleanup (null_cleanup, 0);
+ object_address_set (value_raw_address (val));
+
type = check_typedef (value_type (val));
+
+ do_cleanups (back_to);
+
if (TYPE_CODE (type) != TYPE_CODE_PTR
&& TYPE_CODE (type) != TYPE_CODE_REF
&& TYPE_CODE (type) != TYPE_CODE_ARRAY)
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 44456f8..35f875e 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -146,6 +146,7 @@ f77_create_arrayprint_offset_tbl (struct type *type, struct ui_file *stream)
TYPE_ARRAY_BYTE_STRIDE_VALUE (tmp_type);
tmp_type = TYPE_TARGET_TYPE (tmp_type);
+ CHECK_TYPEDEF (tmp_type);
ndimen++;
}
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index ec32200..f84a20b 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -875,13 +875,18 @@ create_array_type (struct type *result_type,
In such cases, the array length should be zero. TYPE_TARGET_STUB needs to
be checked as it may have dependencies on DWARF blocks depending on
runtime information not available during the CREATE_ARRAY_TYPE time. */
- if (high_bound < low_bound || TYPE_TARGET_STUB (element_type))
+ if (high_bound < low_bound)
+ TYPE_LENGTH (result_type) = 0;
+ else if (TYPE_BYTE_STRIDE (range_type) > 0)
+ TYPE_LENGTH (result_type) = TYPE_BYTE_STRIDE (range_type)
+ * (high_bound - low_bound + 1);
+ else if (TYPE_TARGET_STUB (element_type))
TYPE_LENGTH (result_type) = 0;
else
{
CHECK_TYPEDEF (element_type);
- TYPE_LENGTH (result_type) =
- TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
+ TYPE_LENGTH (result_type) = TYPE_LENGTH (element_type)
+ * (high_bound - low_bound + 1);
}
if (TYPE_LENGTH (result_type) == 0)
@@ -1638,12 +1643,7 @@ check_typedef (struct type *type)
constant values expected by the callers of this function. */
if (TYPE_DYNAMIC (type))
{
- htab_t copied_types;
- struct type *type_old = type;
-
- copied_types = create_copied_types_hash (NULL);
- type = copy_type_recursive (type, copied_types);
- htab_delete (copied_types);
+ type = copy_type_recursive (type, NULL);
gdb_assert (TYPE_DYNAMIC (type) == 0);
}
@@ -3104,10 +3104,15 @@ copy_type_recursive_1 (struct objfile *objfile,
if it did, the type might disappear unexpectedly. */
gdb_assert (TYPE_OBJFILE (type) == objfile);
- pair.old = type;
- slot = htab_find_slot (copied_types, &pair, INSERT);
- if (*slot != NULL)
- return ((struct type_pair *) *slot)->new;
+ if (copied_types)
+ {
+ pair.old = type;
+ slot = htab_find_slot (copied_types, &pair, INSERT);
+ if (*slot != NULL)
+ return ((struct type_pair *) *slot)->new;
+ }
+ else
+ slot = NULL;
new_type = alloc_type (NULL);
@@ -3115,10 +3120,13 @@ copy_type_recursive_1 (struct objfile *objfile,
we encounter this type again during a recursive call below. Memory could
be allocated from OBJFILE in the case we will be removing OBJFILE, this
optimization is missed and xfree is called for it from COPIED_TYPES. */
- stored = xmalloc (sizeof (*stored));
- stored->old = type;
- stored->new = new_type;
- *slot = stored;
+ if (slot)
+ {
+ stored = xmalloc (sizeof (*stored));
+ stored->old = type;
+ stored->new = new_type;
+ *slot = stored;
+ }
/* Copy the common fields of types. For the main type, we simply
copy the entire thing and then update specific fields as needed. */
@@ -3191,10 +3199,15 @@ copy_type_recursive_1 (struct objfile *objfile,
TYPE_FIELD_ARTIFICIAL (new_type, i) =
TYPE_FIELD_ARTIFICIAL (type, i);
TYPE_FIELD_BITSIZE (new_type, i) = TYPE_FIELD_BITSIZE (type, i);
- if (TYPE_FIELD_TYPE (type, i))
- TYPE_FIELD_TYPE (new_type, i)
- = copy_type_recursive_1 (objfile, TYPE_FIELD_TYPE (type, i),
- copied_types);
+ if (1 || copied_types)
+ {
+ if (TYPE_FIELD_TYPE (type, i))
+ TYPE_FIELD_TYPE (new_type, i)
+ = copy_type_recursive_1 (objfile, TYPE_FIELD_TYPE (type, i),
+ copied_types);
+ }
+ else
+ TYPE_FIELD_TYPE (new_type, i) = TYPE_FIELD_TYPE (type, i);
if (TYPE_FIELD_NAME (type, i))
TYPE_FIELD_NAME (new_type, i) =
xstrdup (TYPE_FIELD_NAME (type, i));
@@ -3216,7 +3229,10 @@ 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. */
- if (TYPE_NOT_ALLOCATED (new_type)
+ if (0 && copied_types)
+ SET_FIELD_DWARF_BLOCK (TYPE_FIELD (new_type, i),
+ TYPE_FIELD_DWARF_BLOCK (type, i));
+ else if (TYPE_NOT_ALLOCATED (new_type)
|| TYPE_NOT_ASSOCIATED (new_type))
SET_FIELD_DWARF_BLOCK (TYPE_FIELD (new_type, i), NULL);
else
@@ -3231,30 +3247,42 @@ copy_type_recursive_1 (struct objfile *objfile,
}
}
- /* Convert TYPE_RANGE_HIGH_BOUND_IS_COUNT into a regular bound. */
- if (TYPE_CODE (type) == TYPE_CODE_RANGE
- && TYPE_RANGE_HIGH_BOUND_IS_COUNT (type))
+ if (copied_types)
{
- TYPE_RANGE_HIGH_BOUND_IS_COUNT (new_type) = 0;
- TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (type)
- + TYPE_HIGH_BOUND (type) - 1;
+ /* Copy pointers to other types. */
+ if (TYPE_TARGET_TYPE (type))
+ TYPE_TARGET_TYPE (new_type) =
+ copy_type_recursive_1 (objfile,
+ TYPE_TARGET_TYPE (type),
+ copied_types);
+ if (TYPE_VPTR_BASETYPE (type))
+ TYPE_VPTR_BASETYPE (new_type) =
+ copy_type_recursive_1 (objfile,
+ TYPE_VPTR_BASETYPE (type),
+ copied_types);
+ }
+ else
+ {
+ TYPE_TARGET_TYPE (new_type) = TYPE_TARGET_TYPE (type);
+ TYPE_VPTR_BASETYPE (new_type) = TYPE_VPTR_BASETYPE (type);
}
- /* Both FIELD_LOC_KIND_DWARF_BLOCK and TYPE_RANGE_HIGH_BOUND_IS_COUNT were
- possibly converted. */
- TYPE_DYNAMIC (new_type) = 0;
+ if (copied_types == NULL)
+ {
+ /* Convert TYPE_RANGE_HIGH_BOUND_IS_COUNT into a regular bound. */
+ if (TYPE_CODE (type) == TYPE_CODE_RANGE
+ && TYPE_RANGE_HIGH_BOUND_IS_COUNT (type))
+ {
+ TYPE_RANGE_HIGH_BOUND_IS_COUNT (new_type) = 0;
+ TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (type)
+ + TYPE_HIGH_BOUND (type) - 1;
+ }
+
+ /* Both FIELD_LOC_KIND_DWARF_BLOCK and TYPE_RANGE_HIGH_BOUND_IS_COUNT were
+ possibly converted. */
+ TYPE_DYNAMIC (new_type) = 0;
+ }
- /* Copy pointers to other types. */
- if (TYPE_TARGET_TYPE (type))
- TYPE_TARGET_TYPE (new_type) =
- copy_type_recursive_1 (objfile,
- TYPE_TARGET_TYPE (type),
- copied_types);
- if (TYPE_VPTR_BASETYPE (type))
- TYPE_VPTR_BASETYPE (new_type) =
- copy_type_recursive_1 (objfile,
- TYPE_VPTR_BASETYPE (type),
- copied_types);
/* Maybe copy the type_specific bits.
NOTE drow/2005-12-09: We do not copy the C++-specific bits like
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index aca3f07..362d31c 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -945,10 +945,11 @@ extern void allocate_cplus_struct_type (struct type *);
#define FIELD_TYPE(thisfld) ((thisfld).type)
#define FIELD_NAME(thisfld) ((thisfld).name)
#define FIELD_LOC_KIND(thisfld) ((thisfld).loc_kind)
-#define FIELD_BITPOS(thisfld) ((thisfld).loc.bitpos)
-#define FIELD_STATIC_PHYSNAME(thisfld) ((thisfld).loc.physname)
-#define FIELD_STATIC_PHYSADDR(thisfld) ((thisfld).loc.physaddr)
-#define FIELD_DWARF_BLOCK(thisfld) ((thisfld).loc.dwarf_block)
+#include "gdb_assert.h"
+#define FIELD_BITPOS(thisfld) (*({ gdb_assert (FIELD_LOC_KIND (thisfld) == FIELD_LOC_KIND_BITPOS); &(thisfld).loc.bitpos; }))
+#define FIELD_STATIC_PHYSNAME(thisfld) (*({ gdb_assert (FIELD_LOC_KIND (thisfld) == FIELD_LOC_KIND_PHYSNAME); &(thisfld).loc.physname; }))
+#define FIELD_STATIC_PHYSADDR(thisfld) (*({ gdb_assert (FIELD_LOC_KIND (thisfld) == FIELD_LOC_KIND_PHYSADDR); &(thisfld).loc.physaddr; }))
+#define FIELD_DWARF_BLOCK(thisfld) (*({ gdb_assert (FIELD_LOC_KIND (thisfld) == FIELD_LOC_KIND_DWARF_BLOCK); &(thisfld).loc.dwarf_block; }))
#define SET_FIELD_BITPOS(thisfld, bitpos) \
(FIELD_LOC_KIND (thisfld) = FIELD_LOC_KIND_BITPOS, \
FIELD_BITPOS (thisfld) = (bitpos))
diff --git a/gdb/p-typeprint.c b/gdb/p-typeprint.c
index 5085fb4..8dd22c8 100644
--- a/gdb/p-typeprint.c
+++ b/gdb/p-typeprint.c
@@ -265,8 +265,7 @@ pascal_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
if (passed_a_ptr)
fprintf_filtered (stream, "(");
fprintf_filtered (stream, "array ");
- if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
- && !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
+ if (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
fprintf_filtered (stream, "[%d..%d] ",
TYPE_ARRAY_LOWER_BOUND_VALUE (type),
TYPE_ARRAY_UPPER_BOUND_VALUE (type)
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index 30d0650..174b74d 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -71,6 +71,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
case TYPE_CODE_ARRAY:
if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
{
+ case TYPE_CODE_STRING:
elttype = check_typedef (TYPE_TARGET_TYPE (type));
eltlen = TYPE_LENGTH (elttype);
len = TYPE_LENGTH (type) / eltlen;
diff --git a/gdb/testsuite/gdb.arch/x86_64-pascal-string-array-foo.S b/gdb/testsuite/gdb.arch/x86_64-pascal-string-array-foo.S
new file mode 100644
index 0000000..ef4ba2a
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/x86_64-pascal-string-array-foo.S
@@ -0,0 +1,447 @@
+ .file "x86_64-pascal-string-array.c"
+ .section .debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+ .section .debug_info,"",@progbits
+.Ldebug_info0:
+ .section .debug_line,"",@progbits
+.Ldebug_line0:
+ .text
+.Ltext0:
+ .section .rodata
+.LC0:
+ .string "alX"
+ .text
+.globl foo
+ .type foo, @function
+foo:
+.LFB0:
+ .file 1 "x86_64-pascal-string-array.c"
+ # x86_64-pascal-string-array.c:22
+ .loc 1 22 0
+ .cfi_startproc
+ # basic block 2
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ movq %rsp, %rbp
+ .cfi_offset 6, -16
+ .cfi_def_cfa_register 6
+ pushq %rbx
+ movl %edi, -116(%rbp)
+ # x86_64-pascal-string-array.c:23
+ .loc 1 23 0
+ movw $22636, -32(%rbp)
+ movb $0, -30(%rbp)
+ # x86_64-pascal-string-array.c:24
+ .loc 1 24 0
+ movl .LC0(%rip), %eax
+ movl %eax, -48(%rbp)
+ # x86_64-pascal-string-array.c:25
+ .loc 1 25 0
+ movl $1483498338, -64(%rbp)
+ movb $0, -60(%rbp)
+ # x86_64-pascal-string-array.c:33
+ .loc 1 33 0
+ movl -116(%rbp), %eax
+ movslq %eax,%rcx
+ # x86_64-pascal-string-array.c:32
+ .loc 1 32 0
+ movl -116(%rbp), %eax
+ addl $1, %eax
+ # x86_64-pascal-string-array.c:33
+ .loc 1 33 0
+ movslq %eax,%rdx
+ movl -116(%rbp), %eax
+ addl $2, %eax
+ cltq
+ leaq -32(%rbp), %rbx
+ .cfi_offset 3, -24
+ movq %rbx, -112(%rbp)
+ movq %rcx, -104(%rbp)
+ leaq -48(%rbp), %rcx
+ movq %rcx, -96(%rbp)
+ movq %rdx, -88(%rbp)
+ leaq -64(%rbp), %rdx
+ movq %rdx, -80(%rbp)
+ movq %rax, -72(%rbp)
+ # x86_64-pascal-string-array.c:36
+ .loc 1 36 0
+ popq %rbx
+ leave
+ ret
+ .cfi_endproc
+.LFE0:
+ .size foo, .-foo
+.Letext0:
+ .section .debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+ .quad .LFB0-.Ltext0 # Location list begin address (*.LLST0)
+ .quad .LFE0-.Ltext0 # Location list end address (*.LLST0)
+ .value 0x2 # Location expression size
+ .byte 0x76 # DW_OP_breg6
+ .sleb128 16
+ .quad 0x0 # Location list terminator begin (*.LLST0)
+ .quad 0x0 # Location list terminator end (*.LLST0)
+ .section .debug_info
+.Lo0:
+ .long .Ldebuginfo_end-1f # Length of Compilation Unit Info
+1:
+ .value 0x2 # DWARF version number
+ .long .Ldebug_abbrev0 # Offset Into Abbrev. Section
+ .byte 0x8 # Pointer Size (in bytes)
+ .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit)
+ .long .LASF8 # DW_AT_producer: "GNU C 4.4.0 20090506 (Red Hat 4.4.0-4)"
+ .byte 0x9 # DW_AT_language = DW_LANG_Pascal83
+ .long .LASF9 # DW_AT_name: "x86_64-pascal-string-array.c"
+ .long .LASF10 # DW_AT_comp_dir: ""
+ .quad .Ltext0 # DW_AT_low_pc
+ .quad .Letext0 # DW_AT_high_pc
+ .long .Ldebug_line0 # DW_AT_stmt_list
+ .uleb128 0x2 # (DIE (0x2d) DW_TAG_subprogram)
+ .byte 0x1 # DW_AT_external
+ .ascii "foo\0" # DW_AT_name
+ .byte 0x1 # DW_AT_decl_file (x86_64-pascal-string-array.c)
+ .byte 0x15 # DW_AT_decl_line
+ .byte 0x1 # DW_AT_prototyped
+ .quad .LFB0 # DW_AT_low_pc
+ .quad .LFE0 # DW_AT_high_pc
+ .long .LLST0 # DW_AT_frame_base
+ .uleb128 0x3 # (DIE (0x4e) DW_TAG_formal_parameter)
+ .long .LASF11 # DW_AT_name: "show_l"
+ .byte 0x1 # DW_AT_decl_file (x86_64-pascal-string-array.c)
+ .byte 0x15 # DW_AT_decl_line
+ .long .Ldie0xc1-.Lo0 # DW_AT_type
+ .byte 0x3 # DW_AT_location
+ .byte 0x91 # DW_OP_fbreg
+ .sleb128 -132
+ .uleb128 0x4 # (DIE (0x5d) DW_TAG_variable)
+ .long .LASF0 # DW_AT_name: "string0"
+ .byte 0x1 # DW_AT_decl_file (x86_64-pascal-string-array.c)
+ .byte 0x17 # DW_AT_decl_line
+ .long .Ldie0xe2-.Lo0 # DW_AT_type
+ .byte 0x2 # DW_AT_location
+ .byte 0x91 # DW_OP_fbreg
+ .sleb128 -48
+ .uleb128 0x4 # (DIE (0x6b) DW_TAG_variable)
+ .long .LASF1 # DW_AT_name: "string1"
+ .byte 0x1 # DW_AT_decl_file (x86_64-pascal-string-array.c)
+ .byte 0x18 # DW_AT_decl_line
+ .long .Ldie0xf7-.Lo0 # DW_AT_type
+ .byte 0x2 # DW_AT_location
+ .byte 0x91 # DW_OP_fbreg
+ .sleb128 -64
+ .uleb128 0x4 # (DIE (0x79) DW_TAG_variable)
+ .long .LASF2 # DW_AT_name: "string2"
+ .byte 0x1 # DW_AT_decl_file (x86_64-pascal-string-array.c)
+ .byte 0x19 # DW_AT_decl_line
+ .long .Ldie0x10c-.Lo0 # DW_AT_type
+ .byte 0x3 # DW_AT_location
+ .byte 0x91 # DW_OP_fbreg
+ .sleb128 -80
+.Ldie0x88:
+ .uleb128 0x5 # (DIE (0x88) DW_TAG_string_type)
+ .long .LASF12 # DW_AT_name: "string_t"
+ .byte 0x8 # DW_AT_byte_size = sizeof (string_t.length)
+ .byte 2f-1f # DW_AT_string_length
+1: .byte 0x97 # DW_OP_push_object_address
+ .byte 0x23 # DW_OP_plus_uconst
+ .uleb128 8 # offsetof (struct string_t, length)
+2:
+ .byte 2f-1f # DW_AT_data_location
+1: .byte 0x97 # DW_OP_push_object_address
+ .byte 0x06 # DW_OP_deref
+2:
+ .byte 0x1 # DW_AT_decl_file (x86_64-pascal-string-array.c)
+ .byte 0x1b # DW_AT_decl_line
+ .uleb128 0x4 # (DIE (0xb1) DW_TAG_variable)
+ .long .LASF5 # DW_AT_name: "array"
+ .byte 0x1 # DW_AT_decl_file (x86_64-pascal-string-array.c)
+ .byte 0x1f # DW_AT_decl_line
+ .long .Ldie0x123-.Lo0 # DW_AT_type
+ .byte 0x3 # DW_AT_location
+ .byte 0x91 # DW_OP_fbreg
+ .sleb128 -128
+ .byte 0x0 # end of children of DIE 0x2d
+.Ldie0xc1:
+ .uleb128 0x7 # (DIE (0xc1) DW_TAG_base_type)
+ .byte 0x4 # DW_AT_byte_size
+ .byte 0x5 # DW_AT_encoding
+ .ascii "int\0" # DW_AT_name
+.Ldie0xc8:
+ .uleb128 0x8 # (DIE (0xc8) DW_TAG_array_type)
+ .long .Ldie0xdb-.Lo0 # DW_AT_type
+ .uleb128 0x9 # (DIE (0xd1) DW_TAG_subrange_type)
+ .long .Ldie0xd8-.Lo0 # DW_AT_type
+ .byte 0x2 # DW_AT_upper_bound
+ .byte 0x0 # end of children of DIE 0xc8
+.Ldie0xd8:
+ .uleb128 0xa # (DIE (0xd8) DW_TAG_base_type)
+ .byte 0x8 # DW_AT_byte_size
+ .byte 0x7 # DW_AT_encoding
+.Ldie0xdb:
+ .uleb128 0xb # (DIE (0xdb) DW_TAG_base_type)
+ .byte 0x1 # DW_AT_byte_size
+ .byte 0x6 # DW_AT_encoding
+ .long .LASF6 # DW_AT_name: "char"
+.Ldie0xe2:
+ .uleb128 0xc # (DIE (0xe2) DW_TAG_const_type)
+ .long .Ldie0xc8-.Lo0 # DW_AT_type
+.Ldie0xe7:
+ .uleb128 0x8 # (DIE (0xe7) DW_TAG_array_type)
+ .long .Ldie0xdb-.Lo0 # DW_AT_type
+ .uleb128 0x9 # (DIE (0xf0) DW_TAG_subrange_type)
+ .long .Ldie0xd8-.Lo0 # DW_AT_type
+ .byte 0x3 # DW_AT_upper_bound
+ .byte 0x0 # end of children of DIE 0xe7
+.Ldie0xf7:
+ .uleb128 0xc # (DIE (0xf7) DW_TAG_const_type)
+ .long .Ldie0xe7-.Lo0 # DW_AT_type
+.Ldie0xfc:
+ .uleb128 0x8 # (DIE (0xfc) DW_TAG_array_type)
+ .long .Ldie0xdb-.Lo0 # DW_AT_type
+ .uleb128 0x9 # (DIE (0x105) DW_TAG_subrange_type)
+ .long .Ldie0xd8-.Lo0 # DW_AT_type
+ .byte 0x4 # DW_AT_upper_bound
+ .byte 0x0 # end of children of DIE 0xfc
+.Ldie0x10c:
+ .uleb128 0xc # (DIE (0x10c) DW_TAG_const_type)
+ .long .Ldie0xfc-.Lo0 # DW_AT_type
+ .uleb128 0xd # (DIE (0x111) DW_TAG_pointer_type)
+ .byte 0x8 # DW_AT_byte_size
+ .long .Ldie0x117-.Lo0 # DW_AT_type
+.Ldie0x117:
+ .uleb128 0xc # (DIE (0x117) DW_TAG_const_type)
+ .long .Ldie0xdb-.Lo0 # DW_AT_type
+ .uleb128 0xb # (DIE (0x11c) DW_TAG_base_type)
+ .byte 0x8 # DW_AT_byte_size
+ .byte 0x7 # DW_AT_encoding
+ .long .LASF7 # DW_AT_name: "long unsigned int"
+.Ldie0x123:
+ .uleb128 0xe # (DIE (0x123) DW_TAG_array_type)
+ .long .Ldie0x88-.Lo0 # DW_AT_type
+ .uleb128 0xf # (DIE (0x128) DW_TAG_subrange_type)
+ .long .Ldie0xd8-.Lo0 # DW_AT_type
+ .byte 0x2 # DW_AT_upper_bound
+ .byte 0x10 # DW_AT_byte_stride
+ .byte 0x0 # end of children of DIE 0x123
+ .byte 0x0 # end of children of DIE 0xb
+.Ldebuginfo_end:
+ .section .debug_abbrev
+ .uleb128 0x1 # (abbrev code)
+ .uleb128 0x11 # (TAG: DW_TAG_compile_unit)
+ .byte 0x1 # DW_children_yes
+ .uleb128 0x25 # (DW_AT_producer)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0x13 # (DW_AT_language)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0x1b # (DW_AT_comp_dir)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0x11 # (DW_AT_low_pc)
+ .uleb128 0x1 # (DW_FORM_addr)
+ .uleb128 0x12 # (DW_AT_high_pc)
+ .uleb128 0x1 # (DW_FORM_addr)
+ .uleb128 0x10 # (DW_AT_stmt_list)
+ .uleb128 0x6 # (DW_FORM_data4)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x2 # (abbrev code)
+ .uleb128 0x2e # (TAG: DW_TAG_subprogram)
+ .byte 0x1 # DW_children_yes
+ .uleb128 0x3f # (DW_AT_external)
+ .uleb128 0xc # (DW_FORM_flag)
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0x8 # (DW_FORM_string)
+ .uleb128 0x3a # (DW_AT_decl_file)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3b # (DW_AT_decl_line)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x27 # (DW_AT_prototyped)
+ .uleb128 0xc # (DW_FORM_flag)
+ .uleb128 0x11 # (DW_AT_low_pc)
+ .uleb128 0x1 # (DW_FORM_addr)
+ .uleb128 0x12 # (DW_AT_high_pc)
+ .uleb128 0x1 # (DW_FORM_addr)
+ .uleb128 0x40 # (DW_AT_frame_base)
+ .uleb128 0x6 # (DW_FORM_data4)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x3 # (abbrev code)
+ .uleb128 0x5 # (TAG: DW_TAG_formal_parameter)
+ .byte 0x0 # DW_children_no
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0x3a # (DW_AT_decl_file)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3b # (DW_AT_decl_line)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .uleb128 0x2 # (DW_AT_location)
+ .uleb128 0xa # (DW_FORM_block1)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x4 # (abbrev code)
+ .uleb128 0x34 # (TAG: DW_TAG_variable)
+ .byte 0x0 # DW_children_no
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0x3a # (DW_AT_decl_file)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3b # (DW_AT_decl_line)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .uleb128 0x2 # (DW_AT_location)
+ .uleb128 0xa # (DW_FORM_block1)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x5 # (abbrev code)
+ .uleb128 0x12 # (TAG: DW_TAG_string_type)
+ .byte 0x0 # DW_children_no
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0xe # (DW_FORM_strp)
+ .uleb128 0xb # (DW_AT_byte_size)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x19 # (DW_AT_string_length)
+ .uleb128 0xa # (DW_FORM_block1)
+ .uleb128 0x50 # (DW_AT_data_location)
+ .uleb128 0xa # (DW_FORM_block1)
+ .uleb128 0x3a # (DW_AT_decl_file)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3b # (DW_AT_decl_line)
+ .uleb128 0xb # (DW_FORM_data1)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x7 # (abbrev code)
+ .uleb128 0x24 # (TAG: DW_TAG_base_type)
+ .byte 0x0 # DW_children_no
+ .uleb128 0xb # (DW_AT_byte_size)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3e # (DW_AT_encoding)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0x8 # (DW_FORM_string)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x8 # (abbrev code)
+ .uleb128 0x1 # (TAG: DW_TAG_array_type)
+ .byte 0x1 # DW_children_yes
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0x9 # (abbrev code)
+ .uleb128 0x21 # (TAG: DW_TAG_subrange_type)
+ .byte 0x0 # DW_children_no
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .uleb128 0x2f # (DW_AT_upper_bound)
+ .uleb128 0xb # (DW_FORM_data1)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xa # (abbrev code)
+ .uleb128 0x24 # (TAG: DW_TAG_base_type)
+ .byte 0x0 # DW_children_no
+ .uleb128 0xb # (DW_AT_byte_size)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3e # (DW_AT_encoding)
+ .uleb128 0xb # (DW_FORM_data1)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xb # (abbrev code)
+ .uleb128 0x24 # (TAG: DW_TAG_base_type)
+ .byte 0x0 # DW_children_no
+ .uleb128 0xb # (DW_AT_byte_size)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3e # (DW_AT_encoding)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0xe # (DW_FORM_strp)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xc # (abbrev code)
+ .uleb128 0x26 # (TAG: DW_TAG_const_type)
+ .byte 0x0 # DW_children_no
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xd # (abbrev code)
+ .uleb128 0xf # (TAG: DW_TAG_pointer_type)
+ .byte 0x0 # DW_children_no
+ .uleb128 0xb # (DW_AT_byte_size)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xe # (abbrev code)
+ .uleb128 0x1 # (TAG: DW_TAG_array_type)
+ .byte 0x1 # DW_children_yes
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .byte 0x0
+ .byte 0x0
+ .uleb128 0xf # (abbrev code)
+ .uleb128 0x21 # (TAG: DW_TAG_subrange_type)
+ .byte 0x0 # DW_children_no
+ .uleb128 0x49 # (DW_AT_type)
+ .uleb128 0x13 # (DW_FORM_ref4)
+ .uleb128 0x2f # (DW_AT_upper_bound)
+ .uleb128 0xb # (DW_FORM_data1)
+ .uleb128 0x51 # (DW_AT_byte_stride)
+ .uleb128 0xb # (DW_FORM_data1)
+ .byte 0x0
+ .byte 0x0
+ .byte 0x0
+ .section .debug_pubnames,"",@progbits
+ .long 0x16 # Length of Public Names Info
+ .value 0x2 # DWARF Version
+ .long .Ldebug_info0 # Offset of Compilation Unit Info
+ .long 0x130 # Compilation Unit Length
+ .long 0x2d # DIE offset
+ .ascii "foo\0" # external name
+ .long 0x0
+ .section .debug_aranges,"",@progbits
+ .long 0x2c # Length of Address Ranges Info
+ .value 0x2 # DWARF Version
+ .long .Ldebug_info0 # Offset of Compilation Unit Info
+ .byte 0x8 # Size of Address
+ .byte 0x0 # Size of Segment Descriptor
+ .value 0x0 # Pad to 16 byte boundary
+ .value 0x0
+ .quad .Ltext0 # Address
+ .quad .Letext0-.Ltext0 # Length
+ .quad 0x0
+ .quad 0x0
+ .section .debug_str,"MS",@progbits,1
+.LASF12:
+ .string "string_t"
+.LASF0:
+ .string "string0"
+.LASF5:
+ .string "array"
+.LASF1:
+ .string "string1"
+.LASF4:
+ .string "length"
+.LASF10:
+ .string ""
+.LASF7:
+ .string "long unsigned int"
+.LASF6:
+ .string "char"
+.LASF3:
+ .string "string"
+.LASF9:
+ .string "x86_64-pascal-string-array.c"
+.LASF8:
+ .string "GNU C 4.4.0 20090506 (Red Hat 4.4.0-4)"
+.LASF11:
+ .string "show_l"
+.LASF2:
+ .string "string2"
+ .ident "GCC: (GNU) 4.4.0 20090506 (Red Hat 4.4.0-4)"
+ .section .note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.arch/x86_64-pascal-string-array.c b/gdb/testsuite/gdb.arch/x86_64-pascal-string-array.c
new file mode 100644
index 0000000..fc2c541
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/x86_64-pascal-string-array.c
@@ -0,0 +1,48 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2009 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#if 0
+
+void
+foo (int show_l)
+{
+ const char string0[] = "lX";
+ const char string1[] = "alX";
+ const char string2[] = "bclX";
+ struct string_t
+ {
+ const char *string;
+ unsigned long length;
+ }
+ array[3] = {{string0, 0 + show_l},
+ {string1, 1 + show_l},
+ {string2, 2 + show_l}};
+
+ show_l = show_l; /* break-here */
+}
+
+#else
+
+int
+main (void)
+{
+ foo (0);
+ foo (1);
+ return 0;
+}
+
+#endif
diff --git a/gdb/testsuite/gdb.arch/x86_64-pascal-string-array.exp b/gdb/testsuite/gdb.arch/x86_64-pascal-string-array.exp
new file mode 100644
index 0000000..94e4547
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/x86_64-pascal-string-array.exp
@@ -0,0 +1,64 @@
+# Copyright 2009 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Test DW_AT_data_location accessed through DW_TAG_typedef intermediate.
+
+if ![istarget "x86_64-*-*"] then {
+ verbose "Skipping over gdb.arch/x86_64-pascal-string-array.exp test made only for x86_64."
+ return
+}
+
+set test x86_64-pascal-string-array
+set srcfile ${test}.c
+
+# Disable {debug} options as the .c debug_line would conflict with -foo.S.
+if { [prepare_for_testing ${test}.exp ${test} [list ${test}-foo.S ${test}.c] {}] } {
+ return -1
+}
+
+if ![runto_main] {
+ untested ${test}.exp
+ return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "break-here"]
+gdb_continue_to_breakpoint "break-here"
+
+gdb_test "whatis array" "type = array \\\[0\\.\\.2\\\] of string_t" "first: whatis array"
+gdb_test "ptype array" "type = array \\\[0\\.\\.2\\\] of string_t" "first: ptype array"
+
+set test "first: p array\[0\]"
+gdb_test_multiple "p array\[0\]" $test {
+ -re " = 0x\[0-9a-f\]+ 'lX'\r\n$gdb_prompt $" {
+ # pascal_val_print currently considers TYPE_LENGTH == 0 as unspecified.
+### setup_kfail *-*-* gdb/9999
+ fail $test
+ }
+ -re " = ''\r\n$gdb_prompt $" {
+ pass $test
+ }
+}
+gdb_test "p array\[1\]" " = 'a'" "first: p array\[1\]"
+gdb_test "p array\[2\]" " = 'bc'" "first: p array\[2\]"
+
+gdb_continue_to_breakpoint "break-here"
+
+gdb_test "whatis array" "type = array \\\[0\\.\\.2\\\] of string_t" "second: whatis array"
+gdb_test "ptype array" "type = array \\\[0\\.\\.2\\\] of string_t" "second: ptype array"
+
+gdb_test "p array\[0\]" " = 'l'" "second: p array\[0\]"
+gdb_test "p array\[1\]" " = 'al'" "second: p array\[1\]"
+gdb_test "p array\[2\]" " = 'bcl'" "second: p array\[2\]"
+
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 8a635b6..ad4489c 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -31,6 +31,7 @@
#include "dfp.h"
#include
#include "infcall.h"
+#include "dwarf2loc.h"
/* Define whether or not the C operator '/' truncates towards zero for
differently signed operands (truncation direction is undefined in C). */
@@ -178,11 +179,12 @@ value_subscript (struct value *array, struct value *idx)
LONGEST lowerbound, upperbound;
get_discrete_bounds (range_type, &lowerbound, &upperbound);
- if (VALUE_LVAL (array) != lval_memory)
+ if (VALUE_LVAL (array) != lval_memory
+ || TYPE_BYTE_STRIDE (range_type) > 0)
{
if (index >= lowerbound && index <= upperbound)
{
- CORE_ADDR element_size = TYPE_LENGTH (TYPE_TARGET_TYPE (tarray));
+ CORE_ADDR element_size = TYPE_ARRAY_BYTE_STRIDE_VALUE (tarray);
CORE_ADDR offset = (index - lowerbound) * element_size;
return value_subscripted_rvalue (array, offset);
@@ -232,8 +234,26 @@ struct value *
value_subscripted_rvalue (struct value *array, CORE_ADDR offset)
{
struct type *array_type = check_typedef (value_type (array));
- struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type));
+ struct type *elt_type;
struct value *v;
+ struct cleanup *back_to;
+ CORE_ADDR elt_addr;
+
+ back_to = make_cleanup (null_cleanup, 0);
+
+ /* Find the element object address - derived from the array _data_ address
+ shifted by OFFSET. */
+ elt_addr = value_raw_address (array);
+ object_address_get_data (value_type (array), &elt_addr);
+ elt_addr += offset;
+
+ /* And get the appropriate TYPE for the specific element of the array.
+ Different elements of the array may get different (such as by their string
+ length) types). */
+ object_address_set (elt_addr);
+ elt_type = check_typedef (TYPE_TARGET_TYPE (array_type));
+
+ do_cleanups (back_to);
/* Do not check TYPE_LENGTH (array_type) as we may have been given the
innermost dimension of a multi-dimensional Fortran array where its length
@@ -252,7 +272,7 @@ value_subscripted_rvalue (struct value *array, CORE_ADDR offset)
set_value_component_location (v, array);
VALUE_REGNUM (v) = VALUE_REGNUM (array);
VALUE_FRAME_ID (v) = VALUE_FRAME_ID (array);
- set_value_offset (v, value_offset (array) + offset);
+ set_value_address (v, elt_addr);
return v;
}
diff --git a/gdb/valops.c b/gdb/valops.c
index acd67f0..befc6be 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -318,6 +318,7 @@ value_cast (struct type *type, struct value *arg2)
enum type_code code2;
int scalar;
struct type *type2;
+ struct cleanup *back_to;
int convert_to_boolean = 0;
@@ -338,17 +339,26 @@ value_cast (struct type *type, struct value *arg2)
return value_ref (val);
}
+ back_to = make_cleanup (null_cleanup, 0);
+ object_address_set (value_raw_address (arg2));
+
code2 = TYPE_CODE (check_typedef (value_type (arg2)));
+ arg2 = coerce_ref (arg2);
if (code2 == TYPE_CODE_REF)
- /* We deref the value and then do the cast. */
- return value_cast (type, coerce_ref (arg2));
+ {
+ do_cleanups (back_to);
+
+ /* We deref the value and then do the cast. */
+ return value_cast (type, arg2);
+ }
CHECK_TYPEDEF (type);
code1 = TYPE_CODE (type);
- arg2 = coerce_ref (arg2);
type2 = check_typedef (value_type (arg2));
+ do_cleanups (back_to);
+
/* You can't cast to a reference type. See value_cast_pointers
instead. */
gdb_assert (code1 != TYPE_CODE_REF);