4f698ded6f
459414). - Extend the Fortran dynamic variables patch also for dynamic Fortran strings.
2553 lines
92 KiB
Diff
2553 lines
92 KiB
Diff
The last version posted upstream:
|
||
|
||
0: http://sources.redhat.com/ml/gdb-patches/2007-11/msg00438.html
|
||
1: http://sources.redhat.com/ml/gdb-patches/2007-11/msg00439.html
|
||
2: http://sources.redhat.com/ml/gdb-patches/2007-11/msg00440.html
|
||
3: http://sources.redhat.com/ml/gdb-patches/2007-11/msg00441.html
|
||
4: http://sources.redhat.com/ml/gdb-patches/2007-11/msg00442.html
|
||
5: http://sources.redhat.com/ml/gdb-patches/2007-11/msg00443.html
|
||
6: http://sources.redhat.com/ml/gdb-patches/2007-11/msg00444.html
|
||
|
||
2008-02-24 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
|
||
Port to GDB-6.8pre.
|
||
|
||
2008-08-23 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
|
||
Include dynamic strings support.
|
||
|
||
diff -up -ruNp gdb-6.8-0/gdb/Makefile.in gdb-6.8-1/gdb/Makefile.in
|
||
--- gdb-6.8-0/gdb/Makefile.in 2008-08-23 22:29:57.000000000 +0200
|
||
+++ gdb-6.8-1/gdb/Makefile.in 2008-08-23 22:31:08.000000000 +0200
|
||
@@ -758,6 +758,7 @@ disasm_h = disasm.h
|
||
doublest_h = doublest.h $(floatformat_h)
|
||
dummy_frame_h = dummy-frame.h
|
||
dfp_h = dfp.h
|
||
+dwarf2block_h = dwarf2block.h
|
||
dwarf2expr_h = dwarf2expr.h
|
||
dwarf2_frame_h = dwarf2-frame.h
|
||
dwarf2loc_h = dwarf2loc.h
|
||
@@ -1051,7 +1052,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
|
||
exec.o bcache.o objfiles.o observer.o minsyms.o maint.o demangle.o \
|
||
dbxread.o coffread.o coff-pe-read.o \
|
||
dwarf2read.o mipsread.o stabsread.o corefile.o \
|
||
- dwarf2expr.o dwarf2loc.o dwarf2-frame.o \
|
||
+ dwarf2block.o dwarf2expr.o dwarf2loc.o dwarf2-frame.o \
|
||
ada-lang.o c-lang.o f-lang.o objc-lang.o \
|
||
ui-out.o cli-out.o \
|
||
varobj.o vec.o wrapper.o \
|
||
@@ -2086,6 +2087,9 @@ dummy-frame.o: dummy-frame.c $(defs_h) $
|
||
$(command_h) $(gdbcmd_h) $(gdb_string_h)
|
||
dfp.o: dfp.c $(defs_h) $(expression_h) $(gdbtypes_h) $(value_h) $(dfp_h) \
|
||
$(decimal128_h) $(decimal64_h) $(decimal32_h)
|
||
+dwarf2block.o: dwarf2block.c $(dwarf2block_h) $(defs_h) $(gdbcore_h) \
|
||
+ $(dwarf2expr_h) $(exceptions_h) $(frame_h) $(regcache_h) $(value_h) \
|
||
+ $(block_h) $(gdb_assert.h) $(dwarf2loc.h)
|
||
dwarf2expr.o: dwarf2expr.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(value_h) \
|
||
$(gdbcore_h) $(elf_dwarf2_h) $(dwarf2expr_h)
|
||
dwarf2-frame.o: dwarf2-frame.c $(defs_h) $(dwarf2expr_h) $(elf_dwarf2_h) \
|
||
@@ -2096,13 +2100,14 @@ dwarf2-frame.o: dwarf2-frame.c $(defs_h)
|
||
dwarf2loc.o: dwarf2loc.c $(defs_h) $(ui_out_h) $(value_h) $(frame_h) \
|
||
$(gdbcore_h) $(target_h) $(inferior_h) $(ax_h) $(ax_gdb_h) \
|
||
$(regcache_h) $(objfiles_h) $(exceptions_h) $(elf_dwarf2_h) \
|
||
- $(dwarf2expr_h) $(dwarf2loc_h) $(gdb_string_h) $(gdb_assert_h)
|
||
+ $(dwarf2expr_h) $(dwarf2loc_h) $(gdb_string_h) $(gdb_assert_h) \
|
||
+ $(dwarf2block_h)
|
||
dwarf2read.o: dwarf2read.c $(defs_h) $(bfd_h) $(symtab_h) $(gdbtypes_h) \
|
||
$(objfiles_h) $(elf_dwarf2_h) $(buildsym_h) $(demangle_h) \
|
||
$(expression_h) $(filenames_h) $(macrotab_h) $(language_h) \
|
||
$(complaints_h) $(bcache_h) $(dwarf2expr_h) $(dwarf2loc_h) \
|
||
$(cp_support_h) $(hashtab_h) $(command_h) $(gdbcmd_h) \
|
||
- $(gdb_string_h) $(gdb_assert_h)
|
||
+ $(gdb_string_h) $(gdb_assert_h) $(dwarf2block_h) $(f_lang_h)
|
||
elfread.o: elfread.c $(defs_h) $(bfd_h) $(gdb_string_h) $(elf_bfd_h) \
|
||
$(elf_mips_h) $(symtab_h) $(symfile_h) $(objfiles_h) $(buildsym_h) \
|
||
$(stabsread_h) $(gdb_stabs_h) $(complaints_h) $(demangle_h) \
|
||
@@ -2138,10 +2143,10 @@ f-exp.o: f-exp.c $(defs_h) $(gdb_string_
|
||
findvar.o: findvar.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(frame_h) \
|
||
$(value_h) $(gdbcore_h) $(inferior_h) $(target_h) $(gdb_string_h) \
|
||
$(gdb_assert_h) $(floatformat_h) $(symfile_h) $(regcache_h) \
|
||
- $(user_regs_h) $(block_h)
|
||
+ $(user_regs_h) $(block_h) $(dwarf2block_h)
|
||
f-lang.o: f-lang.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
|
||
$(expression_h) $(parser_defs_h) $(language_h) $(f_lang_h) \
|
||
- $(valprint_h) $(value_h)
|
||
+ $(valprint_h) $(value_h) $(dwarf2block_h)
|
||
fork-child.o: fork-child.c $(defs_h) $(gdb_string_h) $(frame_h) \
|
||
$(inferior_h) $(target_h) $(gdb_wait_h) $(gdb_vfork_h) $(gdbcore_h) \
|
||
$(terminal_h) $(gdbthread_h) $(command_h) $(solib_h)
|
||
@@ -2166,7 +2171,7 @@ frv-tdep.o: frv-tdep.c $(defs_h) $(gdb_s
|
||
$(frv_tdep_h)
|
||
f-typeprint.o: f-typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \
|
||
$(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(target_h) \
|
||
- $(f_lang_h) $(gdb_string_h)
|
||
+ $(f_lang_h) $(gdb_string_h) $(dwarf2block_h)
|
||
f-valprint.o: f-valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) \
|
||
$(gdbtypes_h) $(expression_h) $(value_h) $(valprint_h) $(language_h) \
|
||
$(f_lang_h) $(frame_h) $(gdbcore_h) $(command_h) $(block_h)
|
||
@@ -2181,7 +2186,8 @@ gdb-events.o: gdb-events.c $(defs_h) $(g
|
||
gdbtypes.o: gdbtypes.c $(defs_h) $(gdb_string_h) $(bfd_h) $(symtab_h) \
|
||
$(symfile_h) $(objfiles_h) $(gdbtypes_h) $(expression_h) \
|
||
$(language_h) $(target_h) $(value_h) $(demangle_h) $(complaints_h) \
|
||
- $(gdbcmd_h) $(wrapper_h) $(cp_abi_h) $(gdb_assert_h) $(hashtab_h)
|
||
+ $(gdbcmd_h) $(wrapper_h) $(cp_abi_h) $(gdb_assert_h) $(hashtab_h) \
|
||
+ $(dwarf2block_h)
|
||
glibc-tdep.o: glibc-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(symfile_h) \
|
||
$(objfiles_h) $(glibc_tdep_h)
|
||
gnu-nat.o: gnu-nat.c $(gdb_string_h) $(defs_h) $(inferior_h) $(symtab_h) \
|
||
@@ -2939,7 +2945,7 @@ tramp-frame.o: tramp-frame.c $(defs_h) $
|
||
typeprint.o: typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \
|
||
$(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(command_h) \
|
||
$(gdbcmd_h) $(target_h) $(language_h) $(cp_abi_h) $(typeprint_h) \
|
||
- $(gdb_string_h)
|
||
+ $(gdb_string_h) $(dwarf2block_h)
|
||
ui-file.o: ui-file.c $(defs_h) $(ui_file_h) $(gdb_string_h)
|
||
ui-out.o: ui-out.c $(defs_h) $(gdb_string_h) $(expression_h) $(language_h) \
|
||
$(ui_out_h) $(gdb_assert_h)
|
||
diff -up -ruNp gdb-6.8-0/gdb/ada-lang.c gdb-6.8-1/gdb/ada-lang.c
|
||
--- gdb-6.8-0/gdb/ada-lang.c 2008-08-23 22:29:57.000000000 +0200
|
||
+++ gdb-6.8-1/gdb/ada-lang.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -11009,6 +11009,7 @@ const struct language_defn ada_language_
|
||
ada_language_arch_info,
|
||
ada_print_array_index,
|
||
default_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
diff -up -ruNp gdb-6.8-0/gdb/c-lang.c gdb-6.8-1/gdb/c-lang.c
|
||
--- gdb-6.8-0/gdb/c-lang.c 2008-02-05 23:17:40.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/c-lang.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -427,6 +427,7 @@ const struct language_defn c_language_de
|
||
c_language_arch_info,
|
||
default_print_array_index,
|
||
default_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
@@ -540,6 +541,7 @@ const struct language_defn cplus_languag
|
||
cplus_language_arch_info,
|
||
default_print_array_index,
|
||
cp_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
@@ -575,6 +577,7 @@ const struct language_defn asm_language_
|
||
c_language_arch_info, /* FIXME: la_language_arch_info. */
|
||
default_print_array_index,
|
||
default_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
@@ -615,6 +618,7 @@ const struct language_defn minimal_langu
|
||
c_language_arch_info,
|
||
default_print_array_index,
|
||
default_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
diff -up -ruNp gdb-6.8-0/gdb/dwarf2block.c gdb-6.8-1/gdb/dwarf2block.c
|
||
--- gdb-6.8-0/gdb/dwarf2block.c 1970-01-01 01:00:00.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/dwarf2block.c 2008-08-23 22:31:08.000000000 +0200
|
||
@@ -0,0 +1,216 @@
|
||
+/* DWARF DW_FORM_block* expression evaluation.
|
||
+
|
||
+ Copyright (C) 2007 Free Software Foundation, Inc.
|
||
+
|
||
+ This file is part of GDB.
|
||
+
|
||
+ 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 <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#include "defs.h"
|
||
+#include "dwarf2block.h"
|
||
+#include "gdbcore.h"
|
||
+#include "dwarf2expr.h"
|
||
+#include "exceptions.h"
|
||
+#include "frame.h"
|
||
+#include "regcache.h"
|
||
+#include "value.h"
|
||
+#include "block.h"
|
||
+#include "gdb_assert.h"
|
||
+#include "dwarf2loc.h"
|
||
+
|
||
+/* This is the baton used when performing dwarf2 DW_BLOCK evaluation. */
|
||
+struct dwarf_block_baton
|
||
+{
|
||
+ CORE_ADDR address;
|
||
+};
|
||
+
|
||
+/* Read memory at ADDR (length LEN) into BUF. */
|
||
+
|
||
+static void
|
||
+dwarf_block_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr, size_t len)
|
||
+{
|
||
+ read_memory (addr, buf, len);
|
||
+}
|
||
+
|
||
+static CORE_ADDR
|
||
+dwarf_block_object_address (void *baton)
|
||
+{
|
||
+ struct dwarf_block_baton *debaton = baton;
|
||
+
|
||
+ /* The message is suppressed in DWARF_BLOCK_EXEC. */
|
||
+ if (debaton->address == 0)
|
||
+ error (_("Cannot resolve DW_OP_push_object_address for a missing object"));
|
||
+
|
||
+ return debaton->address;
|
||
+}
|
||
+
|
||
+/* A copy from dwarf2-frame.c:read_reg() but without one unwind. */
|
||
+
|
||
+static CORE_ADDR
|
||
+dwarf_block_read_reg (void *baton, int reg)
|
||
+{
|
||
+ struct frame_info *frame = get_selected_frame
|
||
+ (_("Unsupported operation for DW_FORM_block: read_reg"));
|
||
+ struct gdbarch *gdbarch = get_frame_arch (frame);
|
||
+ int regnum;
|
||
+ gdb_byte *buf;
|
||
+
|
||
+ regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, reg);
|
||
+
|
||
+ buf = alloca (register_size (gdbarch, regnum));
|
||
+ get_frame_register (frame, regnum, buf);
|
||
+
|
||
+ /* Convert the register to an integer. This returns a LONGEST
|
||
+ rather than a CORE_ADDR, but unpack_pointer does the same thing
|
||
+ under the covers, and this makes more sense for non-pointer
|
||
+ registers. Maybe read_reg and the associated interfaces should
|
||
+ deal with "struct value" instead of CORE_ADDR. */
|
||
+ return unpack_long (register_type (gdbarch, regnum), buf);
|
||
+}
|
||
+
|
||
+/* A copy from dwarf2loc.c:dwarf_expr_frame_base(). */
|
||
+
|
||
+static void
|
||
+dwarf_block_get_frame_base (void *baton, gdb_byte **start, size_t *length)
|
||
+{
|
||
+ struct frame_info *frame = get_selected_frame
|
||
+ (_("Unsupported operation for DW_FORM_block: read_reg"));
|
||
+ /* FIXME: cagney/2003-03-26: This code should be using
|
||
+ get_frame_base_address(), and then implement a dwarf2 specific
|
||
+ this_base method. */
|
||
+ struct symbol *framefunc;
|
||
+
|
||
+ /* Use block_linkage_function, which returns a real (not inlined)
|
||
+ function, instead of get_frame_function, which may return an
|
||
+ inlined function. */
|
||
+ framefunc = block_linkage_function (get_frame_block (frame, NULL));
|
||
+
|
||
+ /* If we found a frame-relative symbol then it was certainly within
|
||
+ some function associated with a frame. If we can't find the frame,
|
||
+ something has gone wrong. */
|
||
+ gdb_assert (framefunc != NULL);
|
||
+
|
||
+ if (SYMBOL_LOCATION_BATON (framefunc) == NULL)
|
||
+ *start = NULL;
|
||
+ else if (SYMBOL_OPS (framefunc) == &dwarf2_loclist_funcs)
|
||
+ {
|
||
+ struct dwarf2_loclist_baton *symbaton;
|
||
+
|
||
+ symbaton = SYMBOL_LOCATION_BATON (framefunc);
|
||
+ *start = find_location_expression (symbaton, length,
|
||
+ get_frame_address_in_block (frame));
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ struct dwarf2_locexpr_baton *symbaton;
|
||
+
|
||
+ symbaton = SYMBOL_LOCATION_BATON (framefunc);
|
||
+ *length = symbaton->size;
|
||
+ *start = symbaton->data;
|
||
+ }
|
||
+
|
||
+ if (*start == NULL)
|
||
+ error (_("%s: Could not find the frame base for \"%s\"."),
|
||
+ "dwarf_block_get_frame_base", SYMBOL_NATURAL_NAME (framefunc));
|
||
+}
|
||
+
|
||
+static CORE_ADDR
|
||
+dwarf_block_get_tls_address (void *baton, CORE_ADDR offset)
|
||
+{
|
||
+ error (_("Unsupported operation for DW_FORM_block*: %s"), "get_tls_address");
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static CORE_ADDR dwarf_block_exec_core (struct dwarf_block *dwarf_block,
|
||
+ CORE_ADDR address)
|
||
+{
|
||
+ struct dwarf_expr_context *ctx;
|
||
+ struct dwarf_block_baton baton;
|
||
+ struct cleanup *back_to;
|
||
+ CORE_ADDR retval;
|
||
+
|
||
+ back_to = make_cleanup (null_cleanup, 0);
|
||
+
|
||
+ baton.address = address;
|
||
+
|
||
+ ctx = new_dwarf_expr_context ();
|
||
+ back_to = make_cleanup ((make_cleanup_ftype *) free_dwarf_expr_context, ctx);
|
||
+ ctx->baton = &baton;
|
||
+ ctx->read_mem = dwarf_block_read_mem;
|
||
+ ctx->get_object_address = dwarf_block_object_address;
|
||
+ ctx->read_reg = dwarf_block_read_reg;
|
||
+ ctx->get_frame_base = dwarf_block_get_frame_base;
|
||
+ ctx->get_tls_address = dwarf_block_get_tls_address;
|
||
+
|
||
+ dwarf_expr_eval (ctx, dwarf_block->data, dwarf_block->size);
|
||
+
|
||
+ if (ctx->num_pieces > 0)
|
||
+ error (_("DW_OP_piece is an unsupported result for DW_FORM_block*"));
|
||
+ if (ctx->in_reg)
|
||
+ error (_("DW_OP_reg* is an unsupported result for DW_FORM_block*"));
|
||
+
|
||
+ retval = dwarf_expr_fetch (ctx, 0);
|
||
+
|
||
+ do_cleanups (back_to);
|
||
+
|
||
+ return retval;
|
||
+}
|
||
+
|
||
+static CORE_ADDR object_address;
|
||
+
|
||
+static void
|
||
+object_address_cleanup (void *prev_save_voidp)
|
||
+{
|
||
+ CORE_ADDR *prev_save = prev_save_voidp;
|
||
+
|
||
+ object_address = *prev_save;
|
||
+ xfree (prev_save);
|
||
+}
|
||
+
|
||
+void
|
||
+object_address_set (CORE_ADDR address)
|
||
+{
|
||
+ CORE_ADDR *prev_save;
|
||
+
|
||
+ prev_save = xmalloc (sizeof *prev_save);
|
||
+ *prev_save = object_address;
|
||
+ make_cleanup (object_address_cleanup, prev_save);
|
||
+
|
||
+ object_address = address;
|
||
+}
|
||
+
|
||
+CORE_ADDR
|
||
+object_address_get (void)
|
||
+{
|
||
+ return object_address;
|
||
+}
|
||
+
|
||
+CORE_ADDR dwarf_block_exec (struct dwarf_block *dwarf_block)
|
||
+{
|
||
+ volatile struct gdb_exception e;
|
||
+ volatile CORE_ADDR retval = 0;
|
||
+
|
||
+ TRY_CATCH (e, RETURN_MASK_ERROR)
|
||
+ {
|
||
+ retval = dwarf_block_exec_core (dwarf_block, object_address);
|
||
+ }
|
||
+ /* CATCH_ERRORS would print the possible error message of
|
||
+ DWARF_BLOCK_OBJECT_ADDRESS. Sometimes it is valid as CHECK_TYPEDEF is
|
||
+ a very common call even if we still do not know any variable instance of
|
||
+ that type. We cannot fill in the right TYPE_LENGTH at that time. */
|
||
+ if (e.reason < 0)
|
||
+ return 0;
|
||
+
|
||
+ return retval;
|
||
+}
|
||
diff -up -ruNp gdb-6.8-0/gdb/dwarf2block.h gdb-6.8-1/gdb/dwarf2block.h
|
||
--- gdb-6.8-0/gdb/dwarf2block.h 1970-01-01 01:00:00.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/dwarf2block.h 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -0,0 +1,36 @@
|
||
+/* DWARF DW_FORM_block* expression evaluation.
|
||
+
|
||
+ Copyright (C) 2007 Free Software Foundation, Inc.
|
||
+
|
||
+ This file is part of GDB.
|
||
+
|
||
+ 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 <http://www.gnu.org/licenses/>. */
|
||
+
|
||
+#if !defined (DWARF2BLOCK_H)
|
||
+#define DWARF2BLOCK_H 1
|
||
+
|
||
+/* Blocks are a bunch of untyped bytes. */
|
||
+struct dwarf_block
|
||
+ {
|
||
+ unsigned int size;
|
||
+ gdb_byte *data;
|
||
+ };
|
||
+
|
||
+extern CORE_ADDR dwarf_block_exec (struct dwarf_block *dwarf_block);
|
||
+
|
||
+extern void object_address_set (CORE_ADDR address);
|
||
+
|
||
+extern CORE_ADDR object_address_get (void);
|
||
+
|
||
+#endif /* !defined(DWARF2BLOCK_H) */
|
||
diff -up -ruNp gdb-6.8-0/gdb/dwarf2expr.c gdb-6.8-1/gdb/dwarf2expr.c
|
||
--- gdb-6.8-0/gdb/dwarf2expr.c 2008-08-23 22:29:56.000000000 +0200
|
||
+++ gdb-6.8-1/gdb/dwarf2expr.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -750,6 +750,13 @@ execute_stack_op (struct dwarf_expr_cont
|
||
ctx->initialized = 0;
|
||
goto no_push;
|
||
|
||
+ case DW_OP_push_object_address:
|
||
+ if (ctx->get_object_address == NULL)
|
||
+ error (_("DWARF-2 expression error: DW_OP_push_object_address must "
|
||
+ "have a value to push."));
|
||
+ result = (ctx->get_object_address) (ctx->baton);
|
||
+ break;
|
||
+
|
||
default:
|
||
error (_("Unhandled dwarf expression opcode 0x%x"), op);
|
||
}
|
||
diff -up -ruNp gdb-6.8-0/gdb/dwarf2expr.h gdb-6.8-1/gdb/dwarf2expr.h
|
||
--- gdb-6.8-0/gdb/dwarf2expr.h 2008-01-01 23:53:09.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/dwarf2expr.h 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -61,10 +61,10 @@ struct dwarf_expr_context
|
||
The result must be live until the current expression evaluation
|
||
is complete. */
|
||
unsigned char *(*get_subr) (void *baton, off_t offset, size_t *length);
|
||
+#endif
|
||
|
||
/* Return the `object address' for DW_OP_push_object_address. */
|
||
CORE_ADDR (*get_object_address) (void *baton);
|
||
-#endif
|
||
|
||
/* The current depth of dwarf expression recursion, via DW_OP_call*,
|
||
DW_OP_fbreg, DW_OP_push_object_address, etc., and the maximum
|
||
diff -up -ruNp gdb-6.8-0/gdb/dwarf2loc.c gdb-6.8-1/gdb/dwarf2loc.c
|
||
--- gdb-6.8-0/gdb/dwarf2loc.c 2008-01-01 23:53:09.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/dwarf2loc.c 2008-08-23 22:31:08.000000000 +0200
|
||
@@ -35,6 +35,7 @@
|
||
#include "elf/dwarf2.h"
|
||
#include "dwarf2expr.h"
|
||
#include "dwarf2loc.h"
|
||
+#include "dwarf2block.h"
|
||
|
||
#include "gdb_string.h"
|
||
#include "gdb_assert.h"
|
||
@@ -47,7 +48,7 @@
|
||
For now, only return the first matching location expression; there
|
||
can be more than one in the list. */
|
||
|
||
-static gdb_byte *
|
||
+gdb_byte *
|
||
find_location_expression (struct dwarf2_loclist_baton *baton,
|
||
size_t *locexpr_length, CORE_ADDR pc)
|
||
{
|
||
@@ -252,6 +253,9 @@ dwarf2_evaluate_loc_desc (struct symbol
|
||
{
|
||
CORE_ADDR address = dwarf_expr_fetch (ctx, 0);
|
||
|
||
+ /* ADDR is set here for ALLOCATE_VALUE's CHECK_TYPEDEF for
|
||
+ DW_OP_push_object_address. */
|
||
+ object_address_set (address);
|
||
retval = allocate_value (SYMBOL_TYPE (var));
|
||
VALUE_LVAL (retval) = lval_memory;
|
||
set_value_lazy (retval, 1);
|
||
diff -up -ruNp gdb-6.8-0/gdb/dwarf2loc.h gdb-6.8-1/gdb/dwarf2loc.h
|
||
--- gdb-6.8-0/gdb/dwarf2loc.h 2008-01-01 23:53:09.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/dwarf2loc.h 2008-08-23 22:31:08.000000000 +0200
|
||
@@ -66,4 +66,8 @@ struct dwarf2_loclist_baton
|
||
extern const struct symbol_ops dwarf2_locexpr_funcs;
|
||
extern const struct symbol_ops dwarf2_loclist_funcs;
|
||
|
||
+extern gdb_byte *find_location_expression (struct dwarf2_loclist_baton *baton,
|
||
+ size_t *locexpr_length,
|
||
+ CORE_ADDR pc);
|
||
+
|
||
#endif /* dwarf2loc.h */
|
||
diff -up -ruNp gdb-6.8-0/gdb/dwarf2read.c gdb-6.8-1/gdb/dwarf2read.c
|
||
--- gdb-6.8-0/gdb/dwarf2read.c 2008-08-23 22:29:57.000000000 +0200
|
||
+++ gdb-6.8-1/gdb/dwarf2read.c 2008-08-23 22:31:08.000000000 +0200
|
||
@@ -46,6 +46,8 @@
|
||
#include "top.h"
|
||
#include "command.h"
|
||
#include "gdbcmd.h"
|
||
+#include "dwarf2block.h"
|
||
+#include "f-lang.h"
|
||
|
||
#include <fcntl.h>
|
||
#include "gdb_string.h"
|
||
@@ -563,13 +565,6 @@ struct function_range
|
||
#define DW_SND(attr) ((attr)->u.snd)
|
||
#define DW_ADDR(attr) ((attr)->u.addr)
|
||
|
||
-/* Blocks are a bunch of untyped bytes. */
|
||
-struct dwarf_block
|
||
- {
|
||
- unsigned int size;
|
||
- gdb_byte *data;
|
||
- };
|
||
-
|
||
#ifndef ATTR_ALLOC_CHUNK
|
||
#define ATTR_ALLOC_CHUNK 4
|
||
#endif
|
||
@@ -1004,7 +999,14 @@ static void store_in_ref_table (unsigned
|
||
static unsigned int dwarf2_get_ref_die_offset (struct attribute *,
|
||
struct dwarf2_cu *);
|
||
|
||
-static int dwarf2_get_attr_constant_value (struct attribute *, int);
|
||
+enum dwarf2_get_attr_constant_value
|
||
+ {
|
||
+ dwarf2_attr_unknown,
|
||
+ dwarf2_attr_const,
|
||
+ dwarf2_attr_block
|
||
+ };
|
||
+static enum dwarf2_get_attr_constant_value dwarf2_get_attr_constant_value
|
||
+ (struct attribute *attr, int *val_return);
|
||
|
||
static struct die_info *follow_die_ref (struct die_info *,
|
||
struct attribute *,
|
||
@@ -4383,6 +4385,56 @@ process_enumeration_scope (struct die_in
|
||
new_symbol (die, die->type, cu);
|
||
}
|
||
|
||
+static void
|
||
+fortran_array_update (struct fortran_array_type **fortran_array_pointer,
|
||
+ struct die_info *die, struct dwarf2_cu *cu,
|
||
+ int read_data_location, struct type *memory_owner)
|
||
+{
|
||
+ struct fortran_array_type *p;
|
||
+ struct fortran_array_type fortran_array_local;
|
||
+ /* Used only for checking if FORTRAN_ARRAY is non-zero. */
|
||
+ static struct fortran_array_type fortran_array_zero;
|
||
+ struct attribute *attr;
|
||
+
|
||
+ /* Prepare FORTRAN_ARRAY_POINTER. It needs to be present in all the subarray
|
||
+ types and in all the range types at least for
|
||
+ TYPE_VERIFY_VALID_ARRAY_OBJECT. */
|
||
+
|
||
+ if (*fortran_array_pointer != NULL)
|
||
+ p = *fortran_array_pointer;
|
||
+ else
|
||
+ {
|
||
+ memset (&fortran_array_local, 0, sizeof fortran_array_local);
|
||
+ p = &fortran_array_local;
|
||
+ }
|
||
+
|
||
+ if (read_data_location)
|
||
+ {
|
||
+ attr = dwarf2_attr (die, DW_AT_data_location, cu);
|
||
+ if (attr)
|
||
+ p->data_location = DW_BLOCK (attr);
|
||
+ }
|
||
+
|
||
+ attr = dwarf2_attr (die, DW_AT_allocated, cu);
|
||
+ if (attr)
|
||
+ p->allocated = DW_BLOCK (attr);
|
||
+
|
||
+ attr = dwarf2_attr (die, DW_AT_associated, cu);
|
||
+ if (attr)
|
||
+ p->associated = DW_BLOCK (attr);
|
||
+
|
||
+ if (p != &fortran_array_local)
|
||
+ {}
|
||
+ else if (memcmp (p, &fortran_array_zero, sizeof *p) == 0)
|
||
+ *fortran_array_pointer = NULL;
|
||
+ else
|
||
+ {
|
||
+ *fortran_array_pointer = TYPE_ALLOC (memory_owner,
|
||
+ sizeof **fortran_array_pointer);
|
||
+ **fortran_array_pointer = fortran_array_local;
|
||
+ }
|
||
+}
|
||
+
|
||
/* Extract all information from a DW_TAG_array_type DIE and put it in
|
||
the DIE's type field. For now, this only handles one dimensional
|
||
arrays. */
|
||
@@ -4399,6 +4451,7 @@ read_array_type (struct die_info *die, s
|
||
int ndim = 0;
|
||
struct cleanup *back_to;
|
||
char *name;
|
||
+ struct fortran_array_type *fortran_array;
|
||
|
||
/* Return if we've already decoded this type. */
|
||
if (die->type)
|
||
@@ -4408,6 +4461,13 @@ read_array_type (struct die_info *die, s
|
||
|
||
element_type = die_type (die, cu);
|
||
|
||
+ /* Prepare FORTRAN_ARRAY_POINTER. It needs to be present in all the subarray
|
||
+ types and in all the range types at least for
|
||
+ TYPE_VERIFY_VALID_ARRAY_OBJECT. */
|
||
+
|
||
+ fortran_array = NULL;
|
||
+ fortran_array_update (&fortran_array, die, cu, 1, element_type);
|
||
+
|
||
/* Irix 6.2 native cc creates array types without children for
|
||
arrays with unspecified length. */
|
||
if (die->child == NULL)
|
||
@@ -4416,6 +4476,9 @@ read_array_type (struct die_info *die, s
|
||
range_type = create_range_type (NULL, index_type, 0, -1);
|
||
set_die_type (die, create_array_type (NULL, element_type, range_type),
|
||
cu);
|
||
+
|
||
+ TYPE_FORTRAN_ARRAY (range_type) = fortran_array;
|
||
+ TYPE_FORTRAN_ARRAY (die->type) = fortran_array;
|
||
return;
|
||
}
|
||
|
||
@@ -4452,14 +4515,31 @@ read_array_type (struct die_info *die, s
|
||
|
||
if (read_array_order (die, cu) == DW_ORD_col_major)
|
||
{
|
||
- int i = 0;
|
||
- while (i < ndim)
|
||
- type = create_array_type (NULL, type, range_types[i++]);
|
||
+ int i;
|
||
+ for (i = 0; i < ndim; i++)
|
||
+ {
|
||
+ type = create_array_type (NULL, type, range_types[i]);
|
||
+ TYPE_FORTRAN_ARRAY (range_types[i]) = fortran_array;
|
||
+ TYPE_FORTRAN_ARRAY (type) = fortran_array;
|
||
+ TYPE_ARRAY_UPPER_BOUND_TYPE (type) =
|
||
+ TYPE_ARRAY_UPPER_BOUND_TYPE (range_types[i]);
|
||
+ TYPE_ARRAY_LOWER_BOUND_TYPE (type) =
|
||
+ TYPE_ARRAY_LOWER_BOUND_TYPE (range_types[i]);
|
||
+ }
|
||
}
|
||
else
|
||
{
|
||
- while (ndim-- > 0)
|
||
- type = create_array_type (NULL, type, range_types[ndim]);
|
||
+ int i;
|
||
+ for (i = ndim - 1; i >= 0; i--)
|
||
+ {
|
||
+ type = create_array_type (NULL, type, range_types[i]);
|
||
+ TYPE_FORTRAN_ARRAY (range_types[i]) = fortran_array;
|
||
+ TYPE_FORTRAN_ARRAY (type) = fortran_array;
|
||
+ TYPE_ARRAY_UPPER_BOUND_TYPE (type) =
|
||
+ TYPE_ARRAY_UPPER_BOUND_TYPE (range_types[i]);
|
||
+ TYPE_ARRAY_LOWER_BOUND_TYPE (type) =
|
||
+ TYPE_ARRAY_LOWER_BOUND_TYPE (range_types[i]);
|
||
+ }
|
||
}
|
||
|
||
/* Understand Dwarf2 support for vector types (like they occur on
|
||
@@ -4679,13 +4759,25 @@ read_tag_pointer_type (struct die_info *
|
||
struct attribute *attr_byte_size;
|
||
struct attribute *attr_address_class;
|
||
int byte_size, addr_class;
|
||
+ struct type *target_type;
|
||
|
||
if (die->type)
|
||
{
|
||
return;
|
||
}
|
||
|
||
- type = lookup_pointer_type (die_type (die, cu));
|
||
+ target_type = die_type (die, cu);
|
||
+
|
||
+ /* Intel Fortran Compiler 10.1.008 puts DW_AT_associated into
|
||
+ DW_TAG_pointer_type pointing to its target DW_TAG_array_type.
|
||
+ GDB supports DW_AT_associated and DW_AT_allocated only for the
|
||
+ DW_TAG_array_type tags. */
|
||
+ if (TYPE_CODE (target_type) == TYPE_CODE_ARRAY
|
||
+ && TYPE_FORTRAN_ARRAY (target_type) != NULL)
|
||
+ fortran_array_update (&TYPE_FORTRAN_ARRAY (target_type), die, cu, 0,
|
||
+ target_type);
|
||
+
|
||
+ type = lookup_pointer_type (target_type);
|
||
|
||
attr_byte_size = dwarf2_attr (die, DW_AT_byte_size, cu);
|
||
if (attr_byte_size)
|
||
@@ -4822,34 +4914,94 @@ read_tag_string_type (struct die_info *d
|
||
struct objfile *objfile = cu->objfile;
|
||
struct type *type, *range_type, *index_type, *char_type;
|
||
struct attribute *attr;
|
||
- unsigned int length;
|
||
+ union
|
||
+ {
|
||
+ unsigned u;
|
||
+ int i;
|
||
+ } length;
|
||
|
||
if (die->type)
|
||
{
|
||
return;
|
||
}
|
||
|
||
+ index_type = builtin_type_int32;
|
||
+ range_type = create_range_type_nfields (NULL, index_type, 2);
|
||
+ TYPE_FLAGS (range_type) |= TYPE_FLAG_UNSIGNED;
|
||
+
|
||
+ /* C/C++ should probably have the low bound 0 but C/C++ does not use
|
||
+ DW_TAG_string_type. */
|
||
+ TYPE_LOW_BOUND_RAW (range_type) = 1;
|
||
+
|
||
attr = dwarf2_attr (die, DW_AT_string_length, cu);
|
||
- if (attr)
|
||
+ switch (dwarf2_get_attr_constant_value (attr, &length.i))
|
||
{
|
||
- length = DW_UNSND (attr);
|
||
- }
|
||
- else
|
||
- {
|
||
- /* check for the DW_AT_byte_size attribute */
|
||
+ case dwarf2_attr_const:
|
||
+ /* We currently do not support a constant address where the location
|
||
+ should be read from - DWARF2_ATTR_BLOCK is expected instead. */
|
||
+ /* PASSTHRU */
|
||
+ case dwarf2_attr_unknown:
|
||
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
|
||
- if (attr)
|
||
- {
|
||
- length = DW_UNSND (attr);
|
||
- }
|
||
- else
|
||
- {
|
||
- length = 1;
|
||
- }
|
||
+ switch (dwarf2_get_attr_constant_value (attr, &length.i))
|
||
+ {
|
||
+ case dwarf2_attr_unknown:
|
||
+ length.u = 1;
|
||
+ /* PASSTHRU */
|
||
+ case dwarf2_attr_const:
|
||
+ TYPE_HIGH_BOUND_RAW (range_type) = length.u;
|
||
+ break;
|
||
+ case dwarf2_attr_block:
|
||
+ TYPE_BOUND_IS_DWARF_BLOCK_VAR (range_type, 1)
|
||
+ |= TYPE_BOUND_IS_DWARF_BLOCK_MASK;
|
||
+ TYPE_FIELD_DWARF_BLOCK (range_type, 1) = DW_BLOCK (attr);
|
||
+ break;
|
||
+ }
|
||
+ break;
|
||
+ case dwarf2_attr_block:
|
||
+ /* Security check for a size overflow. */
|
||
+ if (DW_BLOCK (attr)->size + 2 < DW_BLOCK (attr)->size)
|
||
+ {
|
||
+ TYPE_HIGH_BOUND_RAW (range_type) = 1;
|
||
+ break;
|
||
+ }
|
||
+ /* Extend the DWARF block by a new DW_OP_deref/DW_OP_deref_size
|
||
+ instruction as DW_AT_string_length specifies the length location, not
|
||
+ its value. */
|
||
+ {
|
||
+ struct dwarf_block *length_block = dwarf_alloc_block (cu);
|
||
+ struct attribute *size_attr;
|
||
+
|
||
+ length_block->data = obstack_alloc (&cu->comp_unit_obstack,
|
||
+ DW_BLOCK (attr)->size + 2);
|
||
+ memcpy (length_block->data, DW_BLOCK (attr)->data,
|
||
+ DW_BLOCK (attr)->size);
|
||
+
|
||
+ size_attr = dwarf2_attr (die, DW_AT_byte_size, cu);
|
||
+ if (size_attr)
|
||
+ {
|
||
+ length_block->size = DW_BLOCK (attr)->size + 2;
|
||
+ length_block->data[DW_BLOCK (attr)->size] = DW_OP_deref_size;
|
||
+ length_block->data[DW_BLOCK (attr)->size + 1]
|
||
+ = DW_UNSND (size_attr);
|
||
+ if (length_block->data[DW_BLOCK (attr)->size + 1]
|
||
+ != DW_UNSND (size_attr))
|
||
+ complaint (&symfile_complaints,
|
||
+ _("DW_AT_string_length's DW_AT_byte_size integer "
|
||
+ "exceeds the byte size storage"));
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ length_block->size = DW_BLOCK (attr)->size + 1;
|
||
+ length_block->data[DW_BLOCK (attr)->size] = DW_OP_deref;
|
||
+ }
|
||
+
|
||
+ TYPE_BOUND_IS_DWARF_BLOCK_VAR (range_type, 1)
|
||
+ |= TYPE_BOUND_IS_DWARF_BLOCK_MASK;
|
||
+ TYPE_FIELD_DWARF_BLOCK (range_type, 1) = length_block;
|
||
+ }
|
||
+ break;
|
||
}
|
||
|
||
- index_type = builtin_type_int32;
|
||
- range_type = create_range_type (NULL, index_type, 1, length);
|
||
type = create_string_type (NULL, range_type);
|
||
|
||
set_die_type (die, type, cu);
|
||
@@ -5048,9 +5200,9 @@ read_subrange_type (struct die_info *die
|
||
{
|
||
struct type *base_type;
|
||
struct type *range_type;
|
||
- struct attribute *attr;
|
||
- int low = 0;
|
||
- int high = -1;
|
||
+ struct attribute *attr, *byte_stride_attr;
|
||
+ int low, high, byte_stride_int;
|
||
+ enum dwarf2_get_attr_constant_value high_type, byte_stride_type;
|
||
char *name;
|
||
|
||
/* If we have already decoded this die, then nothing more to do. */
|
||
@@ -5067,42 +5219,99 @@ read_subrange_type (struct die_info *die
|
||
0, NULL, cu->objfile);
|
||
}
|
||
|
||
- if (cu->language == language_fortran)
|
||
- {
|
||
- /* FORTRAN implies a lower bound of 1, if not given. */
|
||
- low = 1;
|
||
- }
|
||
+ /* DW_AT_bit_stride is unsupported as if it would be non-constant we would
|
||
+ have to wrap it by the division by 8 or provide another value type etc. */
|
||
+ byte_stride_attr = dwarf2_attr (die, DW_AT_byte_stride, cu);
|
||
+ byte_stride_type = dwarf2_get_attr_constant_value (byte_stride_attr,
|
||
+ &byte_stride_int);
|
||
+
|
||
+ range_type = create_range_type_nfields
|
||
+ (NULL, base_type, byte_stride_type == dwarf2_attr_unknown ? 2 : 3);
|
||
|
||
- /* FIXME: For variable sized arrays either of these could be
|
||
- a variable rather than a constant value. We'll allow it,
|
||
- but we don't know how to handle it. */
|
||
attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
|
||
- if (attr)
|
||
- low = dwarf2_get_attr_constant_value (attr, 0);
|
||
+ switch (dwarf2_get_attr_constant_value (attr, &low))
|
||
+ {
|
||
+ case dwarf2_attr_unknown:
|
||
+ if (cu->language == language_fortran)
|
||
+ {
|
||
+ /* FORTRAN implies a lower bound of 1, if not given. */
|
||
+ low = 1;
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ /* According to DWARF3 we should assume the value 0 only for
|
||
+ LANGUAGE_C and LANGUAGE_CPLUS. */
|
||
+ low = 0;
|
||
+ }
|
||
+ /* PASSTHRU */
|
||
+ case dwarf2_attr_const:
|
||
+ TYPE_LOW_BOUND_RAW (range_type) = low;
|
||
+ if (low >= 0)
|
||
+ TYPE_FLAGS (range_type) |= TYPE_FLAG_UNSIGNED;
|
||
+ break;
|
||
+ case dwarf2_attr_block:
|
||
+ TYPE_BOUND_IS_DWARF_BLOCK_VAR (range_type, 0)
|
||
+ |= TYPE_BOUND_IS_DWARF_BLOCK_MASK;
|
||
+ TYPE_FIELD_DWARF_BLOCK (range_type, 0) = DW_BLOCK (attr);
|
||
+ /* For auto-detection of possibly missing DW_AT_upper_bound. */
|
||
+ low = 0;
|
||
+ break;
|
||
+ }
|
||
|
||
attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
|
||
- if (attr)
|
||
- {
|
||
- if (attr->form == DW_FORM_block1)
|
||
- {
|
||
- /* GCC encodes arrays with unspecified or dynamic length
|
||
- with a DW_FORM_block1 attribute.
|
||
- FIXME: GDB does not yet know how to handle dynamic
|
||
- arrays properly, treat them as arrays with unspecified
|
||
- length for now.
|
||
-
|
||
- FIXME: jimb/2003-09-22: GDB does not really know
|
||
- how to handle arrays of unspecified length
|
||
- either; we just represent them as zero-length
|
||
- arrays. Choose an appropriate upper bound given
|
||
- the lower bound we've computed above. */
|
||
- high = low - 1;
|
||
- }
|
||
- else
|
||
- high = dwarf2_get_attr_constant_value (attr, 1);
|
||
+ high_type = dwarf2_get_attr_constant_value (attr, &high);
|
||
+ if (high_type == dwarf2_attr_unknown)
|
||
+ {
|
||
+ int count;
|
||
+
|
||
+ attr = dwarf2_attr (die, DW_AT_count, cu);
|
||
+ high_type = dwarf2_get_attr_constant_value (attr, &count);
|
||
+ switch (high_type)
|
||
+ {
|
||
+ case dwarf2_attr_unknown:
|
||
+ break;
|
||
+ case dwarf2_attr_const:
|
||
+ /* We do not handle LOW being set as DW_BLOCK here. */
|
||
+ high = low + count - 1;
|
||
+ /* PASSTHRU */
|
||
+ case dwarf2_attr_block:
|
||
+ TYPE_HIGH_BOUND_IS_COUNT_VAR (range_type)
|
||
+ |= TYPE_HIGH_BOUND_IS_COUNT_MASK;
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+ switch (high_type)
|
||
+ {
|
||
+ case dwarf2_attr_unknown:
|
||
+ /* It needs to get propagated to he array type owning us. */
|
||
+ TYPE_ARRAY_UPPER_BOUND_TYPE (range_type) = BOUND_CANNOT_BE_DETERMINED;
|
||
+ high = low - 1;
|
||
+ /* PASSTHRU */
|
||
+ case dwarf2_attr_const:
|
||
+ TYPE_HIGH_BOUND_RAW (range_type) = high;
|
||
+ break;
|
||
+ case dwarf2_attr_block:
|
||
+ TYPE_BOUND_IS_DWARF_BLOCK_VAR (range_type, 1)
|
||
+ |= TYPE_BOUND_IS_DWARF_BLOCK_MASK;
|
||
+ TYPE_FIELD_DWARF_BLOCK (range_type, 1) = DW_BLOCK (attr);
|
||
+ break;
|
||
}
|
||
|
||
- range_type = create_range_type (NULL, base_type, low, high);
|
||
+ switch (byte_stride_type)
|
||
+ {
|
||
+ case dwarf2_attr_unknown:
|
||
+ break;
|
||
+ case dwarf2_attr_const:
|
||
+ if (byte_stride_int == 0)
|
||
+ warning (_("Found DW_AT_byte_stride with unsupported value 0"));
|
||
+ TYPE_HIGH_BOUND_RAW (range_type) = byte_stride_int;
|
||
+ break;
|
||
+ case dwarf2_attr_block:
|
||
+ TYPE_BOUND_IS_DWARF_BLOCK_VAR (range_type, 2)
|
||
+ |= TYPE_BOUND_IS_DWARF_BLOCK_MASK;
|
||
+ TYPE_FIELD_DWARF_BLOCK (range_type, 2) = DW_BLOCK (byte_stride_attr);
|
||
+ break;
|
||
+ }
|
||
|
||
name = dwarf2_name (die, cu);
|
||
if (name)
|
||
@@ -9061,26 +9270,35 @@ dwarf2_get_ref_die_offset (struct attrib
|
||
return result;
|
||
}
|
||
|
||
-/* Return the constant value held by the given attribute. Return -1
|
||
- if the value held by the attribute is not constant. */
|
||
+/* *VAL_RETURN is filled only for DWARF2_ATTR_CONST. */
|
||
|
||
-static int
|
||
-dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
|
||
+static enum dwarf2_get_attr_constant_value
|
||
+dwarf2_get_attr_constant_value (struct attribute *attr, int *val_return)
|
||
{
|
||
+ if (attr == NULL)
|
||
+ return dwarf2_attr_unknown;
|
||
if (attr->form == DW_FORM_sdata)
|
||
- return DW_SND (attr);
|
||
- else if (attr->form == DW_FORM_udata
|
||
- || attr->form == DW_FORM_data1
|
||
- || attr->form == DW_FORM_data2
|
||
- || attr->form == DW_FORM_data4
|
||
- || attr->form == DW_FORM_data8)
|
||
- return DW_UNSND (attr);
|
||
- else
|
||
{
|
||
- complaint (&symfile_complaints, _("Attribute value is not a constant (%s)"),
|
||
- dwarf_form_name (attr->form));
|
||
- return default_value;
|
||
+ *val_return = DW_SND (attr);
|
||
+ return dwarf2_attr_const;
|
||
}
|
||
+ if (attr->form == DW_FORM_udata
|
||
+ || attr->form == DW_FORM_data1
|
||
+ || attr->form == DW_FORM_data2
|
||
+ || attr->form == DW_FORM_data4
|
||
+ || attr->form == DW_FORM_data8)
|
||
+ {
|
||
+ *val_return = DW_UNSND (attr);
|
||
+ return dwarf2_attr_const;
|
||
+ }
|
||
+ if (attr->form == DW_FORM_block
|
||
+ || attr->form == DW_FORM_block1
|
||
+ || attr->form == DW_FORM_block2
|
||
+ || attr->form == DW_FORM_block4)
|
||
+ return dwarf2_attr_block;
|
||
+ complaint (&symfile_complaints, _("Attribute value is not a constant (%s)"),
|
||
+ dwarf_form_name (attr->form));
|
||
+ return dwarf2_attr_unknown;
|
||
}
|
||
|
||
static struct die_info *
|
||
diff -up -ruNp gdb-6.8-0/gdb/eval.c gdb-6.8-1/gdb/eval.c
|
||
--- gdb-6.8-0/gdb/eval.c 2008-02-04 01:23:04.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/eval.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -1643,9 +1643,12 @@ evaluate_subexp_standard (struct type *e
|
||
{
|
||
int subscript_array[MAX_FORTRAN_DIMS];
|
||
int array_size_array[MAX_FORTRAN_DIMS];
|
||
+ int byte_stride_array[MAX_FORTRAN_DIMS];
|
||
int ndimensions = 1, i;
|
||
struct type *tmp_type;
|
||
int offset_item; /* The array offset where the item lives */
|
||
+ CORE_ADDR offset_byte; /* byte_stride based offset */
|
||
+ unsigned element_size;
|
||
|
||
if (nargs > MAX_FORTRAN_DIMS)
|
||
error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS);
|
||
@@ -1682,6 +1685,9 @@ evaluate_subexp_standard (struct type *e
|
||
if (retcode == BOUND_FETCH_ERROR)
|
||
error (_("Cannot obtain dynamic lower bound"));
|
||
|
||
+ byte_stride_array[nargs - i - 1] =
|
||
+ TYPE_ARRAY_BYTE_STRIDE_VALUE (tmp_type);
|
||
+
|
||
array_size_array[nargs - i - 1] = upper - lower + 1;
|
||
|
||
/* Zero-normalize subscripts so that offsetting will work. */
|
||
@@ -1702,11 +1708,22 @@ evaluate_subexp_standard (struct type *e
|
||
|
||
/* Now let us calculate the offset for this item */
|
||
|
||
- offset_item = subscript_array[ndimensions - 1];
|
||
+ offset_item = 0;
|
||
+ offset_byte = 0;
|
||
+
|
||
+ for (i = ndimensions - 1; i >= 0; --i)
|
||
+ {
|
||
+ offset_item *= array_size_array[i];
|
||
+ if (byte_stride_array[i] == 0)
|
||
+ offset_item += subscript_array[i];
|
||
+ else
|
||
+ offset_byte += subscript_array[i] * byte_stride_array[i];
|
||
+ }
|
||
|
||
- for (i = ndimensions - 1; i > 0; --i)
|
||
- offset_item =
|
||
- array_size_array[i - 1] * offset_item + subscript_array[i - 1];
|
||
+ element_size = TYPE_LENGTH (TYPE_TARGET_TYPE (tmp_type));
|
||
+ if (offset_byte % element_size != 0)
|
||
+ warning (_("Fortran array stride not divisible by the element size"));
|
||
+ offset_item += offset_byte / element_size;
|
||
|
||
/* Construct a value node with the value of the offset */
|
||
|
||
diff -up -ruNp gdb-6.8-0/gdb/f-lang.c gdb-6.8-1/gdb/f-lang.c
|
||
--- gdb-6.8-0/gdb/f-lang.c 2008-02-05 23:17:40.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/f-lang.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -31,6 +31,7 @@
|
||
#include "f-lang.h"
|
||
#include "valprint.h"
|
||
#include "value.h"
|
||
+#include "dwarf2block.h"
|
||
|
||
|
||
/* Following is dubious stuff that had been in the xcoff reader. */
|
||
@@ -222,6 +223,29 @@ f_printstr (struct ui_file *stream, cons
|
||
if (force_ellipses || i < length)
|
||
fputs_filtered ("...", stream);
|
||
}
|
||
+
|
||
+static int
|
||
+f_value_address_get (struct type *type, CORE_ADDR *address_return)
|
||
+{
|
||
+ if (f_type_object_valid_query (type) != NULL)
|
||
+ {
|
||
+ /* Do not try to evaluate DW_AT_data_location as it may even crash
|
||
+ (it would just return the value zero in the gfortran case). */
|
||
+ return 0;
|
||
+ }
|
||
+
|
||
+ /* Accelerated codepath. */
|
||
+ if (address_return == NULL)
|
||
+ return 1;
|
||
+
|
||
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_FORTRAN_ARRAY (type) != NULL)
|
||
+ {
|
||
+ if (TYPE_FORTRAN_ARRAY_DATA_LOCATION (type) != NULL)
|
||
+ *address_return = dwarf_block_exec (TYPE_FORTRAN_ARRAY_DATA_LOCATION (type));
|
||
+ }
|
||
+
|
||
+ return 1;
|
||
+}
|
||
|
||
|
||
/* Table of operators and their precedences for printing expressions. */
|
||
@@ -337,6 +361,7 @@ const struct language_defn f_language_de
|
||
f_language_arch_info,
|
||
default_print_array_index,
|
||
default_pass_by_reference,
|
||
+ f_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
diff -up -ruNp gdb-6.8-0/gdb/f-lang.h gdb-6.8-1/gdb/f-lang.h
|
||
--- gdb-6.8-0/gdb/f-lang.h 2008-01-01 23:53:09.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/f-lang.h 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -28,6 +28,11 @@ extern void f_error (char *); /* Defined
|
||
extern void f_print_type (struct type *, char *, struct ui_file *, int,
|
||
int);
|
||
|
||
+extern const char *f_type_object_valid_query (struct type *type);
|
||
+extern const char *f_type_object_valid_to_stream (struct type *type,
|
||
+ struct ui_file *stream);
|
||
+extern void f_type_object_valid_error (struct type *type);
|
||
+
|
||
extern int f_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
|
||
struct ui_file *, int, int, int,
|
||
enum val_prettyprint);
|
||
@@ -47,6 +52,32 @@ enum f90_range_type
|
||
NONE_BOUND_DEFAULT /* "(low:high)" */
|
||
};
|
||
|
||
+/* GNU Fortran specific - for TYPE_FORTRAN_ARRAY.
|
||
+ All the DWARF_BLOCK fields are passed for execution to DWARF_BLOCK_EXEC. */
|
||
+
|
||
+struct fortran_array_type
|
||
+{
|
||
+ /* For DW_AT_data_location. This entry is more appropriate for generic
|
||
+ MAIN_TYPE but we save the MAIN_TYPE size as it is in practice not present
|
||
+ for the other types. */
|
||
+ struct dwarf_block *data_location;
|
||
+
|
||
+ /* For DW_AT_allocated. */
|
||
+ struct dwarf_block *allocated;
|
||
+
|
||
+ /* For DW_AT_associated. */
|
||
+ struct dwarf_block *associated;
|
||
+};
|
||
+
|
||
+/* Be sure to check `TYPE_CODE (thistype) == TYPE_CODE_ARRAY
|
||
+ && TYPE_FORTRAN_ARRAY (thistype) != NULL'. */
|
||
+#define TYPE_FORTRAN_ARRAY_DATA_LOCATION(thistype) \
|
||
+ TYPE_FORTRAN_ARRAY (thistype)->data_location
|
||
+#define TYPE_FORTRAN_ARRAY_ALLOCATED(thistype) \
|
||
+ TYPE_FORTRAN_ARRAY (thistype)->allocated
|
||
+#define TYPE_FORTRAN_ARRAY_ASSOCIATED(thistype) \
|
||
+ TYPE_FORTRAN_ARRAY (thistype)->associated
|
||
+
|
||
struct common_entry
|
||
{
|
||
struct symbol *symbol; /* The symbol node corresponding
|
||
diff -up -ruNp gdb-6.8-0/gdb/f-typeprint.c gdb-6.8-1/gdb/f-typeprint.c
|
||
--- gdb-6.8-0/gdb/f-typeprint.c 2008-01-01 23:53:09.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/f-typeprint.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -31,6 +31,7 @@
|
||
#include "gdbcore.h"
|
||
#include "target.h"
|
||
#include "f-lang.h"
|
||
+#include "dwarf2block.h"
|
||
|
||
#include "gdb_string.h"
|
||
#include <errno.h>
|
||
@@ -39,7 +40,7 @@
|
||
static void f_type_print_args (struct type *, struct ui_file *);
|
||
#endif
|
||
|
||
-static void f_type_print_varspec_suffix (struct type *, struct ui_file *,
|
||
+static void f_type_print_varspec_suffix (struct type *, struct ui_file *, int,
|
||
int, int, int);
|
||
|
||
void f_type_print_varspec_prefix (struct type *, struct ui_file *,
|
||
@@ -48,6 +49,50 @@ void f_type_print_varspec_prefix (struct
|
||
void f_type_print_base (struct type *, struct ui_file *, int, int);
|
||
|
||
|
||
+const char *
|
||
+f_type_object_valid_query (struct type *type)
|
||
+{
|
||
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_FORTRAN_ARRAY (type) != NULL)
|
||
+ {
|
||
+ /* DW_AT_associated has a preference over DW_AT_allocated. */
|
||
+ if (TYPE_FORTRAN_ARRAY_ASSOCIATED (type) != NULL
|
||
+ && !dwarf_block_exec (TYPE_FORTRAN_ARRAY_ASSOCIATED (type)))
|
||
+ return N_("the array is not associated");
|
||
+
|
||
+ if (TYPE_FORTRAN_ARRAY_ALLOCATED (type) != NULL
|
||
+ && !dwarf_block_exec (TYPE_FORTRAN_ARRAY_ALLOCATED (type)))
|
||
+ return N_("the array is not allocated");
|
||
+ }
|
||
+ return NULL;
|
||
+}
|
||
+
|
||
+const char *
|
||
+f_type_object_valid_to_stream (struct type *type, struct ui_file *stream)
|
||
+{
|
||
+ const char *msg;
|
||
+
|
||
+ msg = f_type_object_valid_query (type);
|
||
+ if (msg != NULL)
|
||
+ {
|
||
+ /* Assuming the content printed to STREAM should not be localized. */
|
||
+ fprintf_filtered (stream, "<%s>", msg);
|
||
+ }
|
||
+
|
||
+ return msg;
|
||
+}
|
||
+
|
||
+void
|
||
+f_type_object_valid_error (struct type *type)
|
||
+{
|
||
+ const char *msg;
|
||
+
|
||
+ msg = f_type_object_valid_query (type);
|
||
+ if (msg != NULL)
|
||
+ {
|
||
+ error (_("Unable to access the object because %s."), _(msg));
|
||
+ }
|
||
+}
|
||
+
|
||
/* LEVEL is the depth to indent lines by. */
|
||
|
||
void
|
||
@@ -57,6 +102,9 @@ f_print_type (struct type *type, char *v
|
||
enum type_code code;
|
||
int demangled_args;
|
||
|
||
+ if (f_type_object_valid_to_stream (type, stream) != NULL)
|
||
+ return;
|
||
+
|
||
f_type_print_base (type, stream, show, level);
|
||
code = TYPE_CODE (type);
|
||
if ((varstring != NULL && *varstring != '\0')
|
||
@@ -78,7 +126,7 @@ f_print_type (struct type *type, char *v
|
||
so don't print an additional pair of ()'s */
|
||
|
||
demangled_args = varstring[strlen (varstring) - 1] == ')';
|
||
- f_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
|
||
+ f_type_print_varspec_suffix (type, stream, show, 0, demangled_args, 0);
|
||
}
|
||
|
||
/* Print any asterisks or open-parentheses needed before the
|
||
@@ -147,12 +195,14 @@ f_type_print_varspec_prefix (struct type
|
||
|
||
static void
|
||
f_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
|
||
- int show, int passed_a_ptr, int demangled_args)
|
||
+ int show, int passed_a_ptr, int demangled_args,
|
||
+ int arrayprint_recurse_level)
|
||
{
|
||
int upper_bound, lower_bound;
|
||
int lower_bound_was_default = 0;
|
||
- static int arrayprint_recurse_level = 0;
|
||
int retcode;
|
||
+ /* No static variables (such as ARRAYPRINT_RECURSE_LEVEL) permitted as ERROR
|
||
+ may occur during the evaluation of DWARF_BLOCK values. */
|
||
|
||
if (type == 0)
|
||
return;
|
||
@@ -171,7 +221,8 @@ f_type_print_varspec_suffix (struct type
|
||
fprintf_filtered (stream, "(");
|
||
|
||
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY)
|
||
- f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0);
|
||
+ f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0,
|
||
+ arrayprint_recurse_level);
|
||
|
||
retcode = f77_get_dynamic_lowerbound (type, &lower_bound);
|
||
|
||
@@ -205,7 +256,8 @@ f_type_print_varspec_suffix (struct type
|
||
}
|
||
|
||
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_ARRAY)
|
||
- f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0);
|
||
+ f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0,
|
||
+ arrayprint_recurse_level);
|
||
if (arrayprint_recurse_level == 1)
|
||
fprintf_filtered (stream, ")");
|
||
else
|
||
@@ -215,13 +267,14 @@ f_type_print_varspec_suffix (struct type
|
||
|
||
case TYPE_CODE_PTR:
|
||
case TYPE_CODE_REF:
|
||
- f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1, 0);
|
||
+ f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1, 0,
|
||
+ arrayprint_recurse_level);
|
||
fprintf_filtered (stream, ")");
|
||
break;
|
||
|
||
case TYPE_CODE_FUNC:
|
||
f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
|
||
- passed_a_ptr, 0);
|
||
+ passed_a_ptr, 0, arrayprint_recurse_level);
|
||
if (passed_a_ptr)
|
||
fprintf_filtered (stream, ")");
|
||
|
||
diff -up -ruNp gdb-6.8-0/gdb/f-valprint.c gdb-6.8-1/gdb/f-valprint.c
|
||
--- gdb-6.8-0/gdb/f-valprint.c 2008-01-11 14:34:14.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/f-valprint.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -54,11 +54,11 @@ int f77_array_offset_tbl[MAX_FORTRAN_DIM
|
||
/* The following macro gives us the size of the nth dimension, Where
|
||
n is 1 based. */
|
||
|
||
-#define F77_DIM_SIZE(n) (f77_array_offset_tbl[n][1])
|
||
+#define F77_DIM_COUNT(n) (f77_array_offset_tbl[n][1])
|
||
|
||
-/* The following gives us the offset for row n where n is 1-based. */
|
||
+/* The following gives us the element size for row n where n is 1-based. */
|
||
|
||
-#define F77_DIM_OFFSET(n) (f77_array_offset_tbl[n][0])
|
||
+#define F77_DIM_BYTE_STRIDE(n) (f77_array_offset_tbl[n][0])
|
||
|
||
int
|
||
f77_get_dynamic_lowerbound (struct type *type, int *lower_bound)
|
||
@@ -67,6 +67,8 @@ f77_get_dynamic_lowerbound (struct type
|
||
CORE_ADDR current_frame_addr;
|
||
CORE_ADDR ptr_to_lower_bound;
|
||
|
||
+ f_type_object_valid_error (type);
|
||
+
|
||
switch (TYPE_ARRAY_LOWER_BOUND_TYPE (type))
|
||
{
|
||
case BOUND_BY_VALUE_ON_STACK:
|
||
@@ -128,6 +130,8 @@ f77_get_dynamic_upperbound (struct type
|
||
CORE_ADDR current_frame_addr = 0;
|
||
CORE_ADDR ptr_to_upper_bound;
|
||
|
||
+ f_type_object_valid_error (type);
|
||
+
|
||
switch (TYPE_ARRAY_UPPER_BOUND_TYPE (type))
|
||
{
|
||
case BOUND_BY_VALUE_ON_STACK:
|
||
@@ -250,24 +254,29 @@ f77_create_arrayprint_offset_tbl (struct
|
||
if (retcode == BOUND_FETCH_ERROR)
|
||
error (_("Cannot obtain dynamic lower bound"));
|
||
|
||
- F77_DIM_SIZE (ndimen) = upper - lower + 1;
|
||
+ F77_DIM_COUNT (ndimen) = upper - lower + 1;
|
||
+
|
||
+ F77_DIM_BYTE_STRIDE (ndimen) =
|
||
+ TYPE_ARRAY_BYTE_STRIDE_VALUE (tmp_type);
|
||
|
||
tmp_type = TYPE_TARGET_TYPE (tmp_type);
|
||
ndimen++;
|
||
}
|
||
|
||
- /* Now we multiply eltlen by all the offsets, so that later we
|
||
+ /* Now we multiply eltlen by all the BYTE_STRIDEs, so that later we
|
||
can print out array elements correctly. Up till now we
|
||
- know an offset to apply to get the item but we also
|
||
+ know an eltlen to apply to get the item but we also
|
||
have to know how much to add to get to the next item */
|
||
|
||
ndimen--;
|
||
eltlen = TYPE_LENGTH (tmp_type);
|
||
- F77_DIM_OFFSET (ndimen) = eltlen;
|
||
+ if (F77_DIM_BYTE_STRIDE (ndimen) == 0)
|
||
+ F77_DIM_BYTE_STRIDE (ndimen) = eltlen;
|
||
while (--ndimen > 0)
|
||
{
|
||
- eltlen *= F77_DIM_SIZE (ndimen + 1);
|
||
- F77_DIM_OFFSET (ndimen) = eltlen;
|
||
+ eltlen *= F77_DIM_COUNT (ndimen + 1);
|
||
+ if (F77_DIM_BYTE_STRIDE (ndimen) == 0)
|
||
+ F77_DIM_BYTE_STRIDE (ndimen) = eltlen;
|
||
}
|
||
}
|
||
|
||
@@ -287,33 +296,33 @@ f77_print_array_1 (int nss, int ndimensi
|
||
|
||
if (nss != ndimensions)
|
||
{
|
||
- for (i = 0; (i < F77_DIM_SIZE (nss) && (*elts) < print_max); i++)
|
||
+ for (i = 0; (i < F77_DIM_COUNT (nss) && (*elts) < print_max); i++)
|
||
{
|
||
fprintf_filtered (stream, "( ");
|
||
f77_print_array_1 (nss + 1, ndimensions, TYPE_TARGET_TYPE (type),
|
||
- valaddr + i * F77_DIM_OFFSET (nss),
|
||
- address + i * F77_DIM_OFFSET (nss),
|
||
+ valaddr + i * F77_DIM_BYTE_STRIDE (nss),
|
||
+ address + i * F77_DIM_BYTE_STRIDE (nss),
|
||
stream, format, deref_ref, recurse, pretty, elts);
|
||
fprintf_filtered (stream, ") ");
|
||
}
|
||
- if (*elts >= print_max && i < F77_DIM_SIZE (nss))
|
||
+ if (*elts >= print_max && i < F77_DIM_COUNT (nss))
|
||
fprintf_filtered (stream, "...");
|
||
}
|
||
else
|
||
{
|
||
- for (i = 0; i < F77_DIM_SIZE (nss) && (*elts) < print_max;
|
||
+ for (i = 0; i < F77_DIM_COUNT (nss) && (*elts) < print_max;
|
||
i++, (*elts)++)
|
||
{
|
||
val_print (TYPE_TARGET_TYPE (type),
|
||
- valaddr + i * F77_DIM_OFFSET (ndimensions),
|
||
+ valaddr + i * F77_DIM_BYTE_STRIDE (ndimensions),
|
||
0,
|
||
- address + i * F77_DIM_OFFSET (ndimensions),
|
||
+ address + i * F77_DIM_BYTE_STRIDE (ndimensions),
|
||
stream, format, deref_ref, recurse, pretty);
|
||
|
||
- if (i != (F77_DIM_SIZE (nss) - 1))
|
||
+ if (i != (F77_DIM_COUNT (nss) - 1))
|
||
fprintf_filtered (stream, ", ");
|
||
|
||
- if ((*elts == print_max - 1) && (i != (F77_DIM_SIZE (nss) - 1)))
|
||
+ if ((*elts == print_max - 1) && (i != (F77_DIM_COUNT (nss) - 1)))
|
||
fprintf_filtered (stream, "...");
|
||
}
|
||
}
|
||
@@ -372,6 +381,9 @@ f_val_print (struct type *type, const gd
|
||
CORE_ADDR addr;
|
||
int index;
|
||
|
||
+ if (f_type_object_valid_to_stream (type, stream) != NULL)
|
||
+ return 0;
|
||
+
|
||
CHECK_TYPEDEF (type);
|
||
switch (TYPE_CODE (type))
|
||
{
|
||
diff -up -ruNp gdb-6.8-0/gdb/findvar.c gdb-6.8-1/gdb/findvar.c
|
||
--- gdb-6.8-0/gdb/findvar.c 2008-01-01 23:53:09.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/findvar.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -34,6 +34,7 @@
|
||
#include "regcache.h"
|
||
#include "user-regs.h"
|
||
#include "block.h"
|
||
+#include "dwarf2block.h"
|
||
|
||
/* Basic byte-swapping routines. GDB has needed these for a long time...
|
||
All extract a target-format integer at ADDR which is LEN bytes long. */
|
||
@@ -370,24 +371,8 @@ symbol_read_needs_frame (struct symbol *
|
||
struct value *
|
||
read_var_value (struct symbol *var, struct frame_info *frame)
|
||
{
|
||
- struct value *v;
|
||
struct type *type = SYMBOL_TYPE (var);
|
||
CORE_ADDR addr;
|
||
- int len;
|
||
-
|
||
- if (SYMBOL_CLASS (var) == LOC_COMPUTED
|
||
- || SYMBOL_CLASS (var) == LOC_COMPUTED_ARG
|
||
- || SYMBOL_CLASS (var) == LOC_REGISTER
|
||
- || SYMBOL_CLASS (var) == LOC_REGPARM)
|
||
- /* These cases do not use V. */
|
||
- v = NULL;
|
||
- else
|
||
- {
|
||
- v = allocate_value (type);
|
||
- VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */
|
||
- }
|
||
-
|
||
- len = TYPE_LENGTH (type);
|
||
|
||
/* FIXME drow/2003-09-06: this call to the selected frame should be
|
||
pushed upwards to the callers. */
|
||
@@ -397,31 +382,39 @@ read_var_value (struct symbol *var, stru
|
||
switch (SYMBOL_CLASS (var))
|
||
{
|
||
case LOC_CONST:
|
||
- /* Put the constant back in target format. */
|
||
- store_signed_integer (value_contents_raw (v), len,
|
||
- (LONGEST) SYMBOL_VALUE (var));
|
||
- VALUE_LVAL (v) = not_lval;
|
||
- return v;
|
||
+ {
|
||
+ /* Put the constant back in target format. */
|
||
+ struct value *v = allocate_value (type);
|
||
+ VALUE_LVAL (v) = not_lval;
|
||
+ store_signed_integer (value_contents_raw (v), TYPE_LENGTH (type),
|
||
+ (LONGEST) SYMBOL_VALUE (var));
|
||
+ return v;
|
||
+ }
|
||
|
||
case LOC_LABEL:
|
||
- /* Put the constant back in target format. */
|
||
- if (overlay_debugging)
|
||
- {
|
||
- CORE_ADDR addr
|
||
- = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
|
||
- SYMBOL_BFD_SECTION (var));
|
||
- store_typed_address (value_contents_raw (v), type, addr);
|
||
- }
|
||
- else
|
||
- store_typed_address (value_contents_raw (v), type,
|
||
- SYMBOL_VALUE_ADDRESS (var));
|
||
- VALUE_LVAL (v) = not_lval;
|
||
- return v;
|
||
+ {
|
||
+ /* Put the constant back in target format. */
|
||
+ struct value *v = allocate_value (type);
|
||
+ VALUE_LVAL (v) = not_lval;
|
||
+ if (overlay_debugging)
|
||
+ {
|
||
+ CORE_ADDR addr
|
||
+ = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
|
||
+ SYMBOL_BFD_SECTION (var));
|
||
+ store_typed_address (value_contents_raw (v), type, addr);
|
||
+ }
|
||
+ else
|
||
+ store_typed_address (value_contents_raw (v), type,
|
||
+ SYMBOL_VALUE_ADDRESS (var));
|
||
+ return v;
|
||
+ }
|
||
|
||
case LOC_CONST_BYTES:
|
||
{
|
||
- memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var), len);
|
||
+ struct value *v = allocate_value (type);
|
||
VALUE_LVAL (v) = not_lval;
|
||
+ memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var),
|
||
+ TYPE_LENGTH (type));
|
||
return v;
|
||
}
|
||
|
||
@@ -503,12 +496,23 @@ addresses have not been bound by the dyn
|
||
break;
|
||
|
||
case LOC_BLOCK:
|
||
- if (overlay_debugging)
|
||
- VALUE_ADDRESS (v) = symbol_overlayed_address
|
||
- (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_BFD_SECTION (var));
|
||
- else
|
||
- VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (var));
|
||
- return v;
|
||
+ {
|
||
+ CORE_ADDR addr;
|
||
+ struct value *v;
|
||
+
|
||
+ if (overlay_debugging)
|
||
+ addr = symbol_overlayed_address
|
||
+ (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_BFD_SECTION (var));
|
||
+ else
|
||
+ addr = BLOCK_START (SYMBOL_BLOCK_VALUE (var));
|
||
+ /* ADDR is set here for ALLOCATE_VALUE's CHECK_TYPEDEF for
|
||
+ DW_OP_push_object_address. */
|
||
+ object_address_set (addr);
|
||
+ v = allocate_value (type);
|
||
+ VALUE_ADDRESS (v) = addr;
|
||
+ VALUE_LVAL (v) = lval_memory;
|
||
+ return v;
|
||
+ }
|
||
|
||
case LOC_REGISTER:
|
||
case LOC_REGPARM:
|
||
@@ -532,7 +536,6 @@ addresses have not been bound by the dyn
|
||
error (_("Value of register variable not available."));
|
||
|
||
addr = value_as_address (regval);
|
||
- VALUE_LVAL (v) = lval_memory;
|
||
}
|
||
else
|
||
{
|
||
@@ -572,18 +575,33 @@ addresses have not been bound by the dyn
|
||
break;
|
||
|
||
case LOC_OPTIMIZED_OUT:
|
||
- VALUE_LVAL (v) = not_lval;
|
||
- set_value_optimized_out (v, 1);
|
||
- return v;
|
||
+ {
|
||
+ struct value *v = allocate_value (type);
|
||
+
|
||
+ VALUE_LVAL (v) = not_lval;
|
||
+ set_value_optimized_out (v, 1);
|
||
+ return v;
|
||
+ }
|
||
|
||
default:
|
||
error (_("Cannot look up value of a botched symbol."));
|
||
break;
|
||
}
|
||
|
||
- VALUE_ADDRESS (v) = addr;
|
||
- set_value_lazy (v, 1);
|
||
- return v;
|
||
+ {
|
||
+ struct value *v;
|
||
+
|
||
+ /* ADDR is set here for ALLOCATE_VALUE's CHECK_TYPEDEF for
|
||
+ DW_OP_push_object_address. */
|
||
+ object_address_set (addr);
|
||
+ v = allocate_value (type);
|
||
+ VALUE_ADDRESS (v) = addr;
|
||
+ VALUE_LVAL (v) = lval_memory;
|
||
+
|
||
+ set_value_lazy (v, 1);
|
||
+
|
||
+ return v;
|
||
+ }
|
||
}
|
||
|
||
/* Install default attributes for register values. */
|
||
diff -up -ruNp gdb-6.8-0/gdb/gdbtypes.c gdb-6.8-1/gdb/gdbtypes.c
|
||
--- gdb-6.8-0/gdb/gdbtypes.c 2008-08-23 22:29:56.000000000 +0200
|
||
+++ gdb-6.8-1/gdb/gdbtypes.c 2008-08-23 22:31:08.000000000 +0200
|
||
@@ -38,6 +38,7 @@
|
||
#include "cp-abi.h"
|
||
#include "gdb_assert.h"
|
||
#include "hashtab.h"
|
||
+#include "dwarf2block.h"
|
||
|
||
/* These variables point to the objects
|
||
representing the predefined C data types. */
|
||
@@ -682,16 +683,21 @@ allocate_stub_method (struct type *type)
|
||
RESULT_TYPE, or creating a new type, inheriting the objfile from
|
||
INDEX_TYPE.
|
||
|
||
- Indices will be of type INDEX_TYPE, and will range from LOW_BOUND
|
||
- to HIGH_BOUND, inclusive.
|
||
+ Indices will be of type INDEX_TYPE. NFIELDS should be 2 for standard
|
||
+ arrays, 3 for a custom TYPE_BYTE_STRIDE. Use CREATE_RANGE_TYPE for common
|
||
+ constant LOW_BOUND/HIGH_BOUND ranges.
|
||
+
|
||
+ You must set TYPE_FLAG_UNSIGNED yourself as being done in CREATE_RANGE_TYPE.
|
||
|
||
FIXME: Maybe we should check the TYPE_CODE of RESULT_TYPE to make
|
||
sure it is TYPE_CODE_UNDEF before we bash it into a range type? */
|
||
|
||
struct type *
|
||
-create_range_type (struct type *result_type, struct type *index_type,
|
||
- int low_bound, int high_bound)
|
||
+create_range_type_nfields (struct type *result_type, struct type *index_type,
|
||
+ int nfields)
|
||
{
|
||
+ int fieldno;
|
||
+
|
||
if (result_type == NULL)
|
||
{
|
||
result_type = alloc_type (TYPE_OBJFILE (index_type));
|
||
@@ -702,17 +708,33 @@ create_range_type (struct type *result_t
|
||
TYPE_FLAGS (result_type) |= TYPE_FLAG_TARGET_STUB;
|
||
else
|
||
TYPE_LENGTH (result_type) = TYPE_LENGTH (check_typedef (index_type));
|
||
- TYPE_NFIELDS (result_type) = 2;
|
||
+ TYPE_NFIELDS (result_type) = nfields;
|
||
TYPE_FIELDS (result_type) = (struct field *)
|
||
- TYPE_ALLOC (result_type, 2 * sizeof (struct field));
|
||
- memset (TYPE_FIELDS (result_type), 0, 2 * sizeof (struct field));
|
||
- TYPE_FIELD_BITPOS (result_type, 0) = low_bound;
|
||
- TYPE_FIELD_BITPOS (result_type, 1) = high_bound;
|
||
+ TYPE_ALLOC (result_type,
|
||
+ TYPE_NFIELDS (result_type) * sizeof (struct field));
|
||
+ memset (TYPE_FIELDS (result_type), 0,
|
||
+ TYPE_NFIELDS (result_type) * sizeof (struct field));
|
||
+
|
||
+ return (result_type);
|
||
+}
|
||
+
|
||
+/* Simplified CREATE_RANGE_TYPE_NFIELDS for constant ranges from LOW_BOUND to
|
||
+ HIGH_BOUND, inclusive. TYPE_BYTE_STRIDE is always set to zero (default
|
||
+ native target type length). */
|
||
+
|
||
+struct type *
|
||
+create_range_type (struct type *result_type, struct type *index_type,
|
||
+ int low_bound, int high_bound)
|
||
+{
|
||
+ result_type = create_range_type_nfields (result_type, index_type, 2);
|
||
+
|
||
+ TYPE_LOW_BOUND_RAW (result_type) = low_bound;
|
||
+ TYPE_HIGH_BOUND_RAW (result_type) = high_bound;
|
||
|
||
if (low_bound >= 0)
|
||
TYPE_FLAGS (result_type) |= TYPE_FLAG_UNSIGNED;
|
||
|
||
- return (result_type);
|
||
+ return result_type;
|
||
}
|
||
|
||
/* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type
|
||
@@ -800,25 +822,23 @@ create_array_type (struct type *result_t
|
||
struct type *element_type,
|
||
struct type *range_type)
|
||
{
|
||
- LONGEST low_bound, high_bound;
|
||
-
|
||
if (result_type == NULL)
|
||
{
|
||
result_type = alloc_type (TYPE_OBJFILE (range_type));
|
||
}
|
||
TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
|
||
TYPE_TARGET_TYPE (result_type) = element_type;
|
||
- if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
|
||
- low_bound = high_bound = 0;
|
||
CHECK_TYPEDEF (element_type);
|
||
- /* Be careful when setting the array length. Ada arrays can be
|
||
- empty arrays with the high_bound being smaller than the low_bound.
|
||
- In such cases, the array length should be zero. */
|
||
- if (high_bound < low_bound)
|
||
+ /* Dynamically sized arrays cannot be computed now as we may have forward
|
||
+ DWARF references here. */
|
||
+ if ((TYPE_BOUND_IS_DWARF_BLOCK_VAR (range_type, 0)
|
||
+ & TYPE_BOUND_IS_DWARF_BLOCK_MASK) != 0
|
||
+ && (TYPE_BOUND_IS_DWARF_BLOCK_VAR (range_type, 1)
|
||
+ & TYPE_BOUND_IS_DWARF_BLOCK_MASK) != 0)
|
||
TYPE_LENGTH (result_type) = 0;
|
||
else
|
||
- TYPE_LENGTH (result_type) =
|
||
- TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
|
||
+ TYPE_LENGTH (result_type) = TYPE_LENGTH (element_type)
|
||
+ * TYPE_COUNT_BOUND (range_type);
|
||
TYPE_NFIELDS (result_type) = 1;
|
||
TYPE_FIELDS (result_type) =
|
||
(struct field *) TYPE_ALLOC (result_type, sizeof (struct field));
|
||
@@ -1377,6 +1397,117 @@ stub_noname_complaint (void)
|
||
complaint (&symfile_complaints, _("stub type has NULL name"));
|
||
}
|
||
|
||
+CORE_ADDR range_type_any_field_internal (struct type *range_type, int fieldno)
|
||
+{
|
||
+ if ((TYPE_BOUND_IS_DWARF_BLOCK_VAR (range_type, fieldno)
|
||
+ & TYPE_BOUND_IS_DWARF_BLOCK_MASK) != 0)
|
||
+ return dwarf_block_exec (TYPE_FIELD_DWARF_BLOCK (range_type, fieldno));
|
||
+ else
|
||
+ return TYPE_FIELD_BITPOS (range_type, (fieldno));
|
||
+}
|
||
+
|
||
+int
|
||
+range_type_high_bound_internal (struct type *range_type)
|
||
+{
|
||
+ int raw_value = range_type_any_field_internal (range_type, 1);
|
||
+
|
||
+ if ((TYPE_HIGH_BOUND_IS_COUNT_VAR (range_type)
|
||
+ & TYPE_HIGH_BOUND_IS_COUNT_MASK) == 0)
|
||
+ {
|
||
+ /* DW_AT_upper_bound value. */
|
||
+ return raw_value;
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ /* DW_AT_count value. */
|
||
+ return TYPE_LOW_BOUND (range_type) + raw_value - 1;
|
||
+ }
|
||
+}
|
||
+
|
||
+int
|
||
+range_type_count_bound_internal (struct type *range_type)
|
||
+{
|
||
+ int raw_value = range_type_any_field_internal (range_type, 1);
|
||
+ if ((TYPE_HIGH_BOUND_IS_COUNT_VAR (range_type)
|
||
+ & TYPE_HIGH_BOUND_IS_COUNT_MASK) != 0)
|
||
+ {
|
||
+ /* DW_AT_count value. */
|
||
+ return raw_value;
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ /* DW_AT_upper_bound value. */
|
||
+ /* Be careful when getting the array length. Ada arrays can be
|
||
+ empty arrays with the high_bound being smaller than the low_bound.
|
||
+ In such cases, the array length should be zero. */
|
||
+ if (raw_value < TYPE_LOW_BOUND (range_type))
|
||
+ return 0;
|
||
+ return 1 + raw_value - TYPE_LOW_BOUND (range_type);
|
||
+ }
|
||
+}
|
||
+
|
||
+CORE_ADDR range_type_byte_stride_internal (struct type *range_type,
|
||
+ struct type *element_type)
|
||
+{
|
||
+ if (TYPE_NFIELDS (range_type) >= 3)
|
||
+ return range_type_any_field_internal (range_type, 2);
|
||
+ else if (element_type == NULL)
|
||
+ return 0;
|
||
+ else
|
||
+ return TYPE_LENGTH (check_typedef (element_type));
|
||
+}
|
||
+
|
||
+/* Calculate the memory length of array TYPE.
|
||
+
|
||
+ TARGET_TYPE should be set to `check_typedef (TYPE_TARGET_TYPE (type))' as
|
||
+ a performance hint. Feel free to pass NULL. Set FULL_SPAN to return the
|
||
+ size incl. the possibly incomplete last element - it may differ from the
|
||
+ cleared FULL_SPAN return value for larger TYPE_BYTE_STRIDE values. */
|
||
+
|
||
+static CORE_ADDR
|
||
+type_length_get (struct type *type, struct type *target_type, int full_span)
|
||
+{
|
||
+ struct type *range_type;
|
||
+ int count;
|
||
+ CORE_ADDR byte_stride = 0; /* `= 0' for a false GCC warning. */
|
||
+ CORE_ADDR element_size;
|
||
+
|
||
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY
|
||
+ && TYPE_CODE (type) != TYPE_CODE_STRING)
|
||
+ return TYPE_LENGTH (type);
|
||
+
|
||
+ /* Avoid executing TYPE_COUNT_BOUND for invalid (unallocated/unassociated)
|
||
+ Fortran arrays. The allocated data will never be used so they can be
|
||
+ zero-length. */
|
||
+ if (!LA_VALUE_ADDRESS_GET (type, NULL))
|
||
+ return 0;
|
||
+
|
||
+ range_type = TYPE_INDEX_TYPE (type);
|
||
+ count = TYPE_COUNT_BOUND (range_type);
|
||
+ if (count < 0)
|
||
+ warning (_("Object count %d < 0"), count);
|
||
+ if (count <= 0)
|
||
+ return 0;
|
||
+ if (full_span || count > 1)
|
||
+ {
|
||
+ /* We do not use TYPE_ARRAY_BYTE_STRIDE_VALUE (type) here as we want to
|
||
+ force FULL_SPAN to 1. */
|
||
+ byte_stride = TYPE_BYTE_STRIDE (range_type);
|
||
+ if (byte_stride == 0)
|
||
+ {
|
||
+ if (target_type == NULL)
|
||
+ target_type = check_typedef (TYPE_TARGET_TYPE (type));
|
||
+ byte_stride = type_length_get (target_type, NULL, 1);
|
||
+ }
|
||
+ }
|
||
+ if (full_span)
|
||
+ return count * byte_stride;
|
||
+ if (target_type == NULL)
|
||
+ target_type = check_typedef (TYPE_TARGET_TYPE (type));
|
||
+ element_size = type_length_get (target_type, NULL, 1);
|
||
+ return (count - 1) * byte_stride + element_size;
|
||
+}
|
||
+
|
||
/* Added by Bryan Boreham, Kewill, Sun Sep 17 18:07:17 1989.
|
||
|
||
If this is a stubbed struct (i.e. declared as struct foo *), see if
|
||
@@ -1514,25 +1645,15 @@ check_typedef (struct type *type)
|
||
{
|
||
/* Empty. */
|
||
}
|
||
- else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
|
||
+ else if ((TYPE_CODE (type) == TYPE_CODE_ARRAY
|
||
+ || TYPE_CODE (type) == TYPE_CODE_STRING)
|
||
&& TYPE_NFIELDS (type) == 1
|
||
&& (TYPE_CODE (range_type = TYPE_FIELD_TYPE (type, 0))
|
||
== TYPE_CODE_RANGE))
|
||
{
|
||
/* Now recompute the length of the array type, based on its
|
||
- number of elements and the target type's length.
|
||
- Watch out for Ada null Ada arrays where the high bound
|
||
- is smaller than the low bound. */
|
||
- const int low_bound = TYPE_FIELD_BITPOS (range_type, 0);
|
||
- const int high_bound = TYPE_FIELD_BITPOS (range_type, 1);
|
||
- int nb_elements;
|
||
-
|
||
- if (high_bound < low_bound)
|
||
- nb_elements = 0;
|
||
- else
|
||
- nb_elements = high_bound - low_bound + 1;
|
||
-
|
||
- TYPE_LENGTH (type) = nb_elements * TYPE_LENGTH (target_type);
|
||
+ number of elements and the target type's length. */
|
||
+ TYPE_LENGTH (type) = type_length_get (type, target_type, 0);
|
||
TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB;
|
||
}
|
||
else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
|
||
diff -up -ruNp gdb-6.8-0/gdb/gdbtypes.h gdb-6.8-1/gdb/gdbtypes.h
|
||
--- gdb-6.8-0/gdb/gdbtypes.h 2008-08-23 22:29:56.000000000 +0200
|
||
+++ gdb-6.8-1/gdb/gdbtypes.h 2008-08-23 22:31:08.000000000 +0200
|
||
@@ -417,6 +417,9 @@ struct main_type
|
||
|
||
CORE_ADDR physaddr;
|
||
char *physname;
|
||
+
|
||
+ /* For dynamically-sized arrays. Passed to DWARF_BLOCK_EXEC. */
|
||
+ struct dwarf_block *dwarf_block;
|
||
}
|
||
loc;
|
||
|
||
@@ -427,7 +430,11 @@ struct main_type
|
||
|
||
/* This flag is zero for non-static fields, 1 for fields whose location
|
||
is specified by the label loc.physname, and 2 for fields whose location
|
||
- is specified by loc.physaddr. */
|
||
+ is specified by loc.physaddr.
|
||
+ For range bounds bit 0 cleared is for loc.bitpos and bit 0 set is for
|
||
+ loc.dwarf_block (TYPE_BOUND_IS_DWARF_BLOCK_MASK).
|
||
+ For range bounds bit 1 cleared is for DW_AT_upper_bound and bit 1 set is
|
||
+ for DW_AT_count (TYPE_HIGH_BOUND_IS_COUNT_MASK). */
|
||
|
||
unsigned int static_kind : 2;
|
||
|
||
@@ -481,6 +488,10 @@ struct main_type
|
||
targets and the second is for little endian targets. */
|
||
|
||
const struct floatformat **floatformat;
|
||
+
|
||
+ /* FORTRAN_ARRAY is for TYPE_CODE_ARRAY. */
|
||
+
|
||
+ struct fortran_array_type *fortran_array;
|
||
} type_specific;
|
||
};
|
||
|
||
@@ -766,9 +777,9 @@ extern void allocate_cplus_struct_type (
|
||
#define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type
|
||
#define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
|
||
#define TYPE_CHAIN(thistype) (thistype)->chain
|
||
-/* Note that if thistype is a TYPEDEF type, you have to call check_typedef.
|
||
- But check_typedef does set the TYPE_LENGTH of the TYPEDEF type,
|
||
- so you only have to call check_typedef once. Since allocate_value
|
||
+/* Note that if thistype is a TYPEDEF or ARRAY type, you have to call
|
||
+ check_typedef. But check_typedef does set the TYPE_LENGTH of the TYPEDEF
|
||
+ type, so you only have to call check_typedef once. Since allocate_value
|
||
calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe. */
|
||
#define TYPE_LENGTH(thistype) (thistype)->length
|
||
#define TYPE_OBJFILE(thistype) TYPE_MAIN_TYPE(thistype)->objfile
|
||
@@ -782,8 +793,25 @@ extern void allocate_cplus_struct_type (
|
||
#define TYPE_INSTANTIATIONS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->instantiations
|
||
|
||
#define TYPE_INDEX_TYPE(type) TYPE_FIELD_TYPE (type, 0)
|
||
-#define TYPE_LOW_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 0)
|
||
-#define TYPE_HIGH_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 1)
|
||
+#define TYPE_LOW_BOUND_RAW(range_type) TYPE_FIELD_BITPOS (range_type, 0)
|
||
+#define TYPE_HIGH_BOUND_RAW(range_type) TYPE_FIELD_BITPOS (range_type, 1)
|
||
+/* `TYPE_NFIELDS (range_type) >= 3' check is required before accessing it: */
|
||
+#define TYPE_BYTE_STRIDE_RAW(range_type) TYPE_FIELD_BITPOS (range_type, 2)
|
||
+#define TYPE_LOW_BOUND(range_type) \
|
||
+ ((int) range_type_any_field_internal ((range_type), 0))
|
||
+#define TYPE_HIGH_BOUND(range_type) \
|
||
+ range_type_high_bound_internal ((range_type))
|
||
+#define TYPE_COUNT_BOUND(range_type) \
|
||
+ range_type_count_bound_internal ((range_type))
|
||
+#define TYPE_BYTE_STRIDE(type) \
|
||
+ range_type_byte_stride_internal ((type), NULL)
|
||
+
|
||
+#define TYPE_BOUND_IS_DWARF_BLOCK_MASK 1
|
||
+#define TYPE_BOUND_IS_DWARF_BLOCK_VAR(range_type, fieldno) \
|
||
+ TYPE_FIELD_STATIC_KIND (range_type, fieldno)
|
||
+#define TYPE_HIGH_BOUND_IS_COUNT_MASK 2
|
||
+#define TYPE_HIGH_BOUND_IS_COUNT_VAR(range_type) \
|
||
+ TYPE_FIELD_STATIC_KIND (range_type, 1)
|
||
|
||
/* Moto-specific stuff for FORTRAN arrays */
|
||
|
||
@@ -792,11 +820,14 @@ extern void allocate_cplus_struct_type (
|
||
#define TYPE_ARRAY_LOWER_BOUND_TYPE(thistype) \
|
||
TYPE_MAIN_TYPE(thistype)->lower_bound_type
|
||
|
||
-#define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \
|
||
- (TYPE_FIELD_BITPOS((TYPE_FIELD_TYPE((arraytype),0)),1))
|
||
-
|
||
#define TYPE_ARRAY_LOWER_BOUND_VALUE(arraytype) \
|
||
- (TYPE_FIELD_BITPOS((TYPE_FIELD_TYPE((arraytype),0)),0))
|
||
+ (TYPE_LOW_BOUND(TYPE_INDEX_TYPE(arraytype)))
|
||
+#define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \
|
||
+ (TYPE_HIGH_BOUND(TYPE_INDEX_TYPE(arraytype)))
|
||
+/* ELEMENT_TYPE-enhanced TYPE_BYTE_STRIDE(TYPE_INDEX_TYPE(arraytype)) */
|
||
+#define TYPE_ARRAY_BYTE_STRIDE_VALUE(arraytype) \
|
||
+ range_type_byte_stride_internal (TYPE_INDEX_TYPE (arraytype), \
|
||
+ TYPE_TARGET_TYPE (arraytype))
|
||
|
||
/* C++ */
|
||
|
||
@@ -812,6 +843,7 @@ extern void allocate_cplus_struct_type (
|
||
#define TYPE_TYPE_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific
|
||
#define TYPE_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff
|
||
#define TYPE_FLOATFORMAT(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.floatformat
|
||
+#define TYPE_FORTRAN_ARRAY(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.fortran_array
|
||
#define TYPE_BASECLASS(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].type
|
||
#define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses
|
||
#define TYPE_BASECLASS_NAME(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].name
|
||
@@ -826,6 +858,7 @@ extern void allocate_cplus_struct_type (
|
||
#define FIELD_TYPE(thisfld) ((thisfld).type)
|
||
#define FIELD_NAME(thisfld) ((thisfld).name)
|
||
#define FIELD_BITPOS(thisfld) ((thisfld).loc.bitpos)
|
||
+#define FIELD_DWARF_BLOCK(thisfld) ((thisfld).loc.dwarf_block)
|
||
#define FIELD_ARTIFICIAL(thisfld) ((thisfld).artificial)
|
||
#define FIELD_BITSIZE(thisfld) ((thisfld).bitsize)
|
||
#define FIELD_STATIC_KIND(thisfld) ((thisfld).static_kind)
|
||
@@ -839,6 +872,7 @@ extern void allocate_cplus_struct_type (
|
||
#define TYPE_FIELD_TYPE(thistype, n) FIELD_TYPE(TYPE_FIELD(thistype, n))
|
||
#define TYPE_FIELD_NAME(thistype, n) FIELD_NAME(TYPE_FIELD(thistype, n))
|
||
#define TYPE_FIELD_BITPOS(thistype, n) FIELD_BITPOS(TYPE_FIELD(thistype,n))
|
||
+#define TYPE_FIELD_DWARF_BLOCK(thistype, n) FIELD_DWARF_BLOCK(TYPE_FIELD(thistype,n))
|
||
#define TYPE_FIELD_ARTIFICIAL(thistype, n) FIELD_ARTIFICIAL(TYPE_FIELD(thistype,n))
|
||
#define TYPE_FIELD_BITSIZE(thistype, n) FIELD_BITSIZE(TYPE_FIELD(thistype,n))
|
||
#define TYPE_FIELD_PACKED(thistype, n) (FIELD_BITSIZE(TYPE_FIELD(thistype,n))!=0)
|
||
@@ -1251,12 +1285,26 @@ extern struct type *make_function_type (
|
||
|
||
extern struct type *lookup_function_type (struct type *);
|
||
|
||
+extern struct type *create_range_type_nfields (struct type *result_type,
|
||
+ struct type *index_type,
|
||
+ int nfields);
|
||
+
|
||
extern struct type *create_range_type (struct type *, struct type *, int,
|
||
int);
|
||
|
||
extern struct type *create_array_type (struct type *, struct type *,
|
||
struct type *);
|
||
|
||
+extern CORE_ADDR range_type_any_field_internal (struct type *range_type,
|
||
+ int fieldno);
|
||
+
|
||
+extern int range_type_high_bound_internal (struct type *range_type);
|
||
+
|
||
+extern int range_type_count_bound_internal (struct type *range_type);
|
||
+
|
||
+extern CORE_ADDR range_type_byte_stride_internal (struct type *range_type,
|
||
+ struct type *element_type);
|
||
+
|
||
extern struct type *create_string_type (struct type *, struct type *);
|
||
|
||
extern struct type *create_set_type (struct type *, struct type *);
|
||
diff -up -ruNp gdb-6.8-0/gdb/jv-lang.c gdb-6.8-1/gdb/jv-lang.c
|
||
--- gdb-6.8-0/gdb/jv-lang.c 2008-02-05 23:17:40.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/jv-lang.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -1083,6 +1083,7 @@ const struct language_defn java_language
|
||
c_language_arch_info,
|
||
default_print_array_index,
|
||
default_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
diff -up -ruNp gdb-6.8-0/gdb/language.c gdb-6.8-1/gdb/language.c
|
||
--- gdb-6.8-0/gdb/language.c 2008-02-05 23:17:40.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/language.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -1087,6 +1087,15 @@ default_print_array_index (struct value
|
||
fprintf_filtered (stream, "] = ");
|
||
}
|
||
|
||
+/* No *ADDRESS_RETURN change is needed as we do not support DW_AT_data_location
|
||
+ * for general types. */
|
||
+
|
||
+int
|
||
+default_value_address_get (struct type *type, CORE_ADDR *address_return)
|
||
+{
|
||
+ return 1;
|
||
+}
|
||
+
|
||
/* Define the language that is no language. */
|
||
|
||
static int
|
||
@@ -1205,6 +1214,7 @@ const struct language_defn unknown_langu
|
||
unknown_language_arch_info, /* la_language_arch_info. */
|
||
default_print_array_index,
|
||
default_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
@@ -1241,6 +1251,7 @@ const struct language_defn auto_language
|
||
unknown_language_arch_info, /* la_language_arch_info. */
|
||
default_print_array_index,
|
||
default_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
@@ -1276,6 +1287,7 @@ const struct language_defn local_languag
|
||
unknown_language_arch_info, /* la_language_arch_info. */
|
||
default_print_array_index,
|
||
default_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
diff -up -ruNp gdb-6.8-0/gdb/language.h gdb-6.8-1/gdb/language.h
|
||
--- gdb-6.8-0/gdb/language.h 2008-02-05 23:17:40.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/language.h 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -268,6 +268,13 @@ struct language_defn
|
||
reference at the language level. */
|
||
int (*la_pass_by_reference) (struct type *type);
|
||
|
||
+ /* Return the data address (DW_AT_data_location) of TYPE into
|
||
+ *ADDRESS_RETURN. Return non-zero if the variable/data is valid.
|
||
+ You should set *ADDRESS_RETURN as VALUE_ADDRESS (VAL) as if no
|
||
+ DW_AT_data_location is present for TYPE *ADDRESS_RETURN is left
|
||
+ unchanged. ADDRESS_RETURN may be NULL. */
|
||
+ int (*la_value_address_get) (struct type *type, CORE_ADDR *address_return);
|
||
+
|
||
/* Add fields above this point, so the magic number is always last. */
|
||
/* Magic number for compat checking */
|
||
|
||
@@ -363,6 +370,9 @@ extern enum language set_language (enum
|
||
#define LA_PRINT_ARRAY_INDEX(index_value, stream, format, pretty) \
|
||
(current_language->la_print_array_index(index_value, stream, format, pretty))
|
||
|
||
+#define LA_VALUE_ADDRESS_GET(type, address_return) \
|
||
+ (current_language->la_value_address_get(type, address_return))
|
||
+
|
||
/* Test a character to decide whether it can be printed in literal form
|
||
or needs to be printed in another representation. For example,
|
||
in C the literal form of the character with octal value 141 is 'a'
|
||
@@ -470,4 +480,7 @@ int language_pass_by_reference (struct t
|
||
independent of this. */
|
||
int default_pass_by_reference (struct type *type);
|
||
|
||
+extern int default_value_address_get (struct type *type,
|
||
+ CORE_ADDR *address_return);
|
||
+
|
||
#endif /* defined (LANGUAGE_H) */
|
||
diff -up -ruNp gdb-6.8-0/gdb/m2-lang.c gdb-6.8-1/gdb/m2-lang.c
|
||
--- gdb-6.8-0/gdb/m2-lang.c 2008-02-05 23:17:40.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/m2-lang.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -388,6 +388,7 @@ const struct language_defn m2_language_d
|
||
m2_language_arch_info,
|
||
default_print_array_index,
|
||
default_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
diff -up -ruNp gdb-6.8-0/gdb/objc-lang.c gdb-6.8-1/gdb/objc-lang.c
|
||
--- gdb-6.8-0/gdb/objc-lang.c 2008-02-05 23:17:40.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/objc-lang.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -522,6 +522,7 @@ const struct language_defn objc_language
|
||
c_language_arch_info,
|
||
default_print_array_index,
|
||
default_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
diff -up -ruNp gdb-6.8-0/gdb/p-lang.c gdb-6.8-1/gdb/p-lang.c
|
||
--- gdb-6.8-0/gdb/p-lang.c 2008-02-05 23:17:40.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/p-lang.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -427,6 +427,7 @@ const struct language_defn pascal_langua
|
||
pascal_language_arch_info,
|
||
default_print_array_index,
|
||
default_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
diff -up -ruNp gdb-6.8-0/gdb/printcmd.c gdb-6.8-1/gdb/printcmd.c
|
||
--- gdb-6.8-0/gdb/printcmd.c 2008-08-23 22:29:55.000000000 +0200
|
||
+++ gdb-6.8-1/gdb/printcmd.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -888,6 +888,11 @@ print_command_1 (char *exp, int inspect,
|
||
else
|
||
val = access_value_history (0);
|
||
|
||
+ /* Do not try to OBJECT_ADDRESS_SET here anything. We are interested in the
|
||
+ source variable base addresses as found by READ_VAR_VALUE. The value here
|
||
+ can be already a calculated expression address inappropriate for
|
||
+ DW_OP_push_object_address. */
|
||
+
|
||
if (voidprint || (val && value_type (val) &&
|
||
TYPE_CODE (value_type (val)) != TYPE_CODE_VOID))
|
||
{
|
||
diff -up -ruNp gdb-6.8-0/gdb/scm-lang.c gdb-6.8-1/gdb/scm-lang.c
|
||
--- gdb-6.8-0/gdb/scm-lang.c 2008-02-05 23:17:40.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/scm-lang.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -266,6 +266,7 @@ const struct language_defn scm_language_
|
||
c_language_arch_info,
|
||
default_print_array_index,
|
||
default_pass_by_reference,
|
||
+ default_value_address_get, /* Retrieve the real data value */
|
||
LANG_MAGIC
|
||
};
|
||
|
||
diff -up -ruNp gdb-6.8-0/gdb/testsuite/gdb.fortran/dynamic.exp gdb-6.8-1/gdb/testsuite/gdb.fortran/dynamic.exp
|
||
--- gdb-6.8-0/gdb/testsuite/gdb.fortran/dynamic.exp 1970-01-01 01:00:00.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/testsuite/gdb.fortran/dynamic.exp 2008-08-23 22:31:08.000000000 +0200
|
||
@@ -0,0 +1,141 @@
|
||
+# Copyright 2007 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 2 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, write to the Free Software
|
||
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
+
|
||
+# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
|
||
+
|
||
+# This file is part of the gdb testsuite. It contains tests for dynamically
|
||
+# allocated Fortran arrays.
|
||
+# It depends on the GCC dynamic Fortran arrays DWARF support:
|
||
+# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22244
|
||
+
|
||
+set testfile "dynamic"
|
||
+set srcfile ${testfile}.f90
|
||
+set binfile ${objdir}/${subdir}/${testfile}
|
||
+
|
||
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } {
|
||
+ untested "Couldn't compile ${srcfile}"
|
||
+ return -1
|
||
+}
|
||
+
|
||
+gdb_exit
|
||
+gdb_start
|
||
+gdb_reinitialize_dir $srcdir/$subdir
|
||
+gdb_load ${binfile}
|
||
+
|
||
+if ![runto MAIN__] then {
|
||
+ perror "couldn't run to breakpoint MAIN__"
|
||
+ continue
|
||
+}
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "varx-init"]
|
||
+gdb_continue_to_breakpoint "varx-init"
|
||
+gdb_test "p varx" "\\$\[0-9\]* = <the array is not allocated>"
|
||
+gdb_test "ptype varx" "type = <the array is not allocated>"
|
||
+gdb_test "p varx(1,5,17)" "Unable to access the object because the array is not allocated\\."
|
||
+gdb_test "p varx(1,5,17)=1" "Unable to access the object because the array is not allocated\\."
|
||
+gdb_test "ptype varx(1,5,17)" "Unable to access the object because the array is not allocated\\."
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "varx-allocated"]
|
||
+gdb_continue_to_breakpoint "varx-allocated"
|
||
+# $1 = (( ( 0, 0, 0, 0, 0, 0) ( 0, 0, 0, 0, 0, 0) --- , 0) ) ( ( 0, 0, ...) ...) ...)
|
||
+gdb_test "ptype varx" "type = real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)"
|
||
+# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1.
|
||
+gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)"
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "varx-filled"]
|
||
+gdb_continue_to_breakpoint "varx-filled"
|
||
+gdb_test "p varx(2, 5, 17)" "\\$\[0-9\]* = 6"
|
||
+gdb_test "p varx(1, 5, 17)" "\\$\[0-9\]* = 7"
|
||
+gdb_test "p varx(2, 6, 18)" "\\$\[0-9\]* = 8"
|
||
+gdb_test "p varx(6, 15, 28)" "\\$\[0-9\]* = 9"
|
||
+# The latter one is for the Intel Fortran Compiler 10.1.008 pointer type.
|
||
+gdb_test "p varv" "\\$\[0-9\]* = (<the array is not associated>|.*Unable to access the object because the array is not associated.)"
|
||
+gdb_test "ptype varv" "type = (<the array is not associated>|.*Unable to access the object because the array is not associated.)"
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "varv-associated"]
|
||
+gdb_continue_to_breakpoint "varv-associated"
|
||
+gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 6"
|
||
+gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 6"
|
||
+# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1.
|
||
+gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)"
|
||
+gdb_test "ptype varx" "type = real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)"
|
||
+# Intel Fortran Compiler 10.1.008 uses the pointer type.
|
||
+gdb_test "ptype varv" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)\\)?"
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "varv-filled"]
|
||
+gdb_continue_to_breakpoint "varv-filled"
|
||
+gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 10"
|
||
+gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 10"
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "varv-deassociated"]
|
||
+gdb_continue_to_breakpoint "varv-deassociated"
|
||
+# The latter one is for the Intel Fortran Compiler 10.1.008 pointer type.
|
||
+gdb_test "p varv" "\\$\[0-9\]* = (<the array is not associated>|.*Unable to access the object because the array is not associated.)"
|
||
+gdb_test "ptype varv" "type = (<the array is not associated>|.*Unable to access the object because the array is not associated.)"
|
||
+gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\."
|
||
+gdb_test "p varv(1,5,17)" "Unable to access the object because the array is not associated\\."
|
||
+gdb_test "ptype varv(1,5,17)" "Unable to access the object because the array is not associated\\."
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "varx-deallocated"]
|
||
+gdb_continue_to_breakpoint "varx-deallocated"
|
||
+gdb_test "p varx" "\\$\[0-9\]* = <the array is not allocated>"
|
||
+gdb_test "ptype varx" "type = <the array is not allocated>"
|
||
+gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\."
|
||
+gdb_test "p varx(1,5,17)" "Unable to access the object because the array is not allocated\\."
|
||
+gdb_test "ptype varx(1,5,17)" "Unable to access the object because the array is not allocated\\."
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "vary-passed"]
|
||
+gdb_continue_to_breakpoint "vary-passed"
|
||
+# $1 = (( ( 1, 1, 1, 1, 1, 1) ( 1, 1, 1, 1, 1, 1) --- , 1) ) ( ( 1, 1, ...) ...) ...)
|
||
+gdb_test "p vary" "\\$\[0-9\]* = \\(\[()1, .\]*\\)"
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "vary-filled"]
|
||
+gdb_continue_to_breakpoint "vary-filled"
|
||
+gdb_test "ptype vary" "type = real(\\(kind=4\\)|\\*4) \\(10,10\\)"
|
||
+gdb_test "p vary(1, 1)" "\\$\[0-9\]* = 8"
|
||
+gdb_test "p vary(2, 2)" "\\$\[0-9\]* = 9"
|
||
+gdb_test "p vary(1, 3)" "\\$\[0-9\]* = 10"
|
||
+# $1 = (( ( 3, 3, 3, 3, 3, 3) ( 3, 3, 3, 3, 3, 3) --- , 3) ) ( ( 3, 3, ...) ...) ...)
|
||
+gdb_test "p varw" "\\$\[0-9\]* = \\(\[()3, .\]*\\)"
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "varw-almostfilled"]
|
||
+gdb_continue_to_breakpoint "varw-almostfilled"
|
||
+gdb_test "ptype varw" "type = real(\\(kind=4\\)|\\*4) \\(5,4,3\\)"
|
||
+gdb_test "p varw(3,1,1)=1" "\\$\[0-9\]* = 1"
|
||
+# $1 = (( ( 6, 5, 1, 5, 5, 5) ( 5, 5, 5, 5, 5, 5) --- , 5) ) ( ( 5, 5, ...) ...) ...)
|
||
+gdb_test "p varw" "\\$\[0-9\]* = \\( *\\( *\\( *6, *5, *1,\[()5, .\]*\\)"
|
||
+# "up" works with GCC but other Fortran compilers may copy the values into the
|
||
+# outer function only on the exit of the inner function.
|
||
+gdb_test "finish" ".*call bar \\(y, x\\)"
|
||
+gdb_test "p z(2,4,5)" "\\$\[0-9\]* = 3"
|
||
+gdb_test "p z(2,4,6)" "\\$\[0-9\]* = 6"
|
||
+gdb_test "p z(2,4,7)" "\\$\[0-9\]* = 5"
|
||
+gdb_test "p z(4,4,6)" "\\$\[0-9\]* = 1"
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "varz-almostfilled"]
|
||
+gdb_continue_to_breakpoint "varz-almostfilled"
|
||
+# GCC uses the pointer type here, Intel Fortran Compiler 10.1.008 does not.
|
||
+gdb_test "ptype varz" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(\\*\\)\\)?"
|
||
+# Intel Fortran Compiler 10.1.008 has a bug here - (2:11,7:7)
|
||
+# as it produces DW_AT_lower_bound == DW_AT_upper_bound == 7.
|
||
+gdb_test "ptype vart" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(2:11,7:\\*\\)\\)?"
|
||
+gdb_test "p varz(3)" "\\$\[0-9\]* = 4"
|
||
+# maps to foo::vary(1,1)
|
||
+gdb_test "p vart(2,7)" "\\$\[0-9\]* = 8"
|
||
+# maps to foo::vary(2,2)
|
||
+gdb_test "p vart(3,8)" "\\$\[0-9\]* = 9"
|
||
+# maps to foo::vary(1,3)
|
||
+gdb_test "p vart(2,9)" "\\$\[0-9\]* = 10"
|
||
diff -up -ruNp gdb-6.8-0/gdb/testsuite/gdb.fortran/dynamic.f90 gdb-6.8-1/gdb/testsuite/gdb.fortran/dynamic.f90
|
||
--- gdb-6.8-0/gdb/testsuite/gdb.fortran/dynamic.f90 1970-01-01 01:00:00.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/testsuite/gdb.fortran/dynamic.f90 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -0,0 +1,97 @@
|
||
+! Copyright 2007 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 2 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, write to the Free Software
|
||
+! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
+!
|
||
+! Ihis file is the Fortran source file for dynamic.exp.
|
||
+! Original file written by Jakub Jelinek <jakub@redhat.com>.
|
||
+! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>.
|
||
+
|
||
+subroutine baz
|
||
+ real, target, allocatable :: varx (:, :, :)
|
||
+ real, pointer :: varv (:, :, :)
|
||
+ real, target :: varu (1, 2, 3)
|
||
+ logical :: l
|
||
+ allocate (varx (1:6, 5:15, 17:28)) ! varx-init
|
||
+ l = allocated (varx)
|
||
+ varx(:, :, :) = 6 ! varx-allocated
|
||
+ varx(1, 5, 17) = 7
|
||
+ varx(2, 6, 18) = 8
|
||
+ varx(6, 15, 28) = 9
|
||
+ varv => varx ! varx-filled
|
||
+ l = associated (varv)
|
||
+ varv(3, 7, 19) = 10 ! varv-associated
|
||
+ varv => null () ! varv-filled
|
||
+ l = associated (varv)
|
||
+ deallocate (varx) ! varv-deassociated
|
||
+ l = allocated (varx)
|
||
+ varu(:, :, :) = 10 ! varx-deallocated
|
||
+ allocate (varv (1:6, 5:15, 17:28))
|
||
+ l = associated (varv)
|
||
+ varv(:, :, :) = 6
|
||
+ varv(1, 5, 17) = 7
|
||
+ varv(2, 6, 18) = 8
|
||
+ varv(6, 15, 28) = 9
|
||
+ deallocate (varv)
|
||
+ l = associated (varv)
|
||
+ varv => varu
|
||
+ varv(1, 1, 1) = 6
|
||
+ varv(1, 2, 3) = 7
|
||
+ l = associated (varv)
|
||
+end subroutine baz
|
||
+subroutine foo (vary, varw)
|
||
+ real :: vary (:, :)
|
||
+ real :: varw (:, :, :)
|
||
+ vary(:, :) = 4 ! vary-passed
|
||
+ vary(1, 1) = 8
|
||
+ vary(2, 2) = 9
|
||
+ vary(1, 3) = 10
|
||
+ varw(:, :, :) = 5 ! vary-filled
|
||
+ varw(1, 1, 1) = 6
|
||
+ varw(2, 2, 2) = 7 ! varw-almostfilled
|
||
+end subroutine foo
|
||
+subroutine bar (varz, vart)
|
||
+ real :: varz (*)
|
||
+ real :: vart (2:11, 7:*)
|
||
+ varz(1:3) = 4
|
||
+ varz(2) = 5 ! varz-almostfilled
|
||
+end subroutine bar
|
||
+program test
|
||
+ interface
|
||
+ subroutine foo (vary, varw)
|
||
+ real :: vary (:, :)
|
||
+ real :: varw (:, :, :)
|
||
+ end subroutine
|
||
+ end interface
|
||
+ interface
|
||
+ subroutine bar (varz, vart)
|
||
+ real :: varz (*)
|
||
+ real :: vart (2:11, 7:*)
|
||
+ end subroutine
|
||
+ end interface
|
||
+ real :: x (10, 10), y (5), z(8, 8, 8)
|
||
+ x(:,:) = 1
|
||
+ y(:) = 2
|
||
+ z(:,:,:) = 3
|
||
+ call baz
|
||
+ call foo (x, z(2:6, 4:7, 6:8))
|
||
+ call bar (y, x)
|
||
+ if (x (1, 1) .ne. 8 .or. x (2, 2) .ne. 9 .or. x (1, 2) .ne. 4) call abort
|
||
+ if (x (1, 3) .ne. 10) call abort
|
||
+ if (z (2, 4, 6) .ne. 6 .or. z (3, 5, 7) .ne. 7 .or. z (2, 4, 7) .ne. 5) call abort
|
||
+ if (any (y .ne. (/4, 5, 4, 2, 2/))) call abort
|
||
+ call foo (transpose (x), z)
|
||
+ if (x (1, 1) .ne. 8 .or. x (2, 2) .ne. 9 .or. x (1, 2) .ne. 4) call abort
|
||
+ if (x (3, 1) .ne. 10) call abort
|
||
+end
|
||
diff -up -ruNp gdb-6.8-0/gdb/testsuite/gdb.fortran/string.exp gdb-6.8-1/gdb/testsuite/gdb.fortran/string.exp
|
||
--- gdb-6.8-0/gdb/testsuite/gdb.fortran/string.exp 1970-01-01 01:00:00.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/testsuite/gdb.fortran/string.exp 2008-08-23 22:31:08.000000000 +0200
|
||
@@ -0,0 +1,59 @@
|
||
+# Copyright 2008 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 2 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, write to the Free Software
|
||
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
+
|
||
+# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
|
||
+
|
||
+# This file is part of the gdb testsuite. It contains tests for Fortran
|
||
+# strings with dynamic length.
|
||
+
|
||
+set testfile "string"
|
||
+set srcfile ${testfile}.f90
|
||
+set binfile ${objdir}/${subdir}/${testfile}
|
||
+
|
||
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } {
|
||
+ untested "Couldn't compile ${srcfile}"
|
||
+ return -1
|
||
+}
|
||
+
|
||
+gdb_exit
|
||
+gdb_start
|
||
+gdb_reinitialize_dir $srcdir/$subdir
|
||
+gdb_load ${binfile}
|
||
+
|
||
+if ![runto MAIN__] then {
|
||
+ perror "couldn't run to breakpoint MAIN__"
|
||
+ continue
|
||
+}
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "var-init"]
|
||
+gdb_continue_to_breakpoint "var-init"
|
||
+gdb_test "ptype c" "type = character(\\(kind=1\\)|\\*1)"
|
||
+gdb_test "ptype d" "type = character(\\(kind=8\\)|\\*8)"
|
||
+gdb_test "ptype e" "type = REF TO -> \\( character(\\(kind=4\\)|\\*4) \\)"
|
||
+gdb_test "ptype f" "type = PTR TO -> \\( character(\\(kind=4\\)|\\*4) \\(7,8:10\\)\\)"
|
||
+gdb_test "ptype *e" "type = character(\\(kind=4\\)|\\*4)"
|
||
+gdb_test "ptype *f" "type = character(\\(kind=4\\)|\\*4) \\(7,8:10\\)"
|
||
+gdb_test "p c" "\\$\[0-9\]* = 'c'"
|
||
+gdb_test "p d" "\\$\[0-9\]* = 'd '"
|
||
+gdb_test "p e" "\\$\[0-9\]* = \\(REF TO -> \\( character(\\(kind=4\\)|\\*4) \\)\\) @0x\[0-9a-f\]+: 'g '"
|
||
+gdb_test "p f" "\\$\[0-9\]* = \\(PTR TO -> \\( character(\\(kind=4\\)|\\*4) \\(7,8:10\\)\\)\\) 0x\[0-9a-f\]+"
|
||
+gdb_test "p *e" "Attempt to take contents of a non-pointer value."
|
||
+gdb_test "p *f" "\\$\[0-9\]* = \\(\\( 'h ', 'h ', 'h ', 'h ', 'h ', 'h ', 'h '\\) \\( 'h ', 'h ', 'h ', 'h ', 'h ', 'h ', 'h '\\) \\( 'h ', 'h ', 'h ', 'h ', 'h ', 'h ', 'h '\\) \\)"
|
||
+
|
||
+gdb_breakpoint [gdb_get_line_number "var-finish"]
|
||
+gdb_continue_to_breakpoint "var-finish"
|
||
+gdb_test "p e" "\\$\[0-9\]* = \\(REF TO -> \\( character(\\(kind=4\\)|\\*4) \\)\\) @0x\[0-9a-f\]+: 'e '" "p e re-set"
|
||
+gdb_test "p *f" "\\$\[0-9\]* = \\(\\( 'f ', 'f ', 'f ', 'f ', 'f ', 'f ', 'f '\\) \\( 'f2 ', 'f ', 'f ', 'f ', 'f ', 'f ', 'f '\\) \\( 'f ', 'f ', 'f ', 'f ', 'f ', 'f ', 'f '\\) \\)" "p *f re-set"
|
||
diff -up -ruNp gdb-6.8-0/gdb/testsuite/gdb.fortran/string.f90 gdb-6.8-1/gdb/testsuite/gdb.fortran/string.f90
|
||
--- gdb-6.8-0/gdb/testsuite/gdb.fortran/string.f90 1970-01-01 01:00:00.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/testsuite/gdb.fortran/string.f90 2008-08-23 22:31:08.000000000 +0200
|
||
@@ -0,0 +1,37 @@
|
||
+! Copyright 2008 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 2 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, write to the Free Software
|
||
+! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
+!
|
||
+! Ihis file is the Fortran source file for dynamic.exp.
|
||
+! Original file written by Jakub Jelinek <jakub@redhat.com>.
|
||
+! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>.
|
||
+
|
||
+subroutine foo (e, f)
|
||
+ character (len=1) :: c
|
||
+ character (len=8) :: d
|
||
+ character (len=*) :: e
|
||
+ character (len=*) :: f (1:7, 8:10)
|
||
+ c = 'c'
|
||
+ d = 'd'
|
||
+ e = 'e' ! var-init
|
||
+ f = 'f'
|
||
+ f(1,9) = 'f2'
|
||
+ c = 'c' ! var-finish
|
||
+end subroutine foo
|
||
+ character (len=4) :: g, h (1:7, 8:10)
|
||
+ g = 'g'
|
||
+ h = 'h'
|
||
+ call foo (g, h)
|
||
+end
|
||
diff -up -ruNp gdb-6.8-0/gdb/typeprint.c gdb-6.8-1/gdb/typeprint.c
|
||
--- gdb-6.8-0/gdb/typeprint.c 2008-02-03 02:02:47.000000000 +0100
|
||
+++ gdb-6.8-1/gdb/typeprint.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -33,6 +33,7 @@
|
||
#include "cp-abi.h"
|
||
#include "typeprint.h"
|
||
#include "gdb_string.h"
|
||
+#include "dwarf2block.h"
|
||
#include <errno.h>
|
||
|
||
/* For real-type printing in whatis_exp() */
|
||
@@ -130,6 +131,7 @@ whatis_exp (char *exp, int show)
|
||
val = access_value_history (0);
|
||
|
||
type = value_type (val);
|
||
+ object_address_set (VALUE_ADDRESS (val));
|
||
|
||
if (objectprint)
|
||
{
|
||
diff -up -ruNp gdb-6.8-0/gdb/valops.c gdb-6.8-1/gdb/valops.c
|
||
--- gdb-6.8-0/gdb/valops.c 2008-08-23 22:29:56.000000000 +0200
|
||
+++ gdb-6.8-1/gdb/valops.c 2008-08-23 22:30:33.000000000 +0200
|
||
@@ -571,12 +571,21 @@ value_at_lazy (struct type *type, CORE_A
|
||
int
|
||
value_fetch_lazy (struct value *val)
|
||
{
|
||
- CORE_ADDR addr = VALUE_ADDRESS (val) + value_offset (val);
|
||
- int length = TYPE_LENGTH (value_enclosing_type (val));
|
||
+ CORE_ADDR addr;
|
||
+ int length;
|
||
|
||
- struct type *type = value_type (val);
|
||
- if (length)
|
||
- read_memory (addr, value_contents_all_raw (val), length);
|
||
+ addr = VALUE_ADDRESS (val);
|
||
+ if (LA_VALUE_ADDRESS_GET (value_type (val), &addr))
|
||
+ {
|
||
+ struct type *type = value_enclosing_type (val);
|
||
+ int length = TYPE_LENGTH (check_typedef (type));
|
||
+
|
||
+ if (length)
|
||
+ {
|
||
+ addr += value_offset (val);
|
||
+ read_memory (addr, value_contents_all_raw (val), length);
|
||
+ }
|
||
+ }
|
||
|
||
set_value_lazy (val, 0);
|
||
return 0;
|
||
@@ -880,12 +889,17 @@ struct value *
|
||
value_coerce_array (struct value *arg1)
|
||
{
|
||
struct type *type = check_typedef (value_type (arg1));
|
||
+ CORE_ADDR address;
|
||
|
||
if (VALUE_LVAL (arg1) != lval_memory)
|
||
error (_("Attempt to take address of value not located in memory."));
|
||
|
||
+ address = VALUE_ADDRESS (arg1);
|
||
+ if (!LA_VALUE_ADDRESS_GET (type, &address))
|
||
+ error (_("Attempt to take address of non-valid value."));
|
||
+
|
||
return value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
|
||
- (VALUE_ADDRESS (arg1) + value_offset (arg1)));
|
||
+ address + value_offset (arg1));
|
||
}
|
||
|
||
/* Given a value which is a function, return a value which is a pointer
|