http://sourceware.org/gdb/wiki/ArcherBranchManagement
GIT snapshot:
-commit 9f8d47f059091333d178bd249507fd25676860e7
+commit 897686c0aedb7a6da59b823f22b1d24ec5a1d2ba
branch `archer' - the merge of branches:
archer-jankratochvil-vla
-archer-jankratochvil-watchpoint3
archer-tromey-python
-archer-sergiodj-stap
+archer-tromey-dwz-multifile-rebase (but from post-7.5 FSF GDB commits)
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
-index 38c93c9..3acacdb 100644
+index a41cff9..d7786a6 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
-@@ -720,8 +720,8 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
- sentinel-frame.c \
- serial.c ser-base.c ser-unix.c skip.c \
- solib.c solib-target.c source.c \
-- stabsread.c stack.c std-regs.c symfile.c symfile-mem.c symmisc.c \
-- symtab.c \
-+ stabsread.c stack.c stap-probe.c std-regs.c \
-+ symfile.c symfile-mem.c symmisc.c symtab.c \
- target.c target-descriptions.c target-memory.c \
- thread.c top.c tracepoint.c \
- trad-frame.c \
-@@ -817,7 +817,7 @@ osdata.h procfs.h python/py-event.h python/py-events.h python/py-stopevent.h \
- python/python-internal.h python/python.h ravenscar-thread.h record.h \
- solib-darwin.h solib-ia64-hpux.h solib-spu.h windows-nat.h xcoffread.h \
- gnulib/extra/arg-nonnull.h gnulib/extra/c++defs.h gnulib/extra/warn-on-use.h \
--gnulib/stddef.in.h inline-frame.h skip.h \
-+gnulib/stddef.in.h inline-frame.h skip.h stap-probe.h \
+@@ -704,7 +704,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
+ exceptions.c expprint.c \
+ f-exp.y f-lang.c f-typeprint.c f-valprint.c filesystem.c \
+ findcmd.c findvar.c frame.c frame-base.c frame-unwind.c \
+- gdbarch.c arch-utils.c gdbtypes.c gnu-v2-abi.c gnu-v3-abi.c \
++ gdbarch.c arch-utils.c gdb_bfd.c gdbtypes.c gnu-v2-abi.c gnu-v3-abi.c \
+ go-exp.y go-lang.c go-typeprint.c go-valprint.c \
+ inf-loop.c \
+ infcall.c \
+@@ -829,7 +829,7 @@ gnulib/import/extra/snippet/warn-on-use.h \
+ gnulib/import/stddef.in.h gnulib/import/inttypes.in.h inline-frame.h skip.h \
common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
- common/linux-osdata.h gdb-dlfcn.h
-
-@@ -905,7 +905,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
- xml-support.o xml-syscall.o xml-utils.o \
- target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
- inferior.o osdata.o gdb_usleep.o record.o gcore.o \
-- jit.o progspace.o skip.o \
-+ jit.o progspace.o skip.o stap-probe.o \
- common-utils.o buffer.o ptid.o gdb-dlfcn.o
-
- TSOBS = inflow.o
-@@ -1293,6 +1293,12 @@ stamp-h: $(srcdir)/config.in config.status
+ common/format.h \
+-common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h
++common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h gdb_bfd.h
+
+ # Header files that already have srcdir in them, or which are in objdir.
+
+@@ -879,7 +879,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
+ macrotab.o macrocmd.o macroexp.o macroscope.o \
+ mi-common.o \
+ event-loop.o event-top.o inf-loop.o completer.o \
+- gdbarch.o arch-utils.o gdbtypes.o osabi.o copying.o \
++ gdbarch.o arch-utils.o gdbtypes.o gdb_bfd.o osabi.o copying.o \
+ memattr.o mem-break.o target.o parse.o language.o buildsym.o \
+ findcmd.o \
+ std-regs.o \
+@@ -1307,6 +1307,12 @@ stamp-h: $(srcdir)/config.in config.status
CONFIG_LINKS= \
$(SHELL) config.status
$(SHELL) config.status --recheck
diff --git a/gdb/NEWS b/gdb/NEWS
-index 128825e..13dd88c 100644
+index b281824..4da886c 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
-@@ -328,6 +328,10 @@ Renesas RL78 rl78-*-elf
- Initial support for the OpenCL C language (http://www.khronos.org/opencl)
- has been integrated into GDB.
+@@ -1,6 +1,13 @@
+ What has changed in GDB?
+ (Organized release by release)
-+* GDB now has support for SystemTap <sys/sdt.h> probes. You can set a
-+ breakpoint using the new "probe:" linespec and inspect the probe
-+ arguments using the new $_probe_arg family of convenience variables.
++*** Changes since GDB 7.5
+
- * Python scripting
++* New commands (for set/show, see "New options" below)
++
++maint info bfds
++ List the BFDs known to GDB.
++
+ *** Changes in GDB 7.5
- ** The function gdb.Write now accepts an optional keyword 'stream'.
+ * GDB now supports x32 ABI. Visit <http://sites.google.com/site/x32abi/>
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
-index 29956d7..dc1fadd 100644
+index aa090af..e672731 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
-@@ -11896,6 +11896,7 @@ ada_operator_length (const struct expression *exp, int pc, int *oplenp,
+@@ -12037,6 +12037,7 @@ ada_operator_length (const struct expression *exp, int pc, int *oplenp,
static int
ada_operator_check (struct expression *exp, int pos,
int (*objfile_func) (struct objfile *objfile, void *data),
void *data)
{
-@@ -11910,12 +11911,15 @@ ada_operator_check (struct expression *exp, int pos,
+@@ -12051,12 +12052,15 @@ ada_operator_check (struct expression *exp, int pos,
break;
default:
&& (*objfile_func) (TYPE_OBJFILE (type), data))
return 1;
-diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
-index a0bdbd7..98760bf 100644
---- a/gdb/amd64-linux-nat.c
-+++ b/gdb/amd64-linux-nat.c
-@@ -336,8 +336,8 @@ amd64_linux_dr_get_status (void)
- return amd64_linux_dr_get (inferior_ptid, DR_STATUS);
- }
-
--/* Callback for iterate_over_lwps. Update the debug registers of
-- LWP. */
-+/* Callback for linux_nat_iterate_watchpoint_lwps. Update the debug registers
-+ of LWP. */
-
- static int
- update_debug_registers_callback (struct lwp_info *lwp, void *arg)
-@@ -363,9 +363,7 @@ update_debug_registers_callback (struct lwp_info *lwp, void *arg)
- static void
- amd64_linux_dr_set_control (unsigned long control)
- {
-- ptid_t pid_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
--
-- iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL);
-+ linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL);
- }
-
- /* Set address REGNUM (zero based) to ADDR in all LWPs of the current
-@@ -378,7 +376,7 @@ amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
-
- gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
-
-- iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL);
-+ linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL);
- }
-
- /* Called when resuming a thread.
-@@ -400,6 +398,13 @@ amd64_linux_prepare_to_resume (struct lwp_info *lwp)
- struct i386_debug_reg_state *state = i386_debug_reg_state ();
- int i;
-
-+ /* On Linux kernel before 2.6.33 commit
-+ 72f674d203cd230426437cdcf7dd6f681dad8b0d
-+ if you enable a breakpoint by the DR_CONTROL bits you need to have
-+ already written the corresponding DR_FIRSTADDR...DR_LASTADDR registers.
-+
-+ Ensure DR_CONTROL gets written as the very last register here. */
-+
- for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
- if (state->dr_ref_count[i] > 0)
- {
-diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
-index ca9ade6..c30185d 100644
---- a/gdb/amd64-linux-tdep.c
-+++ b/gdb/amd64-linux-tdep.c
-@@ -1362,6 +1362,15 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
- set_gdbarch_process_record (gdbarch, i386_process_record);
- set_gdbarch_process_record_signal (gdbarch, amd64_linux_record_signal);
-
-+ /* SystemTap variables and functions. */
-+ set_gdbarch_stap_integer_prefix (gdbarch, "$");
-+ set_gdbarch_stap_register_prefix (gdbarch, "%");
-+ set_gdbarch_stap_register_indirection_prefix (gdbarch, "(");
-+ set_gdbarch_stap_register_indirection_sufix (gdbarch, ")");
-+ set_gdbarch_stap_is_single_operand (gdbarch, i386_stap_is_single_operand);
-+ set_gdbarch_stap_parse_special_token (gdbarch,
-+ i386_stap_parse_special_token);
-+
- /* Initialize the amd64_linux_record_tdep. */
- /* These values are the size of the type that will be used in a system
- call. They are obtained from Linux Kernel source. */
-diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
-index ac4860c..d710682 100644
---- a/gdb/arm-linux-tdep.c
-+++ b/gdb/arm-linux-tdep.c
-@@ -43,6 +43,12 @@
- #include "gdbthread.h"
- #include "symfile.h"
-
-+#include "cli/cli-utils.h"
-+#include "stap-probe.h"
-+#include "parser-defs.h"
-+#include "user-regs.h"
-+#include <ctype.h>
-+
- #include "gdb_string.h"
-
- /* This is defined in <elf.h> on ARM GNU/Linux systems. */
-@@ -1053,6 +1059,122 @@ arm_linux_displaced_step_copy_insn (struct gdbarch *gdbarch,
- return dsc;
- }
-
-+static int
-+arm_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
-+{
-+ return (*s == '#' /* Literal number. */
-+ || *s == '[' /* Register indirection or
-+ displacement. */
-+ || isalpha (*s)); /* Register value. */
-+}
-+
-+/* This routine is used to parse a special token in ARM's assembly.
-+
-+ The special tokens parsed by it are:
-+
-+ - Register displacement (e.g, [fp, #-8])
-+
-+ It returns one if the special token has been parsed successfully,
-+ or zero if the current token is not considered special. */
-+
-+static int
-+arm_stap_parse_special_token (struct gdbarch *gdbarch,
-+ struct stap_parse_info *p)
-+{
-+ if (*p->arg == '[')
-+ {
-+ /* Temporary holder for lookahead. */
-+ const char *tmp = p->arg;
-+ /* Used to save the register name. */
-+ const char *start;
-+ char *regname;
-+ int len, offset;
-+ int got_minus = 0;
-+ long displacement;
-+ struct stoken str;
-+
-+ ++tmp;
-+ start = tmp;
-+
-+ /* Register name. */
-+ while (isalnum (*tmp))
-+ ++tmp;
-+
-+ if (*tmp != ',')
-+ return 0;
-+
-+ len = tmp - start;
-+ regname = alloca (len + 2);
-+
-+ offset = 0;
-+ if (isdigit (*start))
-+ {
-+ /* If we are dealing with a register whose name begins with a
-+ digit, it means we should prefix the name with the letter
-+ `r', because GDB expects this name pattern. Otherwise (e.g.,
-+ we are dealing with the register `fp'), we don't need to
-+ add such a prefix. */
-+ regname[0] = 'r';
-+ offset = 1;
-+ }
-+
-+ strncpy (regname + offset, start, len);
-+ len += offset;
-+ regname[len] = '\0';
-+
-+ if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
-+ error (_("Invalid register name `%s' on expression `%s'."),
-+ regname, p->saved_arg);
-+
-+ ++tmp;
-+ tmp = skip_spaces_const (tmp);
-+ if (*tmp++ != '#')
-+ return 0;
-+
-+ if (*tmp == '-')
-+ {
-+ ++tmp;
-+ got_minus = 1;
-+ }
-+
-+ displacement = strtol (tmp, (char **) &tmp, 10);
-+
-+ /* Skipping last `]'. */
-+ if (*tmp++ != ']')
-+ return 0;
-+
-+ /* The displacement. */
-+ write_exp_elt_opcode (OP_LONG);
-+ write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
-+ write_exp_elt_longcst (displacement);
-+ write_exp_elt_opcode (OP_LONG);
-+ if (got_minus)
-+ write_exp_elt_opcode (UNOP_NEG);
-+
-+ /* The register name. */
-+ write_exp_elt_opcode (OP_REGISTER);
-+ str.ptr = regname;
-+ str.length = len;
-+ write_exp_string (str);
-+ write_exp_elt_opcode (OP_REGISTER);
-+
-+ write_exp_elt_opcode (BINOP_ADD);
-+
-+ /* Casting to the expected type. */
-+ write_exp_elt_opcode (UNOP_CAST);
-+ write_exp_elt_type (lookup_pointer_type (p->arg_type));
-+ write_exp_elt_opcode (UNOP_CAST);
-+
-+ write_exp_elt_opcode (UNOP_IND);
-+
-+ p->arg = tmp;
-+ }
-+ else
-+ return 0;
-+
-+ return 1;
-+}
-+
- static void
- arm_linux_init_abi (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-@@ -1152,6 +1274,15 @@ arm_linux_init_abi (struct gdbarch_info info,
- simple_displaced_step_free_closure);
- set_gdbarch_displaced_step_location (gdbarch, displaced_step_at_entry_point);
-
-+ /* SystemTap functions. */
-+ set_gdbarch_stap_integer_prefix (gdbarch, "#");
-+ set_gdbarch_stap_register_prefix (gdbarch, "r");
-+ set_gdbarch_stap_register_indirection_prefix (gdbarch, "[");
-+ set_gdbarch_stap_register_indirection_sufix (gdbarch, "]");
-+ set_gdbarch_stap_gdb_register_prefix (gdbarch, "r");
-+ set_gdbarch_stap_is_single_operand (gdbarch, arm_stap_is_single_operand);
-+ set_gdbarch_stap_parse_special_token (gdbarch,
-+ arm_stap_parse_special_token);
-
- tdep->syscall_next_pc = arm_linux_syscall_next_pc;
- }
-diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
-index 31e91b9..4518f6b 100644
---- a/gdb/ax-gdb.c
-+++ b/gdb/ax-gdb.c
-@@ -95,8 +95,6 @@ static void gen_int_literal (struct agent_expr *ax,
- struct axs_value *value,
- LONGEST k, struct type *type);
+diff --git a/gdb/bfd-target.c b/gdb/bfd-target.c
+index 6728800..455d3e6 100644
+--- a/gdb/bfd-target.c
++++ b/gdb/bfd-target.c
+@@ -21,6 +21,7 @@
+ #include "target.h"
+ #include "bfd-target.h"
+ #include "exec.h"
++#include "gdb_bfd.h"
--
--static void require_rvalue (struct agent_expr *ax, struct axs_value *value);
- static void gen_usual_unary (struct expression *exp, struct agent_expr *ax,
- struct axs_value *value);
- static int type_wider_than (struct type *type1, struct type *type2);
-@@ -157,8 +155,6 @@ static void gen_repeat (struct expression *exp, union exp_element **pc,
- static void gen_sizeof (struct expression *exp, union exp_element **pc,
- struct agent_expr *ax, struct axs_value *value,
- struct type *size_type);
--static void gen_expr (struct expression *exp, union exp_element **pc,
-- struct agent_expr *ax, struct axs_value *value);
- static void gen_expr_binop_rest (struct expression *exp,
- enum exp_opcode op, union exp_element **pc,
- struct agent_expr *ax,
-@@ -789,7 +785,7 @@ gen_int_literal (struct agent_expr *ax, struct axs_value *value, LONGEST k,
- /* Take what's on the top of the stack (as described by VALUE), and
- try to make an rvalue out of it. Signal an error if we can't do
- that. */
--static void
-+void
- require_rvalue (struct agent_expr *ax, struct axs_value *value)
- {
- /* Only deal with scalars, structs and such may be too large
-@@ -1807,7 +1803,7 @@ gen_sizeof (struct expression *exp, union exp_element **pc,
- /* XXX: i18n */
- /* A gen_expr function written by a Gen-X'er guy.
- Append code for the subexpression of EXPR starting at *POS_P to AX. */
--static void
-+void
- gen_expr (struct expression *exp, union exp_element **pc,
- struct agent_expr *ax, struct axs_value *value)
+ /* The object that is stored in the target_ops->to_data field has this
+ type. */
+@@ -70,7 +71,7 @@ target_bfd_xclose (struct target_ops *t, int quitting)
{
-@@ -2042,7 +2038,8 @@ gen_expr (struct expression *exp, union exp_element **pc,
-
- case OP_INTERNALVAR:
- {
-- const char *name = internalvar_name ((*pc)[1].internalvar);
-+ struct internalvar *var = (*pc)[1].internalvar;
-+ const char *name = internalvar_name (var);
- struct trace_state_variable *tsv;
-
- (*pc) += 3;
-@@ -2056,7 +2053,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
- value->kind = axs_rvalue;
- value->type = builtin_type (exp->gdbarch)->builtin_long_long;
- }
-- else
-+ else if (! compile_internalvar_to_ax (var, ax, value))
- error (_("$%s is not a trace state variable; GDB agent "
- "expressions cannot use convenience variables."), name);
- }
-diff --git a/gdb/ax-gdb.h b/gdb/ax-gdb.h
-index 48c35a4..09f6889 100644
---- a/gdb/ax-gdb.h
-+++ b/gdb/ax-gdb.h
-@@ -110,6 +110,11 @@ extern struct agent_expr *gen_trace_for_return_address (CORE_ADDR,
-
- extern struct agent_expr *gen_eval_for_expr (CORE_ADDR, struct expression *);
-
-+extern void gen_expr (struct expression *exp, union exp_element **pc,
-+ struct agent_expr *ax, struct axs_value *value);
-+
-+extern void require_rvalue (struct agent_expr *ax, struct axs_value *value);
-+
- extern int trace_kludge;
- extern int trace_string_kludge;
-
+ struct target_bfd_data *data = t->to_data;
+
+- bfd_close (data->bfd);
++ gdb_bfd_unref (data->bfd);
+ xfree (data->table.sections);
+ xfree (data);
+ xfree (t);
+@@ -84,6 +85,7 @@ target_bfd_reopen (struct bfd *abfd)
+
+ data = XZALLOC (struct target_bfd_data);
+ data->bfd = abfd;
++ gdb_bfd_ref (abfd);
+ build_section_table (abfd, &data->table.sections, &data->table.sections_end);
+
+ t = XZALLOC (struct target_ops);
+diff --git a/gdb/bfd-target.h b/gdb/bfd-target.h
+index 71001c5..7f4e628 100644
+--- a/gdb/bfd-target.h
++++ b/gdb/bfd-target.h
+@@ -23,9 +23,9 @@
+ struct bfd;
+ struct target_ops;
+
+-/* Given an existing BFD, re-open it as a "struct target_ops". On
+- close, it will also close the corresponding BFD (which is like
+- freopen and fdopen). */
++/* Given an existing BFD, re-open it as a "struct target_ops". This
++ acquires a new reference to the BFD. This reference will be
++ released when the target is closed. */
+ struct target_ops *target_bfd_reopen (struct bfd *bfd);
+
+ #endif
diff --git a/gdb/block.c b/gdb/block.c
-index 57ab4c2..573630e 100644
+index a0f82ec..097dbf6 100644
--- a/gdb/block.c
+++ b/gdb/block.c
-@@ -369,3 +369,21 @@ allocate_block (struct obstack *obstack)
+@@ -692,3 +692,21 @@ block_iter_match_next (const char *name,
- return bl;
+ return block_iter_match_step (iterator, name, compare, 0);
}
+
+/* Return OBJFILE in which BLOCK is located or NULL if we cannot find it for
+ return SYMBOL_SYMTAB (func)->objfile;
+}
diff --git a/gdb/block.h b/gdb/block.h
-index 2cbcc1b..104c146 100644
+index 99c4788..6ceb704 100644
--- a/gdb/block.h
+++ b/gdb/block.h
-@@ -167,4 +167,6 @@ extern const struct block *block_global_block (const struct block *block);
-
- extern struct block *allocate_block (struct obstack *obstack);
+@@ -279,4 +279,6 @@ extern struct symbol *block_iter_match_next (const char *name,
+ (sym); \
+ (sym) = block_iterator_next (&(iter)))
+extern struct objfile *block_objfile (const struct block *block);
+
#endif /* BLOCK_H */
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
-index f6a0276..e406156 100644
+index 78fffd3..224ba49 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
-@@ -60,6 +60,8 @@
- #include "jit.h"
- #include "xml-syscall.h"
- #include "parser-defs.h"
-+#include "gdb_regex.h"
-+#include "stap-probe.h"
- #include "cli/cli-utils.h"
- #include "continuations.h"
- #include "stack.h"
-@@ -1239,9 +1241,10 @@ is_watchpoint (const struct breakpoint *bpt)
- static int
- watchpoint_in_thread_scope (struct watchpoint *b)
- {
-- return (ptid_equal (b->watchpoint_thread, null_ptid)
-- || (ptid_equal (inferior_ptid, b->watchpoint_thread)
-- && !is_executing (inferior_ptid)));
-+ return (b->base.pspace == current_program_space
-+ && (ptid_equal (b->watchpoint_thread, null_ptid)
-+ || (ptid_equal (inferior_ptid, b->watchpoint_thread)
-+ && !is_executing (inferior_ptid))));
- }
-
- /* Set watchpoint B to disp_del_at_next_stop, even including its possible
-@@ -1648,6 +1651,40 @@ unduplicated_should_be_inserted (struct bp_location *bl)
- return result;
- }
-
-+/* See the comment in breakpoint.h. */
-+
-+void
-+modify_semaphore (struct bp_location *loc, int set)
-+{
-+ struct gdbarch *arch = loc->gdbarch;
-+ gdb_byte bytes[sizeof (LONGEST)];
-+ /* The ABI specifies "unsigned short". */
-+ struct type *type = builtin_type (arch)->builtin_unsigned_short;
-+ CORE_ADDR address = loc->semaphore;
-+ ULONGEST value;
-+
-+ if (address == 0)
-+ return;
-+
-+ /* Swallow errors. */
-+ if (target_read_memory (address, bytes, TYPE_LENGTH (type)) != 0)
-+ return;
-+
-+ value = extract_unsigned_integer (bytes, TYPE_LENGTH (type),
-+ gdbarch_byte_order (arch));
-+ /* Note that we explicitly don't worry about overflow or
-+ underflow. */
-+ if (set)
-+ ++value;
-+ else
-+ --value;
-+
-+ store_unsigned_integer (bytes, TYPE_LENGTH (type),
-+ gdbarch_byte_order (arch), value);
-+
-+ target_write_memory (address, bytes, TYPE_LENGTH (type));
-+}
-+
- /* Insert a low-level "breakpoint" of some type. BL is the breakpoint
- location. Any error messages are printed to TMP_ERROR_STREAM; and
- DISABLED_BREAKS, and HW_BREAKPOINT_ERROR are used to report problems.
-@@ -1741,6 +1778,8 @@ insert_bp_location (struct bp_location *bl,
- /* No overlay handling: just set the breakpoint. */
-
- val = bl->owner->ops->insert_location (bl);
-+
-+ modify_semaphore (bl, 1);
- }
- else
- {
-@@ -2224,11 +2263,23 @@ struct breakpoint_objfile_data
- /* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any). */
- struct minimal_symbol *longjmp_msym[NUM_LONGJMP_NAMES];
-
-+ /* True if we have looked for longjmp probes. */
-+ int longjmp_searched;
-+
-+ /* SystemTap probe points for longjmp (if any). */
-+ VEC (stap_probe_p) *longjmp_probes;
-+
- /* Minimal symbol for "std::terminate()" (if any). */
- struct minimal_symbol *terminate_msym;
-
- /* Minimal symbol for "_Unwind_DebugHook" (if any). */
- struct minimal_symbol *exception_msym;
-+
-+ /* True if we have looked for exception probes. */
-+ int exception_searched;
-+
-+ /* SystemTap probe points for unwinding (if any). */
-+ VEC (stap_probe_p) *exception_probes;
- };
-
- static const struct objfile_data *breakpoint_objfile_key;
-@@ -2265,6 +2316,15 @@ get_breakpoint_objfile_data (struct objfile *objfile)
- }
-
- static void
-+free_breakpoint_probes (struct objfile *obj, void *data)
-+{
-+ struct breakpoint_objfile_data *bp_objfile_data = data;
-+
-+ VEC_free (stap_probe_p, bp_objfile_data->longjmp_probes);
-+ VEC_free (stap_probe_p, bp_objfile_data->exception_probes);
-+}
-+
-+static void
- create_overlay_event_breakpoint (void)
- {
- struct objfile *objfile;
-@@ -2341,6 +2401,37 @@ create_longjmp_master_breakpoint (void)
-
- bp_objfile_data = get_breakpoint_objfile_data (objfile);
-
-+ if (!bp_objfile_data->longjmp_searched)
-+ {
-+ bp_objfile_data->longjmp_probes
-+ = find_probes_in_objfile (objfile, "libc", "longjmp");
-+ bp_objfile_data->longjmp_searched = 1;
-+ }
-+
-+ if (bp_objfile_data->longjmp_probes != NULL)
-+ {
-+ int i;
-+ struct stap_probe *probe;
-+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
-+
-+ for (i = 0;
-+ VEC_iterate (stap_probe_p,
-+ bp_objfile_data->longjmp_probes,
-+ i, probe);
-+ ++i)
-+ {
-+ struct breakpoint *b;
-+
-+ b = create_internal_breakpoint (gdbarch, probe->address,
-+ bp_longjmp_master,
-+ &internal_breakpoint_ops);
-+ b->addr_string = xstrdup ("-p libc:longjmp");
-+ b->enable_state = bp_disabled;
-+ }
-+
-+ continue;
-+ }
-+
- for (i = 0; i < NUM_LONGJMP_NAMES; i++)
- {
- struct breakpoint *b;
-@@ -2451,6 +2542,40 @@ create_exception_master_breakpoint (void)
-
- bp_objfile_data = get_breakpoint_objfile_data (objfile);
-
-+ /* We prefer the SystemTap probe point if it exists. */
-+ if (!bp_objfile_data->exception_searched)
-+ {
-+ bp_objfile_data->exception_probes
-+ = find_probes_in_objfile (objfile, "libgcc", "unwind");
-+ bp_objfile_data->exception_searched = 1;
-+ }
-+
-+ if (bp_objfile_data->exception_probes != NULL)
-+ {
-+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
-+ int i;
-+ struct stap_probe *probe;
-+
-+ for (i = 0;
-+ VEC_iterate (stap_probe_p,
-+ bp_objfile_data->exception_probes,
-+ i, probe);
-+ ++i)
-+ {
-+ struct breakpoint *b;
-+
-+ b = create_internal_breakpoint (gdbarch, probe->address,
-+ bp_exception_master,
-+ &internal_breakpoint_ops);
-+ b->addr_string = xstrdup ("-p libgcc:unwind");
-+ b->enable_state = bp_disabled;
-+ }
-+
-+ continue;
-+ }
-+
-+ /* Otherwise, try the hook function. */
-+
- if (msym_not_found_p (bp_objfile_data->exception_msym))
- continue;
-
-@@ -2666,6 +2791,8 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is)
- {
- /* No overlay handling: just remove the breakpoint. */
- val = bl->owner->ops->remove_location (bl);
-+
-+ modify_semaphore (bl, 0);
- }
- else
- {
-@@ -7111,6 +7238,7 @@ momentary_breakpoint_from_master (struct breakpoint *orig,
- copy->loc->address = orig->loc->address;
- copy->loc->section = orig->loc->section;
- copy->loc->pspace = orig->loc->pspace;
-+ copy->loc->semaphore = orig->loc->semaphore;
-
- if (orig->loc->source_file != NULL)
- copy->loc->source_file = xstrdup (orig->loc->source_file);
-@@ -7196,6 +7324,7 @@ add_location_to_breakpoint (struct breakpoint *b,
- loc->requested_address = sal->pc;
- loc->address = adjusted_address;
- loc->pspace = sal->pspace;
-+ loc->semaphore = sal->semaphore;
- gdb_assert (loc->pspace != NULL);
- loc->section = sal->section;
- loc->gdbarch = loc_gdbarch;
-@@ -13521,6 +13650,24 @@ all_tracepoints (void)
+@@ -15519,6 +15519,24 @@ all_tracepoints (void)
return tp_vec;
}
\f
/* This help string is used for the break, hbreak, tbreak and thbreak
commands. It is defined as a macro to prevent duplication.
-@@ -13815,7 +13962,8 @@ _initialize_breakpoint (void)
- observer_attach_inferior_exit (clear_syscall_counts);
- observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
-
-- breakpoint_objfile_key = register_objfile_data ();
-+ breakpoint_objfile_key
-+ = register_objfile_data_with_cleanup (NULL, free_breakpoint_probes);
-
- breakpoint_chain = 0;
- /* Don't bother to call set_breakpoint_count. $bpnum isn't useful
-@@ -14340,4 +14488,7 @@ range (including START-LOCATION and END-LOCATION)."));
+@@ -16484,4 +16502,7 @@ agent-printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
automatic_hardware_breakpoints = 1;
observer_attach_about_to_proceed (breakpoint_about_to_proceed);
+ observer_attach_mark_used (breakpoint_types_mark_used);
+#endif
}
-diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
-index 8a8d5f2..1e18562 100644
---- a/gdb/breakpoint.h
-+++ b/gdb/breakpoint.h
-@@ -379,6 +379,11 @@ struct bp_location
- processor's architectual constraints. */
- CORE_ADDR requested_address;
-
-+ /* If the location comes from a SystemTap probe point, and the probe
-+ has an associated semaphore variable, then this is the address of
-+ the semaphore. Otherwise, this is zero. */
-+ CORE_ADDR semaphore;
-+
- char *function_name;
-
- /* Details of the placed breakpoint, when inserted. */
-@@ -1412,4 +1417,11 @@ extern int user_breakpoint_p (struct breakpoint *);
- /* Attempt to determine architecture of location identified by SAL. */
- extern struct gdbarch *get_sal_arch (struct symtab_and_line sal);
-
-+/* Set or clear a SystemTap semaphore. LOC is the location which may
-+ hold a semaphore. SET is non-zero if the semaphore should be set,
-+ or zero if the semaphore should be cleared. Semaphores act as
-+ reference counters, so calls to this function must be paired. */
-+
-+extern void modify_semaphore (struct bp_location *location, int set);
-+
- #endif /* !defined (BREAKPOINT_H) */
+diff --git a/gdb/buildsym.c b/gdb/buildsym.c
+index d547012..e4882fb 100644
+--- a/gdb/buildsym.c
++++ b/gdb/buildsym.c
+@@ -966,11 +966,14 @@ reset_symtab_globals (void)
+ file's text.
+
+ If EXPANDABLE is non-zero the STATIC_BLOCK dictionary is made
+- expandable. */
++ expandable.
++
++ If REQUIRED is non-zero, then a symtab is created even if it does
++ not contain any symbols. */
+
+ struct block *
+ end_symtab_get_static_block (CORE_ADDR end_addr, struct objfile *objfile,
+- int expandable)
++ int expandable, int required)
+ {
+ /* Finish the lexical context of the last function in the file; pop
+ the context stack. */
+@@ -1038,7 +1041,8 @@ end_symtab_get_static_block (CORE_ADDR end_addr, struct objfile *objfile,
+ cleanup_undefined_stabs_types (objfile);
+ finish_global_stabs (objfile);
+
+- if (pending_blocks == NULL
++ if (!required
++ && pending_blocks == NULL
+ && file_symbols == NULL
+ && global_symbols == NULL
+ && have_line_numbers == 0
+@@ -1296,7 +1300,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
+ {
+ struct block *static_block;
+
+- static_block = end_symtab_get_static_block (end_addr, objfile, 0);
++ static_block = end_symtab_get_static_block (end_addr, objfile, 0, 0);
+ return end_symtab_from_static_block (static_block, objfile, section, 0);
+ }
+
+@@ -1308,7 +1312,7 @@ end_expandable_symtab (CORE_ADDR end_addr, struct objfile *objfile,
+ {
+ struct block *static_block;
+
+- static_block = end_symtab_get_static_block (end_addr, objfile, 1);
++ static_block = end_symtab_get_static_block (end_addr, objfile, 1, 0);
+ return end_symtab_from_static_block (static_block, objfile, section, 1);
+ }
+
+diff --git a/gdb/buildsym.h b/gdb/buildsym.h
+index 162ee8c..33b34c8 100644
+--- a/gdb/buildsym.h
++++ b/gdb/buildsym.h
+@@ -260,7 +260,8 @@ extern char *pop_subfile (void);
+
+ extern struct block *end_symtab_get_static_block (CORE_ADDR end_addr,
+ struct objfile *objfile,
+- int expandable);
++ int expandable,
++ int required);
+
+ extern struct symtab *end_symtab_from_static_block (struct block *static_block,
+ struct objfile *objfile,
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
-index db254dc..181de05 100644
+index a5892b5..2944c2d 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -624,9 +624,14 @@ c_type_print_varspec_suffix (struct type *type,
fprintf_filtered (stream, "]");
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
-diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c
-index a7b2718..a1e5161 100644
---- a/gdb/cli/cli-utils.c
-+++ b/gdb/cli/cli-utils.c
-@@ -223,6 +223,18 @@ skip_spaces (char *chp)
- return chp;
- }
-
-+/* A const-correct version of the above. */
-+
-+const char *
-+skip_spaces_const (const char *chp)
-+{
-+ if (chp == NULL)
-+ return NULL;
-+ while (*chp && isspace (*chp))
-+ chp++;
-+ return chp;
-+}
-+
- /* See documentation in cli-utils.h. */
+diff --git a/gdb/cc-with-dwz.sh b/gdb/cc-with-dwz.sh
+deleted file mode 100755
+index f66deb1..0000000
+--- a/gdb/cc-with-dwz.sh
++++ /dev/null
+@@ -1,80 +0,0 @@
+-#! /bin/sh
+-# Wrapper around gcc to run 'dwz' when running the testsuite.
+-
+-# Copyright (C) 2010-2012 Free Software Foundation, Inc.
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 3 of the License, or
+-# (at your option) any later version.
+-#
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-# GNU General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+-
+-# This program requires dwz in addition to gcc.
+-#
+-# Example usage:
+-#
+-# bash$ cd $objdir/gdb/testsuite
+-# bash$ runtest \
+-# CC_FOR_TARGET="/bin/sh $srcdir/cc-with-dwz.sh gcc" \
+-# CXX_FOR_TARGET="/bin/sh $srcdir/cc-with-dwz.sh g++"
+-#
+-
+-myname=cc-with-dwz.sh
+-
+-DWZ=${DWZ:-dwz}
+-
+-have_link=unknown
+-next_is_output_file=no
+-output_file=a.out
+-
+-for arg in "$@"
+-do
+- if [ "$next_is_output_file" = "yes" ]
+- then
+- output_file="$arg"
+- next_is_output_file=no
+- continue
+- fi
+-
+- # Poor man's gcc argument parser.
+- # We don't need to handle all arguments, we just need to know if we're
+- # doing a link and what the output file is.
+- # It's not perfect, but it seems to work well enough for the task at hand.
+- case "$arg" in
+- "-c") have_link=no ;;
+- "-E") have_link=no ;;
+- "-S") have_link=no ;;
+- "-o") next_is_output_file=yes ;;
+- esac
+-done
+-
+-if [ "$next_is_output_file" = "yes" ]
+-then
+- echo "$myname: Unable to find output file" >&2
+- exit 1
+-fi
+-
+-if [ "$have_link" = "no" ]
+-then
+- "$@"
+- exit $?
+-fi
+-
+-"$@"
+-rc=$?
+-[ $rc != 0 ] && exit $rc
+-if [ ! -f "$output_file" ]
+-then
+- echo "$myname: Internal error: $output_file missing." >&2
+- exit 1
+-fi
+-
+-$DWZ "$output_file" > /dev/null 2>&1
+-
+-exit 0
+diff --git a/gdb/cc-with-index.sh b/gdb/cc-with-index.sh
+deleted file mode 100644
+index 644ba34..0000000
+--- a/gdb/cc-with-index.sh
++++ /dev/null
+@@ -1,126 +0,0 @@
+-#! /bin/sh
+-# Wrapper around gcc to add the .gdb_index section when running the testsuite.
+-
+-# Copyright (C) 2010-2012 Free Software Foundation, Inc.
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 3 of the License, or
+-# (at your option) any later version.
+-#
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-# GNU General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+-
+-# This program requires gdb and objcopy in addition to gcc.
+-# The default values are gdb from the build tree and objcopy from $PATH.
+-# They may be overridden by setting environment variables GDB and OBJCOPY
+-# respectively.
+-# We assume the current directory is either $obj/gdb or $obj/gdb/testsuite.
+-#
+-# Example usage:
+-#
+-# bash$ cd $objdir/gdb/testsuite
+-# bash$ runtest \
+-# CC_FOR_TARGET="/bin/sh $srcdir/cc-with-index.sh gcc" \
+-# CXX_FOR_TARGET="/bin/sh $srcdir/cc-with-index.sh g++"
+-#
+-# For documentation on index files: info -f gdb.info -n "Index Files"
+-
+-myname=cc-with-index.sh
+-
+-if [ -z "$GDB" ]
+-then
+- if [ -f ./gdb ]
+- then
+- GDB="./gdb"
+- elif [ -f ../gdb ]
+- then
+- GDB="../gdb"
+- elif [ -f ../../gdb ]
+- then
+- GDB="../../gdb"
+- else
+- echo "$myname: unable to find usable gdb" >&2
+- exit 1
+- fi
+-fi
+-
+-OBJCOPY=${OBJCOPY:-objcopy}
+-
+-have_link=unknown
+-next_is_output_file=no
+-output_file=a.out
+-
+-for arg in "$@"
+-do
+- if [ "$next_is_output_file" = "yes" ]
+- then
+- output_file="$arg"
+- next_is_output_file=no
+- continue
+- fi
+-
+- # Poor man's gcc argument parser.
+- # We don't need to handle all arguments, we just need to know if we're
+- # doing a link and what the output file is.
+- # It's not perfect, but it seems to work well enough for the task at hand.
+- case "$arg" in
+- "-c") have_link=no ;;
+- "-E") have_link=no ;;
+- "-S") have_link=no ;;
+- "-o") next_is_output_file=yes ;;
+- esac
+-done
+-
+-if [ "$next_is_output_file" = "yes" ]
+-then
+- echo "$myname: Unable to find output file" >&2
+- exit 1
+-fi
+-
+-if [ "$have_link" = "no" ]
+-then
+- "$@"
+- exit $?
+-fi
+-
+-index_file="${output_file}.gdb-index"
+-if [ -f "$index_file" ]
+-then
+- echo "$myname: Index file $index_file exists, won't clobber." >&2
+- exit 1
+-fi
+-
+-output_dir="${output_file%/*}"
+-[ "$output_dir" = "$output_file" ] && output_dir="."
+-
+-"$@"
+-rc=$?
+-[ $rc != 0 ] && exit $rc
+-if [ ! -f "$output_file" ]
+-then
+- echo "$myname: Internal error: $output_file missing." >&2
+- exit 1
+-fi
+-
+-$GDB --batch-silent -nx -ex "set auto-load no" -ex "file $output_file" -ex "save gdb-index $output_dir"
+-rc=$?
+-[ $rc != 0 ] && exit $rc
+-
+-# GDB might not always create an index. Cope.
+-if [ -f "$index_file" ]
+-then
+- $OBJCOPY --add-section .gdb_index="$index_file" \
+- --set-section-flags .gdb_index=readonly \
+- "$output_file" "$output_file"
+- rc=$?
+-else
+- rc=0
+-fi
+-
+-rm -f "$index_file"
+-exit $rc
+diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c
+index 4a8b5d1..7341f00 100644
+--- a/gdb/cli/cli-dump.c
++++ b/gdb/cli/cli-dump.c
+@@ -32,6 +32,7 @@
+ #include "readline/readline.h"
+ #include "gdbcore.h"
+ #include "cli/cli-utils.h"
++#include "gdb_bfd.h"
- char *
-@@ -245,3 +257,32 @@ remove_trailing_whitespace (const char *start, char *s)
+ #define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
- return s;
- }
-+
-+/* See documentation in cli-utils.h. */
-+
-+char *
-+extract_arg (char **arg)
-+{
-+ char *result, *copy;
-+
-+ if (!*arg)
-+ return NULL;
-+
-+ /* Find the start of the argument. */
-+ *arg = skip_spaces (*arg);
-+ if (! **arg)
-+ return NULL;
-+ result = *arg;
-+
-+ /* Find the end of the argument. */
-+ *arg = skip_to_space (*arg + 1);
-+
-+ if (result == *arg)
-+ return NULL;
-+
-+ copy = xmalloc (*arg - result + 1);
-+ memcpy (copy, result, *arg - result);
-+ copy[*arg - result] = '\0';
-+
-+ return copy;
-+}
-diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h
-index e23c7d8..5f8a91d 100644
---- a/gdb/cli/cli-utils.h
-+++ b/gdb/cli/cli-utils.h
-@@ -94,6 +94,10 @@ extern int number_is_in_list (char *list, int number);
+@@ -111,12 +112,12 @@ bfd_openr_with_cleanup (const char *filename, const char *target)
+ {
+ bfd *ibfd;
- extern char *skip_spaces (char *inp);
+- ibfd = bfd_openr (filename, target);
++ ibfd = gdb_bfd_openr (filename, target);
+ if (ibfd == NULL)
+ error (_("Failed to open %s: %s."), filename,
+ bfd_errmsg (bfd_get_error ()));
-+/* A const-correct version of the above. */
-+
-+extern const char *skip_spaces_const (const char *inp);
-+
- /* Skip leading non-whitespace characters in INP, returning an updated
- pointer. If INP is NULL, return NULL. */
+- make_cleanup_bfd_close (ibfd);
++ make_cleanup_bfd_unref (ibfd);
+ if (!bfd_check_format (ibfd, bfd_object))
+ error (_("'%s' is not a recognized file format."), filename);
-@@ -103,4 +107,11 @@ extern char *skip_to_space (char *inp);
- START. */
+@@ -131,11 +132,11 @@ bfd_openw_with_cleanup (const char *filename, const char *target,
- extern char *remove_trailing_whitespace (const char *start, char *s);
-+
-+/* A helper function to extract an argument from *ARG. An argument is
-+ delimited by whitespace. The return value is either NULL if no
-+ argument was found, or an xmalloc'd string. */
-+
-+extern char *extract_arg (char **arg);
-+
- #endif /* CLI_UTILS_H */
+ if (*mode == 'w') /* Write: create new file */
+ {
+- obfd = bfd_openw (filename, target);
++ obfd = gdb_bfd_openw (filename, target);
+ if (obfd == NULL)
+ error (_("Failed to open %s: %s."), filename,
+ bfd_errmsg (bfd_get_error ()));
+- make_cleanup_bfd_close (obfd);
++ make_cleanup_bfd_unref (obfd);
+ if (!bfd_set_format (obfd, bfd_object))
+ error (_("bfd_openw_with_cleanup: %s."), bfd_errmsg (bfd_get_error ()));
+ }
diff --git a/gdb/coffread.c b/gdb/coffread.c
-index c727228..e1fab6d 100644
+index b0a8b82..0c7e6d9 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
-@@ -2195,6 +2195,7 @@ static const struct sym_fns coff_sym_fns =
+@@ -653,13 +653,14 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags)
+ char *debugfile;
- default_symfile_relocate, /* sym_relocate: Relocate a debug
- section. */
-+ NULL, /* sym_probe_fns */
- &psym_functions
- };
+ debugfile = find_separate_debug_file_by_debuglink (objfile);
++ make_cleanup (xfree, debugfile);
-diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in
-index 4296e5a..b04d12f 100644
---- a/gdb/data-directory/Makefile.in
-+++ b/gdb/data-directory/Makefile.in
-@@ -52,13 +52,24 @@ SYSCALLS_FILES = \
- PYTHON_DIR = python
- PYTHON_INSTALL_DIR = $(DESTDIR)$(GDB_DATADIR)/$(PYTHON_DIR)
- PYTHON_FILES = \
-+ gdb/FrameIterator.py \
-+ gdb/FrameWrapper.py \
- gdb/__init__.py \
-- gdb/types.py \
-- gdb/printing.py \
-- gdb/prompt.py \
-+ gdb/backtrace.py \
- gdb/command/__init__.py \
-+ gdb/command/backtrace.py \
-+ gdb/command/ignore_errors.py \
-+ gdb/command/pahole.py \
- gdb/command/pretty_printers.py \
-- gdb/command/prompt.py
-+ gdb/command/prompt.py \
-+ gdb/command/require.py \
-+ gdb/command/upto.py \
-+ gdb/function/__init__.py \
-+ gdb/function/caller_is.py \
-+ gdb/function/in_scope.py \
-+ gdb/printing.py \
-+ gdb/prompt.py \
-+ gdb/types.py
+ if (debugfile)
+ {
+ bfd *abfd = symfile_bfd_open (debugfile);
- FLAGS_TO_PASS = \
- "prefix=$(prefix)" \
-diff --git a/gdb/dbxread.c b/gdb/dbxread.c
-index adf8315..c11e4d4 100644
---- a/gdb/dbxread.c
-+++ b/gdb/dbxread.c
-@@ -3588,6 +3588,7 @@ static const struct sym_fns aout_sym_fns =
- default_symfile_segments, /* Get segment information from a file. */
- NULL,
- default_symfile_relocate, /* Relocate a debug section. */
-+ NULL, /* sym_probe_fns */
- &psym_functions
- };
++ make_cleanup_bfd_unref (abfd);
+ symbol_file_add_separate (abfd, symfile_flags, objfile);
+- xfree (debugfile);
+ }
+ }
+
+diff --git a/gdb/contrib/cc-with-tweaks.sh b/gdb/contrib/cc-with-tweaks.sh
+new file mode 100755
+index 0000000..7d7932c
+--- /dev/null
++++ b/gdb/contrib/cc-with-tweaks.sh
+@@ -0,0 +1,162 @@
++#! /bin/sh
++# Wrapper around gcc to tweak the output in various ways when running
++# the testsuite.
++
++# Copyright (C) 2010-2012 Free Software Foundation, Inc.
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program. If not, see <http://www.gnu.org/licenses/>.
++
++# This program requires gdb and objcopy in addition to gcc.
++# The default values are gdb from the build tree and objcopy from $PATH.
++# They may be overridden by setting environment variables GDB and OBJCOPY
++# respectively.
++# We assume the current directory is either $obj/gdb or $obj/gdb/testsuite.
++#
++# Example usage:
++#
++# bash$ cd $objdir/gdb/testsuite
++# bash$ runtest \
++# CC_FOR_TARGET="/bin/sh $srcdir/gdb/contrib/cc-with-tweaks.sh ARGS gcc" \
++# CXX_FOR_TARGET="/bin/sh $srcdir/gdb/contrib/cc-with-tweaks.sh ARGS g++"
++#
++# For documentation on index files: info -f gdb.info -n "Index Files"
++# For information about 'dwz', see the announcement:
++# http://gcc.gnu.org/ml/gcc/2012-04/msg00686.html
++# (More documentation is to come.)
++
++# ARGS determine what is done. They can be:
++# -z compress using dwz
++# -m compress using dwz -m
++# -i make an index
++# If nothing is given, no changes are made
++
++myname=cc-with-tweaks.sh
++
++if [ -z "$GDB" ]
++then
++ if [ -f ./gdb ]
++ then
++ GDB="./gdb"
++ elif [ -f ../gdb ]
++ then
++ GDB="../gdb"
++ elif [ -f ../../gdb ]
++ then
++ GDB="../../gdb"
++ else
++ echo "$myname: unable to find usable gdb" >&2
++ exit 1
++ fi
++fi
++
++OBJCOPY=${OBJCOPY:-objcopy}
++
++DWZ=${DWZ:-dwz}
++
++have_link=unknown
++next_is_output_file=no
++output_file=a.out
++
++want_index=false
++want_dwz=false
++want_multi=false
++
++while [ $# -gt 0 ]; do
++ case "$1" in
++ -z) want_dwz=true ;;
++ -i) want_index=true ;;
++ -m) want_multi=true ;;
++ *) break ;;
++ esac
++ shift
++done
++
++for arg in "$@"
++do
++ if [ "$next_is_output_file" = "yes" ]
++ then
++ output_file="$arg"
++ next_is_output_file=no
++ continue
++ fi
++
++ # Poor man's gcc argument parser.
++ # We don't need to handle all arguments, we just need to know if we're
++ # doing a link and what the output file is.
++ # It's not perfect, but it seems to work well enough for the task at hand.
++ case "$arg" in
++ "-c") have_link=no ;;
++ "-E") have_link=no ;;
++ "-S") have_link=no ;;
++ "-o") next_is_output_file=yes ;;
++ esac
++done
++
++if [ "$next_is_output_file" = "yes" ]
++then
++ echo "$myname: Unable to find output file" >&2
++ exit 1
++fi
++
++if [ "$have_link" = "no" ]
++then
++ "$@"
++ exit $?
++fi
++
++index_file="${output_file}.gdb-index"
++if [ "$want_index" = true ] && [ -f "$index_file" ]
++then
++ echo "$myname: Index file $index_file exists, won't clobber." >&2
++ exit 1
++fi
++
++output_dir="${output_file%/*}"
++[ "$output_dir" = "$output_file" ] && output_dir="."
++
++"$@"
++rc=$?
++[ $rc != 0 ] && exit $rc
++if [ ! -f "$output_file" ]
++then
++ echo "$myname: Internal error: $output_file missing." >&2
++ exit 1
++fi
++
++if [ "$want_index" = true ]; then
++ $GDB --batch-silent -nx -ex "set auto-load no" -ex "file $output_file" -ex "save gdb-index $output_dir"
++ rc=$?
++ [ $rc != 0 ] && exit $rc
++
++ # GDB might not always create an index. Cope.
++ if [ -f "$index_file" ]
++ then
++ $OBJCOPY --add-section .gdb_index="$index_file" \
++ --set-section-flags .gdb_index=readonly \
++ "$output_file" "$output_file"
++ rc=$?
++ else
++ rc=0
++ fi
++ [ $rc != 0 ] && exit $rc
++fi
++
++if [ "$want_dwz" = true ]; then
++ $DWZ "$output_file" > /dev/null 2>&1
++elif [ "$want_multi" = true ]; then
++ cp $output_file ${output_file}.alt
++ $DWZ -m ${output_file}.dwz "$output_file" ${output_file}.alt > /dev/null 2>&1
++fi
++
++rm -f "$index_file"
++exit $rc
+diff --git a/gdb/corelow.c b/gdb/corelow.c
+index dd62560..340b149 100644
+--- a/gdb/corelow.c
++++ b/gdb/corelow.c
+@@ -46,6 +46,7 @@
+ #include "filenames.h"
+ #include "progspace.h"
+ #include "objfiles.h"
++#include "gdb_bfd.h"
+
+ #ifndef O_LARGEFILE
+ #define O_LARGEFILE 0
+@@ -215,9 +216,7 @@ core_close (int quitting)
+ core_data = NULL;
+ }
+
+- name = bfd_get_filename (core_bfd);
+- gdb_bfd_close_or_warn (core_bfd);
+- xfree (name);
++ gdb_bfd_unref (core_bfd);
+ core_bfd = NULL;
+ }
+ core_vec = NULL;
+@@ -319,9 +318,9 @@ core_open (char *filename, int from_tty)
+ if (scratch_chan < 0)
+ perror_with_name (filename);
+
+- temp_bfd = bfd_fopen (filename, gnutarget,
+- write_files ? FOPEN_RUB : FOPEN_RB,
+- scratch_chan);
++ temp_bfd = gdb_bfd_fopen (filename, gnutarget,
++ write_files ? FOPEN_RUB : FOPEN_RB,
++ scratch_chan);
+ if (temp_bfd == NULL)
+ perror_with_name (filename);
+
+@@ -332,7 +331,7 @@ core_open (char *filename, int from_tty)
+ /* FIXME: should be checking for errors from bfd_close (for one
+ thing, on error it does not free all the storage associated
+ with the bfd). */
+- make_cleanup_bfd_close (temp_bfd);
++ make_cleanup_bfd_unref (temp_bfd);
+ error (_("\"%s\" is not a core dump: %s"),
+ filename, bfd_errmsg (bfd_get_error ()));
+ }
+@@ -340,7 +339,7 @@ core_open (char *filename, int from_tty)
+ /* Looks semi-reasonable. Toss the old core file and work on the
+ new. */
+
+- discard_cleanups (old_chain); /* Don't free filename any more */
++ do_cleanups (old_chain);
+ unpush_target (&core_ops);
+ core_bfd = temp_bfd;
+ old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/);
+diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in
+index 87c6dd4..1c26652 100644
+--- a/gdb/data-directory/Makefile.in
++++ b/gdb/data-directory/Makefile.in
+@@ -52,14 +52,25 @@ SYSCALLS_FILES = \
+ PYTHON_DIR = python
+ PYTHON_INSTALL_DIR = $(DESTDIR)$(GDB_DATADIR)/$(PYTHON_DIR)
+ PYTHON_FILES = \
++ gdb/FrameIterator.py \
++ gdb/FrameWrapper.py \
+ gdb/__init__.py \
+- gdb/types.py \
+- gdb/printing.py \
+- gdb/prompt.py \
++ gdb/backtrace.py \
+ gdb/command/__init__.py \
++ gdb/command/backtrace.py \
++ gdb/command/ignore_errors.py \
++ gdb/command/pahole.py \
+ gdb/command/pretty_printers.py \
+ gdb/command/prompt.py \
+- gdb/command/explore.py
++ gdb/command/explore.py \
++ gdb/command/require.py \
++ gdb/command/upto.py \
++ gdb/function/__init__.py \
++ gdb/function/caller_is.py \
++ gdb/function/in_scope.py \
++ gdb/printing.py \
++ gdb/prompt.py \
++ gdb/types.py
+ FLAGS_TO_PASS = \
+ "prefix=$(prefix)" \
diff --git a/gdb/defs.h b/gdb/defs.h
-index 83a716a..7f8752e 100644
+index 1c6fa79..ec08348 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
-@@ -411,6 +411,8 @@ extern struct cleanup *make_cleanup_restore_page_info (void);
+@@ -315,7 +315,7 @@ extern struct cleanup *make_cleanup_close (int fd);
+
+ extern struct cleanup *make_cleanup_fclose (FILE *file);
+
+-extern struct cleanup *make_cleanup_bfd_close (bfd *abfd);
++extern struct cleanup *make_cleanup_bfd_unref (bfd *abfd);
+
+ struct obstack;
+ extern struct cleanup *make_cleanup_obstack_free (struct obstack *obstack);
+@@ -353,6 +353,8 @@ extern struct cleanup *make_cleanup_restore_page_info (void);
extern struct cleanup *
set_batch_flag_and_make_cleanup_restore_page_info (void);
extern char *xfullpath (const char *);
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
-index 20b0b67..57068c3 100644
+index 68ea817..5945bac 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
-@@ -1173,6 +1173,16 @@ for remote debugging.
+@@ -1200,6 +1200,16 @@ for remote debugging.
Run using @var{device} for your program's standard input and output.
@c FIXME: kingdon thinks there is more to -tty. Investigate.
@c resolve the situation of these eventually
@item -tui
@cindex @code{--tui}
-@@ -3301,6 +3311,7 @@ all breakpoints in that range are operated on.
- * Conditions:: Break conditions
- * Break Commands:: Breakpoint command lists
- * Save Breakpoints:: How to save breakpoints in a file
-+* Static Probe Points:: Listing static probe points
- * Error in Breakpoints:: ``Cannot insert breakpoints''
- * Breakpoint-related Warnings:: ``Breakpoint address adjusted...''
- @end menu
-@@ -4530,6 +4541,50 @@ and remove the breakpoint definitions you're not interested in, or
- that can no longer be recreated.
- @end table
-
-+@node Static Probe Points
-+@subsection Static Probe Points
-+
-+@cindex SystemTap static probe point
-+@cindex sdt-probe
-+The @sc{gnu}/Linux tool @code{SystemTap} provides a way for
-+applications to embed static probes, using @file{sys/sdt.h}. @value{GDBN}
-+can list the available probes, and you can put breakpoints at the
-+probe points (@pxref{Specify Location}).
-+
-+You can examine the available @code{SystemTap} static probes using
-+@code{info probes}:
-+
-+@table @code
-+@kindex info probes
-+@item info probes [@var{provider} [@var{name} [@var{objfile}]]]
-+List the available @code{SystemTap} static probes.
-+
-+If given, @var{provider} is a regular expression used to select which
-+providers to list. If omitted, all providers are listed.
-+
-+If given, @var{name} is a regular expression used to select which
-+probes to list. If omitted, all probes are listed.
-+
-+If given, @var{objfile} is a regular expression used to select which
-+object files (executable or shared libraries) to examine. If not
-+given, all object files are considered.
-+@end table
-+
-+@vindex $_probe_arg@r{, convenience variable}
-+A probe may specify up to ten arguments. These are available at the
-+point at which the probe is defined---that is, when the current PC is
-+at the probe's location. The arguments are available using the
-+convenience variables (@pxref{Convenience Vars})
-+@code{$_probe_arg0}@dots{}@code{$_probe_arg11}. Each probe argument is
-+an integer of the appropriate size; types are not preserved. The
-+convenience variable @code{$_probe_argc} holds the number of arguments
-+at the current probe point.
-+
-+These variables are always available, but attempts to access them at
-+any location other than a probe point will cause @value{GDBN} to give
-+an error.
-+
-+
- @c @ifclear BARETARGET
- @node Error in Breakpoints
- @subsection ``Cannot insert breakpoints''
-@@ -6555,6 +6610,29 @@ specify the function unambiguously, e.g., if there are several
- functions with identical names in different source files.
- @end table
-
-+@cindex SystemTap static probe point
-+@item -p @r{[}@var{objfile}:@r{]}@r{[}@var{provider}:@r{]}@var{name}
-+The @sc{gnu}/Linux tool @code{SystemTap} provides a way for
-+applications to embed static probes. This form of linespec specifies
-+the location of such a static probe. See
-+@uref{http://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps}
-+for more information on static probes.
-+
-+If @var{objfile} is given, only probes coming from that shared library
-+or executable are considered. If @var{provider} is given, then only
-+probes from that provider are considered.
-+
-+@xref{Static Probe Points}, for more information on finding and using
-+static probes.
-+
-+Some probes have an associated semaphore variable; for instance, this
-+happens automatically if you defined your probe using a DTrace-style
-+@file{.d} file. If your probe has a semaphore, @value{GDBN} will
-+automatically enable it when you specify a breakpoint using the
-+@samp{-p} notation. But, if you put a breakpoint at a probe's
-+location by some other method (e.g., @code{break file:line}), then
-+@value{GDBN} will not automatically set the semaphore.
-+
- @end table
-
-
-@@ -8811,6 +8889,10 @@ to match the format in which the data was printed.
- The variable @code{$_exitcode} is automatically set to the exit code when
- the program being debugged terminates.
-
-+@item $_probe_argc
-+@itemx $_probe_arg0@dots{}$_probe_arg11
-+Arguments to a SystemTap static probe. @xref{Static Probe Points}.
-+
- @item $_sdata
- @vindex $_sdata@r{, inspect, convenience variable}
- The variable @code{$_sdata} contains extra collected static tracepoint
-@@ -10763,6 +10845,16 @@ Collect all local variables.
- Collect the return address. This is helpful if you want to see more
- of a backtrace.
-
-+@item $_probe_argc
-+Collects the number of arguments from the @code{SystemTap} probe at
-+which the tracepoint is located.
-+@xref{Static Probe Points,,Static Probe Points}.
-+
-+@item $_probe_arg@var{N}
-+Where @var{N} varies from 0 to 11. Collects the @var{N}th argument
-+from the @code{SystemTap} probe at which the tracepoint is located.
-+@xref{Static Probe Points,,Static Probe Points}.
-+
- @item $_sdata
- @vindex $_sdata@r{, collect}
- Collect static tracepoint marker specific data. Only available for
-@@ -21506,8 +21598,6 @@ containing @code{end}. For example:
+@@ -22563,8 +22573,6 @@ containing @code{end}. For example:
@smallexample
(@value{GDBP}) python
>print 23
>end
23
-@@ -21521,6 +21611,14 @@ controlled using @code{set python print-stack}: if @code{full}, then
+@@ -22578,6 +22586,14 @@ controlled using @code{set python print-stack}: if @code{full}, then
full Python stack printing is enabled; if @code{none}, then Python stack
and message printing is disabled; if @code{message}, the default, only
the message component of the error is printed.
@end table
It is also possible to execute a Python script from the @value{GDBN}
-@@ -21542,6 +21640,14 @@ and thus is always available.
+@@ -22599,6 +22615,14 @@ and thus is always available.
@cindex python api
@cindex programming in python
@cindex python stdout
@cindex python pagination
At startup, @value{GDBN} overrides Python's @code{sys.stdout} and
+@@ -34536,6 +34560,11 @@ Shared library events.
+
+ @end table
+
++@kindex maint info bfds
++@item maint info bfds
++This prints information about each @code{bfd} object that is known to
++@value{GDBN}. @xref{Top, , BFD, bfd, The Binary File Descriptor Library}.
++
+ @kindex set displaced-stepping
+ @kindex show displaced-stepping
+ @cindex displaced stepping support
diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo
-index 026dc59..f0f6ee3 100644
+index 5e00f1f..c5c432b 100644
--- a/gdb/doc/gdbint.texinfo
+++ b/gdb/doc/gdbint.texinfo
-@@ -2103,6 +2103,18 @@ time, and so we attempt to handle symbols incrementally. For instance,
+@@ -2102,6 +2102,18 @@ time, and so we attempt to handle symbols incrementally. For instance,
we create @dfn{partial symbol tables} consisting of only selected
symbols, and only expand them to full symbol tables when necessary.
@section Symbol Reading
@cindex symbol reading
-@@ -2195,6 +2207,7 @@ symtab. Upon return, @code{pst->readin} should have been set to 1, and
+@@ -2194,6 +2206,7 @@ symtab. Upon return, @code{pst->readin} should have been set to 1, and
zero if there were no symbols in that part of the symbol file.
@end table
@section Partial Symbol Tables
@value{GDBN} has three types of symbol tables:
-@@ -2296,6 +2309,7 @@ and partial symbol tables behind a set of function pointers known as
+@@ -2295,6 +2308,7 @@ and partial symbol tables behind a set of function pointers known as
the @dfn{quick symbol functions}. These are documented in
@file{symfile.h}.
@section Types
@unnumberedsubsec Fundamental Types (e.g., @code{FT_VOID}, @code{FT_BOOLEAN}).
-@@ -2318,6 +2332,7 @@ types map to one @code{TYPE_CODE_*} type, and are distinguished by
+@@ -2317,6 +2331,7 @@ types map to one @code{TYPE_CODE_*} type, and are distinguished by
other members of the type struct, such as whether the type is signed
or unsigned, and how many bits it uses.
@unnumberedsubsec Builtin Types (e.g., @code{builtin_type_void}, @code{builtin_type_char}).
These are instances of type structs that roughly correspond to
-@@ -2332,6 +2347,7 @@ only one instance exists, while @file{c-lang.c} builds as many
+@@ -2331,6 +2346,7 @@ only one instance exists, while @file{c-lang.c} builds as many
@code{TYPE_CODE_INT} types as needed, with each one associated with
some particular objfile.
@section Object File Formats
@cindex object file formats
-@@ -2417,6 +2433,7 @@ SOM, which is a cross-language ABI).
+@@ -2416,6 +2432,7 @@ SOM, which is a cross-language ABI).
The SOM reader is in @file{somread.c}.
@section Debugging File Formats
This section describes characteristics of debugging information that
-@@ -2488,6 +2505,7 @@ DWARF 3 is an improved version of DWARF 2.
+@@ -2487,6 +2504,7 @@ DWARF 3 is an improved version of DWARF 2.
@cindex SOM debugging info
Like COFF, the SOM definition includes debugging information.
@section Adding a New Symbol Reader to @value{GDBN}
@cindex adding debugging info reader
-@@ -2510,6 +2528,7 @@ will only ever be implemented by one object file format may be called
+@@ -2509,6 +2527,7 @@ will only ever be implemented by one object file format may be called
directly. This interface should be described in a file
@file{bfd/lib@var{xyz}.h}, which is included by @value{GDBN}.
@section Memory Management for Symbol Files
Most memory associated with a loaded symbol file is stored on
-@@ -2521,10 +2540,45 @@ released when the objfile is unloaded or reloaded. Therefore one
+@@ -2520,10 +2539,45 @@ released when the objfile is unloaded or reloaded. Therefore one
objfile must not reference symbol or type data from another objfile;
they could be unloaded at different times.
@node Language Support
diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi
-index 24233cb..efb2013 100644
+index 6827ed8..c63b901 100644
--- a/gdb/doc/observer.texi
+++ b/gdb/doc/observer.texi
-@@ -226,6 +226,11 @@ Called before a top-level prompt is displayed. @var{current_prompt} is
- the current top-level prompt.
+@@ -230,6 +230,11 @@ the current top-level prompt.
+ Variable gdb_datadir has been set. The value may not necessarily change.
@end deftypefun
+@c @deftypefun void mark_used (void)
@deftypefun void test_notification (int @var{somearg})
This observer is used for internal testing. Do not use.
See testsuite/gdb.gdb/observer.exp.
+diff --git a/gdb/dsrec.c b/gdb/dsrec.c
+index d2c99b2..f39d0ed 100644
+--- a/gdb/dsrec.c
++++ b/gdb/dsrec.c
+@@ -23,6 +23,7 @@
+ #include <time.h>
+ #include "gdb_assert.h"
+ #include "gdb_string.h"
++#include "gdb_bfd.h"
+
+ extern void report_transfer_performance (unsigned long, time_t, time_t);
+
+@@ -56,19 +57,22 @@ load_srec (struct serial *desc, const char *file, bfd_vma load_offset,
+ int reclen;
+ time_t start_time, end_time;
+ unsigned long data_count = 0;
++ struct cleanup *cleanup;
+
+ srec = (char *) alloca (maxrecsize + 1);
+
+- abfd = bfd_openr (file, 0);
++ abfd = gdb_bfd_openr (file, 0);
+ if (!abfd)
+ {
+ printf_filtered (_("Unable to open file %s\n"), file);
+ return;
+ }
+
++ cleanup = make_cleanup_bfd_unref (abfd);
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered (_("File is not an object file\n"));
++ do_cleanups (cleanup);
+ return;
+ }
+
+@@ -170,6 +174,7 @@ load_srec (struct serial *desc, const char *file, bfd_vma load_offset,
+ serial_flush_input (desc);
+
+ report_transfer_performance (data_count, start_time, end_time);
++ do_cleanups (cleanup);
+ }
+
+ /*
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
-index 222fcc3..93389e0 100644
+index 214b371..d9b3751 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
-@@ -1449,6 +1449,14 @@ execute_stack_op (struct dwarf_expr_context *ctx,
+@@ -1480,6 +1480,14 @@ execute_stack_op (struct dwarf_expr_context *ctx,
}
break;
error (_("Unhandled dwarf expression opcode 0x%x"), op);
}
diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h
-index fd70bf9..5129c4e 100644
+index 19efbfd..0e0e498 100644
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
-@@ -73,12 +73,10 @@ struct dwarf_expr_context_funcs
- int dwarf_reg, CORE_ADDR fb_offset,
- int deref_size);
+@@ -78,12 +78,8 @@ struct dwarf_expr_context_funcs
+ This can throw an exception if the index is out of range. */
+ CORE_ADDR (*get_addr_index) (void *baton, unsigned int index);
-#if 0
- /* Not yet implemented. */
-
+- /* Not yet implemented. */
+-
/* Return the `object address' for DW_OP_push_object_address. */
CORE_ADDR (*get_object_address) (void *baton);
-#endif
/* The location of a value. */
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
-index 313df7b..35e0766 100644
+index 38e4814..46a033d 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
-@@ -157,6 +157,9 @@ struct dwarf_expr_baton
+@@ -293,6 +293,9 @@ struct dwarf_expr_baton
{
struct frame_info *frame;
struct dwarf2_per_cu_data *per_cu;
};
/* Helper functions for dwarf2_evaluate_loc_desc. */
-@@ -216,16 +219,14 @@ static void
+@@ -352,16 +355,14 @@ static void
dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
const gdb_byte **start, size_t *length)
{
{
struct dwarf2_locexpr_baton *symbaton;
-@@ -238,10 +239,23 @@ dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
+@@ -374,10 +375,23 @@ dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
else
*length = 0;
}
}
/* Helper function for dwarf2_evaluate_loc_desc. Computes the CFA for
-@@ -309,6 +323,85 @@ dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
+@@ -445,6 +459,85 @@ dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset)
ctx->funcs->get_frame_pc, ctx->baton);
}
/* Callback function for dwarf2_evaluate_loc_desc. */
static struct type *
-@@ -990,10 +1083,12 @@ dwarf_expr_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
+@@ -1139,10 +1232,12 @@ dwarf_expr_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
saved_ctx.gdbarch = ctx->gdbarch;
saved_ctx.addr_size = ctx->addr_size;
ctx->offset = dwarf2_per_cu_text_offset (baton_local.per_cu);
ctx->baton = &baton_local;
-@@ -1001,10 +1096,92 @@ dwarf_expr_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
+@@ -1150,10 +1245,95 @@ dwarf_expr_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
ctx->gdbarch = saved_ctx.gdbarch;
ctx->addr_size = saved_ctx.addr_size;
ctx->baton = saved_ctx.baton;
}
++static CORE_ADDR dwarf_expr_get_addr_index (void *baton, unsigned int index);
++
+/* Virtual method table for dwarf2_evaluate_loc_desc_full below. */
+
+static const struct dwarf_expr_context_funcs dwarf_expr_ctx_funcs =
+ dwarf_expr_dwarf_call,
+ dwarf_expr_get_base_type,
+ dwarf_expr_push_dwarf_reg_entry_value,
++ dwarf_expr_get_addr_index,
+ dwarf_expr_object_address
+};
+
+ return retval;
+}
+
- /* VALUE must be of type lval_computed with entry_data_value_funcs. Perform
- the indirect method on it, that is use its stored target value, the sole
- purpose of entry_data_value_funcs.. */
-@@ -1927,21 +2104,6 @@ invalid_synthetic_pointer (void)
+ /* Callback function for dwarf2_evaluate_loc_desc.
+ Fetch the address indexed by DW_OP_GNU_addr_index. */
+
+@@ -2088,22 +2268,6 @@ invalid_synthetic_pointer (void)
"referenced via synthetic pointer"));
}
- dwarf_expr_tls_address,
- dwarf_expr_dwarf_call,
- dwarf_expr_get_base_type,
-- dwarf_expr_push_dwarf_reg_entry_value
+- dwarf_expr_push_dwarf_reg_entry_value,
+- dwarf_expr_get_addr_index
-};
-
/* Evaluate a location description, starting at DATA and with length
SIZE, to find the current location of variable of TYPE in the
context of FRAME. BYTE_OFFSET is applied after the contents are
-@@ -1954,7 +2116,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
+@@ -2116,7 +2280,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
LONGEST byte_offset)
{
struct value *retval;
struct dwarf_expr_context *ctx;
struct cleanup *old_chain, *value_chain;
struct objfile *objfile = dwarf2_per_cu_objfile (per_cu);
-@@ -1966,29 +2127,18 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
+@@ -2128,29 +2291,18 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
if (size == 0)
return allocate_optimized_out_value (type);
retval = allocate_value (type);
mark_value_bytes_unavailable (retval, 0, TYPE_LENGTH (type));
return retval;
-@@ -2052,6 +2202,16 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
+@@ -2214,6 +2366,16 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
do_cleanups (value_chain);
retval = allocate_value_lazy (type);
VALUE_LVAL (retval) = lval_memory;
if (in_stack_memory)
-@@ -3896,8 +4056,7 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
+@@ -4130,8 +4292,7 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
dlbaton->per_cu);
}
const struct symbol_computed_ops dwarf2_loclist_funcs = {
loclist_read_variable,
loclist_read_variable_at_entry,
-@@ -3906,6 +4065,48 @@ const struct symbol_computed_ops dwarf2_loclist_funcs = {
+@@ -4140,6 +4301,48 @@ const struct symbol_computed_ops dwarf2_loclist_funcs = {
loclist_tracepoint_var_ref
};
+ missing_tracepoint_var_ref
+};
+
- void
- _initialize_dwarf2loc (void)
- {
+ /* Provide a prototype to silence -Wmissing-prototypes. */
+ extern initialize_file_ftype _initialize_dwarf2loc;
+
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
-index a7f835f..52a44f1 100644
+index e9d06a3..bfa6776 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
-@@ -118,6 +118,15 @@ struct dwarf2_loclist_baton
+@@ -127,6 +127,15 @@ struct dwarf2_loclist_baton
extern const struct symbol_computed_ops dwarf2_locexpr_funcs;
extern const struct symbol_computed_ops dwarf2_loclist_funcs;
/* Compile a DWARF location expression to an agent expression.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
-index 0ef0a5b..80e5fe4 100644
+index deee5a2..b2f052b 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
-@@ -1209,6 +1209,9 @@ static void fill_in_loclist_baton (struct dwarf2_cu *cu,
+@@ -64,20 +64,12 @@
+ #include "gdbcore.h" /* for gnutarget */
+ #include "gdb/gdb-index.h"
+ #include <ctype.h>
++#include "gdb_bfd.h"
+
+ #include <fcntl.h>
+ #include "gdb_string.h"
+ #include "gdb_assert.h"
+ #include <sys/types.h>
+-#ifdef HAVE_ZLIB_H
+-#include <zlib.h>
+-#endif
+-#ifdef HAVE_MMAP
+-#include <sys/mman.h>
+-#ifndef MAP_FAILED
+-#define MAP_FAILED ((void *) -1)
+-#endif
+-#endif
+
+ typedef struct symbol *symbolp;
+ DEF_VEC_P (symbolp);
+@@ -95,8 +87,6 @@ static int check_physname = 0;
+ /* When non-zero, do not reject deprecated .gdb_index sections. */
+ static int use_deprecated_index_sections = 0;
+
+-static int pagesize;
+-
+ /* When set, the file that we're processing is known to have debugging
+ info for C++ namespaces. GCC 3.3.x did not produce this information,
+ but later versions do. */
+@@ -110,10 +100,6 @@ struct dwarf2_section_info
+ asection *asection;
+ gdb_byte *buffer;
+ bfd_size_type size;
+- /* Not NULL if the section was actually mmapped. */
+- void *map_addr;
+- /* Page aligned size of mmapped area. */
+- bfd_size_type map_len;
+ /* True if we have tried to read this section. */
+ int readin;
+ };
+@@ -247,6 +233,10 @@ struct dwarf2_per_objfile
+ This is NULL if the table hasn't been allocated yet. */
+ htab_t dwo_files;
+
++ /* The shared '.dwz' file, if one exists. This is used when the
++ original data was compressed using 'dwz -m'. */
++ struct dwz_file *dwz_file;
++
+ /* A flag indicating wether this objfile has a section loaded at a
+ VMA of 0. */
+ int has_section_at_zero;
+@@ -505,15 +495,13 @@ struct dwarf2_cu
+
+ struct dwarf2_per_cu_data
+ {
+- /* The start offset and length of this compilation unit. 2**29-1
+- bytes should suffice to store the length of any compilation unit
+- - if it doesn't, GDB will fall over anyway.
++ /* The start offset and length of this compilation unit.
+ NOTE: Unlike comp_unit_head.length, this length includes
+ initial_length_size.
+ If the DIE refers to a DWO file, this is always of the original die,
+ not the DWO file. */
+ sect_offset offset;
+- unsigned int length : 29;
++ unsigned int length;
+
+ /* Flag indicating this compilation unit will be read in before
+ any of the current compilation units are processed. */
+@@ -528,6 +516,9 @@ struct dwarf2_per_cu_data
+ /* Non-zero if this CU is from .debug_types. */
+ unsigned int is_debug_types : 1;
+
++ /* Non-zero if this CU is from the .dwz file. */
++ unsigned int is_dwz : 1;
++
+ /* The section this CU/TU lives in.
+ If the DIE refers to a DWO file, this is always the original die,
+ not the DWO file. */
+@@ -715,6 +706,22 @@ struct dwo_file
+ htab_t tus;
+ };
+
++/* This represents a '.dwz' file. */
++
++struct dwz_file
++{
++ /* A dwz file can only contain a few sections. */
++ struct dwarf2_section_info abbrev;
++ struct dwarf2_section_info info;
++ struct dwarf2_section_info str;
++ struct dwarf2_section_info line;
++ struct dwarf2_section_info macro;
++ struct dwarf2_section_info gdb_index;
++
++ /* The dwz's BFD. */
++ bfd *dwz_bfd;
++};
++
+ /* Struct used to pass misc. parameters to read_die_and_children, et
+ al. which are used for both .debug_info and .debug_types dies.
+ All parameters here are unchanging for the life of the call. This
+@@ -828,6 +835,12 @@ struct partial_die_info
+ /* Flag set if fixup_partial_die has been called on this die. */
+ unsigned int fixup_called : 1;
+
++ /* Flag set if DW_TAG_imported_unit uses DW_FORM_GNU_ref_alt. */
++ unsigned int is_dwz : 1;
++
++ /* Flag set if spec_offset uses DW_FORM_GNU_ref_alt. */
++ unsigned int spec_is_dwz : 1;
++
+ /* The name of this DIE. Normally the value of DW_AT_name, but
+ sometimes a default name for unnamed DIEs. */
+ char *name;
+@@ -1213,7 +1226,7 @@ static gdb_byte *read_partial_die (const struct die_reader_specs *,
+ unsigned int,
+ gdb_byte *);
+
+-static struct partial_die_info *find_partial_die (sect_offset,
++static struct partial_die_info *find_partial_die (sect_offset, int,
+ struct dwarf2_cu *);
+
+ static void fixup_partial_die (struct partial_die_info *,
+@@ -1258,6 +1271,8 @@ static char *read_indirect_string (bfd *, gdb_byte *,
+ const struct comp_unit_head *,
+ unsigned int *);
+
++static char *read_indirect_string_from_dwz (struct dwz_file *, LONGEST);
++
+ static ULONGEST read_unsigned_leb128 (bfd *, gdb_byte *, unsigned int *);
+
+ static LONGEST read_signed_leb128 (bfd *, gdb_byte *, unsigned int *);
+@@ -1509,6 +1524,9 @@ static void fill_in_loclist_baton (struct dwarf2_cu *cu,
struct dwarf2_loclist_baton *baton,
struct attribute *attr);
static void dwarf2_symbol_mark_computed (struct attribute *attr,
struct symbol *sym,
struct dwarf2_cu *cu);
-@@ -1240,6 +1243,9 @@ static void age_cached_comp_units (void);
+@@ -1524,7 +1542,7 @@ static hashval_t partial_die_hash (const void *item);
+ static int partial_die_eq (const void *item_lhs, const void *item_rhs);
+
+ static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
+- (sect_offset offset, struct objfile *objfile);
++ (sect_offset offset, unsigned int offset_in_dwz, struct objfile *objfile);
- static void free_one_cached_comp_unit (void *);
+ static void init_one_comp_unit (struct dwarf2_cu *cu,
+ struct dwarf2_per_cu_data *per_cu);
+@@ -1541,6 +1559,9 @@ static void age_cached_comp_units (void);
+
+ static void free_one_cached_comp_unit (struct dwarf2_per_cu_data *);
+static void fetch_die_type_attrs (struct die_info *die, struct type *type,
+ struct dwarf2_cu *cu);
static struct type *set_die_type (struct die_info *, struct type *,
struct dwarf2_cu *);
-@@ -1263,6 +1269,9 @@ static struct type *get_die_type_at_offset (unsigned int,
+@@ -1569,6 +1590,9 @@ static struct type *get_die_type_at_offset (sect_offset,
static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
+
static void dwarf2_release_queue (void *dummy);
- static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu);
-@@ -8001,6 +8010,29 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
- new_symbol (die, this_type, cu);
+ static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
+@@ -1587,6 +1611,12 @@ static void find_file_and_directory (struct die_info *die,
+ static char *file_full_name (int file, struct line_header *lh,
+ const char *comp_dir);
+
++static gdb_byte *read_and_check_comp_unit_head
++ (struct comp_unit_head *header,
++ struct dwarf2_section_info *section,
++ struct dwarf2_section_info *abbrev_section, gdb_byte *info_ptr,
++ int is_debug_types_section);
++
+ static void init_cutu_and_read_dies
+ (struct dwarf2_per_cu_data *this_cu, struct abbrev_table *abbrev_table,
+ int use_existing_cu, int keep,
+@@ -1608,8 +1638,6 @@ static struct dwo_unit *lookup_dwo_type_unit
+
+ static void free_dwo_file_cleanup (void *);
+
+-static void munmap_section_buffer (struct dwarf2_section_info *);
+-
+ static void process_cu_includes (void);
+
+ #if WORDS_BIGENDIAN
+@@ -1779,85 +1807,6 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
+ dwarf2_per_objfile->has_section_at_zero = 1;
}
-+/* Create a new array dimension referencing its target type TYPE.
+-/* Decompress a section that was compressed using zlib. Store the
+- decompressed buffer, and its size, in OUTBUF and OUTSIZE. */
+-
+-static void
+-zlib_decompress_section (struct objfile *objfile, asection *sectp,
+- gdb_byte **outbuf, bfd_size_type *outsize)
+-{
+- bfd *abfd = sectp->owner;
+-#ifndef HAVE_ZLIB_H
+- error (_("Support for zlib-compressed DWARF data (from '%s') "
+- "is disabled in this copy of GDB"),
+- bfd_get_filename (abfd));
+-#else
+- bfd_size_type compressed_size = bfd_get_section_size (sectp);
+- gdb_byte *compressed_buffer = xmalloc (compressed_size);
+- struct cleanup *cleanup = make_cleanup (xfree, compressed_buffer);
+- bfd_size_type uncompressed_size;
+- gdb_byte *uncompressed_buffer;
+- z_stream strm;
+- int rc;
+- int header_size = 12;
+-
+- if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
+- || bfd_bread (compressed_buffer,
+- compressed_size, abfd) != compressed_size)
+- error (_("Dwarf Error: Can't read DWARF data from '%s'"),
+- bfd_get_filename (abfd));
+-
+- /* Read the zlib header. In this case, it should be "ZLIB" followed
+- by the uncompressed section size, 8 bytes in big-endian order. */
+- if (compressed_size < header_size
+- || strncmp (compressed_buffer, "ZLIB", 4) != 0)
+- error (_("Dwarf Error: Corrupt DWARF ZLIB header from '%s'"),
+- bfd_get_filename (abfd));
+- uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
+- uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
+- uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
+- uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
+- uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
+- uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
+- uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
+- uncompressed_size += compressed_buffer[11];
+-
+- /* It is possible the section consists of several compressed
+- buffers concatenated together, so we uncompress in a loop. */
+- strm.zalloc = NULL;
+- strm.zfree = NULL;
+- strm.opaque = NULL;
+- strm.avail_in = compressed_size - header_size;
+- strm.next_in = (Bytef*) compressed_buffer + header_size;
+- strm.avail_out = uncompressed_size;
+- uncompressed_buffer = obstack_alloc (&objfile->objfile_obstack,
+- uncompressed_size);
+- rc = inflateInit (&strm);
+- while (strm.avail_in > 0)
+- {
+- if (rc != Z_OK)
+- error (_("Dwarf Error: setting up DWARF uncompression in '%s': %d"),
+- bfd_get_filename (abfd), rc);
+- strm.next_out = ((Bytef*) uncompressed_buffer
+- + (uncompressed_size - strm.avail_out));
+- rc = inflate (&strm, Z_FINISH);
+- if (rc != Z_STREAM_END)
+- error (_("Dwarf Error: zlib error uncompressing from '%s': %d"),
+- bfd_get_filename (abfd), rc);
+- rc = inflateReset (&strm);
+- }
+- rc = inflateEnd (&strm);
+- if (rc != Z_OK
+- || strm.avail_out != 0)
+- error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"),
+- bfd_get_filename (abfd), rc);
+-
+- do_cleanups (cleanup);
+- *outbuf = uncompressed_buffer;
+- *outsize = uncompressed_size;
+-#endif
+-}
+-
+ /* A helper function that decides whether a section is empty,
+ or not present. */
+
+@@ -1884,56 +1833,27 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
+ if (info->readin)
+ return;
+ info->buffer = NULL;
+- info->map_addr = NULL;
+ info->readin = 1;
+
+ if (dwarf2_section_empty_p (info))
+ return;
+
+- /* Note that ABFD may not be from OBJFILE, e.g. a DWO section. */
+ abfd = sectp->owner;
+
+- /* Check if the file has a 4-byte header indicating compression. */
+- if (info->size > sizeof (header)
+- && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
+- && bfd_bread (header, sizeof (header), abfd) == sizeof (header))
+- {
+- /* Upon decompression, update the buffer and its size. */
+- if (strncmp (header, "ZLIB", sizeof (header)) == 0)
+- {
+- zlib_decompress_section (objfile, sectp, &info->buffer,
+- &info->size);
+- return;
+- }
+- }
+-
+-#ifdef HAVE_MMAP
+- if (pagesize == 0)
+- pagesize = getpagesize ();
+-
+- /* Only try to mmap sections which are large enough: we don't want to
+- waste space due to fragmentation. Also, only try mmap for sections
+- without relocations. */
+-
+- if (info->size > 4 * pagesize && (sectp->flags & SEC_RELOC) == 0)
++ /* If the section has relocations, we must read it ourselves.
++ Otherwise we attach it to the BFD. */
++ if ((sectp->flags & SEC_RELOC) == 0)
+ {
+- info->buffer = bfd_mmap (abfd, 0, info->size, PROT_READ,
+- MAP_PRIVATE, sectp->filepos,
+- &info->map_addr, &info->map_len);
++ const gdb_byte *bytes = gdb_bfd_map_section (sectp, &info->size);
+
+- if ((caddr_t)info->buffer != MAP_FAILED)
+- {
+-#if HAVE_POSIX_MADVISE
+- posix_madvise (info->map_addr, info->map_len, POSIX_MADV_WILLNEED);
+-#endif
+- return;
+- }
++ /* We have to cast away const here for historical reasons.
++ Fixing dwarf2read to be const-correct would be quite nice. */
++ info->buffer = (gdb_byte *) bytes;
++ return;
+ }
+-#endif
+
+- /* If we get here, we are a normal, not-compressed section. */
+- info->buffer = buf
+- = obstack_alloc (&objfile->objfile_obstack, info->size);
++ buf = obstack_alloc (&objfile->objfile_obstack, info->size);
++ info->buffer = buf;
+
+ /* When debugging .o files, we may need to apply relocations; see
+ http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
+@@ -2009,6 +1929,111 @@ dwarf2_get_section_info (struct objfile *objfile,
+ *sizep = info->size;
+ }
+
++/* A helper function to find the sections for a .dwz file. */
+
-+ Multidimensional arrays are internally represented as a stack of
-+ singledimensional arrays being referenced by their TYPE_TARGET_TYPE. */
++static void
++locate_dwz_sections (bfd *abfd, asection *sectp, void *arg)
++{
++ struct dwz_file *dwz_file = arg;
+
-+static struct type *
-+create_single_array_dimension (struct type *type, struct type *range_type,
-+ struct die_info *die, struct dwarf2_cu *cu)
++ /* Note that we only support the standard ELF names, because .dwz
++ is ELF-only (at the time of writing). */
++ if (section_is_p (sectp->name, &dwarf2_elf_names.abbrev))
++ {
++ dwz_file->abbrev.asection = sectp;
++ dwz_file->abbrev.size = bfd_get_section_size (sectp);
++ }
++ else if (section_is_p (sectp->name, &dwarf2_elf_names.info))
++ {
++ dwz_file->info.asection = sectp;
++ dwz_file->info.size = bfd_get_section_size (sectp);
++ }
++ else if (section_is_p (sectp->name, &dwarf2_elf_names.str))
++ {
++ dwz_file->str.asection = sectp;
++ dwz_file->str.size = bfd_get_section_size (sectp);
++ }
++ else if (section_is_p (sectp->name, &dwarf2_elf_names.line))
++ {
++ dwz_file->line.asection = sectp;
++ dwz_file->line.size = bfd_get_section_size (sectp);
++ }
++ else if (section_is_p (sectp->name, &dwarf2_elf_names.macro))
++ {
++ dwz_file->macro.asection = sectp;
++ dwz_file->macro.size = bfd_get_section_size (sectp);
++ }
++ else if (section_is_p (sectp->name, &dwarf2_elf_names.gdb_index))
++ {
++ dwz_file->gdb_index.asection = sectp;
++ dwz_file->gdb_index.size = bfd_get_section_size (sectp);
++ }
++}
++
++/* Open the separate '.dwz' debug file, if needed. Error if the file
++ cannot be found. */
++
++static struct dwz_file *
++dwarf2_get_dwz_file (void)
+{
-+ type = create_array_type (NULL, type, range_type);
++ bfd *abfd, *dwz_bfd;
++ asection *section;
++ gdb_byte *data;
++ struct cleanup *cleanup;
++ const char *filename;
++ struct dwz_file *result;
++
++ if (dwarf2_per_objfile->dwz_file != NULL)
++ return dwarf2_per_objfile->dwz_file;
++
++ abfd = dwarf2_per_objfile->objfile->obfd;
++ section = bfd_get_section_by_name (abfd, ".gnu_debugaltlink");
++ if (section == NULL)
++ error (_("could not find '.gnu_debugaltlink' section"));
++ if (!bfd_malloc_and_get_section (abfd, section, &data))
++ error (_("could not read '.gnu_debugaltlink' section: %s"),
++ bfd_errmsg (bfd_get_error ()));
++ cleanup = make_cleanup (xfree, data);
++
++ filename = data;
++ if (!IS_ABSOLUTE_PATH (filename))
++ {
++ char *abs = gdb_realpath (dwarf2_per_objfile->objfile->name);
++ char *rel;
+
-+ /* These generic type attributes need to be fetched by
-+ evaluate_subexp_standard <multi_f77_subscript>'s call of
-+ value_subscripted_rvalue only for the innermost array type. */
-+ fetch_die_type_attrs (die, type, cu);
++ make_cleanup (xfree, abs);
++ abs = ldirname (abs);
++ make_cleanup (xfree, abs);
+
-+ /* These generic type attributes are checked for allocated/associated
-+ validity while accessing FIELD_LOC_KIND_DWARF_BLOCK. */
-+ fetch_die_type_attrs (die, range_type, cu);
++ rel = concat (abs, SLASH_STRING, filename, (char *) NULL);
++ make_cleanup (xfree, rel);
++ filename = rel;
++ }
+
-+ return type;
-+}
++ /* The format is just a NUL-terminated file name, followed by the
++ build-id. For now, though, we ignore the build-id. */
++ dwz_bfd = gdb_bfd_open (filename, gnutarget, -1);
++ if (dwz_bfd == NULL)
++ error (_("could not read '%s': %s"), filename,
++ bfd_errmsg (bfd_get_error ()));
+
- /* 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. */
-@@ -8014,7 +8046,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
- struct type *element_type, *range_type, *index_type;
- struct type **range_types = NULL;
- struct attribute *attr;
-- int ndim = 0;
-+ int ndim = 0, i;
- struct cleanup *back_to;
- char *name;
++ if (!bfd_check_format (dwz_bfd, bfd_object))
++ {
++ gdb_bfd_unref (dwz_bfd);
++ error (_("file '%s' was not usable: %s"), filename,
++ bfd_errmsg (bfd_get_error ()));
++ }
++
++ result = OBSTACK_ZALLOC (&dwarf2_per_objfile->objfile->objfile_obstack,
++ struct dwz_file);
++ result->dwz_bfd = dwz_bfd;
++
++ bfd_map_over_sections (dwz_bfd, locate_dwz_sections, result);
++
++ do_cleanups (cleanup);
++
++ return result;
++}
+ \f
+ /* DWARF quick_symbols_functions support. */
-@@ -8067,17 +8099,19 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
- type = element_type;
+@@ -2279,23 +2304,19 @@ extract_cu_value (const char *bytes, ULONGEST *result)
+ return 1;
+ }
- if (read_array_order (die, cu) == DW_ORD_col_major)
-- {
-- int i = 0;
+-/* Read the CU list from the mapped index, and use it to create all
+- the CU objects for this objfile. Return 0 if something went wrong,
+- 1 if everything went ok. */
++/* A helper for create_cus_from_index that handles a given list of
++ CUs. */
+
+ static int
+-create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list,
+- offset_type cu_list_elements)
++create_cus_from_index_list (struct objfile *objfile,
++ const gdb_byte *cu_list, offset_type n_elements,
++ struct dwarf2_section_info *section,
++ int is_dwz,
++ int base_offset)
+ {
+ offset_type i;
+
+- dwarf2_per_objfile->n_comp_units = cu_list_elements / 2;
+- dwarf2_per_objfile->all_comp_units
+- = obstack_alloc (&objfile->objfile_obstack,
+- dwarf2_per_objfile->n_comp_units
+- * sizeof (struct dwarf2_per_cu_data *));
-
-- while (i < ndim)
-- type = create_array_type (NULL, type, range_types[i++]);
-- }
-- else
-- {
-- while (ndim-- > 0)
-- type = create_array_type (NULL, type, range_types[ndim]);
-- }
-+ for (i = 0; i < ndim; i++)
-+ type = create_single_array_dimension (type, range_types[i], die, cu);
-+ else /* (read_array_order (die, cu) == DW_ORD_row_major) */
-+ for (i = ndim - 1; i >= 0; i--)
-+ type = create_single_array_dimension (type, range_types[i], die, cu);
+- for (i = 0; i < cu_list_elements; i += 2)
++ for (i = 0; i < n_elements; i += 2)
+ {
+ struct dwarf2_per_cu_data *the_cu;
+ ULONGEST offset, length;
+@@ -2310,15 +2331,45 @@ create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list,
+ the_cu->offset.sect_off = offset;
+ the_cu->length = length;
+ the_cu->objfile = objfile;
+- the_cu->info_or_types_section = &dwarf2_per_objfile->info;
++ the_cu->info_or_types_section = section;
+ the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwarf2_per_cu_quick_data);
+- dwarf2_per_objfile->all_comp_units[i / 2] = the_cu;
++ the_cu->is_dwz = is_dwz;
++ dwarf2_per_objfile->all_comp_units[base_offset + i / 2] = the_cu;
+ }
+
+ return 1;
+ }
+
++/* Read the CU list from the mapped index, and use it to create all
++ the CU objects for this objfile. Return 0 if something went wrong,
++ 1 if everything went ok. */
++
++static int
++create_cus_from_index (struct objfile *objfile,
++ const gdb_byte *cu_list, offset_type cu_list_elements,
++ const gdb_byte *dwz_list, offset_type dwz_elements)
++{
++ struct dwz_file *dwz;
++
++ dwarf2_per_objfile->n_comp_units = (cu_list_elements + dwz_elements) / 2;
++ dwarf2_per_objfile->all_comp_units
++ = obstack_alloc (&objfile->objfile_obstack,
++ dwarf2_per_objfile->n_comp_units
++ * sizeof (struct dwarf2_per_cu_data *));
++
++ if (!create_cus_from_index_list (objfile, cu_list, cu_list_elements,
++ &dwarf2_per_objfile->info, 0, 0))
++ return 0;
++
++ if (dwz_elements == 0)
++ return 1;
++
++ dwz = dwarf2_get_dwz_file ();
++ return create_cus_from_index_list (objfile, dwz_list, dwz_elements,
++ &dwz->info, 1, cu_list_elements / 2);
++}
++
+ /* Create the signatured type hash table from the index. */
+
+ static int
+@@ -2508,33 +2559,44 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
+ }
+ }
+
+-/* Read the index file. If everything went ok, initialize the "quick"
+- elements of all the CUs and return 1. Otherwise, return 0. */
++/* A helper function that reads the .gdb_index from SECTION and fills
++ in MAP. FILENAME is the name of the file containing the section;
++ it is used for error reporting. DEPRECATED_OK is nonzero if it is
++ ok to use deprecated sections.
++
++ CU_LIST, CU_LIST_ELEMENTS, TYPES_LIST, and TYPES_LIST_ELEMENTS are
++ out parameters that are filled in with information about the CU and
++ TU lists in the section.
++
++ Returns 1 if all went well, 0 otherwise. */
+
+ static int
+-dwarf2_read_index (struct objfile *objfile)
++read_index_from_section (struct objfile *objfile,
++ const char *filename,
++ int deprecated_ok,
++ struct dwarf2_section_info *section,
++ struct mapped_index *map,
++ const gdb_byte **cu_list,
++ offset_type *cu_list_elements,
++ const gdb_byte **types_list,
++ offset_type *types_list_elements)
+ {
+ char *addr;
+- struct mapped_index *map;
++ offset_type version;
+ offset_type *metadata;
+- const gdb_byte *cu_list;
+- const gdb_byte *types_list = NULL;
+- offset_type version, cu_list_elements;
+- offset_type types_list_elements = 0;
+ int i;
+
+- if (dwarf2_section_empty_p (&dwarf2_per_objfile->gdb_index))
++ if (dwarf2_section_empty_p (section))
+ return 0;
+
+ /* Older elfutils strip versions could keep the section in the main
+ executable while splitting it for the separate debug info file. */
+- if ((bfd_get_file_flags (dwarf2_per_objfile->gdb_index.asection)
+- & SEC_HAS_CONTENTS) == 0)
++ if ((bfd_get_file_flags (section->asection) & SEC_HAS_CONTENTS) == 0)
+ return 0;
+
+- dwarf2_read_section (objfile, &dwarf2_per_objfile->gdb_index);
++ dwarf2_read_section (objfile, section);
+
+- addr = dwarf2_per_objfile->gdb_index.buffer;
++ addr = section->buffer;
+ /* Version check. */
+ version = MAYBE_SWAP (*(offset_type *) addr);
+ /* Versions earlier than 3 emitted every copy of a psymbol. This
+@@ -2547,7 +2609,7 @@ dwarf2_read_index (struct objfile *objfile)
+ if (!warning_printed)
+ {
+ warning (_("Skipping obsolete .gdb_index section in %s."),
+- objfile->name);
++ filename);
+ warning_printed = 1;
+ }
+ return 0;
+@@ -2560,7 +2622,7 @@ dwarf2_read_index (struct objfile *objfile)
+ set breakpoints on inlined functions by name, so we ignore these
+ indices unless the user has done
+ "set use-deprecated-index-sections on". */
+- if (version < 6 && !use_deprecated_index_sections)
++ if (version < 6 && !deprecated_ok)
+ {
+ static int warning_printed = 0;
+ if (!warning_printed)
+@@ -2569,7 +2631,7 @@ dwarf2_read_index (struct objfile *objfile)
+ Skipping deprecated .gdb_index section in %s.\n\
+ Do \"set use-deprecated-index-sections on\" before the file is read\n\
+ to use the section anyway."),
+- objfile->name);
++ filename);
+ warning_printed = 1;
+ }
+ return 0;
+@@ -2579,22 +2641,21 @@ to use the section anyway."),
+ if (version > 7)
+ return 0;
+
+- map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
+ map->version = version;
+- map->total_size = dwarf2_per_objfile->gdb_index.size;
++ map->total_size = section->size;
+
+ metadata = (offset_type *) (addr + sizeof (offset_type));
+
+ i = 0;
+- cu_list = addr + MAYBE_SWAP (metadata[i]);
+- cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i]))
+- / 8);
++ *cu_list = addr + MAYBE_SWAP (metadata[i]);
++ *cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i]))
++ / 8);
+ ++i;
+
+- types_list = addr + MAYBE_SWAP (metadata[i]);
+- types_list_elements = ((MAYBE_SWAP (metadata[i + 1])
+- - MAYBE_SWAP (metadata[i]))
+- / 8);
++ *types_list = addr + MAYBE_SWAP (metadata[i]);
++ *types_list_elements = ((MAYBE_SWAP (metadata[i + 1])
++ - MAYBE_SWAP (metadata[i]))
++ / 8);
+ ++i;
+
+ map->address_table = addr + MAYBE_SWAP (metadata[i]);
+@@ -2610,11 +2671,55 @@ to use the section anyway."),
+
+ map->constant_pool = addr + MAYBE_SWAP (metadata[i]);
+
++ return 1;
++}
++
++
++/* Read the index file. If everything went ok, initialize the "quick"
++ elements of all the CUs and return 1. Otherwise, return 0. */
++
++static int
++dwarf2_read_index (struct objfile *objfile)
++{
++ struct mapped_index local_map, *map;
++ const gdb_byte *cu_list, *types_list, *dwz_list = NULL;
++ offset_type cu_list_elements, types_list_elements, dwz_list_elements = 0;
++
++ if (!read_index_from_section (objfile, objfile->name,
++ use_deprecated_index_sections,
++ &dwarf2_per_objfile->gdb_index, &local_map,
++ &cu_list, &cu_list_elements,
++ &types_list, &types_list_elements))
++ return 0;
++
+ /* Don't use the index if it's empty. */
+- if (map->symbol_table_slots == 0)
++ if (local_map.symbol_table_slots == 0)
+ return 0;
+
+- if (!create_cus_from_index (objfile, cu_list, cu_list_elements))
++ /* If there is a .dwz file, read it so we can get its CU list as
++ well. */
++ if (bfd_get_section_by_name (objfile->obfd, ".gnu_debugaltlink") != NULL)
++ {
++ struct dwz_file *dwz = dwarf2_get_dwz_file ();
++ struct mapped_index dwz_map;
++ const gdb_byte *dwz_types_ignore;
++ offset_type dwz_types_elements_ignore;
++
++ if (!read_index_from_section (objfile, bfd_get_filename (dwz->dwz_bfd),
++ 1,
++ &dwz->gdb_index, &dwz_map,
++ &dwz_list, &dwz_list_elements,
++ &dwz_types_ignore,
++ &dwz_types_elements_ignore))
++ {
++ warning (_("could not read '.gdb_index' section from %s; skipping"),
++ bfd_get_filename (dwz->dwz_bfd));
++ return 0;
++ }
++ }
++
++ if (!create_cus_from_index (objfile, cu_list, cu_list_elements,
++ dwz_list, dwz_list_elements))
+ return 0;
+
+ if (types_list_elements)
+@@ -2635,7 +2740,10 @@ to use the section anyway."),
+ return 0;
+ }
+
+- create_addrmap_from_index (objfile, map);
++ create_addrmap_from_index (objfile, &local_map);
++
++ map = obstack_alloc (&objfile->objfile_obstack, sizeof (struct mapped_index));
++ *map = local_map;
+
+ dwarf2_per_objfile->index_table = map;
+ dwarf2_per_objfile->using_index = 1;
+@@ -3686,6 +3794,22 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
+ return info_ptr;
+ }
+
++/* Helper function that returns the proper abbrev section for
++ THIS_CU. */
++
++static struct dwarf2_section_info *
++get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu)
++{
++ struct dwarf2_section_info *abbrev;
++
++ if (this_cu->is_dwz)
++ abbrev = &dwarf2_get_dwz_file ()->abbrev;
++ else
++ abbrev = &dwarf2_per_objfile->abbrev;
++
++ return abbrev;
++}
++
+ /* Subroutine of read_and_check_comp_unit_head and
+ read_and_check_type_unit_head to simplify them.
+ Perform various error checking on the header. */
+@@ -3704,8 +3828,7 @@ error_check_comp_unit_head (struct comp_unit_head *header,
+ filename);
+
+ if (header->abbrev_offset.sect_off
+- >= dwarf2_section_size (dwarf2_per_objfile->objfile,
+- &dwarf2_per_objfile->abbrev))
++ >= dwarf2_section_size (dwarf2_per_objfile->objfile, abbrev_section))
+ error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
+ "(offset 0x%lx + 6) [in module %s]"),
+ (long) header->abbrev_offset.sect_off, (long) header->offset.sect_off,
+@@ -3942,6 +4065,7 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
+ {
+ bfd *abfd;
+ gdb_byte *info_ptr, *end_ptr;
++ struct dwarf2_section_info *abbrev_section;
+
+ dwarf2_read_section (objfile, section);
+ info_ptr = section->buffer;
+@@ -3953,6 +4077,11 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
+ not present, in which case section->asection will be NULL. */
+ abfd = section->asection->owner;
+
++ if (dwo_file)
++ abbrev_section = &dwo_file->sections.abbrev;
++ else
++ abbrev_section = &dwarf2_per_objfile->abbrev;
++
+ if (types_htab == NULL)
+ {
+ if (dwo_file)
+@@ -4192,7 +4321,8 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
+ dwarf2_read_section (objfile, section);
+
+ begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off;
+- abbrev_section = &dwarf2_per_objfile->abbrev;
++
++ abbrev_section = get_abbrev_section_for_cu (this_cu);
+
+ if (use_existing_cu && this_cu->cu != NULL)
+ {
+@@ -4574,7 +4704,7 @@ init_cutu_and_read_dies_simple (struct dwarf2_per_cu_data *this_cu,
+ void *data)
+ {
+ init_cutu_and_read_dies_no_follow (this_cu,
+- &dwarf2_per_objfile->abbrev,
++ get_abbrev_section_for_cu (this_cu),
+ NULL,
+ die_reader_func, data);
+ }
+@@ -5202,6 +5332,9 @@ set_partial_user (struct objfile *objfile)
+ struct partial_symtab *pst = per_cu->v.psymtab;
+ int j;
+
++ if (pst == NULL)
++ continue;
++
+ for (j = 0; j < pst->number_of_dependencies; ++j)
+ {
+ /* Set the 'user' field only if it is not already set. */
+@@ -5296,38 +5429,32 @@ load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu)
+ load_partial_comp_unit_reader, NULL);
+ }
+
+-/* Create a list of all compilation units in OBJFILE.
+- This is only done for -readnow and building partial symtabs. */
+-
+ static void
+-create_all_comp_units (struct objfile *objfile)
++read_comp_units_from_section (struct objfile *objfile,
++ struct dwarf2_section_info *section,
++ unsigned int is_dwz,
++ int *n_allocated,
++ int *n_comp_units,
++ struct dwarf2_per_cu_data ***all_comp_units)
+ {
+- int n_allocated;
+- int n_comp_units;
+- struct dwarf2_per_cu_data **all_comp_units;
+ gdb_byte *info_ptr;
++ bfd *abfd = section->asection->owner;
+
+- dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
+- info_ptr = dwarf2_per_objfile->info.buffer;
++ dwarf2_read_section (objfile, section);
+
+- n_comp_units = 0;
+- n_allocated = 10;
+- all_comp_units = xmalloc (n_allocated
+- * sizeof (struct dwarf2_per_cu_data *));
++ info_ptr = section->buffer;
+
+- while (info_ptr < dwarf2_per_objfile->info.buffer
+- + dwarf2_per_objfile->info.size)
++ while (info_ptr < section->buffer + section->size)
+ {
+ unsigned int length, initial_length_size;
+ struct dwarf2_per_cu_data *this_cu;
+ sect_offset offset;
+
+- offset.sect_off = info_ptr - dwarf2_per_objfile->info.buffer;
++ offset.sect_off = info_ptr - section->buffer;
+
+ /* Read just enough information to find out where the next
+ compilation unit is. */
+- length = read_initial_length (objfile->obfd, info_ptr,
+- &initial_length_size);
++ length = read_initial_length (abfd, info_ptr, &initial_length_size);
+
+ /* Save the compilation unit for later lookup. */
+ this_cu = obstack_alloc (&objfile->objfile_obstack,
+@@ -5335,20 +5462,50 @@ create_all_comp_units (struct objfile *objfile)
+ memset (this_cu, 0, sizeof (*this_cu));
+ this_cu->offset = offset;
+ this_cu->length = length + initial_length_size;
++ this_cu->is_dwz = is_dwz;
+ this_cu->objfile = objfile;
+- this_cu->info_or_types_section = &dwarf2_per_objfile->info;
++ this_cu->info_or_types_section = section;
+
+- if (n_comp_units == n_allocated)
++ if (*n_comp_units == *n_allocated)
+ {
+- n_allocated *= 2;
+- all_comp_units = xrealloc (all_comp_units,
+- n_allocated
+- * sizeof (struct dwarf2_per_cu_data *));
++ *n_allocated *= 2;
++ *all_comp_units = xrealloc (*all_comp_units,
++ *n_allocated
++ * sizeof (struct dwarf2_per_cu_data *));
+ }
+- all_comp_units[n_comp_units++] = this_cu;
++ (*all_comp_units)[*n_comp_units] = this_cu;
++ ++*n_comp_units;
+
+ info_ptr = info_ptr + this_cu->length;
+ }
++}
++
++/* Create a list of all compilation units in OBJFILE.
++ This is only done for -readnow and building partial symtabs. */
++
++static void
++create_all_comp_units (struct objfile *objfile)
++{
++ int n_allocated;
++ int n_comp_units;
++ struct dwarf2_per_cu_data **all_comp_units;
++
++ n_comp_units = 0;
++ n_allocated = 10;
++ all_comp_units = xmalloc (n_allocated
++ * sizeof (struct dwarf2_per_cu_data *));
++
++ read_comp_units_from_section (objfile, &dwarf2_per_objfile->info, 0,
++ &n_allocated, &n_comp_units, &all_comp_units);
++
++ if (bfd_get_section_by_name (objfile->obfd, ".gnu_debugaltlink") != NULL)
++ {
++ struct dwz_file *dwz = dwarf2_get_dwz_file ();
++
++ read_comp_units_from_section (objfile, &dwz->info, 1,
++ &n_allocated, &n_comp_units,
++ &all_comp_units);
++ }
+
+ dwarf2_per_objfile->all_comp_units
+ = obstack_alloc (&objfile->objfile_obstack,
+@@ -5441,6 +5598,7 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
+ }
+
+ per_cu = dwarf2_find_containing_comp_unit (pdi->d.offset,
++ pdi->is_dwz,
+ cu->objfile);
+
+ /* Go read the partial unit, if needed. */
+@@ -5498,7 +5656,8 @@ partial_die_parent_scope (struct partial_die_info *pdi,
+
+ real_pdi = pdi;
+ while (real_pdi->has_specification)
+- real_pdi = find_partial_die (real_pdi->spec_offset, cu);
++ real_pdi = find_partial_die (real_pdi->spec_offset,
++ real_pdi->spec_is_dwz, cu);
+
+ parent = real_pdi->die_parent;
+ if (parent == NULL)
+@@ -5998,6 +6157,9 @@ skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr,
+ else
+ info_ptr += cu->header.offset_size;
+ break;
++ case DW_FORM_GNU_ref_alt:
++ info_ptr += cu->header.offset_size;
++ break;
+ case DW_FORM_addr:
+ info_ptr += cu->header.addr_size;
+ break;
+@@ -6027,6 +6189,7 @@ skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr,
+ break;
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp:
++ case DW_FORM_GNU_strp_alt:
+ info_ptr += cu->header.offset_size;
+ break;
+ case DW_FORM_exprloc:
+@@ -6694,7 +6857,9 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
+ it, by scanning the DIE's below the compilation unit. */
+ get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu);
+
+- static_block = end_symtab_get_static_block (highpc + baseaddr, objfile, 0);
++ static_block
++ = end_symtab_get_static_block (highpc + baseaddr, objfile, 0,
++ per_cu->s.imported_symtabs != NULL);
+
+ /* If the comp unit has DW_AT_ranges, it may have discontiguous ranges.
+ Also, DW_AT_ranges may record ranges not belonging to any child DIEs
+@@ -6845,9 +7010,11 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
+ struct dwarf2_per_cu_data *per_cu;
+ struct symtab *imported_symtab;
+ sect_offset offset;
++ int is_dwz;
+
+ offset = dwarf2_get_ref_die_offset (attr);
+- per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
++ is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
++ per_cu = dwarf2_find_containing_comp_unit (offset, is_dwz, cu->objfile);
+
+ /* Queue the unit, if needed. */
+ if (maybe_queue_comp_unit (cu, per_cu, cu->language))
+@@ -8116,24 +8283,21 @@ try_open_dwo_file (const char *file_name)
+ if (desc < 0)
+ return NULL;
+
+- sym_bfd = bfd_fopen (absolute_name, gnutarget, FOPEN_RB, desc);
++ sym_bfd = gdb_bfd_open (absolute_name, gnutarget, desc);
+ if (!sym_bfd)
+ {
+ xfree (absolute_name);
+ return NULL;
+ }
++ xfree (absolute_name);
+ bfd_set_cacheable (sym_bfd, 1);
+
+ if (!bfd_check_format (sym_bfd, bfd_object))
+ {
+- bfd_close (sym_bfd); /* This also closes desc. */
+- xfree (absolute_name);
++ gdb_bfd_unref (sym_bfd); /* This also closes desc. */
+ return NULL;
+ }
+
+- /* bfd_usrdata exists for applications and libbfd must not touch it. */
+- gdb_assert (bfd_usrdata (sym_bfd) == NULL);
+-
+ return sym_bfd;
+ }
+
+@@ -8325,20 +8489,7 @@ free_dwo_file (struct dwo_file *dwo_file, struct objfile *objfile)
+ struct dwarf2_section_info *section;
+
+ gdb_assert (dwo_file->dwo_bfd != objfile->obfd);
+- bfd_close (dwo_file->dwo_bfd);
+-
+- munmap_section_buffer (&dwo_file->sections.abbrev);
+- munmap_section_buffer (&dwo_file->sections.info);
+- munmap_section_buffer (&dwo_file->sections.line);
+- munmap_section_buffer (&dwo_file->sections.loc);
+- munmap_section_buffer (&dwo_file->sections.str);
+- munmap_section_buffer (&dwo_file->sections.str_offsets);
+-
+- for (ix = 0;
+- VEC_iterate (dwarf2_section_info_def, dwo_file->sections.types,
+- ix, section);
+- ++ix)
+- munmap_section_buffer (section);
++ gdb_bfd_unref (dwo_file->dwo_bfd);
+
+ VEC_free (dwarf2_section_info_def, dwo_file->sections.types);
+ }
+@@ -10721,6 +10872,29 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
+ new_symbol (die, this_type, cu);
+ }
+
++/* Create a new array dimension referencing its target type TYPE.
++
++ Multidimensional arrays are internally represented as a stack of
++ singledimensional arrays being referenced by their TYPE_TARGET_TYPE. */
++
++static struct type *
++create_single_array_dimension (struct type *type, struct type *range_type,
++ struct die_info *die, struct dwarf2_cu *cu)
++{
++ type = create_array_type (NULL, type, range_type);
++
++ /* These generic type attributes need to be fetched by
++ evaluate_subexp_standard <multi_f77_subscript>'s call of
++ value_subscripted_rvalue only for the innermost array type. */
++ fetch_die_type_attrs (die, type, cu);
++
++ /* These generic type attributes are checked for allocated/associated
++ validity while accessing FIELD_LOC_KIND_DWARF_BLOCK. */
++ fetch_die_type_attrs (die, range_type, cu);
++
++ return type;
++}
++
+ /* 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. */
+@@ -10734,7 +10908,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
+ struct type *element_type, *range_type, *index_type;
+ struct type **range_types = NULL;
+ struct attribute *attr;
+- int ndim = 0;
++ int ndim = 0, i;
+ struct cleanup *back_to;
+ char *name;
+
+@@ -10787,17 +10961,19 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
+ type = element_type;
+
+ 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++]);
+- }
+- else
+- {
+- while (ndim-- > 0)
+- type = create_array_type (NULL, type, range_types[ndim]);
+- }
++ for (i = 0; i < ndim; i++)
++ type = create_single_array_dimension (type, range_types[i], die, cu);
++ else /* (read_array_order (die, cu) == DW_ORD_row_major) */
++ for (i = ndim - 1; i >= 0; i--)
++ type = create_single_array_dimension (type, range_types[i], die, cu);
+
+ /* Data locations should be set only for the outermost dimension as they
+ would be confusing for the dereferenced offset on the inner ones. */
/* Understand Dwarf2 support for vector types (like they occur on
the PowerPC w/ AltiVec). Gcc just adds another attribute to the
-@@ -8561,29 +8595,114 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
+@@ -11281,29 +11457,114 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct type *type, *range_type, *index_type, *char_type;
struct attribute *attr;
+ ULONGEST ulongest;
+ const gdb_byte *end;
+
-+ end = read_uleb128 (&blk->data[1], &blk->data[blk->size],
-+ &ulongest);
++ end = safe_read_uleb128 (&blk->data[1], &blk->data[blk->size],
++ &ulongest);
+ if (end == &blk->data[blk->size])
+ length_baton = dwarf2_attr_to_locexpr_baton (attr, cu);
+ }
char_type = language_string_char_type (cu->language_defn, gdbarch);
type = create_string_type (NULL, char_type, range_type);
-@@ -8887,8 +9006,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
+@@ -11607,7 +11868,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
struct type *base_type;
struct type *range_type;
struct attribute *attr;
-- LONGEST low = 0;
-- LONGEST high = -1;
+- LONGEST low, high;
+ LONGEST low;
+ int low_default_is_valid;
char *name;
LONGEST negative_mask;
+@@ -11663,42 +11924,6 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
+ "- DIE at 0x%x [in module %s]"),
+ die->offset.sect_off, cu->objfile->name);
-@@ -8901,53 +9019,126 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
- if (range_type)
- return range_type;
-
-- if (cu->language == language_fortran)
+- attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
+- if (attr)
+- {
+- if (attr_form_is_block (attr) || is_ref_attr (attr))
+- {
+- /* GCC encodes arrays with unspecified or dynamic length
+- with a DW_FORM_block1 attribute or a reference 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);
+- }
+- else
- {
-- /* FORTRAN implies a lower bound of 1, if not given. */
-- low = 1;
+- attr = dwarf2_attr (die, DW_AT_count, cu);
+- if (attr)
+- {
+- int count = dwarf2_get_attr_constant_value (attr, 1);
+- high = low + count - 1;
+- }
+- else
+- {
+- /* Unspecified array length. */
+- high = low - 1;
+- }
- }
+-
+ /* Dwarf-2 specifications explicitly allows to create subrange types
+ without specifying a base type.
+ In that case, the base type must be set to the type of
+@@ -11737,24 +11962,163 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
+ }
+ }
+
+- negative_mask =
+ /* LOW_BOUND and HIGH_BOUND are set for real below. */
+ range_type = create_range_type (NULL, base_type, 0, -1);
+ TYPE_UNSIGNED (range_type) = 0;
+
+ negative_mask =
-+ (LONGEST) -1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1);
-+
+ (LONGEST) -1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1);
+- if (!TYPE_UNSIGNED (base_type) && (low & negative_mask))
+- low |= negative_mask;
+- if (!TYPE_UNSIGNED (base_type) && (high & negative_mask))
+- high |= negative_mask;
+
+- range_type = create_range_type (NULL, base_type, low, high);
+ /* Exclude language_ada from any TYPE_DYNAMIC constructs below. GDB Ada
+ supports implements the dynamic bounds in a non-DWARF way and the
+ existing DWARF dynamic bounds are invalid, leading to memory access
+ errors. */
-- /* 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);
+- /* Mark arrays with dynamic length at least as an array of unspecified
+- length. GDB could check the boundary but before it gets implemented at
+- least allow accessing the array elements. */
+- if (attr && attr_form_is_block (attr))
+- TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
++ attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
+ if (attr && attr_form_is_block (attr) && cu->language != language_ada)
+ {
+ TYPE_RANGE_DATA (range_type)->low.kind = RANGE_BOUND_KIND_DWARF_BLOCK;
+ struct dwarf2_cu *target_cu = cu;
+ struct attribute *target_loc_attr;
-- attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
-- if (attr)
+- /* Ada expects an empty array on no boundary attributes. */
+- if (attr == NULL && cu->language != language_ada)
+- TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
+ target_die = follow_die_ref_or_sig (die, attr, &target_cu);
+ gdb_assert (target_cu->objfile == cu->objfile);
+ target_loc_attr = dwarf2_attr (target_die, DW_AT_location, target_cu);
+ low = 0;
+ }
+ else
- {
-- if (attr_form_is_block (attr) || is_ref_attr (attr))
-- {
-- /* GCC encodes arrays with unspecified or dynamic length
-- with a DW_FORM_block1 attribute or a reference 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;
-- }
++ {
+ if (attr && attr_form_is_constant (attr))
+ low = dwarf2_get_attr_constant_value (attr, 0);
- else
-- high = dwarf2_get_attr_constant_value (attr, 1);
++ else
+ {
+ if (cu->language == language_fortran)
+ {
+ TYPE_LOW_BOUND (range_type) = low;
+ if (low >= 0)
+ TYPE_UNSIGNED (range_type) = 1;
- }
-- else
++ }
+
+ attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
+ if (!attr || (!attr_form_is_block (attr) && !attr_form_is_constant (attr)
+ && !is_ref_attr (attr)))
- {
- attr = dwarf2_attr (die, DW_AT_count, cu);
-- if (attr)
-- {
-- int count = dwarf2_get_attr_constant_value (attr, 1);
-- high = low + count - 1;
++ {
++ attr = dwarf2_attr (die, DW_AT_count, cu);
+ /* It does not hurt but it is needlessly ineffective in check_typedef. */
+ if (attr && (attr_form_is_block (attr) || attr_form_is_constant (attr)))
+ {
+ TYPE_RANGE_HIGH_BOUND_IS_COUNT (range_type) = 1;
+ TYPE_DYNAMIC (range_type) = 1;
- }
++ }
+ /* Pass it now as the regular DW_AT_upper_bound. */
+ }
+
+
+ if (attr && attr_form_is_constant (attr))
+ high = dwarf2_get_attr_constant_value (attr, 0);
- else
- {
-- /* Unspecified array length. */
++ else
++ {
+ /* Ada expects an empty array on no boundary attributes. */
+ if (cu->language != language_ada)
+ TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
- high = low - 1;
- }
++ high = low - 1;
++ }
+ if (!TYPE_UNSIGNED (base_type) && (high & negative_mask))
+ high |= negative_mask;
+ TYPE_HIGH_BOUND (range_type) = high;
- }
-
- /* Dwarf-2 specifications explicitly allows to create subrange types
-@@ -8988,24 +9179,41 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
- }
- }
-
-- negative_mask =
-- (LONGEST) -1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1);
-- if (!TYPE_UNSIGNED (base_type) && (low & negative_mask))
-- low |= negative_mask;
-- if (!TYPE_UNSIGNED (base_type) && (high & negative_mask))
-- high |= negative_mask;
--
-- range_type = create_range_type (NULL, base_type, low, high);
++ }
++
+ /* DW_AT_bit_stride is currently unsupported as we count in bytes. */
+ attr = dwarf2_attr (die, DW_AT_byte_stride, cu);
+ if (attr && attr_form_is_block (attr) && cu->language != language_ada)
+ struct die_info *target_die;
+ struct dwarf2_cu *target_cu = cu;
+ struct attribute *target_loc_attr;
-
-- /* Mark arrays with dynamic length at least as an array of unspecified
-- length. GDB could check the boundary but before it gets implemented at
-- least allow accessing the array elements. */
-- if (attr && attr_form_is_block (attr))
-- TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
++
+ target_die = follow_die_ref_or_sig (die, attr, &target_cu);
+ gdb_assert (target_cu->objfile == cu->objfile);
+ target_loc_attr = dwarf2_attr (target_die, DW_AT_location, target_cu);
-
-- /* Ada expects an empty array on no boundary attributes. */
-- if (attr == NULL && cu->language != language_ada)
-- TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
++
+ TYPE_RANGE_DATA (range_type)->byte_stride.kind
+ = RANGE_BOUND_KIND_DWARF_LOCLIST;
+ TYPE_RANGE_DATA (range_type)->byte_stride.u.dwarf_loclist.loclist
name = dwarf2_name (die, cu);
if (name)
-@@ -11545,10 +11753,12 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
+@@ -12544,6 +12908,8 @@ read_partial_die (const struct die_reader_specs *reader,
+ case DW_AT_extension:
+ part_die->has_specification = 1;
+ part_die->spec_offset = dwarf2_get_ref_die_offset (&attr);
++ part_die->spec_is_dwz = (attr.form == DW_FORM_GNU_ref_alt
++ || cu->per_cu->is_dwz);
+ break;
+ case DW_AT_sibling:
+ /* Ignore absolute siblings, they might point outside of
+@@ -12590,7 +12956,11 @@ read_partial_die (const struct die_reader_specs *reader,
+
+ case DW_AT_import:
+ if (part_die->tag == DW_TAG_imported_unit)
+- part_die->d.offset = dwarf2_get_ref_die_offset (&attr);
++ {
++ part_die->d.offset = dwarf2_get_ref_die_offset (&attr);
++ part_die->is_dwz = (attr.form == DW_FORM_GNU_ref_alt
++ || cu->per_cu->is_dwz);
++ }
+ break;
+
+ default:
+@@ -12661,13 +13031,14 @@ find_partial_die_in_comp_unit (sect_offset offset, struct dwarf2_cu *cu)
+ DW_FORM_ref_sig8). */
+
+ static struct partial_die_info *
+-find_partial_die (sect_offset offset, struct dwarf2_cu *cu)
++find_partial_die (sect_offset offset, int offset_in_dwz, struct dwarf2_cu *cu)
+ {
+ struct objfile *objfile = cu->objfile;
+ struct dwarf2_per_cu_data *per_cu = NULL;
+ struct partial_die_info *pd = NULL;
+
+- if (offset_in_cu_p (&cu->header, offset))
++ if (offset_in_dwz == cu->per_cu->is_dwz
++ && offset_in_cu_p (&cu->header, offset))
+ {
+ pd = find_partial_die_in_comp_unit (offset, cu);
+ if (pd != NULL)
+@@ -12686,7 +13057,8 @@ find_partial_die (sect_offset offset, struct dwarf2_cu *cu)
+ (long) cu->header.offset.sect_off, (long) offset.sect_off,
+ bfd_get_filename (objfile->obfd));
+ }
+- per_cu = dwarf2_find_containing_comp_unit (offset, objfile);
++ per_cu = dwarf2_find_containing_comp_unit (offset, offset_in_dwz,
++ objfile);
+
+ if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
+ load_partial_comp_unit (per_cu);
+@@ -12744,7 +13116,8 @@ guess_partial_die_structure_name (struct partial_die_info *struct_pdi,
+
+ real_pdi = struct_pdi;
+ while (real_pdi->has_specification)
+- real_pdi = find_partial_die (real_pdi->spec_offset, cu);
++ real_pdi = find_partial_die (real_pdi->spec_offset,
++ real_pdi->spec_is_dwz, cu);
+
+ if (real_pdi->die_parent != NULL)
+ return;
+@@ -12792,7 +13165,8 @@ fixup_partial_die (struct partial_die_info *part_die,
+ {
+ struct partial_die_info *spec_die;
+
+- spec_die = find_partial_die (part_die->spec_offset, cu);
++ spec_die = find_partial_die (part_die->spec_offset,
++ part_die->spec_is_dwz, cu);
+
+ fixup_partial_die (spec_die, cu);
+
+@@ -12880,6 +13254,10 @@ read_attribute_value (const struct die_reader_specs *reader,
+ &cu->header, &bytes_read);
+ info_ptr += bytes_read;
+ break;
++ case DW_FORM_GNU_ref_alt:
++ DW_UNSND (attr) = read_offset (abfd, info_ptr, &cu->header, &bytes_read);
++ info_ptr += bytes_read;
++ break;
+ case DW_FORM_addr:
+ DW_ADDR (attr) = read_address (abfd, info_ptr, cu, &bytes_read);
+ info_ptr += bytes_read;
+@@ -12922,10 +13300,25 @@ read_attribute_value (const struct die_reader_specs *reader,
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_strp:
+- DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header,
+- &bytes_read);
+- DW_STRING_IS_CANONICAL (attr) = 0;
+- info_ptr += bytes_read;
++ if (!cu->per_cu->is_dwz)
++ {
++ DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header,
++ &bytes_read);
++ DW_STRING_IS_CANONICAL (attr) = 0;
++ info_ptr += bytes_read;
++ break;
++ }
++ /* FALLTHROUGH */
++ case DW_FORM_GNU_strp_alt:
++ {
++ struct dwz_file *dwz = dwarf2_get_dwz_file ();
++ LONGEST str_offset = read_offset (abfd, info_ptr, cu_header,
++ &bytes_read);
++
++ DW_STRING (attr) = read_indirect_string_from_dwz (dwz, str_offset);
++ DW_STRING_IS_CANONICAL (attr) = 0;
++ info_ptr += bytes_read;
++ }
+ break;
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+@@ -13037,6 +13430,10 @@ read_attribute_value (const struct die_reader_specs *reader,
+ bfd_get_filename (abfd));
+ }
+
++ /* Super hack. */
++ if (cu->per_cu->is_dwz && is_ref_attr (attr))
++ attr->form = DW_FORM_GNU_ref_alt;
++
+ /* We have seen instances where the compiler tried to emit a byte
+ size attribute of -1 which ended up being encoded as an unsigned
+ 0xffffffff. Although 0xffffffff is technically a valid size value,
+@@ -13333,6 +13730,30 @@ read_indirect_string_at_offset (bfd *abfd, LONGEST str_offset)
+ return (char *) (dwarf2_per_objfile->str.buffer + str_offset);
+ }
+
++/* Read a string at offset STR_OFFSET in the .debug_str section from
++ the .dwz file DWZ. Throw an error if the offset is too large. If
++ the string consists of a single NUL byte, return NULL; otherwise
++ return a pointer to the string. */
++
++static char *
++read_indirect_string_from_dwz (struct dwz_file *dwz, LONGEST str_offset)
++{
++ dwarf2_read_section (dwarf2_per_objfile->objfile, &dwz->str);
++
++ if (dwz->str.buffer == NULL)
++ error (_("DW_FORM_GNU_strp_alt used without .debug_str "
++ "section [in module %s]"),
++ bfd_get_filename (dwz->dwz_bfd));
++ if (str_offset >= dwz->str.size)
++ error (_("DW_FORM_GNU_strp_alt pointing outside of "
++ ".debug_str section [in module %s]"),
++ bfd_get_filename (dwz->dwz_bfd));
++ gdb_assert (HOST_CHAR_BIT == 8);
++ if (dwz->str.buffer[str_offset] == '\0')
++ return NULL;
++ return (char *) (dwz->str.buffer + str_offset);
++}
++
+ static char *
+ read_indirect_string (bfd *abfd, gdb_byte *buf,
+ const struct comp_unit_head *cu_header,
+@@ -13804,6 +14225,30 @@ add_file_name (struct line_header *lh,
+ fe->symtab = NULL;
+ }
+
++/* A convenience function to find the proper .debug_line section for a
++ CU. */
++
++static struct dwarf2_section_info *
++get_debug_line_section (struct dwarf2_cu *cu)
++{
++ struct dwarf2_section_info *section;
++
++ /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
++ DWO file. */
++ if (cu->dwo_unit && cu->per_cu->is_debug_types)
++ section = &cu->dwo_unit->dwo_file->sections.line;
++ else if (cu->per_cu->is_dwz)
++ {
++ struct dwz_file *dwz = dwarf2_get_dwz_file ();
++
++ section = &dwz->line;
++ }
++ else
++ section = &dwarf2_per_objfile->line;
++
++ return section;
++}
++
+ /* Read the statement program header starting at OFFSET in
+ .debug_line, or .debug_line.dwo. Return a pointer
+ to a struct line_header, allocated using xmalloc.
+@@ -13824,13 +14269,7 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
+ struct dwarf2_section_info *section;
+ bfd *abfd;
+
+- /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
+- DWO file. */
+- if (cu->dwo_unit && cu->per_cu->is_debug_types)
+- section = &cu->dwo_unit->dwo_file->sections.line;
+- else
+- section = &dwarf2_per_objfile->line;
+-
++ section = get_debug_line_section (cu);
+ dwarf2_read_section (dwarf2_per_objfile->objfile, section);
+ if (section->buffer == NULL)
+ {
+@@ -14155,7 +14594,7 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
+ GCd by the linker. Ignore it. PR gdb/12528 */
+
+ long line_offset
+- = line_ptr - dwarf2_per_objfile->line.buffer;
++ = line_ptr - get_debug_line_section (cu)->buffer;
+
+ complaint (&symfile_complaints,
+ _(".debug_line address at offset 0x%lx is 0 "
+@@ -14534,10 +14973,12 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
(i.e. when the value of a register or memory location is
referenced, or a thread-local block, etc.). Then again, it might
not be worthwhile. I'm assuming that it isn't unless performance
if (SYMBOL_COMPUTED_OPS (sym) == &dwarf2_loclist_funcs)
cu->has_loclist = 1;
-@@ -11589,6 +11799,8 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
+@@ -14578,6 +15019,8 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
else
sym = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol);
OBJSTAT (objfile, n_syms++);
/* Cache this symbol's name and the name's demangled form (if any). */
SYMBOL_SET_LANGUAGE (sym, cu->language);
-@@ -12354,6 +12566,9 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
+@@ -15001,6 +15444,7 @@ dwarf2_const_value_attr (struct attribute *attr, struct type *type,
+ case DW_FORM_string:
+ case DW_FORM_strp:
+ case DW_FORM_GNU_str_index:
++ case DW_FORM_GNU_strp_alt:
+ /* DW_STRING is already allocated on the objfile obstack, point
+ directly to it. */
+ *bytes = (gdb_byte *) DW_STRING (attr);
+@@ -15187,7 +15631,15 @@ lookup_die_type (struct die_info *die, struct attribute *attr,
+
+ /* First see if we have it cached. */
+
+- if (is_ref_attr (attr))
++ if (attr->form == DW_FORM_GNU_ref_alt)
++ {
++ struct dwarf2_per_cu_data *per_cu;
++ sect_offset offset = dwarf2_get_ref_die_offset (attr);
++
++ per_cu = dwarf2_find_containing_comp_unit (offset, 1, cu->objfile);
++ this_type = get_die_type_at_offset (offset, per_cu);
++ }
++ else if (is_ref_attr (attr))
+ {
+ sect_offset offset = dwarf2_get_ref_die_offset (attr);
+
+@@ -15352,6 +15804,9 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
break;
}
return this_type;
}
-@@ -15590,62 +15805,100 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
- baton->base_address = cu->base_address;
+@@ -15960,6 +16415,10 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
+ fprintf_unfiltered (f, "ref address: ");
+ fputs_filtered (hex_string (DW_UNSND (&die->attrs[i])), f);
+ break;
++ case DW_FORM_GNU_ref_alt:
++ fprintf_unfiltered (f, "alt ref address: ");
++ fputs_filtered (hex_string (DW_UNSND (&die->attrs[i])), f);
++ break;
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+@@ -15991,6 +16450,7 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
+ case DW_FORM_string:
+ case DW_FORM_strp:
+ case DW_FORM_GNU_str_index:
++ case DW_FORM_GNU_strp_alt:
+ fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)",
+ DW_STRING (&die->attrs[i])
+ ? DW_STRING (&die->attrs[i]) : "",
+@@ -16094,6 +16554,7 @@ is_ref_attr (struct attribute *attr)
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
++ case DW_FORM_GNU_ref_alt:
+ return 1;
+ default:
+ return 0;
+@@ -16171,7 +16632,8 @@ follow_die_ref_or_sig (struct die_info *src_die, struct attribute *attr,
+ Returns NULL if OFFSET is invalid. */
+
+ static struct die_info *
+-follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
++follow_die_offset (sect_offset offset, int offset_in_dwz,
++ struct dwarf2_cu **ref_cu)
+ {
+ struct die_info temp_die;
+ struct dwarf2_cu *target_cu, *cu = *ref_cu;
+@@ -16188,11 +16650,13 @@ follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
+ if (! offset_in_cu_p (&cu->header, offset))
+ return NULL;
+ }
+- else if (! offset_in_cu_p (&cu->header, offset))
++ else if (offset_in_dwz != cu->per_cu->is_dwz
++ || ! offset_in_cu_p (&cu->header, offset))
+ {
+ struct dwarf2_per_cu_data *per_cu;
+
+- per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
++ per_cu = dwarf2_find_containing_comp_unit (offset, offset_in_dwz,
++ cu->objfile);
+
+ /* If necessary, add it to the queue and load its DIEs. */
+ if (maybe_queue_comp_unit (cu, per_cu, cu->language))
+@@ -16224,7 +16688,10 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr,
+ struct dwarf2_cu *cu = *ref_cu;
+ struct die_info *die;
+
+- die = follow_die_offset (offset, ref_cu);
++ die = follow_die_offset (offset,
++ (attr->form == DW_FORM_GNU_ref_alt
++ || cu->per_cu->is_dwz),
++ ref_cu);
+ if (!die)
+ error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE "
+ "at 0x%x [in module %s]"),
+@@ -16255,7 +16722,7 @@ dwarf2_fetch_die_location_block (cu_offset offset_in_cu,
+ load_cu (per_cu);
+ cu = per_cu->cu;
+
+- die = follow_die_offset (offset, &cu);
++ die = follow_die_offset (offset, per_cu->is_dwz, &cu);
+ if (!die)
+ error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
+ offset.sect_off, per_cu->objfile->name);
+@@ -17049,6 +17516,7 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes, gdb_byte *buffer_end,
+
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp:
++ case DW_FORM_GNU_strp_alt:
+ bytes += offset_size;
+ break;
+
+@@ -17204,7 +17672,7 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
+ struct macro_source_file *current_file,
+ struct line_header *lh, char *comp_dir,
+ struct dwarf2_section_info *section,
+- int section_is_gnu,
++ int section_is_gnu, int section_is_dwz,
+ unsigned int offset_size,
+ struct objfile *objfile,
+ htab_t include_hash)
+@@ -17255,6 +17723,8 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
+ case DW_MACRO_GNU_undef:
+ case DW_MACRO_GNU_define_indirect:
+ case DW_MACRO_GNU_undef_indirect:
++ case DW_MACRO_GNU_define_indirect_alt:
++ case DW_MACRO_GNU_undef_indirect_alt:
+ {
+ unsigned int bytes_read;
+ int line;
+@@ -17277,11 +17747,21 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
+ str_offset = read_offset_1 (abfd, mac_ptr, offset_size);
+ mac_ptr += offset_size;
+
+- body = read_indirect_string_at_offset (abfd, str_offset);
++ if (macinfo_type == DW_MACRO_GNU_define_indirect_alt
++ || macinfo_type == DW_MACRO_GNU_undef_indirect_alt
++ || section_is_dwz)
++ {
++ struct dwz_file *dwz = dwarf2_get_dwz_file ();
++
++ body = read_indirect_string_from_dwz (dwz, str_offset);
++ }
++ else
++ body = read_indirect_string_at_offset (abfd, str_offset);
+ }
+
+ is_define = (macinfo_type == DW_MACRO_GNU_define
+- || macinfo_type == DW_MACRO_GNU_define_indirect);
++ || macinfo_type == DW_MACRO_GNU_define_indirect
++ || macinfo_type == DW_MACRO_GNU_define_indirect_alt);
+ if (! current_file)
+ {
+ /* DWARF violation as no main source is present. */
+@@ -17305,7 +17785,8 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
+ else
+ {
+ gdb_assert (macinfo_type == DW_MACRO_GNU_undef
+- || macinfo_type == DW_MACRO_GNU_undef_indirect);
++ || macinfo_type == DW_MACRO_GNU_undef_indirect
++ || macinfo_type == DW_MACRO_GNU_undef_indirect_alt);
+ macro_undef (current_file, line, body);
+ }
+ }
+@@ -17380,6 +17861,7 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
+ break;
+
+ case DW_MACRO_GNU_transparent_include:
++ case DW_MACRO_GNU_transparent_include_alt:
+ {
+ LONGEST offset;
+ void **slot;
+@@ -17398,13 +17880,32 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
+ }
+ else
+ {
++ bfd *include_bfd = abfd;
++ struct dwarf2_section_info *include_section = section;
++ struct dwarf2_section_info alt_section;
++ gdb_byte *include_mac_end = mac_end;
++ int is_dwz = section_is_dwz;
++
+ *slot = mac_ptr;
+
+- dwarf_decode_macro_bytes (abfd,
+- section->buffer + offset,
+- mac_end, current_file,
++ if (macinfo_type == DW_MACRO_GNU_transparent_include_alt)
++ {
++ struct dwz_file *dwz = dwarf2_get_dwz_file ();
++
++ dwarf2_read_section (dwarf2_per_objfile->objfile,
++ &dwz->macro);
++
++ include_bfd = dwz->macro.asection->owner;
++ include_section = &dwz->macro;
++ include_mac_end = dwz->macro.buffer + dwz->macro.size;
++ is_dwz = 1;
++ }
++
++ dwarf_decode_macro_bytes (include_bfd,
++ include_section->buffer + offset,
++ include_mac_end, current_file,
+ lh, comp_dir,
+- section, section_is_gnu,
++ section, section_is_gnu, is_dwz,
+ offset_size, objfile, include_hash);
+
+ htab_remove_elt (include_hash, mac_ptr);
+@@ -17571,6 +18072,8 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
+
+ case DW_MACRO_GNU_define_indirect:
+ case DW_MACRO_GNU_undef_indirect:
++ case DW_MACRO_GNU_define_indirect_alt:
++ case DW_MACRO_GNU_undef_indirect_alt:
+ {
+ unsigned int bytes_read;
+
+@@ -17581,6 +18084,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
+ break;
+
+ case DW_MACRO_GNU_transparent_include:
++ case DW_MACRO_GNU_transparent_include_alt:
+ /* Note that, according to the spec, a transparent include
+ chain cannot call DW_MACRO_GNU_start_file. So, we can just
+ skip this opcode. */
+@@ -17623,7 +18127,8 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
+ slot = htab_find_slot (include_hash, mac_ptr, INSERT);
+ *slot = mac_ptr;
+ dwarf_decode_macro_bytes (abfd, mac_ptr, mac_end,
+- current_file, lh, comp_dir, section, section_is_gnu,
++ current_file, lh, comp_dir, section,
++ section_is_gnu, 0,
+ offset_size, objfile, include_hash);
+ do_cleanups (cleanup);
+ }
+@@ -17721,62 +18226,100 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
+ baton->from_dwo = cu->dwo_unit != NULL;
}
-static void
+
+static struct dwarf2_locexpr_baton *
+dwarf2_attr_to_locexpr_baton (struct attribute *attr, struct dwarf2_cu *cu)
- {
- struct objfile *objfile = dwarf2_per_objfile->objfile;
++{
++ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_locexpr_baton *baton;
-
-- if (attr_form_is_section_offset (attr)
-- /* ".debug_loc" may not exist at all, or the offset may be outside
-- the section. If so, fall through to the complaint in the
-- other branch. */
-- && DW_UNSND (attr) < dwarf2_section_size (objfile,
-- &dwarf2_per_objfile->loc))
-- {
-- struct dwarf2_loclist_baton *baton;
++
+ gdb_assert (attr_form_is_block (attr));
+
+ baton = obstack_alloc (&objfile->objfile_obstack, sizeof (*baton));
+ baton->per_cu = cu->per_cu;
+ gdb_assert (baton->per_cu);
-
-- baton = obstack_alloc (&objfile->objfile_obstack,
-- sizeof (struct dwarf2_loclist_baton));
++
+ /* Note that we're just copying the block's data pointer
+ here, not the actual data. We're still pointing into the
+ info_buffer for SYM's objfile; right now we never release
+ baton->size = DW_BLOCK (attr)->size;
+ baton->data = DW_BLOCK (attr)->data;
+ gdb_assert (baton->size == 0 || baton->data != NULL);
-
-- fill_in_loclist_baton (cu, baton, attr);
++
+ return baton;
+}
-
-- if (cu->base_known == 0)
-- complaint (&symfile_complaints,
-- _("Location list used without "
-- "specifying the CU base address."));
++
+static struct dwarf2_loclist_baton *
+dwarf2_attr_to_loclist_baton (struct attribute *attr, struct dwarf2_cu *cu)
-+{
+ {
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_section_info *section = cu_debug_loc_section (cu);
+ struct dwarf2_loclist_baton *baton;
+
+ /* DW_AT_location of the referenced DIE may be missing if the referenced
+ if (!attr)
+ return NULL;
+
-+ dwarf2_read_section (dwarf2_per_objfile->objfile,
-+ &dwarf2_per_objfile->loc);
-+
++ dwarf2_read_section (dwarf2_per_objfile->objfile, section);
+
+- if (attr_form_is_section_offset (attr)
+ if (!(attr_form_is_section_offset (attr)
-+ /* ".debug_loc" may not exist at all, or the offset may be outside
-+ the section. If so, fall through to the complaint in the
-+ other branch. */
-+ && DW_UNSND (attr) < dwarf2_section_size (dwarf2_per_objfile->objfile,
-+ &dwarf2_per_objfile->loc)))
+ /* .debug_loc{,.dwo} may not exist at all, or the offset may be outside
+ the section. If so, fall through to the complaint in the
+ other branch. */
+- && DW_UNSND (attr) < dwarf2_section_size (objfile, section))
+- {
+- struct dwarf2_loclist_baton *baton;
++ && DW_UNSND (attr) < dwarf2_section_size (objfile, section)))
+ return NULL;
-+
-+ baton = obstack_alloc (&cu->objfile->objfile_obstack,
+
+- baton = obstack_alloc (&objfile->objfile_obstack,
+- sizeof (struct dwarf2_loclist_baton));
++ baton = obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct dwarf2_loclist_baton));
-+
+
+- fill_in_loclist_baton (cu, baton, attr);
+ fill_in_loclist_baton (cu, baton, attr);
-+
+
+- if (cu->base_known == 0)
+- complaint (&symfile_complaints,
+- _("Location list used without "
+- "specifying the CU base address."));
+ if (cu->base_known == 0)
+ complaint (&symfile_complaints,
+ _("Location list used without "
+ "specifying the CU base address."));
-
++
+ return baton;
+}
+
+ struct dwarf2_cu *cu)
+{
+ struct dwarf2_loclist_baton *loclist_baton;
-+
+
+ loclist_baton = dwarf2_attr_to_loclist_baton (attr, cu);
+ if (loclist_baton)
+ {
}
}
-@@ -16003,6 +16256,25 @@ offset_and_type_eq (const void *item_lhs, const void *item_rhs)
- return ofs_lhs->offset == ofs_rhs->offset;
+@@ -17878,28 +18421,35 @@ dwarf2_per_cu_text_offset (struct dwarf2_per_cu_data *per_cu)
+
+ static struct dwarf2_per_cu_data *
+ dwarf2_find_containing_comp_unit (sect_offset offset,
++ unsigned int offset_in_dwz,
+ struct objfile *objfile)
+ {
+ struct dwarf2_per_cu_data *this_cu;
+ int low, high;
++ const sect_offset *cu_off;
+
+ low = 0;
+ high = dwarf2_per_objfile->n_comp_units - 1;
+ while (high > low)
+ {
++ struct dwarf2_per_cu_data *mid_cu;
+ int mid = low + (high - low) / 2;
+
+- if (dwarf2_per_objfile->all_comp_units[mid]->offset.sect_off
+- >= offset.sect_off)
++ mid_cu = dwarf2_per_objfile->all_comp_units[mid];
++ cu_off = &mid_cu->offset;
++ if (mid_cu->is_dwz > offset_in_dwz
++ || (mid_cu->is_dwz == offset_in_dwz
++ && cu_off->sect_off >= offset.sect_off))
+ high = mid;
+ else
+ low = mid + 1;
+ }
+ gdb_assert (low == high);
+- if (dwarf2_per_objfile->all_comp_units[low]->offset.sect_off
+- > offset.sect_off)
++ this_cu = dwarf2_per_objfile->all_comp_units[low];
++ cu_off = &this_cu->offset;
++ if (this_cu->is_dwz != offset_in_dwz || cu_off->sect_off > offset.sect_off)
+ {
+- if (low == 0)
++ if (low == 0 || this_cu->is_dwz != offset_in_dwz)
+ error (_("Dwarf Error: could not find partial DIE containing "
+ "offset 0x%lx [in module %s]"),
+ (long) offset.sect_off, bfd_get_filename (objfile->obfd));
+@@ -18140,6 +18690,25 @@ per_cu_offset_and_type_eq (const void *item_lhs, const void *item_rhs)
+ && ofs_lhs->offset.sect_off == ofs_rhs->offset.sect_off);
}
+/* Fill in generic attributes applicable for type DIEs. */
/* Set the type associated with DIE to TYPE. Save it in CU's hash
table if necessary. For convenience, return TYPE.
-@@ -16028,6 +16300,8 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
+@@ -18164,6 +18733,8 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
+ struct dwarf2_per_cu_offset_and_type **slot, ofs;
struct objfile *objfile = cu->objfile;
- htab_t *type_hash_ptr;
+ fetch_die_type_attrs (die, type, cu);
+
/* For Ada types, make sure that the gnat-specific data is always
initialized (if not already set). There are a few types where
we should not be doing so, because the type-specific area is
+@@ -18341,53 +18912,13 @@ show_dwarf2_cmd (char *args, int from_tty)
+ cmd_show_list (show_dwarf2_cmdlist, from_tty, "");
+ }
+
+-/* If section described by INFO was mmapped, munmap it now. */
+-
+-static void
+-munmap_section_buffer (struct dwarf2_section_info *info)
+-{
+- if (info->map_addr != NULL)
+- {
+-#ifdef HAVE_MMAP
+- int res;
+-
+- res = munmap (info->map_addr, info->map_len);
+- gdb_assert (res == 0);
+-#else
+- /* Without HAVE_MMAP, we should never be here to begin with. */
+- gdb_assert_not_reached ("no mmap support");
+-#endif
+- }
+-}
+-
+-/* munmap debug sections for OBJFILE, if necessary. */
++/* Free data associated with OBJFILE, if necessary. */
+
+ static void
+ dwarf2_per_objfile_free (struct objfile *objfile, void *d)
+ {
+ struct dwarf2_per_objfile *data = d;
+ int ix;
+- struct dwarf2_section_info *section;
+-
+- /* This is sorted according to the order they're defined in to make it easier
+- to keep in sync. */
+- munmap_section_buffer (&data->info);
+- munmap_section_buffer (&data->abbrev);
+- munmap_section_buffer (&data->line);
+- munmap_section_buffer (&data->loc);
+- munmap_section_buffer (&data->macinfo);
+- munmap_section_buffer (&data->macro);
+- munmap_section_buffer (&data->str);
+- munmap_section_buffer (&data->ranges);
+- munmap_section_buffer (&data->addr);
+- munmap_section_buffer (&data->frame);
+- munmap_section_buffer (&data->eh_frame);
+- munmap_section_buffer (&data->gdb_index);
+-
+- for (ix = 0;
+- VEC_iterate (dwarf2_section_info_def, data->types, ix, section);
+- ++ix)
+- munmap_section_buffer (section);
+
+ for (ix = 0; ix < dwarf2_per_objfile->n_comp_units; ++ix)
+ VEC_free (dwarf2_per_cu_ptr,
+@@ -18397,6 +18928,9 @@ dwarf2_per_objfile_free (struct objfile *objfile, void *d)
+
+ if (data->dwo_files)
+ free_dwo_files (data->dwo_files, objfile);
++
++ if (data->dwz_file && data->dwz_file->dwz_bfd)
++ gdb_bfd_unref (data->dwz_file->dwz_bfd);
+ }
+
+ \f
diff --git a/gdb/elfread.c b/gdb/elfread.c
-index ddae099..aea443f 100644
+index 1edfb27..0b54b8a 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
-@@ -36,6 +36,8 @@
- #include "demangle.h"
- #include "psympriv.h"
- #include "filenames.h"
-+#include "stap-probe.h"
-+#include "arch-utils.h"
- #include "gdbtypes.h"
- #include "value.h"
- #include "infcall.h"
-@@ -60,6 +62,21 @@ struct elfinfo
- asection *mdebugsect; /* Section pointer for .mdebug section */
- };
+@@ -44,6 +44,7 @@
+ #include "gdbthread.h"
+ #include "regcache.h"
+ #include "bcache.h"
++#include "gdb_bfd.h"
-+/* Per-objfile data for SystemTap probe info. */
-+
-+static const struct objfile_data *stap_probe_key = NULL;
-+
-+/* Per-objfile data about SystemTap probes. */
-+
-+struct stap_probe_per_objfile
-+ {
-+ /* The number of probes in this objfile. */
-+ int stap_num_probes;
-+
-+ /* The probes themselves. */
-+ struct stap_probe *probes;
-+ };
-+
- static void free_elfinfo (void *);
+ extern void _initialize_elfread (void);
+
+@@ -1108,7 +1109,7 @@ build_id_verify (const char *filename, struct build_id *check)
+ int retval = 0;
+
+ /* We expect to be silent on the non-existing files. */
+- abfd = bfd_open_maybe_remote (filename);
++ abfd = gdb_bfd_open_maybe_remote (filename);
+ if (abfd == NULL)
+ return 0;
+
+@@ -1123,7 +1124,7 @@ build_id_verify (const char *filename, struct build_id *check)
+ else
+ retval = 1;
+
+- gdb_bfd_close_or_warn (abfd);
++ gdb_bfd_unref (abfd);
- /* Minimal symbols located at the GOT entries for .plt - that is the real
-@@ -1576,7 +1593,270 @@ elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst)
- complaint (&symfile_complaints,
- _("elf/stab section information missing for %s"), filename);
- }
-+
-+/* Helper function that parses the information contained in a
-+ SystemTap's probe. Basically, the information consists in:
-+
-+ - Probe's PC address;
-+ - Link-time section address of `.stapsdt.base' section;
-+ - Link-time address of the semaphore variable, or ZERO if the
-+ probe doesn't have an associated semaphore;
-+ - Probe's provider name;
-+ - Probe's name;
-+ - Probe's argument format. */
-+
-+static void
-+handle_probe (struct objfile *objfile, struct sdt_note *el,
-+ struct stap_probe *ret, CORE_ADDR base)
-+{
-+ bfd *abfd = objfile->obfd;
-+ int size = bfd_get_arch_size (abfd) / 8;
-+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
-+ struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
-+ CORE_ADDR base_ref;
-+
-+ ret->gdbarch = gdbarch;
-+
-+ /* Provider and the name of the probe. */
-+ ret->provider = (const char *) &el->data[3 * size];
-+ ret->name = memchr (ret->provider, '\0',
-+ (unsigned long *) el->data
-+ + el->size - (unsigned long *) ret->provider);
-+ /* Making sure there is a name. */
-+ if (!ret->name)
-+ complaint (&symfile_complaints, _("corrupt probe when reading `%s'"),
-+ objfile->name);
-+ else
-+ ++ret->name;
-+
-+ /* Retrieving the probe's address. */
-+ ret->address = extract_typed_address ((const gdb_byte *) &el->data[0],
-+ ptr_type);
-+ /* Link-time sh_addr of `.stapsdt.base' section. */
-+ base_ref = extract_typed_address ((const gdb_byte *) &el->data[size],
-+ ptr_type);
-+ /* Semaphore address. */
-+ ret->sem_addr = extract_typed_address ((const gdb_byte *) &el->data[2 * size],
-+ ptr_type);
-+
-+ ret->address += (ANOFFSET (objfile->section_offsets,
-+ SECT_OFF_TEXT (objfile))
-+ + base - base_ref);
-+ if (ret->sem_addr)
-+ ret->sem_addr += (ANOFFSET (objfile->section_offsets,
-+ SECT_OFF_DATA (objfile))
-+ + base - base_ref);
-+
-+ /* Arguments. We can only extract the argument format if there is a valid
-+ name for this probe. */
-+ if (ret->name)
-+ {
-+ ret->args = memchr (ret->name, '\0',
-+ (unsigned long *) el->data
-+ + el->size - (unsigned long *) ret->name);
-+
-+ if (ret->args != NULL)
-+ ++ret->args;
-+ if (ret->args == NULL
-+ || (memchr (ret->args, '\0', (unsigned long *) el->data
-+ + el->size - (unsigned long *) ret->name)
-+ != el->data + el->size - 1))
-+ complaint (&symfile_complaints, _("corrupt probe when reading `%s'"),
-+ objfile->name);
-+ }
-+ else
-+ ret->args = NULL;
-+}
-+
-+/* The name of the SystemTap section where we will find information about
-+ the probes. */
-+
-+#define STAP_BASE_SECTION_NAME ".stapsdt.base"
-+
-+/* Helper function which tries to find the base address of the SystemTap
-+ base section named STAP_BASE_SECTION_NAME. */
-+
-+static void
-+get_base_address_1 (bfd *abfd, asection *sect, void *obj)
-+{
-+ bfd_vma *base = (bfd_vma *) obj;
-+
-+ if (*base == (bfd_vma) -1
-+ && (sect->flags & (SEC_DATA | SEC_ALLOC | SEC_HAS_CONTENTS))
-+ && sect->name && !strcmp (sect->name, STAP_BASE_SECTION_NAME))
-+ *base = sect->vma;
-+}
-+
-+/* Helper function which iterates over every section in the BFD file,
-+ trying to find the base address of the SystemTap base section.
-+ Returns the section address if found, or -1 otherwise. */
-+
-+static bfd_vma
-+get_base_address (bfd *obfd)
-+{
-+ bfd_vma base = (bfd_vma) -1;
-+
-+ bfd_map_over_sections (obfd, get_base_address_1, (void *) &base);
-+
-+ return base;
-+}
-+
-+/* Implementation of `sym_get_probes', as documented in symfile.h. */
-+
-+static struct stap_probe *
-+elf_get_probes (struct objfile *objfile, int *num_probes)
-+{
-+ struct stap_probe *ret = NULL;
-+ struct stap_probe_per_objfile *probes_per_objfile;
-+
-+ /* Initially, no probes. */
-+ *num_probes = 0;
-+
-+ /* Have we parsed this objfile's probes already? */
-+ probes_per_objfile
-+ = (struct stap_probe_per_objfile *) objfile_data (objfile,
-+ stap_probe_key);
-+
-+ if (!probes_per_objfile)
-+ {
-+ /* If we are here, then this is the first time we are parsing the
-+ probe's information. We basically have to count how many probes
-+ the objfile has, and then fill in the necessary information
-+ for each one. */
-+
-+ bfd *obfd = objfile->obfd;
-+ bfd_vma base = get_base_address (obfd);
-+ struct sdt_note *iter;
-+ int i;
-+ int n = 0;
-+
-+ if (! elf_tdata (obfd)->sdt_note_head)
-+ /* There isn't any probe here. */
-+ return NULL;
-+
-+ /* Allocating space for probe info. */
-+ for (iter = elf_tdata (obfd)->sdt_note_head;
-+ iter;
-+ iter = iter->next, ++n);
-+
-+ ret = xcalloc (n, sizeof (struct stap_probe));
-+
-+ /* Parsing each probe's information. */
-+ for (iter = elf_tdata (obfd)->sdt_note_head, i = 0;
-+ iter;
-+ iter = iter->next, i++)
-+ /* We first have to handle all the information about the
-+ probe which is present in the section. */
-+ handle_probe (objfile, iter, &ret[i], base);
-+
-+ /* Creating a cache for these probes in the objfile's registry. */
-+ probes_per_objfile = xmalloc (sizeof (struct stap_probe_per_objfile));
-+
-+ probes_per_objfile->stap_num_probes = n;
-+ probes_per_objfile->probes = ret;
-+
-+ set_objfile_data (objfile, stap_probe_key, probes_per_objfile);
-+ }
-+ else
-+ ret = probes_per_objfile->probes;
-+
-+ *num_probes = probes_per_objfile->stap_num_probes;
-+
-+ return ret;
-+}
-+
-+/* Implementation of `sym_get_probe_argument_count', as documented in
-+ symfile.h. */
-+
-+static int
-+elf_get_probe_argument_count (struct objfile *objfile,
-+ struct stap_probe *probe)
-+{
-+ const char *pargs = probe->args;
-+
-+ if (!pargs || !*pargs || *pargs == ':')
-+ /* No arguments. */
-+ return 0;
-+
-+ return stap_get_probe_argument_count (probe);
-+}
-+
-+/* Implementation of `sym_evaluate_probe_argument', as documented in
-+ symfile.h. */
-+
-+static struct value *
-+elf_evaluate_probe_argument (struct objfile *objfile,
-+ struct stap_probe *probe,
-+ struct frame_info *frame,
-+ int n)
-+{
-+ return stap_evaluate_probe_argument (objfile, probe, frame, n);
-+}
-+
-+/* Implementation of `sym_compile_to_ax', as documented in symfile.h. */
-+
-+static void
-+elf_compile_to_ax (struct objfile *objfile,
-+ struct stap_probe *probe,
-+ struct agent_expr *expr,
-+ struct axs_value *value,
-+ int n)
-+{
-+ stap_compile_to_ax (objfile, probe, expr, value, n);
-+}
-+
-+/* Implementation of `sym_relocate_probe', as documented in symfile.h. */
-+
-+static void
-+elf_symfile_relocate_probe (struct objfile *objfile,
-+ struct section_offsets *new_offsets,
-+ struct section_offsets *delta)
-+{
-+ int i;
-+ struct stap_probe_per_objfile *p
-+ = (struct stap_probe_per_objfile *) objfile_data (objfile,
-+ stap_probe_key);
-+
-+ if (!p)
-+ /* No probe to relocate. */
-+ return;
-+
-+ for (i = 0; i < p->stap_num_probes; i++)
-+ {
-+ p->probes[i].address += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
-+ if (p->probes[i].sem_addr)
-+ p->probes[i].sem_addr += ANOFFSET (delta, SECT_OFF_DATA (objfile));
-+ }
-+}
-+
-+/* Helper function used to free the space allocated for storing SystemTap
-+ probe information. */
-+
-+static void
-+stap_probe_key_free (struct objfile *objfile, void *d)
-+{
-+ int i;
-+ struct stap_probe_per_objfile *data = (struct stap_probe_per_objfile *) d;
-+
-+ for (i = 0; i < data->stap_num_probes; i++)
-+ stap_free_parsed_args (data->probes[i].parsed_args);
-+ xfree (data->probes);
-+ xfree (data);
-+}
-+
- \f
-+
-+/* Implementation `sym_probe_fns', as documented in symfile.h. */
-+
-+static const struct sym_probe_fns elf_probe_fns =
-+{
-+ elf_get_probes, /* sym_get_probes */
-+ elf_get_probe_argument_count, /* sym_get_probe_argument_count */
-+ elf_evaluate_probe_argument, /* sym_evaluate_probe_argument */
-+ elf_compile_to_ax, /* sym_compile_to_ax */
-+ elf_symfile_relocate_probe, /* sym_relocate_probe */
-+};
-+
- /* Register that we are able to handle ELF object file formats. */
-
- static const struct sym_fns elf_sym_fns =
-@@ -1591,6 +1871,7 @@ static const struct sym_fns elf_sym_fns =
- elf_symfile_segments, /* Get segment information from a file. */
- NULL,
- default_symfile_relocate, /* Relocate a debug section. */
-+ &elf_probe_fns, /* sym_probe_fns */
- &psym_functions
- };
-
-@@ -1609,6 +1890,7 @@ static const struct sym_fns elf_sym_fns_lazy_psyms =
- elf_symfile_segments, /* Get segment information from a file. */
- NULL,
- default_symfile_relocate, /* Relocate a debug section. */
-+ &elf_probe_fns, /* sym_probe_fns */
- &psym_functions
- };
-
-@@ -1626,6 +1908,7 @@ static const struct sym_fns elf_sym_fns_gdb_index =
- elf_symfile_segments, /* Get segment information from a file. */
- NULL,
- default_symfile_relocate, /* Relocate a debug section. */
-+ &elf_probe_fns, /* sym_probe_fns */
- &dwarf2_gdb_index_functions
- };
-
-@@ -1642,6 +1925,8 @@ static const struct gnu_ifunc_fns elf_gnu_ifunc_fns =
- void
- _initialize_elfread (void)
- {
-+ stap_probe_key
-+ = register_objfile_data_with_cleanup (NULL, stap_probe_key_free);
- add_symtab_fns (&elf_sym_fns);
-
- elf_objfile_gnu_ifunc_cache_data = register_objfile_data ();
-diff --git a/gdb/eval.c b/gdb/eval.c
-index 0244f7a..b33d367 100644
---- a/gdb/eval.c
-+++ b/gdb/eval.c
-@@ -41,6 +41,7 @@
- #include "gdb_obstack.h"
- #include "objfiles.h"
- #include "python/python.h"
-+#include "dwarf2loc.h"
-
- #include "gdb_assert.h"
-
-@@ -498,27 +499,217 @@ init_array_element (struct value *array, struct value *element,
+ xfree (found);
+
+@@ -1444,10 +1445,12 @@ elf_symfile_read (struct objfile *objfile, int symfile_flags)
+
+ if (debugfile)
+ {
++ struct cleanup *cleanup = make_cleanup (xfree, debugfile);
+ bfd *abfd = symfile_bfd_open (debugfile);
+
++ make_cleanup_bfd_unref (abfd);
+ symbol_file_add_separate (abfd, symfile_flags, objfile);
+- xfree (debugfile);
++ do_cleanups (cleanup);
+ }
+ }
+
+diff --git a/gdb/eval.c b/gdb/eval.c
+index 7d3a8b9..f69dff0 100644
+--- a/gdb/eval.c
++++ b/gdb/eval.c
+@@ -41,6 +41,7 @@
+ #include "gdb_obstack.h"
+ #include "objfiles.h"
+ #include "python/python.h"
++#include "dwarf2loc.h"
+
+ #include "gdb_assert.h"
+
+@@ -500,27 +501,217 @@ init_array_element (struct value *array, struct value *element,
}
static struct value *
}
-@@ -799,6 +990,7 @@ evaluate_subexp_standard (struct type *expect_type,
+@@ -818,6 +1009,7 @@ evaluate_subexp_standard (struct type *expect_type,
int save_pos1;
struct symbol *function = NULL;
char *function_name = NULL;
pc = (*pos)++;
op = exp->elts[pc].opcode;
-@@ -1874,6 +2066,8 @@ evaluate_subexp_standard (struct type *expect_type,
+@@ -1892,6 +2084,8 @@ evaluate_subexp_standard (struct type *expect_type,
/* First determine the type code we are dealing with. */
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
type = check_typedef (value_type (arg1));
code = TYPE_CODE (type);
-@@ -1894,23 +2088,13 @@ evaluate_subexp_standard (struct type *expect_type,
+@@ -1912,23 +2106,13 @@ evaluate_subexp_standard (struct type *expect_type,
code = TYPE_CODE (type);
}
}
case TYPE_CODE_PTR:
case TYPE_CODE_FUNC:
-@@ -2349,49 +2533,6 @@ evaluate_subexp_standard (struct type *expect_type,
+@@ -2361,49 +2545,6 @@ evaluate_subexp_standard (struct type *expect_type,
}
return (arg1);
case BINOP_LOGICAL_AND:
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
if (noside == EVAL_SKIP)
-@@ -2623,15 +2764,23 @@ evaluate_subexp_standard (struct type *expect_type,
+@@ -2635,15 +2776,23 @@ evaluate_subexp_standard (struct type *expect_type,
if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR)
expect_type = TYPE_TARGET_TYPE (check_typedef (expect_type));
arg1 = evaluate_subexp (expect_type, exp, pos, noside);
else if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
type = check_typedef (value_type (arg1));
-@@ -2640,12 +2789,18 @@ evaluate_subexp_standard (struct type *expect_type,
+@@ -2652,12 +2801,18 @@ evaluate_subexp_standard (struct type *expect_type,
/* In C you can dereference an array to get the 1st elt. */
|| TYPE_CODE (type) == TYPE_CODE_ARRAY
)
else
error (_("Attempt to take contents of a non-pointer value."));
}
-@@ -2655,9 +2810,14 @@ evaluate_subexp_standard (struct type *expect_type,
+@@ -2667,9 +2822,14 @@ evaluate_subexp_standard (struct type *expect_type,
do. "long long" variables are rare enough that
BUILTIN_TYPE_LONGEST would seem to be a mistake. */
if (TYPE_CODE (type) == TYPE_CODE_INT)
case UNOP_ADDR:
/* C++: check for and handle pointer to members. */
-@@ -2999,7 +3159,7 @@ evaluate_subexp_with_coercion (struct expression *exp,
+@@ -3011,7 +3171,7 @@ evaluate_subexp_with_coercion (struct expression *exp,
{
enum exp_opcode op;
int pc;
struct symbol *var;
struct type *type;
-@@ -3010,13 +3170,18 @@ evaluate_subexp_with_coercion (struct expression *exp,
+@@ -3022,13 +3182,18 @@ evaluate_subexp_with_coercion (struct expression *exp,
{
case OP_VAR_VALUE:
var = exp->elts[pc + 2].symbol;
return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
val);
}
-@@ -3068,9 +3233,13 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
+@@ -3080,9 +3245,13 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
case OP_VAR_VALUE:
(*pos) += 4;
default:
val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
-@@ -3101,18 +3270,25 @@ parse_and_eval_type (char *p, int length)
+@@ -3113,18 +3282,25 @@ parse_and_eval_type (char *p, int length)
int
calc_f77_array_dims (struct type *array_type)
{
- return ndimen;
+
}
+diff --git a/gdb/exec.c b/gdb/exec.c
+index 6ba1986..e076609 100644
+--- a/gdb/exec.c
++++ b/gdb/exec.c
+@@ -33,6 +33,7 @@
+ #include "arch-utils.h"
+ #include "gdbthread.h"
+ #include "progspace.h"
++#include "gdb_bfd.h"
+
+ #include <fcntl.h>
+ #include "readline/readline.h"
+@@ -98,10 +99,8 @@ exec_close (void)
+ if (exec_bfd)
+ {
+ bfd *abfd = exec_bfd;
+- char *name = bfd_get_filename (abfd);
+
+- gdb_bfd_close_or_warn (abfd);
+- xfree (name);
++ gdb_bfd_unref (abfd);
+
+ /* Removing target sections may close the exec_ops target.
+ Clear exec_bfd before doing so to prevent recursion. */
+@@ -128,17 +127,13 @@ exec_close_1 (int quitting)
+ vp = nxt;
+ nxt = vp->nxt;
+
+- /* if there is an objfile associated with this bfd,
+- free_objfile() will do proper cleanup of objfile *and* bfd. */
+-
+ if (vp->objfile)
+ {
+ free_objfile (vp->objfile);
+ need_symtab_cleanup = 1;
+ }
+- else if (vp->bfd != exec_bfd)
+- /* FIXME-leak: We should be freeing vp->name too, I think. */
+- gdb_bfd_close_or_warn (vp->bfd);
++
++ gdb_bfd_unref (vp->bfd);
+
+ xfree (vp);
+ }
+@@ -230,11 +225,14 @@ exec_file_attach (char *filename, int from_tty)
+ &scratch_pathname);
+ }
+ #endif
++
++ cleanups = make_cleanup (xfree, scratch_pathname);
++
+ if (scratch_chan < 0)
+ perror_with_name (filename);
+- exec_bfd = bfd_fopen (scratch_pathname, gnutarget,
+- write_files ? FOPEN_RUB : FOPEN_RB,
+- scratch_chan);
++ exec_bfd = gdb_bfd_fopen (scratch_pathname, gnutarget,
++ write_files ? FOPEN_RUB : FOPEN_RB,
++ scratch_chan);
+
+ if (!exec_bfd)
+ {
+@@ -242,13 +240,6 @@ exec_file_attach (char *filename, int from_tty)
+ scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+
+- /* At this point, scratch_pathname and exec_bfd->name both point to the
+- same malloc'd string. However exec_close() will attempt to free it
+- via the exec_bfd->name pointer, so we need to make another copy and
+- leave exec_bfd as the new owner of the original copy. */
+- scratch_pathname = xstrdup (scratch_pathname);
+- cleanups = make_cleanup (xfree, scratch_pathname);
+-
+ if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
+ {
+ /* Make sure to close exec_bfd, or else "run" might try to use
+@@ -554,6 +545,7 @@ map_vmap (bfd *abfd, bfd *arch)
+ memset ((char *) vp, '\0', sizeof (*vp));
+ vp->nxt = 0;
+ vp->bfd = abfd;
++ gdb_bfd_ref (abfd);
+ vp->name = bfd_get_filename (arch ? arch : abfd);
+ vp->member = arch ? bfd_get_filename (abfd) : "";
+
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
-index b258c0a..1752973 100644
+index 33c7418..4db1bfa 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
-@@ -292,7 +292,9 @@ arglist : subrange
+@@ -298,7 +298,9 @@ arglist : subrange
{ arglist_len = 1; }
;
;
diff --git a/gdb/f-lang.h b/gdb/f-lang.h
-index 3a46ebf..2b73e1f 100644
+index 4aae3c5..51a4e1e 100644
--- a/gdb/f-lang.h
+++ b/gdb/f-lang.h
@@ -28,6 +28,10 @@ extern void f_error (char *); /* Defined in f-exp.y */
+ (struct type *type, struct ui_file *stream);
+extern void f_object_address_data_valid_or_error (struct type *type);
+
- extern int f_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
- struct ui_file *, int,
- const struct value *,
+ extern void f_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
+ struct ui_file *, int,
+ const struct value *,
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index a95ef84..830917d 100644
--- a/gdb/f-typeprint.c
{
case TYPE_CODE_ARRAY:
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
-index 87b2ed1..5d263f2 100644
+index 4359f6f..8ff834b 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -54,15 +54,17 @@ int f77_array_offset_tbl[MAX_FORTRAN_DIMS + 1][2];
fprintf_filtered (stream, "...");
}
}
-@@ -260,6 +268,9 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
+@@ -270,6 +278,9 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
CORE_ADDR addr;
int index;
+ if (f_object_address_data_valid_print_to_stream (type, stream) != NULL)
-+ return 0;
++ return;
+
CHECK_TYPEDEF (type);
switch (TYPE_CODE (type))
{
diff --git a/gdb/findvar.c b/gdb/findvar.c
-index 79c4221..1bb7c22 100644
+index 66bcebe..e59e5f2 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
-@@ -34,6 +34,7 @@
- #include "user-regs.h"
+@@ -35,6 +35,7 @@
#include "block.h"
#include "objfiles.h"
+ #include "language.h"
+#include "dwarf2loc.h"
/* Basic byte-swapping routines. All 'extract' functions return a
host-format integer from a target-format integer at ADDR which is
-@@ -407,8 +408,11 @@ symbol_read_needs_frame (struct symbol *sym)
-
- /* Given a struct symbol for a variable,
- and a stack frame id, read the value of the variable
-- and return a (pointer to a) struct value containing the value.
-- If the variable cannot be found, throw error. */
-+ and return a (pointer to a) struct value containing the value.
-+ If the variable cannot be found, throw error.
+@@ -438,7 +439,10 @@ minsym_lookup_iterator_cb (struct objfile *objfile, void *cb_data)
+ }
+
+ /* A default implementation for the "la_read_var_value" hook in
+- the language vector which should work in most situations. */
++ the language vector which should work in most situations.
+ We have to first find the address of the variable before allocating struct
+ value to return as its size may depend on DW_OP_PUSH_OBJECT_ADDRESS possibly
+ used by its type. */
struct value *
- read_var_value (struct symbol *var, struct frame_info *frame)
-@@ -416,16 +420,6 @@ read_var_value (struct symbol *var, struct frame_info *frame)
+ default_read_var_value (struct symbol *var, struct frame_info *frame)
+@@ -446,16 +450,6 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
struct value *v;
struct type *type = SYMBOL_TYPE (var);
CORE_ADDR addr;
if (symbol_read_needs_frame (var))
gdb_assert (frame);
-@@ -435,7 +429,7 @@ read_var_value (struct symbol *var, struct frame_info *frame)
+@@ -465,7 +459,7 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
case LOC_CONST:
/* Put the constant back in target format. */
v = allocate_value (type);
gdbarch_byte_order (get_type_arch (type)),
(LONGEST) SYMBOL_VALUE (var));
VALUE_LVAL (v) = not_lval;
-@@ -460,12 +454,12 @@ read_var_value (struct symbol *var, struct frame_info *frame)
+@@ -490,12 +484,12 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
case LOC_CONST_BYTES:
v = allocate_value (type);
if (overlay_debugging)
addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
SYMBOL_OBJ_SECTION (var));
-@@ -479,7 +473,6 @@ read_var_value (struct symbol *var, struct frame_info *frame)
+@@ -509,7 +503,6 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
error (_("Unknown argument list address for `%s'."),
SYMBOL_PRINT_NAME (var));
addr += SYMBOL_VALUE (var);
break;
case LOC_REF_ARG:
-@@ -494,14 +487,12 @@ read_var_value (struct symbol *var, struct frame_info *frame)
+@@ -524,14 +517,12 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
argref += SYMBOL_VALUE (var);
ref = value_at (lookup_pointer_type (type), argref);
addr = value_as_address (ref);
break;
case LOC_TYPEDEF:
-@@ -510,7 +501,6 @@ read_var_value (struct symbol *var, struct frame_info *frame)
+@@ -540,7 +531,6 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
break;
case LOC_BLOCK:
if (overlay_debugging)
addr = symbol_overlayed_address
(BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_OBJ_SECTION (var));
-@@ -536,7 +526,6 @@ read_var_value (struct symbol *var, struct frame_info *frame)
+@@ -566,7 +556,6 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
SYMBOL_PRINT_NAME (var));
addr = value_as_address (regval);
}
else
{
-@@ -576,7 +565,6 @@ read_var_value (struct symbol *var, struct frame_info *frame)
+@@ -615,7 +604,6 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
if (obj_section
&& (obj_section->the_bfd_section->flags & SEC_THREAD_LOCAL) != 0)
addr = target_translate_tls_address (obj_section->objfile, addr);
}
break;
-@@ -589,6 +577,10 @@ read_var_value (struct symbol *var, struct frame_info *frame)
+@@ -628,6 +616,10 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
break;
}
VALUE_LVAL (v) = lval_memory;
set_value_address (v, addr);
return v;
-@@ -671,10 +663,11 @@ struct value *
+@@ -723,10 +715,11 @@ struct value *
value_from_register (struct type *type, int regnum, struct frame_info *frame)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
{
int optim, unavail, ok;
-@@ -689,7 +682,7 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
+@@ -741,7 +734,7 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
VALUE_LVAL (v) = lval_register;
VALUE_FRAME_ID (v) = get_frame_id (frame);
VALUE_REGNUM (v) = regnum;
value_contents_raw (v), &optim,
&unavail);
-diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
-index 1bd2341..431ddcc 100644
---- a/gdb/gdbarch.c
-+++ b/gdb/gdbarch.c
-@@ -265,6 +265,16 @@ struct gdbarch
- gdbarch_get_siginfo_type_ftype *get_siginfo_type;
- gdbarch_record_special_symbol_ftype *record_special_symbol;
- gdbarch_get_syscall_number_ftype *get_syscall_number;
-+ const char * stap_integer_prefix;
-+ const char * stap_integer_sufix;
-+ const char * stap_register_prefix;
-+ const char * stap_register_sufix;
-+ const char * stap_register_indirection_prefix;
-+ const char * stap_register_indirection_sufix;
-+ const char * stap_gdb_register_prefix;
-+ const char * stap_gdb_register_sufix;
-+ gdbarch_stap_is_single_operand_ftype *stap_is_single_operand;
-+ gdbarch_stap_parse_special_token_ftype *stap_parse_special_token;
- int has_global_solist;
- int has_global_breakpoints;
- gdbarch_has_shared_address_space_ftype *has_shared_address_space;
-@@ -423,6 +433,16 @@ struct gdbarch startup_gdbarch =
- 0, /* get_siginfo_type */
- 0, /* record_special_symbol */
- 0, /* get_syscall_number */
-+ 0, /* stap_integer_prefix */
-+ 0, /* stap_integer_sufix */
-+ 0, /* stap_register_prefix */
-+ 0, /* stap_register_sufix */
-+ 0, /* stap_register_indirection_prefix */
-+ 0, /* stap_register_indirection_sufix */
-+ 0, /* stap_gdb_register_prefix */
-+ 0, /* stap_gdb_register_sufix */
-+ 0, /* stap_is_single_operand */
-+ 0, /* stap_parse_special_token */
- 0, /* has_global_solist */
- 0, /* has_global_breakpoints */
- default_has_shared_address_space, /* has_shared_address_space */
-@@ -715,6 +735,16 @@ verify_gdbarch (struct gdbarch *gdbarch)
- /* Skip verify of get_siginfo_type, has predicate. */
- /* Skip verify of record_special_symbol, has predicate. */
- /* Skip verify of get_syscall_number, has predicate. */
-+ /* Skip verify of stap_integer_prefix, invalid_p == 0 */
-+ /* Skip verify of stap_integer_sufix, invalid_p == 0 */
-+ /* Skip verify of stap_register_prefix, invalid_p == 0 */
-+ /* Skip verify of stap_register_sufix, invalid_p == 0 */
-+ /* Skip verify of stap_register_indirection_prefix, invalid_p == 0 */
-+ /* Skip verify of stap_register_indirection_sufix, invalid_p == 0 */
-+ /* Skip verify of stap_gdb_register_prefix, invalid_p == 0 */
-+ /* Skip verify of stap_gdb_register_sufix, invalid_p == 0 */
-+ /* Skip verify of stap_is_single_operand, has predicate. */
-+ /* Skip verify of stap_parse_special_token, has predicate. */
- /* Skip verify of has_global_solist, invalid_p == 0 */
- /* Skip verify of has_global_breakpoints, invalid_p == 0 */
- /* Skip verify of has_shared_address_space, invalid_p == 0 */
-@@ -1267,6 +1297,42 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
- "gdbarch_dump: stabs_argument_has_addr = <%s>\n",
- host_address_to_string (gdbarch->stabs_argument_has_addr));
- fprintf_unfiltered (file,
-+ "gdbarch_dump: stap_gdb_register_prefix = %s\n",
-+ gdbarch->stap_gdb_register_prefix);
-+ fprintf_unfiltered (file,
-+ "gdbarch_dump: stap_gdb_register_sufix = %s\n",
-+ gdbarch->stap_gdb_register_sufix);
-+ fprintf_unfiltered (file,
-+ "gdbarch_dump: stap_integer_prefix = %s\n",
-+ gdbarch->stap_integer_prefix);
-+ fprintf_unfiltered (file,
-+ "gdbarch_dump: stap_integer_sufix = %s\n",
-+ gdbarch->stap_integer_sufix);
-+ fprintf_unfiltered (file,
-+ "gdbarch_dump: gdbarch_stap_is_single_operand_p() = %d\n",
-+ gdbarch_stap_is_single_operand_p (gdbarch));
-+ fprintf_unfiltered (file,
-+ "gdbarch_dump: stap_is_single_operand = <%s>\n",
-+ host_address_to_string (gdbarch->stap_is_single_operand));
-+ fprintf_unfiltered (file,
-+ "gdbarch_dump: gdbarch_stap_parse_special_token_p() = %d\n",
-+ gdbarch_stap_parse_special_token_p (gdbarch));
-+ fprintf_unfiltered (file,
-+ "gdbarch_dump: stap_parse_special_token = <%s>\n",
-+ host_address_to_string (gdbarch->stap_parse_special_token));
-+ fprintf_unfiltered (file,
-+ "gdbarch_dump: stap_register_indirection_prefix = %s\n",
-+ gdbarch->stap_register_indirection_prefix);
-+ fprintf_unfiltered (file,
-+ "gdbarch_dump: stap_register_indirection_sufix = %s\n",
-+ gdbarch->stap_register_indirection_sufix);
-+ fprintf_unfiltered (file,
-+ "gdbarch_dump: stap_register_prefix = %s\n",
-+ gdbarch->stap_register_prefix);
-+ fprintf_unfiltered (file,
-+ "gdbarch_dump: stap_register_sufix = %s\n",
-+ gdbarch->stap_register_sufix);
-+ fprintf_unfiltered (file,
- "gdbarch_dump: gdbarch_static_transform_name_p() = %d\n",
- gdbarch_static_transform_name_p (gdbarch));
- fprintf_unfiltered (file,
-@@ -3834,6 +3900,190 @@ set_gdbarch_get_syscall_number (struct gdbarch *gdbarch,
- gdbarch->get_syscall_number = get_syscall_number;
+diff --git a/gdb/gcore.c b/gdb/gcore.c
+index aedda41..a45e787 100644
+--- a/gdb/gcore.c
++++ b/gdb/gcore.c
+@@ -33,6 +33,7 @@
+ #include <fcntl.h>
+ #include "regcache.h"
+ #include "regset.h"
++#include "gdb_bfd.h"
+
+ /* The largest amount of memory to read from the target at once. We
+ must throttle it to limit the amount of memory used by GDB during
+@@ -50,7 +51,7 @@ static int gcore_memory_sections (bfd *);
+ bfd *
+ create_gcore_bfd (char *filename)
+ {
+- bfd *obfd = bfd_openw (filename, default_gcore_target ());
++ bfd *obfd = gdb_bfd_openw (filename, default_gcore_target ());
+
+ if (!obfd)
+ error (_("Failed to open '%s' for output."), filename);
+@@ -110,7 +111,7 @@ do_bfd_delete_cleanup (void *arg)
+ bfd *obfd = arg;
+ const char *filename = obfd->filename;
+
+- bfd_close (arg);
++ gdb_bfd_unref (arg);
+ unlink (filename);
}
-+const char *
-+gdbarch_stap_integer_prefix (struct gdbarch *gdbarch)
-+{
-+ gdb_assert (gdbarch != NULL);
-+ /* Skip verify of stap_integer_prefix, invalid_p == 0 */
-+ if (gdbarch_debug >= 2)
-+ fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_integer_prefix called\n");
-+ return gdbarch->stap_integer_prefix;
-+}
+@@ -154,7 +155,7 @@ gcore_command (char *args, int from_tty)
+ fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename);
+
+ discard_cleanups (old_chain);
+- bfd_close (obfd);
++ gdb_bfd_unref (obfd);
+ }
+
+ static unsigned long
+diff --git a/gdb/gdb-gdb.gdb.in b/gdb/gdb-gdb.gdb.in
+index ffb7f53..a2e7e94 100644
+--- a/gdb/gdb-gdb.gdb.in
++++ b/gdb/gdb-gdb.gdb.in
+@@ -1,5 +1,15 @@
+ echo Setting up the environment for debugging gdb.\n
+
++# Set up the Python library and "require" command.
++python
++from os.path import abspath
++gdb.datadir = abspath ('@srcdir@/python/lib')
++gdb.pythonlibdir = gdb.datadir
++gdb.__path__ = [gdb.datadir + '/gdb']
++sys.path.insert(0, gdb.datadir)
++end
++source @srcdir@/python/lib/gdb/__init__.py
+
-+void
-+set_gdbarch_stap_integer_prefix (struct gdbarch *gdbarch,
-+ const char * stap_integer_prefix)
-+{
-+ gdbarch->stap_integer_prefix = stap_integer_prefix;
-+}
+ set complaints 1
+
+ b internal_error
+diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c
+new file mode 100644
+index 0000000..fac8776
+--- /dev/null
++++ b/gdb/gdb_bfd.c
+@@ -0,0 +1,670 @@
++/* Definitions for BFD wrappers used by GDB.
+
-+const char *
-+gdbarch_stap_integer_sufix (struct gdbarch *gdbarch)
-+{
-+ gdb_assert (gdbarch != NULL);
-+ /* Skip verify of stap_integer_sufix, invalid_p == 0 */
-+ if (gdbarch_debug >= 2)
-+ fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_integer_sufix called\n");
-+ return gdbarch->stap_integer_sufix;
-+}
++ Copyright (C) 2011, 2012
++ Free Software Foundation, Inc.
+
-+void
-+set_gdbarch_stap_integer_sufix (struct gdbarch *gdbarch,
-+ const char * stap_integer_sufix)
-+{
-+ gdbarch->stap_integer_sufix = stap_integer_sufix;
-+}
++ This file is part of GDB.
+
-+const char *
-+gdbarch_stap_register_prefix (struct gdbarch *gdbarch)
-+{
-+ gdb_assert (gdbarch != NULL);
-+ /* Skip verify of stap_register_prefix, invalid_p == 0 */
-+ if (gdbarch_debug >= 2)
-+ fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_prefix called\n");
-+ return gdbarch->stap_register_prefix;
-+}
++ 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.
+
-+void
-+set_gdbarch_stap_register_prefix (struct gdbarch *gdbarch,
-+ const char * stap_register_prefix)
-+{
-+ gdbarch->stap_register_prefix = stap_register_prefix;
-+}
++ 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.
+
-+const char *
-+gdbarch_stap_register_sufix (struct gdbarch *gdbarch)
-+{
-+ gdb_assert (gdbarch != NULL);
-+ /* Skip verify of stap_register_sufix, invalid_p == 0 */
-+ if (gdbarch_debug >= 2)
-+ fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_sufix called\n");
-+ return gdbarch->stap_register_sufix;
-+}
++ You should have received a copy of the GNU General Public License
++ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
-+void
-+set_gdbarch_stap_register_sufix (struct gdbarch *gdbarch,
-+ const char * stap_register_sufix)
-+{
-+ gdbarch->stap_register_sufix = stap_register_sufix;
-+}
++#include "defs.h"
++#include "gdb_bfd.h"
++#include "gdb_assert.h"
++#include "gdb_string.h"
++#include "ui-out.h"
++#include "gdbcmd.h"
++#include "hashtab.h"
++#ifdef HAVE_ZLIB_H
++#include <zlib.h>
++#endif
++#ifdef HAVE_MMAP
++#include <sys/mman.h>
++#ifndef MAP_FAILED
++#define MAP_FAILED ((void *) -1)
++#endif
++#endif
+
-+const char *
-+gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch)
-+{
-+ gdb_assert (gdbarch != NULL);
-+ /* Skip verify of stap_register_indirection_prefix, invalid_p == 0 */
-+ if (gdbarch_debug >= 2)
-+ fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_indirection_prefix called\n");
-+ return gdbarch->stap_register_indirection_prefix;
-+}
++/* An object of this type is stored in the section's user data when
++ mapping a section. */
+
-+void
-+set_gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch,
-+ const char * stap_register_indirection_prefix)
++struct gdb_bfd_section_data
+{
-+ gdbarch->stap_register_indirection_prefix = stap_register_indirection_prefix;
-+}
++ /* Size of the data. */
++ bfd_size_type size;
++ /* If the data was mmapped, this is the length of the map. */
++ bfd_size_type map_len;
++ /* The data. If NULL, the section data has not been read. */
++ void *data;
++ /* If the data was mmapped, this is the map address. */
++ void *map_addr;
++};
+
-+const char *
-+gdbarch_stap_register_indirection_sufix (struct gdbarch *gdbarch)
-+{
-+ gdb_assert (gdbarch != NULL);
-+ /* Skip verify of stap_register_indirection_sufix, invalid_p == 0 */
-+ if (gdbarch_debug >= 2)
-+ fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_indirection_sufix called\n");
-+ return gdbarch->stap_register_indirection_sufix;
-+}
++/* A hash table holding every BFD that gdb knows about. This is not
++ to be confused with 'gdb_bfd_cache', which is used for sharing
++ BFDs; in contrast, this hash is used just to implement
++ "maint info bfd". */
+
-+void
-+set_gdbarch_stap_register_indirection_sufix (struct gdbarch *gdbarch,
-+ const char * stap_register_indirection_sufix)
-+{
-+ gdbarch->stap_register_indirection_sufix = stap_register_indirection_sufix;
-+}
++static htab_t all_bfds;
+
-+const char *
-+gdbarch_stap_gdb_register_prefix (struct gdbarch *gdbarch)
-+{
-+ gdb_assert (gdbarch != NULL);
-+ /* Skip verify of stap_gdb_register_prefix, invalid_p == 0 */
-+ if (gdbarch_debug >= 2)
-+ fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_gdb_register_prefix called\n");
-+ return gdbarch->stap_gdb_register_prefix;
-+}
++/* See gdb_bfd.h. */
+
+void
-+set_gdbarch_stap_gdb_register_prefix (struct gdbarch *gdbarch,
-+ const char * stap_gdb_register_prefix)
++gdb_bfd_stash_filename (struct bfd *abfd)
+{
-+ gdbarch->stap_gdb_register_prefix = stap_gdb_register_prefix;
-+}
++ char *name = bfd_get_filename (abfd);
++ char *data;
+
-+const char *
-+gdbarch_stap_gdb_register_sufix (struct gdbarch *gdbarch)
-+{
-+ gdb_assert (gdbarch != NULL);
-+ /* Skip verify of stap_gdb_register_sufix, invalid_p == 0 */
-+ if (gdbarch_debug >= 2)
-+ fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_gdb_register_sufix called\n");
-+ return gdbarch->stap_gdb_register_sufix;
-+}
++ data = bfd_alloc (abfd, strlen (name) + 1);
++ strcpy (data, name);
+
-+void
-+set_gdbarch_stap_gdb_register_sufix (struct gdbarch *gdbarch,
-+ const char * stap_gdb_register_sufix)
-+{
-+ gdbarch->stap_gdb_register_sufix = stap_gdb_register_sufix;
++ /* Unwarranted chumminess with BFD. */
++ abfd->filename = data;
+}
+
-+int
-+gdbarch_stap_is_single_operand_p (struct gdbarch *gdbarch)
-+{
-+ gdb_assert (gdbarch != NULL);
-+ return gdbarch->stap_is_single_operand != NULL;
-+}
++/* An object of this type is stored in each BFD's user data. */
+
-+int
-+gdbarch_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
++struct gdb_bfd_data
+{
-+ gdb_assert (gdbarch != NULL);
-+ gdb_assert (gdbarch->stap_is_single_operand != NULL);
-+ if (gdbarch_debug >= 2)
-+ fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_is_single_operand called\n");
-+ return gdbarch->stap_is_single_operand (gdbarch, s);
-+}
++ /* The reference count. */
++ int refc;
+
-+void
-+set_gdbarch_stap_is_single_operand (struct gdbarch *gdbarch,
-+ gdbarch_stap_is_single_operand_ftype stap_is_single_operand)
++ /* The mtime of the BFD at the point the cache entry was made. */
++ time_t mtime;
++};
++
++/* A hash table storing all the BFDs maintained in the cache. */
++
++static htab_t gdb_bfd_cache;
++
++/* The type of an object being looked up in gdb_bfd_cache. We use
++ htab's capability of storing one kind of object (BFD in this case)
++ and using a different sort of object for searching. */
++
++struct gdb_bfd_cache_search
+{
-+ gdbarch->stap_is_single_operand = stap_is_single_operand;
-+}
++ /* The filename. */
++ const char *filename;
++ /* The mtime. */
++ time_t mtime;
++};
+
-+int
-+gdbarch_stap_parse_special_token_p (struct gdbarch *gdbarch)
++/* A hash function for BFDs. */
++
++static hashval_t
++hash_bfd (const void *b)
+{
-+ gdb_assert (gdbarch != NULL);
-+ return gdbarch->stap_parse_special_token != NULL;
++ const bfd *abfd = b;
++
++ /* It is simplest to just hash the filename. */
++ return htab_hash_string (bfd_get_filename (abfd));
+}
+
-+int
-+gdbarch_stap_parse_special_token (struct gdbarch *gdbarch, struct stap_parse_info *p)
++/* An equality function for BFDs. Note that this expects the caller
++ to search using struct gdb_bfd_cache_search only, not BFDs. */
++
++static int
++eq_bfd (const void *a, const void *b)
+{
-+ gdb_assert (gdbarch != NULL);
-+ gdb_assert (gdbarch->stap_parse_special_token != NULL);
-+ if (gdbarch_debug >= 2)
-+ fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_parse_special_token called\n");
-+ return gdbarch->stap_parse_special_token (gdbarch, p);
++ const bfd *abfd = a;
++ const struct gdb_bfd_cache_search *s = b;
++ struct gdb_bfd_data *gdata = bfd_usrdata (abfd);
++
++ return (gdata->mtime == s->mtime
++ && strcmp (bfd_get_filename (abfd), s->filename) == 0);
+}
+
-+void
-+set_gdbarch_stap_parse_special_token (struct gdbarch *gdbarch,
-+ gdbarch_stap_parse_special_token_ftype stap_parse_special_token)
++/* See gdb_bfd.h. */
++
++struct bfd *
++gdb_bfd_open (const char *name, const char *target, int fd)
+{
-+ gdbarch->stap_parse_special_token = stap_parse_special_token;
-+}
++ hashval_t hash;
++ void **slot;
++ bfd *abfd;
++ struct gdb_bfd_cache_search search;
++ struct stat st;
+
- int
- gdbarch_has_global_solist (struct gdbarch *gdbarch)
- {
-diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
-index 044281c..294a63f 100644
---- a/gdb/gdbarch.h
-+++ b/gdb/gdbarch.h
-@@ -55,6 +55,7 @@ struct core_regset_section;
- struct syscall;
- struct agent_expr;
- struct axs_value;
-+struct stap_parse_info;
-
- /* The architecture associated with the connection to the target.
-
-@@ -979,6 +980,125 @@ typedef LONGEST (gdbarch_get_syscall_number_ftype) (struct gdbarch *gdbarch, pti
- extern LONGEST gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid);
- extern void set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch_get_syscall_number_ftype *get_syscall_number);
-
-+/* SystemTap related fields and functions.
-+ Prefix used to mark an integer constant on the architecture's assembly
-+ For example, on x86 integer constants are written as:
-+
-+ $10 ;; integer constant 10
-+
-+ in this case, this prefix would be the character `$'. */
++ if (gdb_bfd_cache == NULL)
++ gdb_bfd_cache = htab_create_alloc (1, hash_bfd, eq_bfd, NULL,
++ xcalloc, xfree);
+
-+extern const char * gdbarch_stap_integer_prefix (struct gdbarch *gdbarch);
-+extern void set_gdbarch_stap_integer_prefix (struct gdbarch *gdbarch, const char * stap_integer_prefix);
++ if (fd == -1)
++ {
++ fd = open (name, O_RDONLY | O_BINARY);
++ if (fd == -1)
++ {
++ bfd_set_error (bfd_error_system_call);
++ return NULL;
++ }
++ }
+
-+/* Sufix used to mark an integer constant on the architecture's assembly. */
++ search.filename = name;
++ if (fstat (fd, &st) < 0)
++ {
++ /* Weird situation here. */
++ search.mtime = 0;
++ }
++ else
++ search.mtime = st.st_mtime;
++
++ /* Note that this must compute the same result as hash_bfd. */
++ hash = htab_hash_string (name);
++ /* Note that we cannot use htab_find_slot_with_hash here, because
++ opening the BFD may fail; and this would violate hashtab
++ invariants. */
++ abfd = htab_find_with_hash (gdb_bfd_cache, &search, hash);
++ if (abfd != NULL)
++ {
++ close (fd);
++ gdb_bfd_ref (abfd);
++ return abfd;
++ }
+
-+extern const char * gdbarch_stap_integer_sufix (struct gdbarch *gdbarch);
-+extern void set_gdbarch_stap_integer_sufix (struct gdbarch *gdbarch, const char * stap_integer_sufix);
++ abfd = bfd_fopen (name, target, FOPEN_RB, fd);
++ if (abfd == NULL)
++ return NULL;
+
-+/* Prefix used to mark a register name on the architecture's assembly.
-+ For example, on x86 the register name is written as:
-+
-+ %eax ;; register eax
-+
-+ in this case, this prefix would be the character `%'. */
++ slot = htab_find_slot_with_hash (gdb_bfd_cache, &search, hash, INSERT);
++ gdb_assert (!*slot);
++ *slot = abfd;
+
-+extern const char * gdbarch_stap_register_prefix (struct gdbarch *gdbarch);
-+extern void set_gdbarch_stap_register_prefix (struct gdbarch *gdbarch, const char * stap_register_prefix);
++ gdb_bfd_stash_filename (abfd);
++ gdb_bfd_ref (abfd);
++ return abfd;
++}
+
-+/* Sufix used to mark a register name on the architecture's assembly */
++/* A helper function that releases any section data attached to the
++ BFD. */
+
-+extern const char * gdbarch_stap_register_sufix (struct gdbarch *gdbarch);
-+extern void set_gdbarch_stap_register_sufix (struct gdbarch *gdbarch, const char * stap_register_sufix);
++static void
++free_one_bfd_section (bfd *abfd, asection *sectp, void *ignore)
++{
++ struct gdb_bfd_section_data *sect = bfd_get_section_userdata (abfd, sectp);
+
-+/* Prefix used to mark a register indirection on the architecture's assembly.
-+ For example, on x86 the register indirection is written as:
-+
-+ (%eax) ;; indirecting eax
-+
-+ in this case, this prefix would be the charater `('.
-+
-+ Please note that we use the indirection prefix also for register
-+ displacement, e.g., `4(%eax)' on x86. */
++ if (sect != NULL && sect->data != NULL)
++ {
++#ifdef HAVE_MMAP
++ if (sect->map_addr != NULL)
++ {
++ int res;
+
-+extern const char * gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch);
-+extern void set_gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch, const char * stap_register_indirection_prefix);
++ res = munmap (sect->map_addr, sect->map_len);
++ gdb_assert (res == 0);
++ }
++ else
++#endif
++ xfree (sect->data);
++ }
++}
+
-+/* Sufix used to mark a register indirection on the architecture's assembly.
-+ For example, on x86 the register indirection is written as:
-+
-+ (%eax) ;; indirecting eax
-+
-+ in this case, this prefix would be the charater `)'.
-+
-+ Please note that we use the indirection sufix also for register
-+ displacement, e.g., `4(%eax)' on x86. */
++/* Close ABFD, and warn if that fails. */
+
-+extern const char * gdbarch_stap_register_indirection_sufix (struct gdbarch *gdbarch);
-+extern void set_gdbarch_stap_register_indirection_sufix (struct gdbarch *gdbarch, const char * stap_register_indirection_sufix);
++static int
++gdb_bfd_close_or_warn (struct bfd *abfd)
++{
++ int ret;
++ char *name = bfd_get_filename (abfd);
+
-+/* Prefix used to name a register using GDB's nomenclature.
-+
-+ For example, on PPC a register is represented by a number in the assembly
-+ language (e.g., `10' is the 10th general-purpose register). However,
-+ inside GDB this same register has an `r' appended to its name, so the 10th
-+ register would be represented as `r10' internally. */
++ bfd_map_over_sections (abfd, free_one_bfd_section, NULL);
+
-+extern const char * gdbarch_stap_gdb_register_prefix (struct gdbarch *gdbarch);
-+extern void set_gdbarch_stap_gdb_register_prefix (struct gdbarch *gdbarch, const char * stap_gdb_register_prefix);
++ ret = bfd_close (abfd);
+
-+/* Sufix used to name a register using GDB's nomenclature. */
++ if (!ret)
++ warning (_("cannot close \"%s\": %s"),
++ name, bfd_errmsg (bfd_get_error ()));
+
-+extern const char * gdbarch_stap_gdb_register_sufix (struct gdbarch *gdbarch);
-+extern void set_gdbarch_stap_gdb_register_sufix (struct gdbarch *gdbarch, const char * stap_gdb_register_sufix);
++ return ret;
++}
+
-+/* Check if S is a single operand.
-+
-+ Single operands can be:
-+ - Literal integers, e.g. `$10' on x86
-+ - Register access, e.g. `%eax' on x86
-+ - Register indirection, e.g. `(%eax)' on x86
-+ - Register displacement, e.g. `4(%eax)' on x86
-+
-+ This function should check for these patterns on the string
-+ and return 1 if some were found, or zero otherwise. Please try to match
-+ as much info as you can from the string, i.e., if you have to match
-+ something like `(%', do not match just the `('. */
++/* See gdb_bfd.h. */
+
-+extern int gdbarch_stap_is_single_operand_p (struct gdbarch *gdbarch);
++void
++gdb_bfd_ref (struct bfd *abfd)
++{
++ struct gdb_bfd_data *gdata;
++ void **slot;
+
-+typedef int (gdbarch_stap_is_single_operand_ftype) (struct gdbarch *gdbarch, const char *s);
-+extern int gdbarch_stap_is_single_operand (struct gdbarch *gdbarch, const char *s);
-+extern void set_gdbarch_stap_is_single_operand (struct gdbarch *gdbarch, gdbarch_stap_is_single_operand_ftype *stap_is_single_operand);
++ if (abfd == NULL)
++ return;
+
-+/* Function used to handle a "special case" in the parser.
-+
-+ A "special case" is considered to be an unknown token, i.e., a token
-+ that the parser does not know how to parse. A good example of special
-+ case would be ARM's register displacement syntax:
-+
-+ [R0, #4] ;; displacing R0 by 4
-+
-+ Since the parser assumes that a register displacement is of the form:
-+
-+ <number> <indirection_prefix> <register_name> <indirection_sufix>
-+
-+ it means that it will not be able to recognize and parse this odd syntax.
-+ Therefore, we should add a special case function that will handle this token.
-+
-+ This function should generate the proper expression form of the expression
-+ using GDB's internal expression mechanism (e.g., `write_exp_elt_opcode'
-+ and so on). It should also return 1 if the parsing was successful, or zero
-+ if the token was not recognized as a special token (in this case, returning
-+ zero means that the special parser is deferring the parsing to the generic
-+ parser), and should advance the buffer pointer (p->arg). */
-+
-+extern int gdbarch_stap_parse_special_token_p (struct gdbarch *gdbarch);
-+
-+typedef int (gdbarch_stap_parse_special_token_ftype) (struct gdbarch *gdbarch, struct stap_parse_info *p);
-+extern int gdbarch_stap_parse_special_token (struct gdbarch *gdbarch, struct stap_parse_info *p);
-+extern void set_gdbarch_stap_parse_special_token (struct gdbarch *gdbarch, gdbarch_stap_parse_special_token_ftype *stap_parse_special_token);
-+
- /* True if the list of shared libraries is one and only for all
- processes, as opposed to a list of shared libraries per inferior.
- This usually means that all processes, although may or may not share
-diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
-index 37281ba..879fab7 100755
---- a/gdb/gdbarch.sh
-+++ b/gdb/gdbarch.sh
-@@ -792,6 +792,101 @@ M:void:record_special_symbol:struct objfile *objfile, asymbol *sym:objfile, sym
- # Get architecture-specific system calls information from registers.
- M:LONGEST:get_syscall_number:ptid_t ptid:ptid
-
-+# SystemTap related fields and functions.
-+
-+# Prefix used to mark an integer constant on the architecture's assembly
-+# For example, on x86 integer constants are written as:
-+#
-+# \$10 ;; integer constant 10
-+#
-+# in this case, this prefix would be the character \`\$\'.
-+v:const char *:stap_integer_prefix:::0:0::0:gdbarch->stap_integer_prefix
++ gdata = bfd_usrdata (abfd);
+
-+# Sufix used to mark an integer constant on the architecture's assembly.
-+v:const char *:stap_integer_sufix:::0:0::0:gdbarch->stap_integer_sufix
++ if (gdata != NULL)
++ {
++ gdata->refc += 1;
++ return;
++ }
+
-+# Prefix used to mark a register name on the architecture's assembly.
-+# For example, on x86 the register name is written as:
-+#
-+# \%eax ;; register eax
-+#
-+# in this case, this prefix would be the character \`\%\'.
-+v:const char *:stap_register_prefix:::0:0::0:gdbarch->stap_register_prefix
++ gdata = bfd_zalloc (abfd, sizeof (struct gdb_bfd_data));
++ gdata->refc = 1;
++ gdata->mtime = bfd_get_mtime (abfd);
++ bfd_usrdata (abfd) = gdata;
+
-+# Sufix used to mark a register name on the architecture's assembly
-+v:const char *:stap_register_sufix:::0:0::0:gdbarch->stap_register_sufix
++ /* This is the first we've seen it, so add it to the hash table. */
++ slot = htab_find_slot (all_bfds, abfd, INSERT);
++ gdb_assert (slot && !*slot);
++ *slot = abfd;
++}
+
-+# Prefix used to mark a register indirection on the architecture's assembly.
-+# For example, on x86 the register indirection is written as:
-+#
-+# \(\%eax\) ;; indirecting eax
-+#
-+# in this case, this prefix would be the charater \`\(\'.
-+#
-+# Please note that we use the indirection prefix also for register
-+# displacement, e.g., \`4\(\%eax\)\' on x86.
-+v:const char *:stap_register_indirection_prefix:::0:0::0:gdbarch->stap_register_indirection_prefix
++/* See gdb_bfd.h. */
+
-+# Sufix used to mark a register indirection on the architecture's assembly.
-+# For example, on x86 the register indirection is written as:
-+#
-+# \(\%eax\) ;; indirecting eax
-+#
-+# in this case, this prefix would be the charater \`\)\'.
-+#
-+# Please note that we use the indirection sufix also for register
-+# displacement, e.g., \`4\(\%eax\)\' on x86.
-+v:const char *:stap_register_indirection_sufix:::0:0::0:gdbarch->stap_register_indirection_sufix
++void
++gdb_bfd_unref (struct bfd *abfd)
++{
++ struct gdb_bfd_data *gdata;
++ struct gdb_bfd_cache_search search;
++ void **slot;
+
-+# Prefix used to name a register using GDB's nomenclature.
-+#
-+# For example, on PPC a register is represented by a number in the assembly
-+# language (e.g., \`10\' is the 10th general-purpose register). However,
-+# inside GDB this same register has an \`r\' appended to its name, so the 10th
-+# register would be represented as \`r10\' internally.
-+v:const char *:stap_gdb_register_prefix:::0:0::0:gdbarch->stap_gdb_register_prefix
++ if (abfd == NULL)
++ return;
+
-+# Sufix used to name a register using GDB's nomenclature.
-+v:const char *:stap_gdb_register_sufix:::0:0::0:gdbarch->stap_gdb_register_sufix
++ gdata = bfd_usrdata (abfd);
++ gdb_assert (gdata->refc >= 1);
+
-+# Check if S is a single operand.
-+#
-+# Single operands can be:
-+# \- Literal integers, e.g. \`\$10\' on x86
-+# \- Register access, e.g. \`\%eax\' on x86
-+# \- Register indirection, e.g. \`\(\%eax\)\' on x86
-+# \- Register displacement, e.g. \`4\(\%eax\)\' on x86
-+#
-+# This function should check for these patterns on the string
-+# and return 1 if some were found, or zero otherwise. Please try to match
-+# as much info as you can from the string, i.e., if you have to match
-+# something like \`\(\%\', do not match just the \`\(\'.
-+M:int:stap_is_single_operand:const char *s:s
++ gdata->refc -= 1;
++ if (gdata->refc > 0)
++ return;
+
-+# Function used to handle a "special case" in the parser.
-+#
-+# A "special case" is considered to be an unknown token, i.e., a token
-+# that the parser does not know how to parse. A good example of special
-+# case would be ARM's register displacement syntax:
-+#
-+# [R0, #4] ;; displacing R0 by 4
-+#
-+# Since the parser assumes that a register displacement is of the form:
-+#
-+# <number> <indirection_prefix> <register_name> <indirection_sufix>
-+#
-+# it means that it will not be able to recognize and parse this odd syntax.
-+# Therefore, we should add a special case function that will handle this token.
-+#
-+# This function should generate the proper expression form of the expression
-+# using GDB\'s internal expression mechanism (e.g., \`write_exp_elt_opcode\'
-+# and so on). It should also return 1 if the parsing was successful, or zero
-+# if the token was not recognized as a special token (in this case, returning
-+# zero means that the special parser is deferring the parsing to the generic
-+# parser), and should advance the buffer pointer (p->arg).
-+M:int:stap_parse_special_token:struct stap_parse_info *p:p
-+
-+
- # True if the list of shared libraries is one and only for all
- # processes, as opposed to a list of shared libraries per inferior.
- # This usually means that all processes, although may or may not share
-@@ -954,6 +1049,7 @@ struct core_regset_section;
- struct syscall;
- struct agent_expr;
- struct axs_value;
-+struct stap_parse_info;
-
- /* The architecture associated with the connection to the target.
-
-diff --git a/gdb/gdbinit.in b/gdb/gdbinit.in
-index ffb7f53..a2e7e94 100644
---- a/gdb/gdbinit.in
-+++ b/gdb/gdbinit.in
-@@ -1,5 +1,15 @@
- echo Setting up the environment for debugging gdb.\n
-
-+# Set up the Python library and "require" command.
-+python
-+from os.path import abspath
-+gdb.datadir = abspath ('@srcdir@/python/lib')
-+gdb.pythonlibdir = gdb.datadir
-+gdb.__path__ = [gdb.datadir + '/gdb']
-+sys.path.insert(0, gdb.datadir)
-+end
-+source @srcdir@/python/lib/gdb/__init__.py
++ search.filename = bfd_get_filename (abfd);
+
- set complaints 1
-
- b internal_error
-diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
-index b09c1ec..8e0256c 100644
---- a/gdb/gdbtypes.c
-+++ b/gdb/gdbtypes.c
-@@ -37,6 +37,9 @@
- #include "gdb_assert.h"
- #include "hashtab.h"
- #include "exceptions.h"
-+#include "observer.h"
-+#include "dwarf2expr.h"
-+#include "dwarf2loc.h"
-
- /* Initialize BADNESS constants. */
-
-@@ -141,7 +144,16 @@ static void print_bit_vector (B_TYPE *, int);
- static void print_arg_types (struct field *, int, int);
- static void dump_fn_fieldlists (struct type *, int);
- static void print_cplus_stuff (struct type *, int);
-+static LONGEST type_length_get (struct type *type, struct type *target_type,
-+ int full_span);
-
-+#if 0
-+/* The hash table holding all discardable `struct type *' references. */
-+static htab_t type_discardable_table;
++ if (gdb_bfd_cache && search.filename)
++ {
++ hashval_t hash = htab_hash_string (search.filename);
++ void **slot;
+
-+/* Current type_discardable_check pass used for TYPE_DISCARDABLE_AGE. */
-+static int type_discardable_age_current;
-+#endif
-
- /* Allocate a new OBJFILE-associated type structure and fill it
- with some defaults. Space for the type structure is allocated
-@@ -172,6 +184,43 @@ alloc_type (struct objfile *objfile)
- return type;
- }
-
-+#if 0
-+/* Declare TYPE as discardable on next garbage collection by free_all_types.
-+ You must call type_mark_used during each free_all_types to protect TYPE from
-+ being deallocated. */
++ search.mtime = gdata->mtime;
++ slot = htab_find_slot_with_hash (gdb_bfd_cache, &search, hash,
++ NO_INSERT);
+
-+static void
-+set_type_as_discardable (struct type *type)
++ if (slot && *slot)
++ htab_clear_slot (gdb_bfd_cache, slot);
++ }
++
++ bfd_usrdata (abfd) = NULL; /* Paranoia. */
++
++ htab_remove_elt (all_bfds, abfd);
++
++ gdb_bfd_close_or_warn (abfd);
++}
++
++/* A helper function that returns the section data descriptor
++ associated with SECTION. If no such descriptor exists, a new one
++ is allocated and cleared. */
++
++static struct gdb_bfd_section_data *
++get_section_descriptor (asection *section)
+{
-+ void **slot;
++ struct gdb_bfd_section_data *result;
+
-+ gdb_assert (!TYPE_DISCARDABLE (type));
++ result = bfd_get_section_userdata (section->owner, section);
+
-+ TYPE_DISCARDABLE (type) = 1;
-+ TYPE_DISCARDABLE_AGE (type) = type_discardable_age_current;
++ if (result == NULL)
++ {
++ result = bfd_zalloc (section->owner, sizeof (*result));
++ bfd_set_section_userdata (section->owner, section, result);
++ }
+
-+ slot = htab_find_slot (type_discardable_table, type, INSERT);
-+ gdb_assert (!*slot);
-+ *slot = type;
++ return result;
+}
++
++/* Decompress a section that was compressed using zlib. Store the
++ decompressed buffer, and its size, in DESCRIPTOR. */
++
++static void
++zlib_decompress_section (asection *sectp,
++ struct gdb_bfd_section_data *descriptor)
++{
++ bfd *abfd = sectp->owner;
++#ifndef HAVE_ZLIB_H
++ error (_("Support for zlib-compressed data (from '%s', section '%s') "
++ "is disabled in this copy of GDB"),
++ bfd_get_filename (abfd),
++ bfd_get_section_name (sectp));
++#else
++ bfd_size_type compressed_size = bfd_get_section_size (sectp);
++ gdb_byte *compressed_buffer = xmalloc (compressed_size);
++ struct cleanup *cleanup = make_cleanup (xfree, compressed_buffer);
++ struct cleanup *inner_cleanup;
++ bfd_size_type uncompressed_size;
++ gdb_byte *uncompressed_buffer;
++ z_stream strm;
++ int rc;
++ int header_size = 12;
++ struct dwarf2_per_bfd_section *section_data;
++
++ if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
++ || bfd_bread (compressed_buffer,
++ compressed_size, abfd) != compressed_size)
++ error (_("can't read data from '%s', section '%s'"),
++ bfd_get_filename (abfd),
++ bfd_get_section_name (abfd, sectp));
++
++ /* Read the zlib header. In this case, it should be "ZLIB" followed
++ by the uncompressed section size, 8 bytes in big-endian order. */
++ if (compressed_size < header_size
++ || strncmp (compressed_buffer, "ZLIB", 4) != 0)
++ error (_("corrupt ZLIB header from '%s', section '%s'"),
++ bfd_get_filename (abfd),
++ bfd_get_section_name (abfd, sectp));
++ uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
++ uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
++ uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
++ uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
++ uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
++ uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
++ uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
++ uncompressed_size += compressed_buffer[11];
++
++ /* It is possible the section consists of several compressed
++ buffers concatenated together, so we uncompress in a loop. */
++ strm.zalloc = NULL;
++ strm.zfree = NULL;
++ strm.opaque = NULL;
++ strm.avail_in = compressed_size - header_size;
++ strm.next_in = (Bytef*) compressed_buffer + header_size;
++ strm.avail_out = uncompressed_size;
++ uncompressed_buffer = xmalloc (uncompressed_size);
++ inner_cleanup = make_cleanup (xfree, uncompressed_buffer);
++ rc = inflateInit (&strm);
++ while (strm.avail_in > 0)
++ {
++ if (rc != Z_OK)
++ error (_("setting up uncompression in '%s', section '%s': %d"),
++ bfd_get_filename (abfd),
++ bfd_get_section_name (abfd, sectp),
++ rc);
++ strm.next_out = ((Bytef*) uncompressed_buffer
++ + (uncompressed_size - strm.avail_out));
++ rc = inflate (&strm, Z_FINISH);
++ if (rc != Z_STREAM_END)
++ error (_("zlib error uncompressing from '%s', section '%s': %d"),
++ bfd_get_filename (abfd),
++ bfd_get_section_name (abfd, sectp),
++ rc);
++ rc = inflateReset (&strm);
++ }
++ rc = inflateEnd (&strm);
++ if (rc != Z_OK
++ || strm.avail_out != 0)
++ error (_("concluding uncompression in '%s', section '%s': %d"),
++ bfd_get_filename (abfd),
++ bfd_get_section_name (abfd, sectp),
++ rc);
++
++ discard_cleanups (inner_cleanup);
++ do_cleanups (cleanup);
++
++ /* Attach the data to the BFD section. */
++ descriptor->data = uncompressed_buffer;
++ descriptor->size = uncompressed_size;
+#endif
++}
+
-+/* Allocate a new type like alloc_type but preserve for it the discardability
-+ state of PARENT_TYPE. */
++/* See gdb_bfd.h. */
+
-+static struct type *
-+alloc_type_as_parent (struct type *parent_type)
++const gdb_byte *
++gdb_bfd_map_section (asection *sectp, bfd_size_type *size)
+{
-+ struct type *new_type = alloc_type_copy (parent_type);
++ bfd *abfd;
++ gdb_byte *buf, *retbuf;
++ unsigned char header[4];
++ struct gdb_bfd_section_data *descriptor;
+
-+#if 0
-+ if (TYPE_DISCARDABLE (parent_type))
-+ set_type_as_discardable (new_type);
-+#endif
++ gdb_assert ((sectp->flags & SEC_RELOC) == 0);
++ gdb_assert (size != NULL);
+
-+ return new_type;
-+}
++ abfd = sectp->owner;
+
- /* Allocate a new GDBARCH-associated type structure and fill it
- with some defaults. Space for the type structure is allocated
- on the heap. */
-@@ -297,7 +346,7 @@ make_pointer_type (struct type *type, struct type **typeptr)
-
- if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
- {
-- ntype = alloc_type_copy (type);
-+ ntype = alloc_type_as_parent (type);
- if (typeptr)
- *typeptr = ntype;
- }
-@@ -374,7 +423,7 @@ make_reference_type (struct type *type, struct type **typeptr)
-
- if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
- {
-- ntype = alloc_type_copy (type);
-+ ntype = alloc_type_as_parent (type);
- if (typeptr)
- *typeptr = ntype;
- }
-@@ -747,6 +796,7 @@ create_range_type (struct type *result_type, struct type *index_type,
- TYPE_ZALLOC (result_type, sizeof (struct range_bounds));
- TYPE_LOW_BOUND (result_type) = low_bound;
- TYPE_HIGH_BOUND (result_type) = high_bound;
-+ TYPE_BYTE_STRIDE (result_type) = 0;
-
- if (low_bound >= 0)
- TYPE_UNSIGNED (result_type) = 1;
-@@ -890,26 +940,31 @@ create_array_type (struct type *result_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)
-- TYPE_LENGTH (result_type) = 0;
-- else
-- TYPE_LENGTH (result_type) =
-- TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
- TYPE_NFIELDS (result_type) = 1;
- TYPE_FIELDS (result_type) =
- (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
- TYPE_INDEX_TYPE (result_type) = range_type;
- TYPE_VPTR_FIELDNO (result_type) = -1;
-
-- /* TYPE_FLAG_TARGET_STUB will take care of zero length arrays. */
-+ /* DWARF blocks may depend on runtime information like
-+ DW_OP_PUSH_OBJECT_ADDRESS not being available during the
-+ CREATE_ARRAY_TYPE time. */
-+ if (TYPE_RANGE_DATA (range_type)->low.kind != RANGE_BOUND_KIND_CONSTANT
-+ || TYPE_RANGE_DATA (range_type)->high.kind != RANGE_BOUND_KIND_CONSTANT
-+ || TYPE_DYNAMIC (element_type))
-+ TYPE_LENGTH (result_type) = 0;
-+ else
++ descriptor = get_section_descriptor (sectp);
++
++ /* If the data was already read for this BFD, just reuse it. */
++ if (descriptor->data != NULL)
++ goto done;
++
++ /* Check if the file has a 4-byte header indicating compression. */
++ if (bfd_get_section_size (sectp) > sizeof (header)
++ && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
++ && bfd_bread (header, sizeof (header), abfd) == sizeof (header))
+ {
-+ CHECK_TYPEDEF (element_type);
-+ TYPE_LENGTH (result_type) = type_length_get (result_type, element_type,
-+ 0);
++ /* Upon decompression, update the buffer and its size. */
++ if (strncmp (header, "ZLIB", sizeof (header)) == 0)
++ {
++ zlib_decompress_section (sectp, descriptor);
++ goto done;
++ }
+ }
- if (TYPE_LENGTH (result_type) == 0)
-- TYPE_TARGET_STUB (result_type) = 1;
++
++#ifdef HAVE_MMAP
++ {
++ /* The page size, used when mmapping. */
++ static int pagesize;
++
++ if (pagesize == 0)
++ pagesize = getpagesize ();
++
++ /* Only try to mmap sections which are large enough: we don't want
++ to waste space due to fragmentation. */
++
++ if (bfd_get_section_size (sectp) > 4 * pagesize)
++ {
++ descriptor->size = bfd_get_section_size (sectp);
++ descriptor->data = bfd_mmap (abfd, 0, descriptor->size, PROT_READ,
++ MAP_PRIVATE, sectp->filepos,
++ &descriptor->map_addr,
++ &descriptor->map_len);
++
++ if ((caddr_t)descriptor->data != MAP_FAILED)
++ {
++#if HAVE_POSIX_MADVISE
++ posix_madvise (descriptor->map_addr, descriptor->map_len,
++ POSIX_MADV_WILLNEED);
++#endif
++ goto done;
++ }
++
++ /* On failure, clear out the section data and try again. */
++ memset (descriptor, 0, sizeof (*descriptor));
++ }
++ }
++#endif /* HAVE_MMAP */
++
++ /* If we get here, we are a normal, not-compressed section. */
++
++ descriptor->size = bfd_get_section_size (sectp);
++ descriptor->data = xmalloc (descriptor->size);
++
++ if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
++ || bfd_bread (descriptor->data, bfd_get_section_size (sectp),
++ abfd) != bfd_get_section_size (sectp))
+ {
-+ /* The real size will be computed for specific instances by
-+ CHECK_TYPEDEF. */
-+ TYPE_TARGET_STUB (result_type) = 1;
++ xfree (descriptor->data);
++ descriptor->data = NULL;
++ error (_("Can't read data for section '%s'"),
++ bfd_get_filename (abfd));
+ }
-
- return result_type;
- }
-@@ -1438,6 +1493,105 @@ stub_noname_complaint (void)
- complaint (&symfile_complaints, _("stub type has NULL name"));
- }
-
-+/* 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 possible padding of the last element - it may differ from the
-+ cleared FULL_SPAN return value (the expected SIZEOF) for non-zero
-+ TYPE_BYTE_STRIDE values. */
++ done:
++ gdb_assert (descriptor->data != NULL);
++ *size = descriptor->size;
++ return descriptor->data;
++}
+
-+static LONGEST
-+type_length_get (struct type *type, struct type *target_type, int full_span)
++\f
++
++/* See gdb_bfd.h. */
++
++bfd *
++gdb_bfd_fopen (const char *filename, const char *target, const char *mode,
++ int fd)
+{
-+ struct type *range_type;
-+ LONGEST byte_stride = 0; /* `= 0' for a false GCC warning. */
-+ LONGEST count, element_size, retval;
++ bfd *result = bfd_fopen (filename, target, mode, fd);
+
-+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY
-+ && TYPE_CODE (type) != TYPE_CODE_STRING)
-+ return TYPE_LENGTH (type);
-+
-+ /* Avoid executing TYPE_HIGH_BOUND for invalid (unallocated/unassociated)
-+ Fortran arrays. The allocated data will never be used so they can be
-+ zero-length. */
-+ if (object_address_data_not_valid (type))
-+ return 0;
-+
-+ range_type = TYPE_INDEX_TYPE (type);
-+ if (TYPE_LOW_BOUND_UNDEFINED (range_type)
-+ || TYPE_HIGH_BOUND_UNDEFINED (range_type))
-+ return 0;
-+ count = TYPE_HIGH_BOUND (range_type) - TYPE_LOW_BOUND (range_type) + 1;
-+ /* It may happen for wrong DWARF annotations returning garbage data. */
-+ if (count < 0)
-+ warning (_("Range for type %s has invalid bounds %s..%s"),
-+ TYPE_ERROR_NAME (type), plongest (TYPE_LOW_BOUND (range_type)),
-+ plongest (TYPE_HIGH_BOUND (range_type)));
-+ /* The code below does not handle count == 0 right. */
-+ if (count <= 0)
-+ return 0;
-+ if (full_span || count > 1)
++ if (result)
+ {
-+ /* 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);
-+ }
++ gdb_bfd_stash_filename (result);
++ gdb_bfd_ref (result);
+ }
+
-+ /* For now, we conservatively take the array length to be 0 if its length
-+ exceeds UINT_MAX. The code below assumes that for x < 0,
-+ (ULONGEST) x == -x + ULONGEST_MAX + 1, which is technically not guaranteed
-+ by C, but is usually true (because it would be true if x were unsigned
-+ with its high-order bit on). It uses the fact that high_bound-low_bound is
-+ always representable in ULONGEST and that if high_bound-low_bound+1
-+ overflows, it overflows to 0. We must change these tests if we decide to
-+ increase the representation of TYPE_LENGTH from unsigned int to ULONGEST.
-+ */
++ return result;
++}
+
-+ if (full_span)
++/* See gdb_bfd.h. */
++
++bfd *
++gdb_bfd_openr (const char *filename, const char *target)
++{
++ bfd *result = bfd_openr (filename, target);
++
++ if (result)
+ {
-+ retval = count * byte_stride;
-+ if (count == 0 || retval / count != byte_stride || retval > UINT_MAX)
-+ retval = 0;
-+ return retval;
++ gdb_bfd_stash_filename (result);
++ gdb_bfd_ref (result);
+ }
-+ if (target_type == NULL)
-+ target_type = check_typedef (TYPE_TARGET_TYPE (type));
-+ element_size = type_length_get (target_type, NULL, 1);
-+ retval = (count - 1) * byte_stride + element_size;
-+ if (retval < element_size
-+ || (byte_stride != 0
-+ && (retval - element_size) / byte_stride != count - 1)
-+ || retval > UINT_MAX)
-+ retval = 0;
-+ return retval;
++
++ return result;
+}
+
-+/* Prepare TYPE after being read in by the backend. Currently this function
-+ only propagates the TYPE_DYNAMIC flag. */
++/* See gdb_bfd.h. */
+
-+void
-+finalize_type (struct type *type)
++bfd *
++gdb_bfd_openw (const char *filename, const char *target)
+{
-+ int i;
++ bfd *result = bfd_openw (filename, target);
+
-+ for (i = 0; i < TYPE_NFIELDS (type); ++i)
-+ if (TYPE_FIELD_TYPE (type, i) && TYPE_DYNAMIC (TYPE_FIELD_TYPE (type, i)))
-+ break;
++ if (result)
++ {
++ gdb_bfd_stash_filename (result);
++ gdb_bfd_ref (result);
++ }
+
-+ /* FIXME: cplus_stuff is ignored here. */
-+ if (i < TYPE_NFIELDS (type)
-+ || (TYPE_VPTR_BASETYPE (type) && TYPE_DYNAMIC (TYPE_VPTR_BASETYPE (type)))
-+ || (TYPE_TARGET_TYPE (type) && TYPE_DYNAMIC (TYPE_TARGET_TYPE (type))))
-+ TYPE_DYNAMIC (type) = 1;
++ return result;
+}
+
- /* Find the real type of TYPE. This function returns the real type,
- after removing all layers of typedefs, and completing opaque or stub
- types. Completion changes the TYPE argument, but stripping of
-@@ -1604,52 +1758,37 @@ check_typedef (struct type *type)
- }
- }
-
-- if (TYPE_TARGET_STUB (type))
-+ /* copy_type_recursive automatically makes the resulting type containing only
-+ constant values expected by the callers of this function. */
-+ if (TYPE_DYNAMIC (type))
++/* See gdb_bfd.h. */
++
++bfd *
++gdb_bfd_openr_iovec (const char *filename, const char *target,
++ void *(*open_func) (struct bfd *nbfd,
++ void *open_closure),
++ void *open_closure,
++ file_ptr (*pread_func) (struct bfd *nbfd,
++ void *stream,
++ void *buf,
++ file_ptr nbytes,
++ file_ptr offset),
++ int (*close_func) (struct bfd *nbfd,
++ void *stream),
++ int (*stat_func) (struct bfd *abfd,
++ void *stream,
++ struct stat *sb))
++{
++ bfd *result = bfd_openr_iovec (filename, target,
++ open_func, open_closure,
++ pread_func, close_func, stat_func);
++
++ if (result)
+ {
-+ htab_t copied_types;
++ gdb_bfd_ref (result);
++ gdb_bfd_stash_filename (result);
++ }
+
-+ copied_types = create_copied_types_hash (NULL);
-+ type = copy_type_recursive (type, copied_types);
-+ htab_delete (copied_types);
++ return result;
++}
+
-+ gdb_assert (TYPE_DYNAMIC (type) == 0);
-+ /* Force TYPE_LENGTH (type) recalculation. */
-+ TYPE_DYNAMIC (type) = 1;
-+ }
++/* See gdb_bfd.h. */
+
-+ if (TYPE_TARGET_STUB (type) || TYPE_DYNAMIC (type))
- {
-- struct type *range_type;
- struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
-
-+ if (TYPE_DYNAMIC (type))
-+ TYPE_TARGET_TYPE (type) = target_type;
- if (TYPE_STUB (target_type) || TYPE_TARGET_STUB (target_type))
- {
- /* Nothing we can do. */
- }
- else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
-- && TYPE_NFIELDS (type) == 1
-- && (TYPE_CODE (range_type = TYPE_INDEX_TYPE (type))
-- == TYPE_CODE_RANGE))
-+ || TYPE_CODE (type) == TYPE_CODE_STRING)
- {
- /* 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 LONGEST low_bound = TYPE_LOW_BOUND (range_type);
-- const LONGEST high_bound = TYPE_HIGH_BOUND (range_type);
-- ULONGEST len;
--
-- if (high_bound < low_bound)
-- len = 0;
-- else
-- {
-- /* For now, we conservatively take the array length to be 0
-- if its length exceeds UINT_MAX. The code below assumes
-- that for x < 0, (ULONGEST) x == -x + ULONGEST_MAX + 1,
-- which is technically not guaranteed by C, but is usually true
-- (because it would be true if x were unsigned with its
-- high-order bit on). It uses the fact that
-- high_bound-low_bound is always representable in
-- ULONGEST and that if high_bound-low_bound+1 overflows,
-- it overflows to 0. We must change these tests if we
-- decide to increase the representation of TYPE_LENGTH
-- from unsigned int to ULONGEST. */
-- ULONGEST ulow = low_bound, uhigh = high_bound;
-- ULONGEST tlen = TYPE_LENGTH (target_type);
--
-- len = tlen * (uhigh - ulow + 1);
-- if (tlen == 0 || (len / tlen - 1 + ulow) != uhigh
-- || len > UINT_MAX)
-- len = 0;
-- }
-- TYPE_LENGTH (type) = len;
-+ number of elements and the target type's length. */
-+ TYPE_LENGTH (type) = type_length_get (type, target_type, 0);
- TYPE_TARGET_STUB (type) = 0;
- }
- else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
-@@ -1657,6 +1796,7 @@ check_typedef (struct type *type)
- TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
- TYPE_TARGET_STUB (type) = 0;
- }
-+ TYPE_DYNAMIC (type) = 0;
- }
-
- type = make_qualified_type (type, instance_flags, NULL);
-@@ -3310,33 +3450,42 @@ type_pair_eq (const void *item_lhs, const void *item_rhs)
- }
-
- /* Allocate the hash table used by copy_type_recursive to walk
-- types without duplicates. We use OBJFILE's obstack, because
-- OBJFILE is about to be deleted. */
-+ types without duplicates. */
-
- htab_t
- create_copied_types_hash (struct objfile *objfile)
- {
-- return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq,
-- NULL, &objfile->objfile_obstack,
-- hashtab_obstack_allocate,
-- dummy_obstack_deallocate);
-+ if (objfile == NULL)
++bfd *
++gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous)
++{
++ bfd *result = bfd_openr_next_archived_file (archive, previous);
++
++ if (result)
+ {
-+ /* NULL OBJFILE is for TYPE_DYNAMIC types already contained in
-+ OBJFILE_MALLOC memory, such as those from VALUE_HISTORY_CHAIN. Table
-+ element entries get allocated by xmalloc - so use xfree. */
-+ return htab_create (1, type_pair_hash, type_pair_eq, xfree);
++ gdb_bfd_ref (result);
++ /* No need to stash the filename here. */
+ }
-+ else
++
++ return result;
++}
++
++/* See gdb_bfd.h. */
++
++bfd *
++gdb_bfd_fdopenr (const char *filename, const char *target, int fd)
++{
++ bfd *result = bfd_fdopenr (filename, target, fd);
++
++ if (result)
+ {
-+ /* Use OBJFILE's obstack, because OBJFILE is about to be deleted. Table
-+ element entries get allocated by xmalloc - so use xfree. */
-+ return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq,
-+ xfree, &objfile->objfile_obstack,
-+ hashtab_obstack_allocate,
-+ dummy_obstack_deallocate);
++ gdb_bfd_ref (result);
++ gdb_bfd_stash_filename (result);
+ }
- }
-
--/* Recursively copy (deep copy) TYPE, if it is associated with
-- OBJFILE. Return a new type allocated using malloc, a saved type if
-- we have already visited TYPE (using COPIED_TYPES), or TYPE if it is
-- not associated with OBJFILE. */
-+/* A helper for copy_type_recursive. This does all the work. OBJFILE is used
-+ only for an assertion checking. */
-
--struct type *
--copy_type_recursive (struct objfile *objfile,
-- struct type *type,
-- htab_t copied_types)
-+static struct type *
-+copy_type_recursive_1 (struct objfile *objfile,
-+ struct type *type,
-+ htab_t copied_types)
- {
- struct type_pair *stored, pair;
- void **slot;
- struct type *new_type;
-
-- if (! TYPE_OBJFILE_OWNED (type))
-+ if (! TYPE_OBJFILE_OWNED (type) && !TYPE_DYNAMIC (type))
- return type;
-
- /* This type shouldn't be pointing to any types in other objfiles;
-@@ -3351,9 +3500,10 @@ copy_type_recursive (struct objfile *objfile,
- new_type = alloc_type_arch (get_type_arch (type));
-
- /* We must add the new type to the hash table immediately, in case
-- we encounter this type again during a recursive call below. */
-- stored
-- = obstack_alloc (&objfile->objfile_obstack, sizeof (struct type_pair));
-+ we encounter this type again during a recursive call below. Memory could
-+ be allocated from OBJFILE in the case we will be removing OBJFILE, this
-+ optimization is missed and xfree is called for it from COPIED_TYPES. */
-+ stored = xmalloc (sizeof (*stored));
- stored->old = type;
- stored->new = new_type;
- *slot = stored;
-@@ -3364,6 +3514,21 @@ copy_type_recursive (struct objfile *objfile,
- TYPE_OBJFILE_OWNED (new_type) = 0;
- TYPE_OWNER (new_type).gdbarch = get_type_arch (type);
-
-+#if 0
-+ /* TYPE_MAIN_TYPE memory copy above rewrote the TYPE_DISCARDABLE flag so we
-+ need to initialize it again. And even if TYPE was already discardable
-+ NEW_TYPE so far is not registered in TYPE_DISCARDABLE_TABLE. */
-+ TYPE_DISCARDABLE (new_type) = 0;
-+ set_type_as_discardable (new_type);
-+#endif
+
-+ /* Pre-clear the fields processed by delete_main_type. If DWARF block
-+ evaluations below call error we would leave an unfreeable TYPE. */
-+ TYPE_TARGET_TYPE (new_type) = NULL;
-+ TYPE_VPTR_BASETYPE (new_type) = NULL;
-+ TYPE_NFIELDS (new_type) = 0;
-+ TYPE_FIELDS (new_type) = NULL;
++ return result;
++}
+
- if (TYPE_NAME (type))
- TYPE_NAME (new_type) = xstrdup (TYPE_NAME (type));
- if (TYPE_TAG_NAME (type))
-@@ -3372,12 +3537,48 @@ copy_type_recursive (struct objfile *objfile,
- TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type);
- TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
-
-+ if (TYPE_ALLOCATED (new_type))
-+ {
-+ gdb_assert (!TYPE_NOT_ALLOCATED (new_type));
++\f
+
-+ if (!dwarf_locexpr_baton_eval (TYPE_ALLOCATED (new_type)))
-+ TYPE_NOT_ALLOCATED (new_type) = 1;
-+ TYPE_ALLOCATED (new_type) = NULL;
-+ }
++/* A callback for htab_traverse that prints a single BFD. */
+
-+ if (TYPE_ASSOCIATED (new_type))
-+ {
-+ gdb_assert (!TYPE_NOT_ASSOCIATED (new_type));
++static int
++print_one_bfd (void **slot, void *data)
++{
++ bfd *abfd = *slot;
++ struct gdb_bfd_data *gdata = bfd_usrdata (abfd);
++ struct ui_out *uiout = data;
++ struct cleanup *inner;
+
-+ if (!dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (new_type)))
-+ TYPE_NOT_ASSOCIATED (new_type) = 1;
-+ TYPE_ASSOCIATED (new_type) = NULL;
-+ }
++ inner = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
++ ui_out_field_int (uiout, "refcount", gdata->refc);
++ ui_out_field_string (uiout, "addr", host_address_to_string (abfd));
++ ui_out_field_string (uiout, "filename", bfd_get_filename (abfd));
++ ui_out_text (uiout, "\n");
++ do_cleanups (inner);
+
-+ if (!TYPE_DATA_LOCATION_IS_ADDR (new_type)
-+ && TYPE_DATA_LOCATION_DWARF_BLOCK (new_type))
-+ {
-+ if (TYPE_NOT_ALLOCATED (new_type)
-+ || TYPE_NOT_ASSOCIATED (new_type))
-+ TYPE_DATA_LOCATION_DWARF_BLOCK (new_type) = NULL;
-+ else
-+ {
-+ TYPE_DATA_LOCATION_IS_ADDR (new_type) = 1;
-+ TYPE_DATA_LOCATION_ADDR (new_type) = dwarf_locexpr_baton_eval
-+ (TYPE_DATA_LOCATION_DWARF_BLOCK (new_type));
-+ }
-+ }
++ return 1;
++}
+
- /* Copy the fields. */
- if (TYPE_NFIELDS (type))
- {
- int i, nfields;
-
-+ /* TYPE_CODE_RANGE uses TYPE_RANGE_DATA of the union with TYPE_FIELDS. */
-+ gdb_assert (TYPE_CODE (type) != TYPE_CODE_RANGE);
++/* Implement the 'maint info bfd' command. */
+
- nfields = TYPE_NFIELDS (type);
-+ TYPE_NFIELDS (new_type) = nfields;
- TYPE_FIELDS (new_type) = XCALLOC (nfields, struct field);
- for (i = 0; i < nfields; i++)
- {
-@@ -3386,8 +3587,8 @@ copy_type_recursive (struct objfile *objfile,
- TYPE_FIELD_BITSIZE (new_type, i) = TYPE_FIELD_BITSIZE (type, i);
- if (TYPE_FIELD_TYPE (type, i))
- TYPE_FIELD_TYPE (new_type, i)
-- = copy_type_recursive (objfile, TYPE_FIELD_TYPE (type, i),
-- copied_types);
-+ = copy_type_recursive_1 (objfile, TYPE_FIELD_TYPE (type, i),
-+ copied_types);
- if (TYPE_FIELD_NAME (type, i))
- TYPE_FIELD_NAME (new_type, i) =
- xstrdup (TYPE_FIELD_NAME (type, i));
-@@ -3414,24 +3615,184 @@ copy_type_recursive (struct objfile *objfile,
- }
- }
-
-+ /* Both FIELD_LOC_KIND_DWARF_BLOCK and TYPE_RANGE_HIGH_BOUND_IS_COUNT were
-+ possibly converted. */
-+ TYPE_DYNAMIC (new_type) = 0;
++static void
++maintenance_info_bfds (char *arg, int from_tty)
++{
++ struct cleanup *cleanup;
++ struct ui_out *uiout = current_uiout;
+
- /* For range types, copy the bounds information. */
-- if (TYPE_CODE (type) == TYPE_CODE_RANGE)
-+ if (TYPE_CODE (new_type) == TYPE_CODE_RANGE)
- {
- TYPE_RANGE_DATA (new_type) = xmalloc (sizeof (struct range_bounds));
- *TYPE_RANGE_DATA (new_type) = *TYPE_RANGE_DATA (type);
++ cleanup = make_cleanup_ui_out_table_begin_end (uiout, 3, -1, "bfds");
++ ui_out_table_header (uiout, 10, ui_left, "refcount", "Refcount");
++ ui_out_table_header (uiout, 18, ui_left, "addr", "Address");
++ ui_out_table_header (uiout, 40, ui_left, "filename", "Filename");
+
-+ switch (TYPE_RANGE_DATA (new_type)->low.kind)
-+ {
-+ case RANGE_BOUND_KIND_CONSTANT:
-+ break;
-+ case RANGE_BOUND_KIND_DWARF_BLOCK:
-+ /* `struct dwarf2_locexpr_baton' is too bound to its objfile so
-+ it is expected to be made constant by CHECK_TYPEDEF.
-+ TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE.
-+ */
-+ if (TYPE_NOT_ALLOCATED (new_type) || TYPE_NOT_ASSOCIATED (new_type)
-+ || ! has_stack_frames ())
-+ {
-+ /* We should set 1 for Fortran but how to find the language? */
-+ TYPE_LOW_BOUND (new_type) = 0;
-+ TYPE_LOW_BOUND_UNDEFINED (new_type) = 1;
-+ }
-+ else
-+ {
-+ TYPE_LOW_BOUND (new_type) = dwarf_locexpr_baton_eval
-+ (TYPE_RANGE_DATA (new_type)->low.u.dwarf_block);
-+ if (TYPE_LOW_BOUND (new_type) >= 0)
-+ TYPE_UNSIGNED (new_type) = 1;
-+ }
-+ TYPE_RANGE_DATA (new_type)->low.kind = RANGE_BOUND_KIND_CONSTANT;
-+ break;
-+ case RANGE_BOUND_KIND_DWARF_LOCLIST:
-+ {
-+ CORE_ADDR addr;
++ ui_out_table_body (uiout);
++ htab_traverse (all_bfds, print_one_bfd, uiout);
+
-+ /* `struct dwarf2_loclist_baton' is too bound to its objfile so
-+ it is expected to be made constant by CHECK_TYPEDEF.
-+ TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE.
-+ */
-+ if (! TYPE_NOT_ALLOCATED (new_type)
-+ && ! TYPE_NOT_ASSOCIATED (new_type) && has_stack_frames ()
-+ && dwarf_loclist_baton_eval
-+ (TYPE_RANGE_DATA (new_type)->low.u.dwarf_loclist.loclist,
-+ TYPE_RANGE_DATA (new_type)->low.u.dwarf_loclist.type, &addr))
-+ {
-+ TYPE_LOW_BOUND (new_type) = addr;
-+ if (TYPE_LOW_BOUND (new_type) >= 0)
-+ TYPE_UNSIGNED (new_type) = 1;
-+ }
-+ else
-+ {
-+ /* We should set 1 for Fortran but how to find the language? */
-+ TYPE_LOW_BOUND (new_type) = 0;
-+ TYPE_LOW_BOUND_UNDEFINED (new_type) = 1;
-+ }
-+ TYPE_RANGE_DATA (new_type)->low.kind = RANGE_BOUND_KIND_CONSTANT;
-+ }
-+ break;
-+ }
++ do_cleanups (cleanup);
++}
+
-+ switch (TYPE_RANGE_DATA (new_type)->high.kind)
-+ {
-+ case RANGE_BOUND_KIND_CONSTANT:
-+ break;
-+ case RANGE_BOUND_KIND_DWARF_BLOCK:
-+ /* `struct dwarf2_locexpr_baton' is too bound to its objfile so
-+ it is expected to be made constant by CHECK_TYPEDEF.
-+ TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE.
-+ */
-+ if (TYPE_NOT_ALLOCATED (new_type) || TYPE_NOT_ASSOCIATED (new_type)
-+ || ! has_stack_frames ())
-+ {
-+ TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (new_type) - 1;
-+ TYPE_HIGH_BOUND_UNDEFINED (new_type) = 1;
-+ }
-+ else
-+ TYPE_HIGH_BOUND (new_type) = dwarf_locexpr_baton_eval
-+ (TYPE_RANGE_DATA (new_type)->high.u.dwarf_block);
-+ TYPE_RANGE_DATA (new_type)->high.kind = RANGE_BOUND_KIND_CONSTANT;
-+ break;
-+ case RANGE_BOUND_KIND_DWARF_LOCLIST:
-+ {
-+ CORE_ADDR addr;
++/* -Wmissing-prototypes */
++extern initialize_file_ftype _initialize_gdb_bfd;
+
-+ /* `struct dwarf2_loclist_baton' is too bound to its objfile so
-+ it is expected to be made constant by CHECK_TYPEDEF.
-+ TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE.
-+ */
-+ if (! TYPE_NOT_ALLOCATED (new_type)
-+ && ! TYPE_NOT_ASSOCIATED (new_type) && has_stack_frames ()
-+ && dwarf_loclist_baton_eval
-+ (TYPE_RANGE_DATA (new_type)->high.u.dwarf_loclist.loclist,
-+ TYPE_RANGE_DATA (new_type)->high.u.dwarf_loclist.type,
-+ &addr))
-+ TYPE_HIGH_BOUND (new_type) = addr;
-+ else
-+ {
-+ TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (new_type) - 1;
-+ TYPE_HIGH_BOUND_UNDEFINED (new_type) = 1;
-+ }
-+ TYPE_RANGE_DATA (new_type)->high.kind = RANGE_BOUND_KIND_CONSTANT;
-+ }
-+ break;
-+ }
++void
++_initialize_gdb_bfd (void)
++{
++ all_bfds = htab_create_alloc (10, htab_hash_pointer, htab_eq_pointer,
++ NULL, xcalloc, xfree);
+
-+ switch (TYPE_RANGE_DATA (new_type)->byte_stride.kind)
-+ {
-+ case RANGE_BOUND_KIND_CONSTANT:
-+ break;
-+ case RANGE_BOUND_KIND_DWARF_BLOCK:
-+ /* `struct dwarf2_locexpr_baton' is too bound to its objfile so
-+ it is expected to be made constant by CHECK_TYPEDEF.
-+ TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE.
-+ */
-+ if (TYPE_NOT_ALLOCATED (new_type) || TYPE_NOT_ASSOCIATED (new_type)
-+ || ! has_stack_frames ())
-+ TYPE_BYTE_STRIDE (new_type) = 0;
-+ else
-+ TYPE_BYTE_STRIDE (new_type) = dwarf_locexpr_baton_eval
-+ (TYPE_RANGE_DATA (new_type)->byte_stride.u.dwarf_block);
-+ TYPE_RANGE_DATA (new_type)->byte_stride.kind
-+ = RANGE_BOUND_KIND_CONSTANT;
-+ break;
-+ case RANGE_BOUND_KIND_DWARF_LOCLIST:
-+ {
-+ CORE_ADDR addr = 0;
++ add_cmd ("bfds", class_maintenance, maintenance_info_bfds, _("\
++List the BFDs that are currently open."),
++ &maintenanceinfolist);
++}
+diff --git a/gdb/gdb_bfd.h b/gdb/gdb_bfd.h
+new file mode 100644
+index 0000000..f131ba7
+--- /dev/null
++++ b/gdb/gdb_bfd.h
+@@ -0,0 +1,106 @@
++/* Definitions for BFD wrappers used by GDB.
+
-+ /* `struct dwarf2_loclist_baton' is too bound to its objfile so
-+ it is expected to be made constant by CHECK_TYPEDEF.
-+ TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE.
-+ */
-+ if (! TYPE_NOT_ALLOCATED (new_type)
-+ && ! TYPE_NOT_ASSOCIATED (new_type) && has_stack_frames ())
-+ dwarf_loclist_baton_eval
-+ (TYPE_RANGE_DATA (new_type)->byte_stride.u.dwarf_loclist.loclist,
-+ TYPE_RANGE_DATA (new_type)->byte_stride.u.dwarf_loclist.type,
-+ &addr);
-+ TYPE_BYTE_STRIDE (new_type) = addr;
-+ TYPE_RANGE_DATA (new_type)->byte_stride.kind
-+ = RANGE_BOUND_KIND_CONSTANT;
-+ }
-+ break;
-+ }
++ Copyright (C) 2011, 2012
++ Free Software Foundation, Inc.
+
-+ /* Convert TYPE_RANGE_HIGH_BOUND_IS_COUNT into a regular bound. */
-+ if (TYPE_RANGE_HIGH_BOUND_IS_COUNT (new_type))
-+ {
-+ TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (new_type)
-+ + TYPE_HIGH_BOUND (new_type) - 1;
-+ TYPE_RANGE_HIGH_BOUND_IS_COUNT (new_type) = 0;
-+ }
- }
-
- /* Copy pointers to other types. */
- if (TYPE_TARGET_TYPE (type))
- TYPE_TARGET_TYPE (new_type) =
-- copy_type_recursive (objfile,
-- TYPE_TARGET_TYPE (type),
-- copied_types);
-+ copy_type_recursive_1 (objfile,
-+ TYPE_TARGET_TYPE (type),
-+ copied_types);
- if (TYPE_VPTR_BASETYPE (type))
- TYPE_VPTR_BASETYPE (new_type) =
-- copy_type_recursive (objfile,
-- TYPE_VPTR_BASETYPE (type),
-- copied_types);
-+ copy_type_recursive_1 (objfile,
-+ TYPE_VPTR_BASETYPE (type),
-+ copied_types);
++ This file is part of GDB.
+
-+ if (TYPE_CODE (new_type) == TYPE_CODE_ARRAY)
-+ {
-+ struct type *new_index_type = TYPE_INDEX_TYPE (new_type);
++ 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.
+
-+ if (TYPE_BYTE_STRIDE (new_index_type) == 0)
-+ TYPE_BYTE_STRIDE (new_index_type)
-+ = TYPE_LENGTH (TYPE_TARGET_TYPE (new_type));
-+ }
++ 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.
+
- /* Maybe copy the type_specific bits.
-
- NOTE drow/2005-12-09: We do not copy the C++-specific bits like
-@@ -3448,6 +3809,17 @@ copy_type_recursive (struct objfile *objfile,
- return new_type;
- }
-
-+/* Recursively copy (deep copy) TYPE. Return a new type allocated using
-+ malloc, a saved type if we have already visited TYPE (using COPIED_TYPES),
-+ or TYPE if it is not associated with OBJFILE. */
-+
-+struct type *
-+copy_type_recursive (struct type *type,
-+ htab_t copied_types)
-+{
-+ return copy_type_recursive_1 (TYPE_OBJFILE (type), type, copied_types);
-+}
-+
- /* Make a copy of the given TYPE, except that the pointer & reference
- types are not preserved.
-
-@@ -3470,6 +3842,201 @@ copy_type (const struct type *type)
- return new_type;
- }
-
-+#if 0
-+/* Callback type for main_type_crawl. */
-+typedef int (*main_type_crawl_iter) (struct type *type, void *data);
-+
-+/* Iterate all main_type structures reachable through any `struct type *' from
-+ TYPE. ITER will be called only for one type of each main_type, use
-+ TYPE_CHAIN traversal to find all the type instances. ITER is being called
-+ for each main_type found. ITER returns non-zero if main_type_crawl should
-+ depth-first enter the specific type. ITER must provide some detection for
-+ reentering the same main_type as this function would otherwise endlessly
-+ loop. */
-+
-+static void
-+main_type_crawl (struct type *type, main_type_crawl_iter iter, void *data)
-+{
-+ struct type *type_iter;
-+ int i;
-+
-+ if (!type)
-+ return;
-+
-+ gdb_assert (TYPE_OBJFILE (type) == NULL);
-+
-+ /* `struct cplus_struct_type' handling is unsupported by this function. */
-+ gdb_assert ((TYPE_CODE (type) != TYPE_CODE_STRUCT
-+ && TYPE_CODE (type) != TYPE_CODE_UNION)
-+ || !HAVE_CPLUS_STRUCT (type));
++ 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 (!(*iter) (type, data))
-+ return;
++#ifndef GDB_BFD_H
++#define GDB_BFD_H
+
-+ /* Iterate all the type instances of this main_type. */
-+ type_iter = type;
-+ do
-+ {
-+ gdb_assert (TYPE_MAIN_TYPE (type_iter) == TYPE_MAIN_TYPE (type));
++/* Make a copy ABFD's filename using bfd_alloc, and reassign it to the
++ BFD. This ensures that the BFD's filename has the same lifetime as
++ the BFD itself. */
+
-+ main_type_crawl (TYPE_POINTER_TYPE (type), iter, data);
-+ main_type_crawl (TYPE_REFERENCE_TYPE (type), iter, data);
++void gdb_bfd_stash_filename (struct bfd *abfd);
+
-+ type_iter = TYPE_CHAIN (type_iter);
-+ }
-+ while (type_iter != type);
++/* Open a read-only (FOPEN_RB) BFD given arguments like bfd_fopen.
++ Returns NULL on error. On success, returns a new reference to the
++ BFD, which must be freed with gdb_bfd_unref. BFDs returned by this
++ call are shared among all callers opening the same file. If FD is
++ not -1, then after this call it is owned by BFD. */
+
-+ for (i = 0; i < TYPE_NFIELDS (type); i++)
-+ main_type_crawl (TYPE_FIELD_TYPE (type, i), iter, data);
++struct bfd *gdb_bfd_open (const char *name, const char *target, int fd);
+
-+ main_type_crawl (TYPE_TARGET_TYPE (type), iter, data);
-+ main_type_crawl (TYPE_VPTR_BASETYPE (type), iter, data);
-+}
++/* Increment the reference count of ABFD. It is fine for ABFD to be
++ NULL; in this case the function does nothing. */
+
-+/* A helper for delete_type which deletes a main_type and the things to which
-+ it refers. TYPE is a type whose main_type we wish to destroy. */
++void gdb_bfd_ref (struct bfd *abfd);
+
-+static void
-+delete_main_type (struct type *type)
-+{
-+ int i;
++/* Decrement the reference count of ABFD. If this is the last
++ reference, ABFD will be freed. If ABFD is NULL, this function does
++ nothing. */
+
-+ gdb_assert (TYPE_DISCARDABLE (type));
-+ gdb_assert (TYPE_OBJFILE (type) == NULL);
++void gdb_bfd_unref (struct bfd *abfd);
+
-+ xfree (TYPE_NAME (type));
-+ xfree (TYPE_TAG_NAME (type));
++/* Try to read or map the contents of the section SECT. If
++ successful, the section data is returned and *SIZE is set to the
++ size of the section data; this may not be the same as the size
++ according to bfd_get_section_size if the section was compressed.
++ The returned section data is associated with the BFD and will be
++ destroyed when the BFD is destroyed. There is no other way to free
++ it; for temporary uses of section data, see
++ bfd_malloc_and_get_section. SECT may not have relocations. This
++ function will throw on error. */
+
-+ for (i = 0; i < TYPE_NFIELDS (type); ++i)
-+ {
-+ xfree (TYPE_FIELD_NAME (type, i));
++const gdb_byte *gdb_bfd_map_section (asection *section, bfd_size_type *size);
+
-+ if (TYPE_FIELD_LOC_KIND (type, i) == FIELD_LOC_KIND_PHYSNAME)
-+ xfree (TYPE_FIELD_STATIC_PHYSNAME (type, i));
-+ }
-+ xfree (TYPE_FIELDS (type));
++\f
+
-+ gdb_assert (!HAVE_CPLUS_STRUCT (type));
++/* A wrapper for bfd_fopen that initializes the gdb-specific reference
++ count and calls gdb_bfd_stash_filename. */
+
-+ xfree (TYPE_MAIN_TYPE (type));
-+}
++bfd *gdb_bfd_fopen (const char *, const char *, const char *, int);
+
-+/* Delete all the instances on TYPE_CHAIN of TYPE, including their referenced
-+ main_type. TYPE must be a reclaimable type - neither permanent nor objfile
-+ associated. */
++/* A wrapper for bfd_openr that initializes the gdb-specific reference
++ count and calls gdb_bfd_stash_filename. */
+
-+static void
-+delete_type_chain (struct type *type)
-+{
-+ struct type *type_iter, *type_iter_to_free;
++bfd *gdb_bfd_openr (const char *, const char *);
+
-+ gdb_assert (TYPE_DISCARDABLE (type));
-+ gdb_assert (TYPE_OBJFILE (type) == NULL);
++/* A wrapper for bfd_openw that initializes the gdb-specific reference
++ count and calls gdb_bfd_stash_filename. */
+
-+ delete_main_type (type);
++bfd *gdb_bfd_openw (const char *, const char *);
+
-+ type_iter = type;
-+ do
-+ {
-+ type_iter_to_free = type_iter;
-+ type_iter = TYPE_CHAIN (type_iter);
-+ xfree (type_iter_to_free);
-+ }
-+ while (type_iter != type);
-+}
++/* A wrapper for bfd_openr_iovec that initializes the gdb-specific
++ reference count and calls gdb_bfd_stash_filename. */
+
-+/* Hash function for type_discardable_table. */
++bfd *gdb_bfd_openr_iovec (const char *filename, const char *target,
++ void *(*open_func) (struct bfd *nbfd,
++ void *open_closure),
++ void *open_closure,
++ file_ptr (*pread_func) (struct bfd *nbfd,
++ void *stream,
++ void *buf,
++ file_ptr nbytes,
++ file_ptr offset),
++ int (*close_func) (struct bfd *nbfd,
++ void *stream),
++ int (*stat_func) (struct bfd *abfd,
++ void *stream,
++ struct stat *sb));
+
-+static hashval_t
-+type_discardable_hash (const void *p)
-+{
-+ const struct type *type = p;
++/* A wrapper for bfd_openr_next_archived_file that initializes the
++ gdb-specific reference count and calls gdb_bfd_stash_filename. */
+
-+ return htab_hash_pointer (TYPE_MAIN_TYPE (type));
-+}
++bfd *gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous);
+
-+/* Equality function for type_discardable_table. */
++/* A wrapper for bfd_fdopenr that initializes the gdb-specific
++ reference count and calls gdb_bfd_stash_filename. */
+
-+static int
-+type_discardable_equal (const void *a, const void *b)
-+{
-+ const struct type *left = a;
-+ const struct type *right = b;
++bfd *gdb_bfd_fdopenr (const char *filename, const char *target, int fd);
+
-+ return TYPE_MAIN_TYPE (left) == TYPE_MAIN_TYPE (right);
-+}
++#endif /* GDB_BFD_H */
+diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
+index 8142ab9..a2953cc 100644
+--- a/gdb/gdbtypes.c
++++ b/gdb/gdbtypes.c
+@@ -37,6 +37,9 @@
+ #include "gdb_assert.h"
+ #include "hashtab.h"
+ #include "exceptions.h"
++#include "observer.h"
++#include "dwarf2expr.h"
++#include "dwarf2loc.h"
+
+ /* Initialize BADNESS constants. */
+
+@@ -141,7 +144,16 @@ static void print_bit_vector (B_TYPE *, int);
+ static void print_arg_types (struct field *, int, int);
+ static void dump_fn_fieldlists (struct type *, int);
+ static void print_cplus_stuff (struct type *, int);
++static LONGEST type_length_get (struct type *type, struct type *target_type,
++ int full_span);
+
++#if 0
++/* The hash table holding all discardable `struct type *' references. */
++static htab_t type_discardable_table;
+
-+/* A helper for type_mark_used. */
++/* Current type_discardable_check pass used for TYPE_DISCARDABLE_AGE. */
++static int type_discardable_age_current;
++#endif
+
+ /* Allocate a new OBJFILE-associated type structure and fill it
+ with some defaults. Space for the type structure is allocated
+@@ -172,6 +184,43 @@ alloc_type (struct objfile *objfile)
+ return type;
+ }
+
++#if 0
++/* Declare TYPE as discardable on next garbage collection by free_all_types.
++ You must call type_mark_used during each free_all_types to protect TYPE from
++ being deallocated. */
+
-+static int
-+type_mark_used_crawl (struct type *type, void *unused)
++static void
++set_type_as_discardable (struct type *type)
+{
-+ if (!TYPE_DISCARDABLE (type))
-+ return 0;
++ void **slot;
+
-+ if (TYPE_DISCARDABLE_AGE (type) == type_discardable_age_current)
-+ return 0;
++ gdb_assert (!TYPE_DISCARDABLE (type));
+
++ TYPE_DISCARDABLE (type) = 1;
+ TYPE_DISCARDABLE_AGE (type) = type_discardable_age_current;
+
-+ /* Continue the traversal. */
-+ return 1;
-+}
-+
-+/* Mark TYPE and its connected types as used in this free_all_types pass. */
-+
-+void
-+type_mark_used (struct type *type)
-+{
-+ if (type == NULL)
-+ return;
-+
-+ if (!TYPE_DISCARDABLE (type))
-+ return;
-+
-+ main_type_crawl (type, type_mark_used_crawl, NULL);
++ slot = htab_find_slot (type_discardable_table, type, INSERT);
++ gdb_assert (!*slot);
++ *slot = type;
+}
++#endif
+
-+/* A traverse callback for type_discardable_table which removes any
-+ type_discardable whose reference count is now zero (unused link). */
++/* Allocate a new type like alloc_type but preserve for it the discardability
++ state of PARENT_TYPE. */
+
-+static int
-+type_discardable_remove (void **slot, void *unused)
++static struct type *
++alloc_type_as_parent (struct type *parent_type)
+{
-+ struct type *type = *slot;
-+
-+ gdb_assert (TYPE_DISCARDABLE (type));
-+
-+ if (TYPE_DISCARDABLE_AGE (type) != type_discardable_age_current)
-+ {
-+ delete_type_chain (type);
++ struct type *new_type = alloc_type_copy (parent_type);
+
-+ htab_clear_slot (type_discardable_table, slot);
-+ }
++#if 0
++ if (TYPE_DISCARDABLE (parent_type))
++ set_type_as_discardable (new_type);
++#endif
+
-+ return 1;
++ return new_type;
+}
+
-+/* Free all the reclaimable types that have been allocated and that have
-+ currently zero reference counter.
-+
-+ This function is called after each command, successful or not. Use this
-+ cleanup only in the GDB idle state as GDB only marks those types used by
-+ globally tracked objects (with no autovariable references tracking). */
-+
-+void
-+free_all_types (void)
-+{
-+ /* Mark a new pass. As GDB checks all the entries were visited after each
-+ pass there cannot be any stale entries already containing the changed
-+ value. */
-+ type_discardable_age_current ^= 1;
-+
-+ observer_notify_mark_used ();
-+
-+ htab_traverse (type_discardable_table, type_discardable_remove, NULL);
-+}
-+#endif
+ /* Allocate a new GDBARCH-associated type structure and fill it
+ with some defaults. Space for the type structure is allocated
+ on the heap. */
+@@ -297,7 +346,7 @@ make_pointer_type (struct type *type, struct type **typeptr)
- /* Helper functions to initialize architecture-specific types. */
+ if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
+ {
+- ntype = alloc_type_copy (type);
++ ntype = alloc_type_as_parent (type);
+ if (typeptr)
+ *typeptr = ntype;
+ }
+@@ -374,7 +423,7 @@ make_reference_type (struct type *type, struct type **typeptr)
-@@ -4002,6 +4569,13 @@ void
- _initialize_gdbtypes (void)
- {
- gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init);
-+
-+#if 0
-+ type_discardable_table = htab_create_alloc (20, type_discardable_hash,
-+ type_discardable_equal, NULL,
-+ xcalloc, xfree);
-+#endif
-+
- objfile_type_data = register_objfile_data ();
+ if (typeptr == 0 || *typeptr == 0) /* We'll need to allocate one. */
+ {
+- ntype = alloc_type_copy (type);
++ ntype = alloc_type_as_parent (type);
+ if (typeptr)
+ *typeptr = ntype;
+ }
+@@ -784,6 +833,7 @@ create_range_type (struct type *result_type, struct type *index_type,
+ TYPE_ZALLOC (result_type, sizeof (struct range_bounds));
+ TYPE_LOW_BOUND (result_type) = low_bound;
+ TYPE_HIGH_BOUND (result_type) = high_bound;
++ TYPE_BYTE_STRIDE (result_type) = 0;
- add_setshow_zinteger_cmd ("overload", no_class, &overload_debug,
-diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
-index 2070f00..40db606 100644
---- a/gdb/gdbtypes.h
-+++ b/gdb/gdbtypes.h
-@@ -213,6 +213,11 @@ enum type_instance_flag_value
+ if (low_bound >= 0)
+ TYPE_UNSIGNED (result_type) = 1;
+@@ -927,26 +977,31 @@ create_array_type (struct type *result_type,
- #define TYPE_TARGET_STUB(t) (TYPE_MAIN_TYPE (t)->flag_target_stub)
+ 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)
+- TYPE_LENGTH (result_type) = 0;
+- else
+- TYPE_LENGTH (result_type) =
+- TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
+ TYPE_NFIELDS (result_type) = 1;
+ TYPE_FIELDS (result_type) =
+ (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
+ TYPE_INDEX_TYPE (result_type) = range_type;
+ TYPE_VPTR_FIELDNO (result_type) = -1;
-+/* Type needs to be evaluated on each CHECK_TYPEDEF and its results must not be
-+ sticky. */
-+
-+#define TYPE_DYNAMIC(t) (TYPE_MAIN_TYPE (t)->flag_dynamic)
-+
- /* Static type. If this is set, the corresponding type had
- a static modifier.
- Note: This may be unnecessary, since static data members
-@@ -296,6 +301,50 @@ enum type_instance_flag_value
+- /* TYPE_FLAG_TARGET_STUB will take care of zero length arrays. */
++ /* DWARF blocks may depend on runtime information like
++ DW_OP_PUSH_OBJECT_ADDRESS not being available during the
++ CREATE_ARRAY_TYPE time. */
++ if (TYPE_RANGE_DATA (range_type)->low.kind != RANGE_BOUND_KIND_CONSTANT
++ || TYPE_RANGE_DATA (range_type)->high.kind != RANGE_BOUND_KIND_CONSTANT
++ || TYPE_DYNAMIC (element_type))
++ TYPE_LENGTH (result_type) = 0;
++ else
++ {
++ CHECK_TYPEDEF (element_type);
++ TYPE_LENGTH (result_type) = type_length_get (result_type, element_type,
++ 0);
++ }
+ if (TYPE_LENGTH (result_type) == 0)
+- TYPE_TARGET_STUB (result_type) = 1;
++ {
++ /* The real size will be computed for specific instances by
++ CHECK_TYPEDEF. */
++ TYPE_TARGET_STUB (result_type) = 1;
++ }
- #define TYPE_FLAG_ENUM(t) (TYPE_MAIN_TYPE (t)->flag_flag_enum)
+ return result_type;
+ }
+@@ -1468,6 +1523,105 @@ stub_noname_complaint (void)
+ complaint (&symfile_complaints, _("stub type has NULL name"));
+ }
-+#if 0
-+/* Define this type as being reclaimable during free_all_types. Type is
-+ required to be have TYPE_OBJFILE set to NULL. Setting this flag requires
-+ initializing TYPE_DISCARDABLE_AGE, see alloc_type_discardable. */
++/* Calculate the memory length of array TYPE.
+
-+#define TYPE_DISCARDABLE(t) (TYPE_MAIN_TYPE (t)->flag_discardable)
++ 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 possible padding of the last element - it may differ from the
++ cleared FULL_SPAN return value (the expected SIZEOF) for non-zero
++ TYPE_BYTE_STRIDE values. */
+
-+/* Marker this type has been visited by the type_mark_used by this
-+ mark-and-sweep types garbage collecting pass. Current pass is represented
-+ by TYPE_DISCARDABLE_AGE_CURRENT. */
++static LONGEST
++type_length_get (struct type *type, struct type *target_type, int full_span)
++{
++ struct type *range_type;
++ LONGEST byte_stride = 0; /* `= 0' for a false GCC warning. */
++ LONGEST count, element_size, retval;
+
-+#define TYPE_DISCARDABLE_AGE(t) (TYPE_MAIN_TYPE (t)->flag_discardable_age)
-+#endif
++ if (TYPE_CODE (type) != TYPE_CODE_ARRAY
++ && TYPE_CODE (type) != TYPE_CODE_STRING)
++ return TYPE_LENGTH (type);
+
-+/* Is HIGH_BOUND a low-bound relative count (1) or the high bound itself (0)? */
++ /* Avoid executing TYPE_HIGH_BOUND for invalid (unallocated/unassociated)
++ Fortran arrays. The allocated data will never be used so they can be
++ zero-length. */
++ if (object_address_data_not_valid (type))
++ return 0;
+
-+#define TYPE_RANGE_HIGH_BOUND_IS_COUNT(range_type) \
-+ (TYPE_MAIN_TYPE (range_type)->flag_range_high_bound_is_count)
++ range_type = TYPE_INDEX_TYPE (type);
++ if (TYPE_LOW_BOUND_UNDEFINED (range_type)
++ || TYPE_HIGH_BOUND_UNDEFINED (range_type))
++ return 0;
++ count = TYPE_HIGH_BOUND (range_type) - TYPE_LOW_BOUND (range_type) + 1;
++ /* It may happen for wrong DWARF annotations returning garbage data. */
++ if (count < 0)
++ warning (_("Range for type %s has invalid bounds %s..%s"),
++ TYPE_ERROR_NAME (type), plongest (TYPE_LOW_BOUND (range_type)),
++ plongest (TYPE_HIGH_BOUND (range_type)));
++ /* The code below does not handle count == 0 right. */
++ 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);
++ }
++ }
+
-+/* Not allocated. TYPE_ALLOCATED(t) must be NULL in such case. If this flag
-+ is unset and TYPE_ALLOCATED(t) is NULL then the type is allocated. If this
-+ flag is unset and TYPE_ALLOCATED(t) is not NULL then its DWARF block
-+ determines the actual allocation state. */
++ /* For now, we conservatively take the array length to be 0 if its length
++ exceeds UINT_MAX. The code below assumes that for x < 0,
++ (ULONGEST) x == -x + ULONGEST_MAX + 1, which is technically not guaranteed
++ by C, but is usually true (because it would be true if x were unsigned
++ with its high-order bit on). It uses the fact that high_bound-low_bound is
++ always representable in ULONGEST and that if high_bound-low_bound+1
++ overflows, it overflows to 0. We must change these tests if we decide to
++ increase the representation of TYPE_LENGTH from unsigned int to ULONGEST.
++ */
+
-+#define TYPE_NOT_ALLOCATED(t) (TYPE_MAIN_TYPE (t)->flag_not_allocated)
++ if (full_span)
++ {
++ retval = count * byte_stride;
++ if (count == 0 || retval / count != byte_stride || retval > UINT_MAX)
++ retval = 0;
++ return retval;
++ }
++ if (target_type == NULL)
++ target_type = check_typedef (TYPE_TARGET_TYPE (type));
++ element_size = type_length_get (target_type, NULL, 1);
++ retval = (count - 1) * byte_stride + element_size;
++ if (retval < element_size
++ || (byte_stride != 0
++ && (retval - element_size) / byte_stride != count - 1)
++ || retval > UINT_MAX)
++ retval = 0;
++ return retval;
++}
+
-+/* Not associated. TYPE_ASSOCIATED(t) must be NULL in such case. If this flag
-+ is unset and TYPE_ASSOCIATED(t) is NULL then the type is associated. If
-+ this flag is unset and TYPE_ASSOCIATED(t) is not NULL then its DWARF block
-+ determines the actual association state. */
++/* Prepare TYPE after being read in by the backend. Currently this function
++ only propagates the TYPE_DYNAMIC flag. */
+
-+#define TYPE_NOT_ASSOCIATED(t) (TYPE_MAIN_TYPE (t)->flag_not_associated)
++void
++finalize_type (struct type *type)
++{
++ int i;
+
-+/* Address of the actual data as for DW_AT_data_location. Its dwarf block must
-+ not be evaluated unless both TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are
-+ false. If TYPE_DATA_LOCATION_IS_ADDR set then TYPE_DATA_LOCATION_ADDR value
-+ is the actual data address value. If unset and
-+ TYPE_DATA_LOCATION_DWARF_BLOCK is NULL then the value is the normal
-+ value_raw_address. If unset and TYPE_DATA_LOCATION_DWARF_BLOCK is not NULL
-+ then its DWARF block determines the actual data address. */
++ for (i = 0; i < TYPE_NFIELDS (type); ++i)
++ if (TYPE_FIELD_TYPE (type, i) && TYPE_DYNAMIC (TYPE_FIELD_TYPE (type, i)))
++ break;
+
-+#define TYPE_DATA_LOCATION_IS_ADDR(t) \
-+ (TYPE_MAIN_TYPE (t)->flag_data_location_is_addr)
++ /* FIXME: cplus_stuff is ignored here. */
++ if (i < TYPE_NFIELDS (type)
++ || (TYPE_VPTR_BASETYPE (type) && TYPE_DYNAMIC (TYPE_VPTR_BASETYPE (type)))
++ || (TYPE_TARGET_TYPE (type) && TYPE_DYNAMIC (TYPE_TARGET_TYPE (type))))
++ TYPE_DYNAMIC (type) = 1;
++}
+
- /* Constant type. If this is set, the corresponding type has a
- const modifier. */
-
-@@ -405,6 +454,15 @@ struct main_type
- /* True if this type was declared with "class" rather than
- "struct". */
- unsigned int flag_declared_class : 1;
-+#if 0
-+ unsigned int flag_discardable : 1;
-+ unsigned int flag_discardable_age : 1;
-+#endif
-+ unsigned int flag_dynamic : 1;
-+ unsigned int flag_range_high_bound_is_count : 1;
-+ unsigned int flag_not_allocated : 1;
-+ unsigned int flag_not_associated : 1;
-+ unsigned int flag_data_location_is_addr : 1;
-
- /* True if this is an enum type with disjoint values. This affects
- how the enum is printed. */
-@@ -483,6 +541,20 @@ struct main_type
-
- struct type *target_type;
+ /* Find the real type of TYPE. This function returns the real type,
+ after removing all layers of typedefs, and completing opaque or stub
+ types. Completion changes the TYPE argument, but stripping of
+@@ -1634,52 +1788,37 @@ check_typedef (struct type *type)
+ }
+ }
-+ /* For DW_AT_data_location. */
-+ union
+- if (TYPE_TARGET_STUB (type))
++ /* copy_type_recursive automatically makes the resulting type containing only
++ constant values expected by the callers of this function. */
++ if (TYPE_DYNAMIC (type))
+ {
-+ struct dwarf2_locexpr_baton *dwarf_block;
-+ CORE_ADDR addr;
-+ }
-+ data_location;
++ htab_t copied_types;
+
-+ /* For DW_AT_allocated. */
-+ struct dwarf2_locexpr_baton *allocated;
++ copied_types = create_copied_types_hash (NULL);
++ type = copy_type_recursive (type, copied_types);
++ htab_delete (copied_types);
+
-+ /* For DW_AT_associated. */
-+ struct dwarf2_locexpr_baton *associated;
++ gdb_assert (TYPE_DYNAMIC (type) == 0);
++ /* Force TYPE_LENGTH (type) recalculation. */
++ TYPE_DYNAMIC (type) = 1;
++ }
+
- /* For structure and union types, a description of each field.
- For set and pascal array types, there is one "field",
- whose type is the domain type of the set or array.
-@@ -563,13 +635,34 @@ struct main_type
-
- struct range_bounds
++ if (TYPE_TARGET_STUB (type) || TYPE_DYNAMIC (type))
{
-+ struct
-+ {
-+ union
-+ {
-+ LONGEST constant;
-+ struct dwarf2_locexpr_baton *dwarf_block;
-+ struct
-+ {
-+ struct dwarf2_loclist_baton *loclist;
-+ struct type *type;
-+ }
-+ dwarf_loclist;
-+ }
-+ u;
-+ enum range_bound_kind
-+ {
-+ RANGE_BOUND_KIND_CONSTANT,
-+ RANGE_BOUND_KIND_DWARF_BLOCK,
-+ RANGE_BOUND_KIND_DWARF_LOCLIST
-+ }
-+ kind;
-+ }
- /* Low bound of range. */
--
-- LONGEST low;
+- struct type *range_type;
+ struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
+
++ if (TYPE_DYNAMIC (type))
++ TYPE_TARGET_TYPE (type) = target_type;
+ if (TYPE_STUB (target_type) || TYPE_TARGET_STUB (target_type))
+ {
+ /* Nothing we can do. */
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+- && TYPE_NFIELDS (type) == 1
+- && (TYPE_CODE (range_type = TYPE_INDEX_TYPE (type))
+- == TYPE_CODE_RANGE))
++ || TYPE_CODE (type) == TYPE_CODE_STRING)
+ {
+ /* 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 LONGEST low_bound = TYPE_LOW_BOUND (range_type);
+- const LONGEST high_bound = TYPE_HIGH_BOUND (range_type);
+- ULONGEST len;
-
-+ low,
- /* High bound of range. */
+- if (high_bound < low_bound)
+- len = 0;
+- else
+- {
+- /* For now, we conservatively take the array length to be 0
+- if its length exceeds UINT_MAX. The code below assumes
+- that for x < 0, (ULONGEST) x == -x + ULONGEST_MAX + 1,
+- which is technically not guaranteed by C, but is usually true
+- (because it would be true if x were unsigned with its
+- high-order bit on). It uses the fact that
+- high_bound-low_bound is always representable in
+- ULONGEST and that if high_bound-low_bound+1 overflows,
+- it overflows to 0. We must change these tests if we
+- decide to increase the representation of TYPE_LENGTH
+- from unsigned int to ULONGEST. */
+- ULONGEST ulow = low_bound, uhigh = high_bound;
+- ULONGEST tlen = TYPE_LENGTH (target_type);
-
-- LONGEST high;
-+ high,
-+ /* Byte stride of range. */
-+ byte_stride;
-
- /* Flags indicating whether the values of low and high are
- valid. When true, the respective range value is
-@@ -1016,9 +1109,9 @@ extern void allocate_gnat_aux_type (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, ARRAY or STRING 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
- /* Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you want the real
-@@ -1026,11 +1119,16 @@ extern void allocate_gnat_aux_type (struct type *);
- #define TYPE_CODE(thistype) TYPE_MAIN_TYPE(thistype)->code
- #define TYPE_NFIELDS(thistype) TYPE_MAIN_TYPE(thistype)->nfields
- #define TYPE_FIELDS(thistype) TYPE_MAIN_TYPE(thistype)->flds_bnds.fields
-+#define TYPE_DATA_LOCATION_DWARF_BLOCK(thistype) TYPE_MAIN_TYPE (thistype)->data_location.dwarf_block
-+#define TYPE_DATA_LOCATION_ADDR(thistype) TYPE_MAIN_TYPE (thistype)->data_location.addr
-+#define TYPE_ALLOCATED(thistype) TYPE_MAIN_TYPE (thistype)->allocated
-+#define TYPE_ASSOCIATED(thistype) TYPE_MAIN_TYPE (thistype)->associated
-
- #define TYPE_INDEX_TYPE(type) TYPE_FIELD_TYPE (type, 0)
- #define TYPE_RANGE_DATA(thistype) TYPE_MAIN_TYPE(thistype)->flds_bnds.bounds
--#define TYPE_LOW_BOUND(range_type) TYPE_RANGE_DATA(range_type)->low
--#define TYPE_HIGH_BOUND(range_type) TYPE_RANGE_DATA(range_type)->high
-+#define TYPE_LOW_BOUND(range_type) TYPE_RANGE_DATA(range_type)->low.u.constant
-+#define TYPE_HIGH_BOUND(range_type) TYPE_RANGE_DATA(range_type)->high.u.constant
-+#define TYPE_BYTE_STRIDE(range_type) TYPE_RANGE_DATA(range_type)->byte_stride.u.constant
- #define TYPE_LOW_BOUND_UNDEFINED(range_type) \
- TYPE_RANGE_DATA(range_type)->low_undefined
- #define TYPE_HIGH_BOUND_UNDEFINED(range_type) \
-@@ -1047,7 +1145,14 @@ extern void allocate_gnat_aux_type (struct type *);
- (TYPE_HIGH_BOUND(TYPE_INDEX_TYPE((arraytype))))
-
- #define TYPE_ARRAY_LOWER_BOUND_VALUE(arraytype) \
-- (TYPE_LOW_BOUND(TYPE_INDEX_TYPE((arraytype))))
-+ TYPE_LOW_BOUND (TYPE_INDEX_TYPE (arraytype))
-+
-+/* TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype)) with a fallback to the
-+ element size if no specific stride value is known. */
-+#define TYPE_ARRAY_BYTE_STRIDE_VALUE(arraytype) \
-+ (TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype)) == 0 \
-+ ? TYPE_LENGTH (TYPE_TARGET_TYPE (arraytype)) \
-+ : TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype)))
-
- /* C++ */
+- len = tlen * (uhigh - ulow + 1);
+- if (tlen == 0 || (len / tlen - 1 + ulow) != uhigh
+- || len > UINT_MAX)
+- len = 0;
+- }
+- TYPE_LENGTH (type) = len;
++ number of elements and the target type's length. */
++ TYPE_LENGTH (type) = type_length_get (type, target_type, 0);
+ TYPE_TARGET_STUB (type) = 0;
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
+@@ -1687,6 +1826,7 @@ check_typedef (struct type *type)
+ TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
+ TYPE_TARGET_STUB (type) = 0;
+ }
++ TYPE_DYNAMIC (type) = 0;
+ }
-@@ -1482,6 +1587,18 @@ extern struct type *create_array_type (struct type *, struct type *,
- struct type *);
- extern struct type *lookup_array_range_type (struct type *, int, int);
+ type = make_qualified_type (type, instance_flags, NULL);
+@@ -3345,33 +3485,42 @@ type_pair_eq (const void *item_lhs, const void *item_rhs)
+ }
-+extern CORE_ADDR type_range_any_field_internal (struct type *range_type,
-+ int fieldno);
-+
-+extern int type_range_high_bound_internal (struct type *range_type);
-+
-+extern int type_range_count_bound_internal (struct type *range_type);
-+
-+extern CORE_ADDR type_range_byte_stride_internal (struct type *range_type,
-+ struct type *element_type);
-+
-+extern void finalize_type (struct type *type);
-+
- extern struct type *create_string_type (struct type *, struct type *,
- struct type *);
- extern struct type *lookup_string_range_type (struct type *, int, int);
-@@ -1527,6 +1644,10 @@ extern int is_public_ancestor (struct type *, struct type *);
+ /* Allocate the hash table used by copy_type_recursive to walk
+- types without duplicates. We use OBJFILE's obstack, because
+- OBJFILE is about to be deleted. */
++ types without duplicates. */
- extern int is_unique_ancestor (struct type *, struct value *);
+ htab_t
+ create_copied_types_hash (struct objfile *objfile)
+ {
+- return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq,
+- NULL, &objfile->objfile_obstack,
+- hashtab_obstack_allocate,
+- dummy_obstack_deallocate);
++ if (objfile == NULL)
++ {
++ /* NULL OBJFILE is for TYPE_DYNAMIC types already contained in
++ OBJFILE_MALLOC memory, such as those from VALUE_HISTORY_CHAIN. Table
++ element entries get allocated by xmalloc - so use xfree. */
++ return htab_create (1, type_pair_hash, type_pair_eq, xfree);
++ }
++ else
++ {
++ /* Use OBJFILE's obstack, because OBJFILE is about to be deleted. Table
++ element entries get allocated by xmalloc - so use xfree. */
++ return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq,
++ xfree, &objfile->objfile_obstack,
++ hashtab_obstack_allocate,
++ dummy_obstack_deallocate);
++ }
+ }
-+#if 0
-+extern void type_mark_used (struct type *type);
-+#endif
-+
- /* Overload resolution */
+-/* Recursively copy (deep copy) TYPE, if it is associated with
+- OBJFILE. Return a new type allocated using malloc, a saved type if
+- we have already visited TYPE (using COPIED_TYPES), or TYPE if it is
+- not associated with OBJFILE. */
++/* A helper for copy_type_recursive. This does all the work. OBJFILE is used
++ only for an assertion checking. */
- #define LENGTH_MATCH(bv) ((bv)->rank[0])
-@@ -1602,10 +1723,13 @@ extern void maintenance_print_type (char *, int);
+-struct type *
+-copy_type_recursive (struct objfile *objfile,
+- struct type *type,
+- htab_t copied_types)
++static struct type *
++copy_type_recursive_1 (struct objfile *objfile,
++ struct type *type,
++ htab_t copied_types)
+ {
+ struct type_pair *stored, pair;
+ void **slot;
+ struct type *new_type;
- extern htab_t create_copied_types_hash (struct objfile *objfile);
+- if (! TYPE_OBJFILE_OWNED (type))
++ if (! TYPE_OBJFILE_OWNED (type) && !TYPE_DYNAMIC (type))
+ return type;
--extern struct type *copy_type_recursive (struct objfile *objfile,
-- struct type *type,
-+extern struct type *copy_type_recursive (struct type *type,
- htab_t copied_types);
+ /* This type shouldn't be pointing to any types in other objfiles;
+@@ -3386,9 +3535,10 @@ copy_type_recursive (struct objfile *objfile,
+ new_type = alloc_type_arch (get_type_arch (type));
- extern struct type *copy_type (const struct type *type);
+ /* We must add the new type to the hash table immediately, in case
+- we encounter this type again during a recursive call below. */
+- stored
+- = obstack_alloc (&objfile->objfile_obstack, sizeof (struct type_pair));
++ we encounter this type again during a recursive call below. Memory could
++ be allocated from OBJFILE in the case we will be removing OBJFILE, this
++ optimization is missed and xfree is called for it from COPIED_TYPES. */
++ stored = xmalloc (sizeof (*stored));
+ stored->old = type;
+ stored->new = new_type;
+ *slot = stored;
+@@ -3399,6 +3549,21 @@ copy_type_recursive (struct objfile *objfile,
+ TYPE_OBJFILE_OWNED (new_type) = 0;
+ TYPE_OWNER (new_type).gdbarch = get_type_arch (type);
+#if 0
-+extern void free_all_types (void);
++ /* TYPE_MAIN_TYPE memory copy above rewrote the TYPE_DISCARDABLE flag so we
++ need to initialize it again. And even if TYPE was already discardable
++ NEW_TYPE so far is not registered in TYPE_DISCARDABLE_TABLE. */
++ TYPE_DISCARDABLE (new_type) = 0;
++ set_type_as_discardable (new_type);
+#endif
+
- #endif /* GDBTYPES_H */
-diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
-index 4b1b20f..38e7027 100644
---- a/gdb/i386-linux-nat.c
-+++ b/gdb/i386-linux-nat.c
-@@ -708,8 +708,8 @@ i386_linux_dr_get_status (void)
- return i386_linux_dr_get (inferior_ptid, DR_STATUS);
- }
-
--/* Callback for iterate_over_lwps. Update the debug registers of
-- LWP. */
-+/* Callback for linux_nat_iterate_watchpoint_lwps. Update the debug registers
-+ of LWP. */
-
- static int
- update_debug_registers_callback (struct lwp_info *lwp, void *arg)
-@@ -735,9 +735,7 @@ update_debug_registers_callback (struct lwp_info *lwp, void *arg)
- static void
- i386_linux_dr_set_control (unsigned long control)
- {
-- ptid_t pid_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
--
-- iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL);
-+ linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL);
- }
-
- /* Set address REGNUM (zero based) to ADDR in all LWPs of the current
-@@ -750,7 +748,7 @@ i386_linux_dr_set_addr (int regnum, CORE_ADDR addr)
-
- gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
-
-- iterate_over_lwps (pid_ptid, update_debug_registers_callback, NULL);
-+ linux_nat_iterate_watchpoint_lwps (update_debug_registers_callback, NULL);
- }
-
- /* Called when resuming a thread.
-@@ -772,6 +770,9 @@ i386_linux_prepare_to_resume (struct lwp_info *lwp)
- struct i386_debug_reg_state *state = i386_debug_reg_state ();
- int i;
-
-+ /* See amd64_linux_prepare_to_resume for Linux kernel note on
-+ i386_linux_dr_set calls ordering. */
++ /* Pre-clear the fields processed by delete_main_type. If DWARF block
++ evaluations below call error we would leave an unfreeable TYPE. */
++ TYPE_TARGET_TYPE (new_type) = NULL;
++ TYPE_VPTR_BASETYPE (new_type) = NULL;
++ TYPE_NFIELDS (new_type) = 0;
++ TYPE_FIELDS (new_type) = NULL;
+
- for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
- if (state->dr_ref_count[i] > 0)
- {
-diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
-index eb114ef..f80e05a 100644
---- a/gdb/i386-linux-tdep.c
-+++ b/gdb/i386-linux-tdep.c
-@@ -903,6 +903,15 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
- i386_linux_get_syscall_number);
-
- set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
-+
-+ /* SystemTap variables and functions. */
-+ set_gdbarch_stap_integer_prefix (gdbarch, "$");
-+ set_gdbarch_stap_register_prefix (gdbarch, "%");
-+ set_gdbarch_stap_register_indirection_prefix (gdbarch, "(");
-+ set_gdbarch_stap_register_indirection_sufix (gdbarch, ")");
-+ set_gdbarch_stap_is_single_operand (gdbarch, i386_stap_is_single_operand);
-+ set_gdbarch_stap_parse_special_token (gdbarch,
-+ i386_stap_parse_special_token);
- }
+ if (TYPE_NAME (type))
+ TYPE_NAME (new_type) = xstrdup (TYPE_NAME (type));
+ if (TYPE_TAG_NAME (type))
+@@ -3407,12 +3572,48 @@ copy_type_recursive (struct objfile *objfile,
+ TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type);
+ TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
- /* Provide a prototype to silence -Wmissing-prototypes. */
-diff --git a/gdb/i386-nat.c b/gdb/i386-nat.c
-index fa17823..846b2b8 100644
---- a/gdb/i386-nat.c
-+++ b/gdb/i386-nat.c
-@@ -25,6 +25,7 @@
- #include "gdbcmd.h"
- #include "target.h"
- #include "gdb_assert.h"
-+#include "inferior.h"
-
- /* Support for hardware watchpoints and breakpoints using the i386
- debug registers.
-@@ -170,14 +171,88 @@ i386_init_dregs (struct i386_debug_reg_state *state)
- state->dr_status_mirror = 0;
- }
-
--/* The local mirror of the inferior's debug registers. Currently this
-- is a global, but it should really be per-inferior. */
--static struct i386_debug_reg_state dr_mirror;
-+/* Per-inferior data key. */
-+static const struct inferior_data *i386_inferior_data;
-+
-+/* Per-inferior data. */
-+struct i386_inferior_data
-+ {
-+ /* Copy of i386 hardware debug registers for performance reasons. */
-+ struct i386_debug_reg_state state;
-+ };
-+
-+/* Per-inferior hook for register_inferior_data_with_cleanup. */
-+
-+static void
-+i386_inferior_data_cleanup (struct inferior *inf, void *arg)
-+{
-+ struct i386_inferior_data *inf_data = arg;
-+
-+ xfree (inf_data);
-+}
-+
-+/* Get data specific for INFERIOR_PTID LWP. Return special data area
-+ for processes being detached. */
-+
-+static struct i386_inferior_data *
-+i386_inferior_data_get (void)
-+{
-+ struct inferior *inf = current_inferior ();
-+ struct i386_inferior_data *inf_data;
-+
-+ inf_data = inferior_data (inf, i386_inferior_data);
-+ if (inf_data == NULL)
++ if (TYPE_ALLOCATED (new_type))
+ {
-+ inf_data = xzalloc (sizeof (*inf_data));
-+ set_inferior_data (current_inferior (), i386_inferior_data, inf_data);
++ gdb_assert (!TYPE_NOT_ALLOCATED (new_type));
++
++ if (!dwarf_locexpr_baton_eval (TYPE_ALLOCATED (new_type)))
++ TYPE_NOT_ALLOCATED (new_type) = 1;
++ TYPE_ALLOCATED (new_type) = NULL;
+ }
+
-+ if (inf->pid != ptid_get_pid (inferior_ptid))
++ if (TYPE_ASSOCIATED (new_type))
+ {
-+ /* INFERIOR_PTID is being detached from the inferior INF.
-+ Provide local cache specific for the detached LWP. */
++ gdb_assert (!TYPE_NOT_ASSOCIATED (new_type));
+
-+ static struct i386_inferior_data detached_inf_data_local;
-+ static int detached_inf_pid = -1;
++ if (!dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (new_type)))
++ TYPE_NOT_ASSOCIATED (new_type) = 1;
++ TYPE_ASSOCIATED (new_type) = NULL;
++ }
+
-+ if (detached_inf_pid != ptid_get_pid (inferior_ptid))
++ if (!TYPE_DATA_LOCATION_IS_ADDR (new_type)
++ && TYPE_DATA_LOCATION_DWARF_BLOCK (new_type))
++ {
++ if (TYPE_NOT_ALLOCATED (new_type)
++ || TYPE_NOT_ASSOCIATED (new_type))
++ TYPE_DATA_LOCATION_DWARF_BLOCK (new_type) = NULL;
++ else
+ {
-+ /* Reinitialize the local cache if INFERIOR_PTID is
-+ different from the LWP last detached.
-+
-+ Linux kernel before 2.6.33 commit
-+ 72f674d203cd230426437cdcf7dd6f681dad8b0d
-+ will inherit hardware debug registers from parent
-+ on fork/vfork/clone. Newer Linux kernels create such tasks with
-+ zeroed debug registers.
-+
-+ GDB will remove all breakpoints (and watchpoints) from the forked
-+ off process. We also need to reset the debug registers in that
-+ process to be compatible with the older Linux kernels.
-+
-+ Copy the debug registers mirrors into the new process so that all
-+ breakpoints and watchpoints can be removed together. The debug
-+ registers mirror will become zeroed in the end before detaching
-+ the forked off process. */
-+
-+ detached_inf_pid = ptid_get_pid (inferior_ptid);
-+ memcpy (&detached_inf_data_local, inf_data,
-+ sizeof (detached_inf_data_local));
++ TYPE_DATA_LOCATION_IS_ADDR (new_type) = 1;
++ TYPE_DATA_LOCATION_ADDR (new_type) = dwarf_locexpr_baton_eval
++ (TYPE_DATA_LOCATION_DWARF_BLOCK (new_type));
+ }
-+
-+ return &detached_inf_data_local;
+ }
+
-+ return inf_data;
-+}
-+
-+/* Get debug registers state for INFERIOR_PTID, see
-+ i386_inferior_data_get. */
-
- struct i386_debug_reg_state *
- i386_debug_reg_state (void)
- {
-- return &dr_mirror;
-+ return &i386_inferior_data_get ()->state;
- }
-
- /* Whether or not to print the mirrored debug registers. */
-@@ -230,7 +305,9 @@ static int i386_handle_nonaligned_watchpoint (struct i386_debug_reg_state *state
- void
- i386_cleanup_dregs (void)
- {
-- i386_init_dregs (&dr_mirror);
-+ struct i386_debug_reg_state *state = i386_debug_reg_state ();
-+
-+ i386_init_dregs (state);
- }
-
- /* Print the values of the mirrored debug registers. This is called
-@@ -494,20 +571,21 @@ Invalid value %d of operation in i386_handle_nonaligned_watchpoint.\n"),
- static void
- i386_update_inferior_debug_regs (struct i386_debug_reg_state *new_state)
- {
-+ struct i386_debug_reg_state *state = i386_debug_reg_state ();
- int i;
-
- ALL_DEBUG_REGISTERS (i)
+ /* Copy the fields. */
+ if (TYPE_NFIELDS (type))
{
-- if (I386_DR_VACANT (new_state, i) != I386_DR_VACANT (&dr_mirror, i))
-+ if (I386_DR_VACANT (new_state, i) != I386_DR_VACANT (state, i))
- i386_dr_low.set_addr (i, new_state->dr_mirror[i]);
- else
-- gdb_assert (new_state->dr_mirror[i] == dr_mirror.dr_mirror[i]);
-+ gdb_assert (new_state->dr_mirror[i] == state->dr_mirror[i]);
- }
-
-- if (new_state->dr_control_mirror != dr_mirror.dr_control_mirror)
-+ if (new_state->dr_control_mirror != state->dr_control_mirror)
- i386_dr_low.set_control (new_state->dr_control_mirror);
-
-- dr_mirror = *new_state;
-+ *state = *new_state;
- }
-
- /* Insert a watchpoint to watch a memory region which starts at
-@@ -518,10 +596,11 @@ static int
- i386_insert_watchpoint (CORE_ADDR addr, int len, int type,
- struct expression *cond)
- {
-+ struct i386_debug_reg_state *state = i386_debug_reg_state ();
- int retval;
- /* Work on a local copy of the debug registers, and on success,
- commit the change back to the inferior. */
-- struct i386_debug_reg_state local_state = dr_mirror;
-+ struct i386_debug_reg_state local_state = *state;
-
- if (type == hw_read)
- return 1; /* unsupported */
-@@ -542,7 +621,7 @@ i386_insert_watchpoint (CORE_ADDR addr, int len, int type,
- i386_update_inferior_debug_regs (&local_state);
-
- if (maint_show_dr)
-- i386_show_dr (&dr_mirror, "insert_watchpoint", addr, len, type);
-+ i386_show_dr (state, "insert_watchpoint", addr, len, type);
-
- return retval;
- }
-@@ -554,10 +633,11 @@ static int
- i386_remove_watchpoint (CORE_ADDR addr, int len, int type,
- struct expression *cond)
- {
-+ struct i386_debug_reg_state *state = i386_debug_reg_state ();
- int retval;
- /* Work on a local copy of the debug registers, and on success,
- commit the change back to the inferior. */
-- struct i386_debug_reg_state local_state = dr_mirror;
-+ struct i386_debug_reg_state local_state = *state;
-
- if (((len != 1 && len !=2 && len !=4) && !(TARGET_HAS_DR_LEN_8 && len == 8))
- || addr % len != 0)
-@@ -575,7 +655,7 @@ i386_remove_watchpoint (CORE_ADDR addr, int len, int type,
- i386_update_inferior_debug_regs (&local_state);
-
- if (maint_show_dr)
-- i386_show_dr (&dr_mirror, "remove_watchpoint", addr, len, type);
-+ i386_show_dr (state, "remove_watchpoint", addr, len, type);
-
- return retval;
- }
-@@ -586,11 +666,12 @@ i386_remove_watchpoint (CORE_ADDR addr, int len, int type,
- static int
- i386_region_ok_for_watchpoint (CORE_ADDR addr, int len)
- {
-+ struct i386_debug_reg_state *state = i386_debug_reg_state ();
- int nregs;
+ int i, nfields;
- /* Compute how many aligned watchpoints we would need to cover this
- region. */
-- nregs = i386_handle_nonaligned_watchpoint (&dr_mirror,
-+ nregs = i386_handle_nonaligned_watchpoint (state,
- WP_COUNT, addr, len, hw_write);
- return nregs <= DR_NADDR ? 1 : 0;
- }
-@@ -602,6 +683,7 @@ i386_region_ok_for_watchpoint (CORE_ADDR addr, int len)
- static int
- i386_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
- {
-+ struct i386_debug_reg_state *state = i386_debug_reg_state ();
- CORE_ADDR addr = 0;
- int i;
- int rc = 0;
-@@ -615,25 +697,24 @@ i386_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
- unsigned control = 0;
-
- /* In non-stop/async, threads can be running while we change the
-- global dr_mirror (and friends). Say, we set a watchpoint, and
-- let threads resume. Now, say you delete the watchpoint, or
-- add/remove watchpoints such that dr_mirror changes while threads
-- are running. On targets that support non-stop,
-- inserting/deleting watchpoints updates the global dr_mirror only.
-- It does not update the real thread's debug registers; that's only
-- done prior to resume. Instead, if threads are running when the
-- mirror changes, a temporary and transparent stop on all threads
-- is forced so they can get their copy of the debug registers
-- updated on re-resume. Now, say, a thread hit a watchpoint before
-- having been updated with the new dr_mirror contents, and we
-- haven't yet handled the corresponding SIGTRAP. If we trusted
-- dr_mirror below, we'd mistake the real trapped address (from the
-- last time we had updated debug registers in the thread) with
-- whatever was currently in dr_mirror. So to fix this, dr_mirror
-- always represents intention, what we _want_ threads to have in
-- debug registers. To get at the address and cause of the trap, we
-- need to read the state the thread still has in its debug
-- registers.
-+ STATE (and friends). Say, we set a watchpoint, and let threads
-+ resume. Now, say you delete the watchpoint, or add/remove
-+ watchpoints such that STATE changes while threads are running.
-+ On targets that support non-stop, inserting/deleting watchpoints
-+ updates the STATE only. It does not update the real thread's
-+ debug registers; that's only done prior to resume. Instead, if
-+ threads are running when the mirror changes, a temporary and
-+ transparent stop on all threads is forced so they can get their
-+ copy of the debug registers updated on re-resume. Now, say,
-+ a thread hit a watchpoint before having been updated with the new
-+ STATE contents, and we haven't yet handled the corresponding
-+ SIGTRAP. If we trusted STATE below, we'd mistake the real
-+ trapped address (from the last time we had updated debug
-+ registers in the thread) with whatever was currently in STATE.
-+ So to fix this, STATE always represents intention, what we _want_
-+ threads to have in debug registers. To get at the address and
-+ cause of the trap, we need to read the state the thread still has
-+ in its debug registers.
-
- In sum, always get the current debug register values the current
- thread has, instead of trusting the global mirror. If the thread
-@@ -663,11 +744,11 @@ i386_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
- addr = i386_dr_low.get_addr (i);
- rc = 1;
- if (maint_show_dr)
-- i386_show_dr (&dr_mirror, "watchpoint_hit", addr, -1, hw_write);
-+ i386_show_dr (state, "watchpoint_hit", addr, -1, hw_write);
++ /* TYPE_CODE_RANGE uses TYPE_RANGE_DATA of the union with TYPE_FIELDS. */
++ gdb_assert (TYPE_CODE (type) != TYPE_CODE_RANGE);
++
+ nfields = TYPE_NFIELDS (type);
++ TYPE_NFIELDS (new_type) = nfields;
+ TYPE_FIELDS (new_type) = XCALLOC (nfields, struct field);
+ for (i = 0; i < nfields; i++)
+ {
+@@ -3421,8 +3622,8 @@ copy_type_recursive (struct objfile *objfile,
+ TYPE_FIELD_BITSIZE (new_type, i) = TYPE_FIELD_BITSIZE (type, i);
+ if (TYPE_FIELD_TYPE (type, i))
+ TYPE_FIELD_TYPE (new_type, i)
+- = copy_type_recursive (objfile, TYPE_FIELD_TYPE (type, i),
+- copied_types);
++ = copy_type_recursive_1 (objfile, TYPE_FIELD_TYPE (type, i),
++ copied_types);
+ if (TYPE_FIELD_NAME (type, i))
+ TYPE_FIELD_NAME (new_type, i) =
+ xstrdup (TYPE_FIELD_NAME (type, i));
+@@ -3453,24 +3654,184 @@ copy_type_recursive (struct objfile *objfile,
}
}
- if (maint_show_dr && addr == 0)
-- i386_show_dr (&dr_mirror, "stopped_data_addr", 0, 0, hw_write);
-+ i386_show_dr (state, "stopped_data_addr", 0, 0, hw_write);
-
- if (rc)
- *addr_p = addr;
-@@ -687,11 +768,12 @@ static int
- i386_insert_hw_breakpoint (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
- {
-+ struct i386_debug_reg_state *state = i386_debug_reg_state ();
- unsigned len_rw = i386_length_and_rw_bits (1, hw_execute);
- CORE_ADDR addr = bp_tgt->placed_address;
- /* Work on a local copy of the debug registers, and on success,
- commit the change back to the inferior. */
-- struct i386_debug_reg_state local_state = dr_mirror;
-+ struct i386_debug_reg_state local_state = *state;
- int retval = i386_insert_aligned_watchpoint (&local_state,
- addr, len_rw) ? EBUSY : 0;
-
-@@ -699,7 +781,7 @@ i386_insert_hw_breakpoint (struct gdbarch *gdbarch,
- i386_update_inferior_debug_regs (&local_state);
-
- if (maint_show_dr)
-- i386_show_dr (&dr_mirror, "insert_hwbp", addr, 1, hw_execute);
-+ i386_show_dr (state, "insert_hwbp", addr, 1, hw_execute);
-
- return retval;
- }
-@@ -711,11 +793,12 @@ static int
- i386_remove_hw_breakpoint (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
- {
-+ struct i386_debug_reg_state *state = i386_debug_reg_state ();
- unsigned len_rw = i386_length_and_rw_bits (1, hw_execute);
- CORE_ADDR addr = bp_tgt->placed_address;
- /* Work on a local copy of the debug registers, and on success,
- commit the change back to the inferior. */
-- struct i386_debug_reg_state local_state = dr_mirror;
-+ struct i386_debug_reg_state local_state = *state;
- int retval = i386_remove_aligned_watchpoint (&local_state,
- addr, len_rw);
-
-@@ -723,7 +806,7 @@ i386_remove_hw_breakpoint (struct gdbarch *gdbarch,
- i386_update_inferior_debug_regs (&local_state);
-
- if (maint_show_dr)
-- i386_show_dr (&dr_mirror, "remove_hwbp", addr, 1, hw_execute);
-+ i386_show_dr (state, "remove_hwbp", addr, 1, hw_execute);
-
- return retval;
- }
-@@ -788,6 +871,10 @@ i386_use_watchpoints (struct target_ops *t)
- t->to_remove_watchpoint = i386_remove_watchpoint;
- t->to_insert_hw_breakpoint = i386_insert_hw_breakpoint;
- t->to_remove_hw_breakpoint = i386_remove_hw_breakpoint;
-+
-+ if (i386_inferior_data == NULL)
-+ i386_inferior_data
-+ = register_inferior_data_with_cleanup (i386_inferior_data_cleanup);
- }
-
- void
-diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
-index 549297e..5783c4c 100644
---- a/gdb/i386-tdep.c
-+++ b/gdb/i386-tdep.c
-@@ -58,8 +58,14 @@
- #include "features/i386/i386-avx.c"
- #include "features/i386/i386-mmx.c"
-
-+#include "stap-probe.h"
- #include "ax.h"
- #include "ax-gdb.h"
-+#include "user-regs.h"
-+#include "cli/cli-utils.h"
-+#include "expression.h"
-+#include "parser-defs.h"
-+#include <ctype.h>
-
- /* Register names. */
-
-@@ -7246,6 +7252,312 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
- return valid_p;
- }
-+int
-+i386_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
-+{
-+ return (*s == '$' /* Literal number. */
-+ || (isdigit (*s) && s[1] == '(' && s[2] == '%') /* Displacement. */
-+ || (*s == '(' && s[1] == '%') /* Register indirection. */
-+ || (*s == '%' && isalpha (s[1]))); /* Register access. */
-+}
-+
-+int
-+i386_stap_parse_special_token (struct gdbarch *gdbarch,
-+ struct stap_parse_info *p)
-+{
-+ const char *s = p->arg;
-+
-+ /* In order to parse special tokens, we use a state-machine that go
-+ through every known token and try to get a match. */
-+ enum
-+ {
-+ TRIPLET,
-+ THREE_ARG_DISPLACEMENT,
-+ DONE
-+ } current_state;
-+
-+ current_state = TRIPLET;
-+
-+ /* The special tokens to be parsed here are:
-+
-+ - `register base + (register index * size) + offset', as represented
-+ in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
-+
-+ - Operands of the form `-8+3+1(%rbp)', which must be interpreted as
-+ `*(-8 + 3 - 1 + (void *) $eax)'. */
++ /* Both FIELD_LOC_KIND_DWARF_BLOCK and TYPE_RANGE_HIGH_BOUND_IS_COUNT were
++ possibly converted. */
++ TYPE_DYNAMIC (new_type) = 0;
+
-+ while (current_state != DONE)
-+ {
-+ const char *s = p->arg;
+ /* For range types, copy the bounds information. */
+- if (TYPE_CODE (type) == TYPE_CODE_RANGE)
++ if (TYPE_CODE (new_type) == TYPE_CODE_RANGE)
+ {
+ TYPE_RANGE_DATA (new_type) = xmalloc (sizeof (struct range_bounds));
+ *TYPE_RANGE_DATA (new_type) = *TYPE_RANGE_DATA (type);
+
-+ switch (current_state)
++ switch (TYPE_RANGE_DATA (new_type)->low.kind)
+ {
-+ case TRIPLET:
++ case RANGE_BOUND_KIND_CONSTANT:
++ break;
++ case RANGE_BOUND_KIND_DWARF_BLOCK:
++ /* `struct dwarf2_locexpr_baton' is too bound to its objfile so
++ it is expected to be made constant by CHECK_TYPEDEF.
++ TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE.
++ */
++ if (TYPE_NOT_ALLOCATED (new_type) || TYPE_NOT_ASSOCIATED (new_type)
++ || ! has_stack_frames ())
+ {
-+ if (isdigit (*s) || *s == '-' || *s == '+')
-+ {
-+ int got_minus[3];
-+ int i;
-+ long displacements[3];
-+ const char *start;
-+ char *regname;
-+ int len;
-+ struct stoken str;
-+
-+ got_minus[0] = 0;
-+ if (*s == '+')
-+ ++s;
-+ else if (*s == '-')
-+ {
-+ ++s;
-+ got_minus[0] = 1;
-+ }
-+
-+ displacements[0] = strtol (s, (char **) &s, 10);
-+
-+ if (*s != '+' && *s != '-')
-+ /* We are not dealing with a triplet. */
-+ break;
-+
-+ got_minus[1] = 0;
-+ if (*s == '+')
-+ ++s;
-+ else
-+ {
-+ ++s;
-+ got_minus[1] = 1;
-+ }
-+
-+ displacements[1] = strtol (s, (char **) &s, 10);
-+
-+ if (*s != '+' && *s != '-')
-+ /* We are not dealing with a triplet. */
-+ break;
-+
-+ got_minus[2] = 0;
-+ if (*s == '+')
-+ ++s;
-+ else
-+ {
-+ ++s;
-+ got_minus[2] = 1;
-+ }
-+
-+ displacements[2] = strtol (s, (char **) &s, 10);
-+
-+ if (*s != '(' || s[1] != '%')
-+ break;
-+
-+ s += 2;
-+ start = s;
-+
-+ while (isalnum (*s))
-+ ++s;
-+
-+ if (*s++ != ')')
-+ break;
-+
-+ len = s - start;
-+ regname = alloca (len + 1);
-+
-+ strncpy (regname, start, len);
-+ regname[len] = '\0';
-+
-+ if (user_reg_map_name_to_regnum (gdbarch,
-+ regname, len) == -1)
-+ error (_("Invalid register name `%s' "
-+ "on expression `%s'."),
-+ regname, p->saved_arg);
-+
-+ for (i = 0; i < 3; i++)
-+ {
-+ write_exp_elt_opcode (OP_LONG);
-+ write_exp_elt_type
-+ (builtin_type (gdbarch)->builtin_long);
-+ write_exp_elt_longcst (displacements[i]);
-+ write_exp_elt_opcode (OP_LONG);
-+ if (got_minus[i])
-+ write_exp_elt_opcode (UNOP_NEG);
-+ }
-+
-+ write_exp_elt_opcode (OP_REGISTER);
-+ str.ptr = regname;
-+ str.length = len;
-+ write_exp_string (str);
-+ write_exp_elt_opcode (OP_REGISTER);
-+
-+ write_exp_elt_opcode (UNOP_CAST);
-+ write_exp_elt_type (builtin_type (gdbarch)->builtin_data_ptr);
-+ write_exp_elt_opcode (UNOP_CAST);
-+
-+ write_exp_elt_opcode (BINOP_ADD);
-+ write_exp_elt_opcode (BINOP_ADD);
-+ write_exp_elt_opcode (BINOP_ADD);
-+
-+ write_exp_elt_opcode (UNOP_CAST);
-+ write_exp_elt_type (lookup_pointer_type (p->arg_type));
-+ write_exp_elt_opcode (UNOP_CAST);
-+
-+ write_exp_elt_opcode (UNOP_IND);
-+
-+ p->arg = s;
-+
-+ return 1;
-+ }
-+ break;
++ /* We should set 1 for Fortran but how to find the language? */
++ TYPE_LOW_BOUND (new_type) = 0;
++ TYPE_LOW_BOUND_UNDEFINED (new_type) = 1;
+ }
-+ case THREE_ARG_DISPLACEMENT:
++ else
+ {
-+ if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
-+ {
-+ int offset_minus = 0;
-+ long offset = 0;
-+ int size_minus = 0;
-+ long size = 0;
-+ const char *start;
-+ char *base;
-+ int len_base;
-+ char *index;
-+ int len_index;
-+ struct stoken base_token, index_token;
-+
-+ if (*s == '+')
-+ ++s;
-+ else if (*s == '-')
-+ {
-+ ++s;
-+ offset_minus = 1;
-+ }
-+
-+ if (offset_minus && !isdigit (*s))
-+ break;
-+
-+ if (isdigit (*s))
-+ offset = strtol (s, (char **) &s, 10);
-+
-+ if (*s != '(' || s[1] != '%')
-+ break;
-+
-+ s += 2;
-+ start = s;
-+
-+ while (isalnum (*s))
-+ ++s;
-+
-+ if (*s != ',' || s[1] != '%')
-+ break;
-+
-+ len_base = s - start;
-+ base = alloca (len_base + 1);
-+ strncpy (base, start, len_base);
-+ base[len_base] = '\0';
-+
-+ if (user_reg_map_name_to_regnum (gdbarch,
-+ base, len_base) == -1)
-+ error (_("Invalid register name `%s' "
-+ "on expression `%s'."),
-+ base, p->saved_arg);
-+
-+ s += 2;
-+ start = s;
-+
-+ while (isalnum (*s))
-+ ++s;
-+
-+ len_index = s - start;
-+ index = alloca (len_index + 1);
-+ strncpy (index, start, len_index);
-+ index[len_index] = '\0';
-+
-+ if (user_reg_map_name_to_regnum (gdbarch,
-+ index, len_index) == -1)
-+ error (_("Invalid register name `%s' "
-+ "on expression `%s'."),
-+ index, p->saved_arg);
-+
-+ if (*s != ',' && *s != ')')
-+ break;
-+
-+ if (*s == ',')
-+ {
-+ ++s;
-+ if (*s == '+')
-+ ++s;
-+ else if (*s == '-')
-+ {
-+ ++s;
-+ size_minus = 1;
-+ }
-+
-+ size = strtol (s, (char **) &s, 10);
-+
-+ if (*s != ')')
-+ break;
-+ }
-+
-+ ++s;
-+
-+ if (offset)
-+ {
-+ write_exp_elt_opcode (OP_LONG);
-+ write_exp_elt_type
-+ (builtin_type (gdbarch)->builtin_long);
-+ write_exp_elt_longcst (offset);
-+ write_exp_elt_opcode (OP_LONG);
-+ if (offset_minus)
-+ write_exp_elt_opcode (UNOP_NEG);
-+ }
-+
-+ write_exp_elt_opcode (OP_REGISTER);
-+ base_token.ptr = base;
-+ base_token.length = len_base;
-+ write_exp_string (base_token);
-+ write_exp_elt_opcode (OP_REGISTER);
-+
-+ if (offset)
-+ write_exp_elt_opcode (BINOP_ADD);
-+
-+ write_exp_elt_opcode (OP_REGISTER);
-+ index_token.ptr = index;
-+ index_token.length = len_index;
-+ write_exp_string (index_token);
-+ write_exp_elt_opcode (OP_REGISTER);
-+
-+ if (size)
-+ {
-+ write_exp_elt_opcode (OP_LONG);
-+ write_exp_elt_type
-+ (builtin_type (gdbarch)->builtin_long);
-+ write_exp_elt_longcst (size);
-+ write_exp_elt_opcode (OP_LONG);
-+ if (size_minus)
-+ write_exp_elt_opcode (UNOP_NEG);
-+ write_exp_elt_opcode (BINOP_MUL);
-+ }
-+
-+ write_exp_elt_opcode (BINOP_ADD);
-+
-+ write_exp_elt_opcode (UNOP_CAST);
-+ write_exp_elt_type (lookup_pointer_type (p->arg_type));
-+ write_exp_elt_opcode (UNOP_CAST);
-+
-+ write_exp_elt_opcode (UNOP_IND);
-+
-+ p->arg = s;
-+
-+ return 1;
-+ }
-+ break;
++ TYPE_LOW_BOUND (new_type) = dwarf_locexpr_baton_eval
++ (TYPE_RANGE_DATA (new_type)->low.u.dwarf_block);
++ if (TYPE_LOW_BOUND (new_type) >= 0)
++ TYPE_UNSIGNED (new_type) = 1;
+ }
-+ }
-+
-+ /* Advancing to the next state. */
-+ ++current_state;
-+ }
-+
-+ return 0;
-+}
++ TYPE_RANGE_DATA (new_type)->low.kind = RANGE_BOUND_KIND_CONSTANT;
++ break;
++ case RANGE_BOUND_KIND_DWARF_LOCLIST:
++ {
++ CORE_ADDR addr;
+
- \f
- static struct gdbarch *
- i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
-diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
-index 870054f..9ffbe44 100644
---- a/gdb/i386-tdep.h
-+++ b/gdb/i386-tdep.h
-@@ -379,6 +379,15 @@ extern void i386_svr4_init_abi (struct gdbarch_info, struct gdbarch *);
-
- extern int i386_process_record (struct gdbarch *gdbarch,
- struct regcache *regcache, CORE_ADDR addr);
++ /* `struct dwarf2_loclist_baton' is too bound to its objfile so
++ it is expected to be made constant by CHECK_TYPEDEF.
++ TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE.
++ */
++ if (! TYPE_NOT_ALLOCATED (new_type)
++ && ! TYPE_NOT_ASSOCIATED (new_type) && has_stack_frames ()
++ && dwarf_loclist_baton_eval
++ (TYPE_RANGE_DATA (new_type)->low.u.dwarf_loclist.loclist,
++ TYPE_RANGE_DATA (new_type)->low.u.dwarf_loclist.type, &addr))
++ {
++ TYPE_LOW_BOUND (new_type) = addr;
++ if (TYPE_LOW_BOUND (new_type) >= 0)
++ TYPE_UNSIGNED (new_type) = 1;
++ }
++ else
++ {
++ /* We should set 1 for Fortran but how to find the language? */
++ TYPE_LOW_BOUND (new_type) = 0;
++ TYPE_LOW_BOUND_UNDEFINED (new_type) = 1;
++ }
++ TYPE_RANGE_DATA (new_type)->low.kind = RANGE_BOUND_KIND_CONSTANT;
++ }
++ break;
++ }
+
-+/* SystemTap related functions. */
++ switch (TYPE_RANGE_DATA (new_type)->high.kind)
++ {
++ case RANGE_BOUND_KIND_CONSTANT:
++ break;
++ case RANGE_BOUND_KIND_DWARF_BLOCK:
++ /* `struct dwarf2_locexpr_baton' is too bound to its objfile so
++ it is expected to be made constant by CHECK_TYPEDEF.
++ TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE.
++ */
++ if (TYPE_NOT_ALLOCATED (new_type) || TYPE_NOT_ASSOCIATED (new_type)
++ || ! has_stack_frames ())
++ {
++ TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (new_type) - 1;
++ TYPE_HIGH_BOUND_UNDEFINED (new_type) = 1;
++ }
++ else
++ TYPE_HIGH_BOUND (new_type) = dwarf_locexpr_baton_eval
++ (TYPE_RANGE_DATA (new_type)->high.u.dwarf_block);
++ TYPE_RANGE_DATA (new_type)->high.kind = RANGE_BOUND_KIND_CONSTANT;
++ break;
++ case RANGE_BOUND_KIND_DWARF_LOCLIST:
++ {
++ CORE_ADDR addr;
+
-+extern int i386_stap_is_single_operand (struct gdbarch *gdbarch,
-+ const char *s);
++ /* `struct dwarf2_loclist_baton' is too bound to its objfile so
++ it is expected to be made constant by CHECK_TYPEDEF.
++ TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE.
++ */
++ if (! TYPE_NOT_ALLOCATED (new_type)
++ && ! TYPE_NOT_ASSOCIATED (new_type) && has_stack_frames ()
++ && dwarf_loclist_baton_eval
++ (TYPE_RANGE_DATA (new_type)->high.u.dwarf_loclist.loclist,
++ TYPE_RANGE_DATA (new_type)->high.u.dwarf_loclist.type,
++ &addr))
++ TYPE_HIGH_BOUND (new_type) = addr;
++ else
++ {
++ TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (new_type) - 1;
++ TYPE_HIGH_BOUND_UNDEFINED (new_type) = 1;
++ }
++ TYPE_RANGE_DATA (new_type)->high.kind = RANGE_BOUND_KIND_CONSTANT;
++ }
++ break;
++ }
+
-+extern int i386_stap_parse_special_token (struct gdbarch *gdbarch,
-+ struct stap_parse_info *p);
++ switch (TYPE_RANGE_DATA (new_type)->byte_stride.kind)
++ {
++ case RANGE_BOUND_KIND_CONSTANT:
++ break;
++ case RANGE_BOUND_KIND_DWARF_BLOCK:
++ /* `struct dwarf2_locexpr_baton' is too bound to its objfile so
++ it is expected to be made constant by CHECK_TYPEDEF.
++ TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE.
++ */
++ if (TYPE_NOT_ALLOCATED (new_type) || TYPE_NOT_ASSOCIATED (new_type)
++ || ! has_stack_frames ())
++ TYPE_BYTE_STRIDE (new_type) = 0;
++ else
++ TYPE_BYTE_STRIDE (new_type) = dwarf_locexpr_baton_eval
++ (TYPE_RANGE_DATA (new_type)->byte_stride.u.dwarf_block);
++ TYPE_RANGE_DATA (new_type)->byte_stride.kind
++ = RANGE_BOUND_KIND_CONSTANT;
++ break;
++ case RANGE_BOUND_KIND_DWARF_LOCLIST:
++ {
++ CORE_ADDR addr = 0;
+
- \f
-
- /* Functions and variables exported from i386bsd-tdep.c. */
-diff --git a/gdb/infrun.c b/gdb/infrun.c
-index 24d2720..c516b8b 100644
---- a/gdb/infrun.c
-+++ b/gdb/infrun.c
-@@ -55,6 +55,8 @@
- #include "continuations.h"
- #include "interps.h"
- #include "skip.h"
-+#include "stap-probe.h"
-+#include "objfiles.h"
-
- /* Prototypes for local functions */
-
-@@ -2379,7 +2381,7 @@ static void handle_step_into_function (struct gdbarch *gdbarch,
- static void handle_step_into_function_backward (struct gdbarch *gdbarch,
- struct execution_control_state *ecs);
- static void check_exception_resume (struct execution_control_state *,
-- struct frame_info *, struct symbol *);
-+ struct frame_info *);
-
- static void stop_stepping (struct execution_control_state *ecs);
- static void prepare_to_wait (struct execution_control_state *ecs);
-@@ -4417,9 +4419,17 @@ process_event_stop_test:
++ /* `struct dwarf2_loclist_baton' is too bound to its objfile so
++ it is expected to be made constant by CHECK_TYPEDEF.
++ TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are not valid for TYPE.
++ */
++ if (! TYPE_NOT_ALLOCATED (new_type)
++ && ! TYPE_NOT_ASSOCIATED (new_type) && has_stack_frames ())
++ dwarf_loclist_baton_eval
++ (TYPE_RANGE_DATA (new_type)->byte_stride.u.dwarf_loclist.loclist,
++ TYPE_RANGE_DATA (new_type)->byte_stride.u.dwarf_loclist.type,
++ &addr);
++ TYPE_BYTE_STRIDE (new_type) = addr;
++ TYPE_RANGE_DATA (new_type)->byte_stride.kind
++ = RANGE_BOUND_KIND_CONSTANT;
++ }
++ break;
++ }
++
++ /* Convert TYPE_RANGE_HIGH_BOUND_IS_COUNT into a regular bound. */
++ if (TYPE_RANGE_HIGH_BOUND_IS_COUNT (new_type))
++ {
++ TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (new_type)
++ + TYPE_HIGH_BOUND (new_type) - 1;
++ TYPE_RANGE_HIGH_BOUND_IS_COUNT (new_type) = 0;
++ }
+ }
- if (what.is_longjmp)
- {
-- if (!gdbarch_get_longjmp_target_p (gdbarch)
-- || !gdbarch_get_longjmp_target (gdbarch,
-- frame, &jmp_buf_pc))
-+ struct value *arg_value;
-+
-+ /* If we set the longjmp breakpoint via a SystemTap probe,
-+ then use it to extract the arguments. The destination
-+ PC is the third argument to the probe. */
-+ arg_value = stap_safe_evaluate_at_pc (frame, 2);
-+ if (arg_value)
-+ jmp_buf_pc = value_as_address (arg_value);
-+ else if (!gdbarch_get_longjmp_target_p (gdbarch)
-+ || !gdbarch_get_longjmp_target (gdbarch,
-+ frame, &jmp_buf_pc))
- {
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog,
-@@ -4437,12 +4447,7 @@ process_event_stop_test:
- insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
- }
- else
-- {
-- struct symbol *func = get_frame_function (frame);
--
-- if (func)
-- check_exception_resume (ecs, frame, func);
-- }
-+ check_exception_resume (ecs, frame);
- keep_going (ecs);
- return;
+ /* Copy pointers to other types. */
+ if (TYPE_TARGET_TYPE (type))
+ TYPE_TARGET_TYPE (new_type) =
+- copy_type_recursive (objfile,
+- TYPE_TARGET_TYPE (type),
+- copied_types);
++ copy_type_recursive_1 (objfile,
++ TYPE_TARGET_TYPE (type),
++ copied_types);
+ if (TYPE_VPTR_BASETYPE (type))
+ TYPE_VPTR_BASETYPE (new_type) =
+- copy_type_recursive (objfile,
+- TYPE_VPTR_BASETYPE (type),
+- copied_types);
++ copy_type_recursive_1 (objfile,
++ TYPE_VPTR_BASETYPE (type),
++ copied_types);
++
++ if (TYPE_CODE (new_type) == TYPE_CODE_ARRAY)
++ {
++ struct type *new_index_type = TYPE_INDEX_TYPE (new_type);
++
++ if (TYPE_BYTE_STRIDE (new_index_type) == 0)
++ TYPE_BYTE_STRIDE (new_index_type)
++ = TYPE_LENGTH (TYPE_TARGET_TYPE (new_type));
++ }
++
+ /* Maybe copy the type_specific bits.
-@@ -5524,15 +5529,65 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
- }
+ NOTE drow/2005-12-09: We do not copy the C++-specific bits like
+@@ -3487,6 +3848,17 @@ copy_type_recursive (struct objfile *objfile,
+ return new_type;
}
-+/* A helper for check_exception_resume that sets an
-+ exception-breakpoint based on a SystemTap probe. */
++/* Recursively copy (deep copy) TYPE. Return a new type allocated using
++ malloc, a saved type if we have already visited TYPE (using COPIED_TYPES),
++ or TYPE if it is not associated with OBJFILE. */
++
++struct type *
++copy_type_recursive (struct type *type,
++ htab_t copied_types)
++{
++ return copy_type_recursive_1 (TYPE_OBJFILE (type), type, copied_types);
++}
++
+ /* Make a copy of the given TYPE, except that the pointer & reference
+ types are not preserved.
+
+@@ -3509,6 +3881,201 @@ copy_type (const struct type *type)
+ return new_type;
+ }
+
++#if 0
++/* Callback type for main_type_crawl. */
++typedef int (*main_type_crawl_iter) (struct type *type, void *data);
++
++/* Iterate all main_type structures reachable through any `struct type *' from
++ TYPE. ITER will be called only for one type of each main_type, use
++ TYPE_CHAIN traversal to find all the type instances. ITER is being called
++ for each main_type found. ITER returns non-zero if main_type_crawl should
++ depth-first enter the specific type. ITER must provide some detection for
++ reentering the same main_type as this function would otherwise endlessly
++ loop. */
+
+static void
-+insert_exception_resume_from_probe (struct thread_info *tp,
-+ const struct stap_probe *probe,
-+ struct objfile *objfile,
-+ struct frame_info *frame)
++main_type_crawl (struct type *type, main_type_crawl_iter iter, void *data)
+{
-+ struct value *arg_value;
-+ CORE_ADDR handler;
-+ struct breakpoint *bp;
++ struct type *type_iter;
++ int i;
+
-+ arg_value = stap_safe_evaluate_at_pc (frame, 1);
-+ if (!arg_value)
++ if (!type)
+ return;
+
-+ handler = value_as_address (arg_value);
-+
-+ if (debug_infrun)
-+ fprintf_unfiltered (gdb_stdlog,
-+ "infrun: exception resume at %s\n",
-+ paddress (get_objfile_arch (objfile),
-+ handler));
++ gdb_assert (TYPE_OBJFILE (type) == NULL);
+
-+ bp = set_momentary_breakpoint_at_pc (get_frame_arch (frame),
-+ handler, bp_exception_resume);
-+ bp->thread = tp->num;
-+ inferior_thread ()->control.exception_resume_breakpoint = bp;
-+}
++ /* `struct cplus_struct_type' handling is unsupported by this function. */
++ gdb_assert ((TYPE_CODE (type) != TYPE_CODE_STRUCT
++ && TYPE_CODE (type) != TYPE_CODE_UNION)
++ || !HAVE_CPLUS_STRUCT (type));
+
- /* This is called when an exception has been intercepted. Check to
- see whether the exception's destination is of interest, and if so,
- set an exception resume breakpoint there. */
-
- static void
- check_exception_resume (struct execution_control_state *ecs,
-- struct frame_info *frame, struct symbol *func)
-+ struct frame_info *frame)
- {
- volatile struct gdb_exception e;
-+ struct objfile *objfile;
-+ const struct stap_probe *probe;
-+ struct symbol *func;
++ if (!(*iter) (type, data))
++ return;
+
-+ /* First see if this exception unwinding breakpoint was set via a
-+ SystemTap probe point. If so, the probe has two arguments: the
-+ CFA and the HANDLER. We ignore the CFA, extract the handler, and
-+ set a breakpoint there. */
-+ probe = find_probe_by_pc (get_frame_pc (frame), &objfile);
-+ if (probe)
++ /* Iterate all the type instances of this main_type. */
++ type_iter = type;
++ do
+ {
-+ insert_exception_resume_from_probe (ecs->event_thread, probe,
-+ objfile, frame);
-+ return;
++ gdb_assert (TYPE_MAIN_TYPE (type_iter) == TYPE_MAIN_TYPE (type));
++
++ main_type_crawl (TYPE_POINTER_TYPE (type), iter, data);
++ main_type_crawl (TYPE_REFERENCE_TYPE (type), iter, data);
++
++ type_iter = TYPE_CHAIN (type_iter);
+ }
++ while (type_iter != type);
+
-+ func = get_frame_function (frame);
-+ if (!func)
-+ return;
-
- TRY_CATCH (e, RETURN_MASK_ERROR)
- {
-@@ -6564,7 +6619,8 @@ static const struct lval_funcs siginfo_value_funcs =
- if there's no object available. */
-
- static struct value *
--siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var)
-+siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var,
-+ void *ignore)
- {
- if (target_has_stack
- && !ptid_equal (inferior_ptid, null_ptid)
-@@ -7059,6 +7115,15 @@ show_schedule_multiple (struct ui_file *file, int from_tty,
- "of all processes is %s.\n"), value);
- }
-
-+/* Implementation of `siginfo' variable. */
++ for (i = 0; i < TYPE_NFIELDS (type); i++)
++ main_type_crawl (TYPE_FIELD_TYPE (type, i), iter, data);
++
++ main_type_crawl (TYPE_TARGET_TYPE (type), iter, data);
++ main_type_crawl (TYPE_VPTR_BASETYPE (type), iter, data);
++}
++
++/* A helper for delete_type which deletes a main_type and the things to which
++ it refers. TYPE is a type whose main_type we wish to destroy. */
+
-+static const struct internalvar_funcs siginfo_funcs =
++static void
++delete_main_type (struct type *type)
+{
-+ siginfo_make_value,
-+ NULL,
-+ NULL
-+};
++ int i;
+
- void
- _initialize_infrun (void)
- {
-@@ -7347,7 +7412,7 @@ enabled by default on some platforms."),
- value with a void typed value, and when we get here, gdbarch
- isn't initialized yet. At this point, we're quite sure there
- isn't another convenience variable of the same name. */
-- create_internalvar_type_lazy ("_siginfo", siginfo_make_value);
-+ create_internalvar_type_lazy ("_siginfo", &siginfo_funcs, NULL);
-
- add_setshow_boolean_cmd ("observer", no_class,
- &observer_mode_1, _("\
-diff --git a/gdb/linespec.c b/gdb/linespec.c
-index 0782c54..31bb36c 100644
---- a/gdb/linespec.c
-+++ b/gdb/linespec.c
-@@ -43,6 +43,7 @@
- #include "cli/cli-utils.h"
- #include "filenames.h"
- #include "ada-lang.h"
-+#include "stap-probe.h"
-
- typedef struct symtab *symtab_p;
- DEF_VEC_P (symtab_p);
-@@ -802,6 +803,7 @@ keep_name_info (char *p, int on_boundary)
- PC returned is 0.
- FILE:FUNCTION -- likewise, but prefer functions in that file.
- *EXPR -- line in which address EXPR appears.
-+ -p [OBJFILE:][PROVIDER:]NAME -- a systemtap static probe
-
- This may all be followed by an "if EXPR", which we ignore.
-
-@@ -872,6 +874,9 @@ decode_line_internal (struct linespec_state *self, char **argptr)
- return decode_indirect (self, argptr);
- }
-
-+ if (strncmp (*argptr, "-p", 2) == 0 && isspace ((*argptr)[2]))
-+ return parse_stap_probe (argptr, self->canonical);
++ gdb_assert (TYPE_DISCARDABLE (type));
++ gdb_assert (TYPE_OBJFILE (type) == NULL);
+
- is_quoted = (strchr (get_gdb_completer_quote_characters (),
- **argptr) != NULL);
-
-diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
-index 50d4efd..893b7c4 100644
---- a/gdb/linux-nat.c
-+++ b/gdb/linux-nat.c
-@@ -288,6 +288,7 @@ static void restore_child_signals_mask (sigset_t *prev_mask);
- struct lwp_info;
- static struct lwp_info *add_lwp (ptid_t ptid);
- static void purge_lwp_list (int pid);
-+static void delete_lwp (ptid_t ptid);
- static struct lwp_info *find_lwp_pid (ptid_t ptid);
-
- \f
-@@ -584,6 +585,31 @@ linux_child_post_startup_inferior (ptid_t ptid)
- linux_enable_tracesysgood (ptid);
- }
-
-+/* Return the number of known LWPs in the tgid given by PID. */
++ xfree (TYPE_NAME (type));
++ xfree (TYPE_TAG_NAME (type));
+
-+static int
-+num_lwps (int pid)
-+{
-+ int count = 0;
-+ struct lwp_info *lp;
++ for (i = 0; i < TYPE_NFIELDS (type); ++i)
++ {
++ xfree (TYPE_FIELD_NAME (type, i));
++
++ if (TYPE_FIELD_LOC_KIND (type, i) == FIELD_LOC_KIND_PHYSNAME)
++ xfree (TYPE_FIELD_STATIC_PHYSNAME (type, i));
++ }
++ xfree (TYPE_FIELDS (type));
+
-+ for (lp = lwp_list; lp; lp = lp->next)
-+ if (ptid_get_pid (lp->ptid) == pid)
-+ count++;
++ gdb_assert (!HAVE_CPLUS_STRUCT (type));
+
-+ return count;
++ xfree (TYPE_MAIN_TYPE (type));
+}
+
-+/* Call delete_lwp with prototype compatible for make_cleanup. */
++/* Delete all the instances on TYPE_CHAIN of TYPE, including their referenced
++ main_type. TYPE must be a reclaimable type - neither permanent nor objfile
++ associated. */
+
+static void
-+delete_lwp_cleanup (void *lp_voidp)
++delete_type_chain (struct type *type)
+{
-+ struct lwp_info *lp = lp_voidp;
++ struct type *type_iter, *type_iter_to_free;
+
-+ delete_lwp (lp->ptid);
-+}
++ gdb_assert (TYPE_DISCARDABLE (type));
++ gdb_assert (TYPE_OBJFILE (type) == NULL);
+
- static int
- linux_child_follow_fork (struct target_ops *ops, int follow_child)
- {
-@@ -630,6 +656,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \
- /* Detach new forked process? */
- if (detach_fork)
- {
-+ struct cleanup *old_chain;
++ delete_main_type (type);
+
- /* Before detaching from the child, remove all breakpoints
- from it. If we forked, then this has already been taken
- care of by infrun.c. If we vforked however, any
-@@ -652,7 +680,28 @@ holding the child stopped. Try \"set detach-on-fork\" or \
- child_pid);
- }
-
-+ old_chain = save_inferior_ptid ();
-+ inferior_ptid = ptid_build (child_pid, child_pid, 0);
++ type_iter = type;
++ do
++ {
++ type_iter_to_free = type_iter;
++ type_iter = TYPE_CHAIN (type_iter);
++ xfree (type_iter_to_free);
++ }
++ while (type_iter != type);
++}
+
-+ child_lp = add_lwp (inferior_ptid);
-+ child_lp->stopped = 1;
-+ child_lp->last_resume_kind = resume_stop;
-+ make_cleanup (delete_lwp_cleanup, child_lp);
++/* Hash function for type_discardable_table. */
+
-+ /* CHILD_LP has new PID, therefore linux_nat_new_thread is not called for it.
-+ See i386_inferior_data_get for the Linux kernel specifics.
-+ Ensure linux_nat_prepare_to_resume will reset the hardware debug
-+ registers. It is done by the linux_nat_new_thread call, which is
-+ being skipped in add_lwp above for the first lwp of a pid. */
-+ gdb_assert (num_lwps (GET_PID (child_lp->ptid)) == 1);
-+ if (linux_nat_new_thread != NULL)
-+ linux_nat_new_thread (child_lp);
++static hashval_t
++type_discardable_hash (const void *p)
++{
++ const struct type *type = p;
+
-+ if (linux_nat_prepare_to_resume != NULL)
-+ linux_nat_prepare_to_resume (child_lp);
- ptrace (PTRACE_DETACH, child_pid, 0, 0);
++ return htab_hash_pointer (TYPE_MAIN_TYPE (type));
++}
+
-+ do_cleanups (old_chain);
- }
- else
- {
-@@ -670,6 +719,9 @@ holding the child stopped. Try \"set detach-on-fork\" or \
- save_current_program_space ();
-
- inferior_ptid = ptid_build (child_pid, child_pid, 0);
-+ reinit_frame_cache ();
-+ registers_changed ();
-+
- add_thread (inferior_ptid);
- child_lp = add_lwp (inferior_ptid);
- child_lp->stopped = 1;
-@@ -861,6 +913,9 @@ holding the child stopped. Try \"set detach-on-fork\" or \
- informing the solib layer about this new process. */
-
- inferior_ptid = ptid_build (child_pid, child_pid, 0);
-+ reinit_frame_cache ();
-+ registers_changed ();
-+
- add_thread (inferior_ptid);
- child_lp = add_lwp (inferior_ptid);
- child_lp->stopped = 1;
-@@ -1111,21 +1166,6 @@ purge_lwp_list (int pid)
- }
- }
-
--/* Return the number of known LWPs in the tgid given by PID. */
--
--static int
--num_lwps (int pid)
--{
-- int count = 0;
-- struct lwp_info *lp;
--
-- for (lp = lwp_list; lp; lp = lp->next)
-- if (ptid_get_pid (lp->ptid) == pid)
-- count++;
--
-- return count;
--}
--
- /* Add the LWP specified by PID to the list. Return a pointer to the
- structure describing the new LWP. The LWP should already be stopped
- (with an exception for the very first LWP). */
-@@ -1235,6 +1275,46 @@ iterate_over_lwps (ptid_t filter,
- return NULL;
- }
-
-+/* Iterate like iterate_over_lwps does except when forking-off a child call
-+ CALLBACK with CALLBACK_DATA specifically only for that new child PID. */
++/* Equality function for type_discardable_table. */
+
-+void
-+linux_nat_iterate_watchpoint_lwps
-+ (linux_nat_iterate_watchpoint_lwps_ftype callback, void *callback_data)
++static int
++type_discardable_equal (const void *a, const void *b)
+{
-+ int inferior_pid = ptid_get_pid (inferior_ptid);
-+ struct inferior *inf = current_inferior ();
++ const struct type *left = a;
++ const struct type *right = b;
+
-+ if (inf->pid == inferior_pid)
-+ {
-+ /* Iterate all the threads of the current inferior. Without specifying
-+ INFERIOR_PID it would iterate all threads of all inferiors, which is
-+ inappropriate for watchpoints. */
++ return TYPE_MAIN_TYPE (left) == TYPE_MAIN_TYPE (right);
++}
+
-+ iterate_over_lwps (pid_to_ptid (inferior_pid), callback, callback_data);
-+ }
-+ else
-+ {
-+ /* Detaching a new child PID temporarily present in INFERIOR_PID. */
++/* A helper for type_mark_used. */
+
-+ struct lwp_info *child_lp;
-+ struct cleanup *old_chain;
-+ pid_t child_pid = GET_PID (inferior_ptid);
-+ ptid_t child_ptid = ptid_build (child_pid, child_pid, 0);
++static int
++type_mark_used_crawl (struct type *type, void *unused)
++{
++ if (!TYPE_DISCARDABLE (type))
++ return 0;
+
-+ gdb_assert (!is_lwp (inferior_ptid));
-+ gdb_assert (find_lwp_pid (child_ptid) == NULL);
-+ child_lp = add_lwp (child_ptid);
-+ child_lp->stopped = 1;
-+ child_lp->last_resume_kind = resume_stop;
-+ old_chain = make_cleanup (delete_lwp_cleanup, child_lp);
++ if (TYPE_DISCARDABLE_AGE (type) == type_discardable_age_current)
++ return 0;
+
-+ callback (child_lp, callback_data);
++ TYPE_DISCARDABLE_AGE (type) = type_discardable_age_current;
+
-+ do_cleanups (old_chain);
-+ }
++ /* Continue the traversal. */
++ return 1;
+}
+
- /* Update our internal state when changing from one checkpoint to
- another indicated by NEW_PTID. We can only switch single-threaded
- applications, so we only create one new LWP, and the previous list
-diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
-index d9dc71b..6217370 100644
---- a/gdb/linux-nat.h
-+++ b/gdb/linux-nat.h
-@@ -158,6 +158,12 @@ struct lwp_info *iterate_over_lwps (ptid_t filter,
- void *),
- void *data);
-
-+typedef int (*linux_nat_iterate_watchpoint_lwps_ftype) (struct lwp_info *lwp,
-+ void *arg);
++/* Mark TYPE and its connected types as used in this free_all_types pass. */
+
-+extern void linux_nat_iterate_watchpoint_lwps
-+ (linux_nat_iterate_watchpoint_lwps_ftype callback, void *callback_data);
++void
++type_mark_used (struct type *type)
++{
++ if (type == NULL)
++ return;
+
- /* Create a prototype generic GNU/Linux target. The client can
- override it with local methods. */
- struct target_ops * linux_target (void);
-diff --git a/gdb/machoread.c b/gdb/machoread.c
-index 9fa97e1..d6f0f38 100644
---- a/gdb/machoread.c
-+++ b/gdb/machoread.c
-@@ -1032,6 +1032,7 @@ static const struct sym_fns macho_sym_fns = {
- default_symfile_segments, /* Get segment information from a file. */
- NULL,
- macho_symfile_relocate, /* Relocate a debug section. */
-+ NULL, /* sym_get_probes */
- &psym_functions
- };
-
-diff --git a/gdb/main.c b/gdb/main.c
-index 8b45c25..c7ea0df 100644
---- a/gdb/main.c
-+++ b/gdb/main.c
-@@ -37,6 +37,7 @@
++ if (!TYPE_DISCARDABLE (type))
++ return;
++
++ main_type_crawl (type, type_mark_used_crawl, NULL);
++}
++
++/* A traverse callback for type_discardable_table which removes any
++ type_discardable whose reference count is now zero (unused link). */
++
++static int
++type_discardable_remove (void **slot, void *unused)
++{
++ struct type *type = *slot;
++
++ gdb_assert (TYPE_DISCARDABLE (type));
++
++ if (TYPE_DISCARDABLE_AGE (type) != type_discardable_age_current)
++ {
++ delete_type_chain (type);
++
++ htab_clear_slot (type_discardable_table, slot);
++ }
++
++ return 1;
++}
++
++/* Free all the reclaimable types that have been allocated and that have
++ currently zero reference counter.
++
++ This function is called after each command, successful or not. Use this
++ cleanup only in the GDB idle state as GDB only marks those types used by
++ globally tracked objects (with no autovariable references tracking). */
++
++void
++free_all_types (void)
++{
++ /* Mark a new pass. As GDB checks all the entries were visited after each
++ pass there cannot be any stale entries already containing the changed
++ value. */
++ type_discardable_age_current ^= 1;
++
++ observer_notify_mark_used ();
++
++ htab_traverse (type_discardable_table, type_discardable_remove, NULL);
++}
++#endif
- #include "interps.h"
- #include "main.h"
-+#include "python/python.h"
- #include "source.h"
- #include "cli/cli-cmds.h"
- #include "python/python.h"
-@@ -264,6 +265,8 @@ captured_main (void *data)
- char *cdarg = NULL;
- char *ttyarg = NULL;
+ /* Helper functions to initialize architecture-specific types. */
-+ int python_script = 0;
+@@ -4042,6 +4609,13 @@ void
+ _initialize_gdbtypes (void)
+ {
+ gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init);
+
- /* These are static so that we can take their address in an
- initializer. */
- static int print_help;
-@@ -457,10 +460,14 @@ captured_main (void *data)
- {"args", no_argument, &set_args, 1},
- {"l", required_argument, 0, 'l'},
- {"return-child-result", no_argument, &return_child_result, 1},
-+#if HAVE_PYTHON
-+ {"python", no_argument, 0, 'P'},
-+ {"P", no_argument, 0, 'P'},
++#if 0
++ type_discardable_table = htab_create_alloc (20, type_discardable_hash,
++ type_discardable_equal, NULL,
++ xcalloc, xfree);
+#endif
- {0, no_argument, 0, 0}
- };
++
+ objfile_type_data = register_objfile_data ();
-- while (1)
-+ while (!python_script)
- {
- int option_index;
+ add_setshow_zinteger_cmd ("overload", no_class, &overload_debug,
+diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
+index 17bfbc5..72e9cc5 100644
+--- a/gdb/gdbtypes.h
++++ b/gdb/gdbtypes.h
+@@ -228,6 +228,11 @@ enum type_instance_flag_value
-@@ -478,6 +485,9 @@ captured_main (void *data)
- case 0:
- /* Long option that just sets a flag. */
- break;
-+ case 'P':
-+ python_script = 1;
-+ break;
- case OPT_SE:
- symarg = optarg;
- execarg = optarg;
-@@ -673,7 +683,31 @@ captured_main (void *data)
+ #define TYPE_TARGET_STUB(t) (TYPE_MAIN_TYPE (t)->flag_target_stub)
- /* Now that gdb_init has created the initial inferior, we're in
- position to set args for that inferior. */
-- if (set_args)
-+ if (python_script)
-+ {
-+ /* The first argument is a python script to evaluate, and
-+ subsequent arguments are passed to the script for
-+ processing there. */
-+ if (optind >= argc)
-+ {
-+ fprintf_unfiltered (gdb_stderr,
-+ _("%s: Python script file name required\n"),
-+ argv[0]);
-+ exit (1);
-+ }
++/* Type needs to be evaluated on each CHECK_TYPEDEF and its results must not be
++ sticky. */
+
-+ /* FIXME: should handle inferior I/O intelligently here.
-+ E.g., should be possible to run gdb in pipeline and have
-+ Python (and gdb) output go to stderr or file; and if a
-+ prompt is needed, open the tty. */
-+ quiet = 1;
-+ /* FIXME: should read .gdbinit if, and only if, a prompt is
-+ requested by the script. Though... maybe this is not
-+ ideal? */
-+ /* FIXME: likewise, reading in history. */
-+ inhibit_gdbinit = 1;
-+ }
-+ else if (set_args)
- {
- /* The remaining options are the command-line options for the
- inferior. The first one is the sym/exec file, and the rest
-@@ -922,7 +956,8 @@ captured_main (void *data)
++#define TYPE_DYNAMIC(t) (TYPE_MAIN_TYPE (t)->flag_dynamic)
++
+ /* Static type. If this is set, the corresponding type had
+ a static modifier.
+ Note: This may be unnecessary, since static data members
+@@ -311,6 +316,50 @@ enum type_instance_flag_value
- /* Read in the old history after all the command files have been
- read. */
-- init_history ();
-+ if (!python_script)
-+ init_history ();
+ #define TYPE_FLAG_ENUM(t) (TYPE_MAIN_TYPE (t)->flag_flag_enum)
- if (batch_flag)
- {
-@@ -933,13 +968,25 @@ captured_main (void *data)
- /* Show time and/or space usage. */
- do_cleanups (pre_stat_chain);
++#if 0
++/* Define this type as being reclaimable during free_all_types. Type is
++ required to be have TYPE_OBJFILE set to NULL. Setting this flag requires
++ initializing TYPE_DISCARDABLE_AGE, see alloc_type_discardable. */
++
++#define TYPE_DISCARDABLE(t) (TYPE_MAIN_TYPE (t)->flag_discardable)
++
++/* Marker this type has been visited by the type_mark_used by this
++ mark-and-sweep types garbage collecting pass. Current pass is represented
++ by TYPE_DISCARDABLE_AGE_CURRENT. */
++
++#define TYPE_DISCARDABLE_AGE(t) (TYPE_MAIN_TYPE (t)->flag_discardable_age)
++#endif
++
++/* Is HIGH_BOUND a low-bound relative count (1) or the high bound itself (0)? */
++
++#define TYPE_RANGE_HIGH_BOUND_IS_COUNT(range_type) \
++ (TYPE_MAIN_TYPE (range_type)->flag_range_high_bound_is_count)
++
++/* Not allocated. TYPE_ALLOCATED(t) must be NULL in such case. If this flag
++ is unset and TYPE_ALLOCATED(t) is NULL then the type is allocated. If this
++ flag is unset and TYPE_ALLOCATED(t) is not NULL then its DWARF block
++ determines the actual allocation state. */
++
++#define TYPE_NOT_ALLOCATED(t) (TYPE_MAIN_TYPE (t)->flag_not_allocated)
++
++/* Not associated. TYPE_ASSOCIATED(t) must be NULL in such case. If this flag
++ is unset and TYPE_ASSOCIATED(t) is NULL then the type is associated. If
++ this flag is unset and TYPE_ASSOCIATED(t) is not NULL then its DWARF block
++ determines the actual association state. */
++
++#define TYPE_NOT_ASSOCIATED(t) (TYPE_MAIN_TYPE (t)->flag_not_associated)
++
++/* Address of the actual data as for DW_AT_data_location. Its dwarf block must
++ not be evaluated unless both TYPE_NOT_ALLOCATED and TYPE_NOT_ASSOCIATED are
++ false. If TYPE_DATA_LOCATION_IS_ADDR set then TYPE_DATA_LOCATION_ADDR value
++ is the actual data address value. If unset and
++ TYPE_DATA_LOCATION_DWARF_BLOCK is NULL then the value is the normal
++ value_raw_address. If unset and TYPE_DATA_LOCATION_DWARF_BLOCK is not NULL
++ then its DWARF block determines the actual data address. */
++
++#define TYPE_DATA_LOCATION_IS_ADDR(t) \
++ (TYPE_MAIN_TYPE (t)->flag_data_location_is_addr)
++
+ /* Constant type. If this is set, the corresponding type has a
+ const modifier. */
-- /* NOTE: cagney/1999-11-07: There is probably no reason for not
-- moving this loop and the code found in captured_command_loop()
-- into the command_loop() proper. The main thing holding back that
-- change - SET_TOP_LEVEL() - has been eliminated. */
-- while (1)
-+#if HAVE_PYTHON
-+ if (python_script)
- {
-- catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
-+ extern int pagination_enabled;
-+ pagination_enabled = 0;
-+ run_python_script (argc - optind, &argv[optind]);
-+ return 1;
-+ }
-+ else
+@@ -421,6 +470,15 @@ struct main_type
+ /* True if this type was declared with "class" rather than
+ "struct". */
+ unsigned int flag_declared_class : 1;
++#if 0
++ unsigned int flag_discardable : 1;
++ unsigned int flag_discardable_age : 1;
+#endif
++ unsigned int flag_dynamic : 1;
++ unsigned int flag_range_high_bound_is_count : 1;
++ unsigned int flag_not_allocated : 1;
++ unsigned int flag_not_associated : 1;
++ unsigned int flag_data_location_is_addr : 1;
+
+ /* True if this is an enum type with disjoint values. This affects
+ how the enum is printed. */
+@@ -501,6 +559,20 @@ struct main_type
+
+ struct type *target_type;
+
++ /* For DW_AT_data_location. */
++ union
+ {
-+ /* NOTE: cagney/1999-11-07: There is probably no reason for not
-+ moving this loop and the code found in captured_command_loop()
-+ into the command_loop() proper. The main thing holding back that
-+ change - SET_TOP_LEVEL() - has been eliminated. */
-+ while (1)
++ struct dwarf2_locexpr_baton *dwarf_block;
++ CORE_ADDR addr;
++ }
++ data_location;
++
++ /* For DW_AT_allocated. */
++ struct dwarf2_locexpr_baton *allocated;
++
++ /* For DW_AT_associated. */
++ struct dwarf2_locexpr_baton *associated;
++
+ /* For structure and union types, a description of each field.
+ For set and pascal array types, there is one "field",
+ whose type is the domain type of the set or array.
+@@ -583,13 +655,34 @@ struct main_type
+
+ struct range_bounds
+ {
++ struct
+ {
-+ catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
-+ }
- }
- /* No exit -- exit is through quit_command. */
- }
-@@ -971,7 +1018,12 @@ print_gdb_help (struct ui_file *stream)
- fputs_unfiltered (_("\
- This is the GNU debugger. Usage:\n\n\
- gdb [options] [executable-file [core-file or process-id]]\n\
-- gdb [options] --args executable-file [inferior-arguments ...]\n\n\
-+ gdb [options] --args executable-file [inferior-arguments ...]\n"), stream);
-+#if HAVE_PYTHON
-+ fputs_unfiltered (_("\
-+ gdb [options] [--python|-P] script-file [script-arguments ...]\n"), stream);
-+#endif
-+ fputs_unfiltered (_("\n\
- Options:\n\n\
- "), stream);
- fputs_unfiltered (_("\
-@@ -1009,7 +1061,13 @@ Options:\n\n\
- --nw Do not use a window interface.\n\
- --nx Do not read "), stream);
- fputs_unfiltered (gdbinit, stream);
-- fputs_unfiltered (_(" file.\n\
-+ fputs_unfiltered (_(" file.\n"), stream);
-+#if HAVE_PYTHON
-+ fputs_unfiltered (_("\
-+ --python, -P Following argument is Python script file; remaining\n\
-+ arguments are passed to script.\n"), stream);
-+#endif
-+ fputs_unfiltered (_("\
- --quiet Do not print version number on startup.\n\
- --readnow Fully read symbol files on first access.\n\
- "), stream);
-diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
-index 4de7392..fb0b550 100644
---- a/gdb/mi/mi-cmd-var.c
-+++ b/gdb/mi/mi-cmd-var.c
-@@ -721,7 +721,6 @@ mi_cmd_var_update (char *command, char **argv, int argc)
- }
- else
- {
-- /* Get varobj handle, if a valid var obj name was specified */
- struct varobj *var = varobj_get_handle (name);
-
- varobj_update_one (var, print_values, 1 /* explicit */);
-diff --git a/gdb/mipsread.c b/gdb/mipsread.c
-index 5790730..23ceece 100644
---- a/gdb/mipsread.c
-+++ b/gdb/mipsread.c
-@@ -401,6 +401,7 @@ static const struct sym_fns ecoff_sym_fns =
- default_symfile_segments, /* Get segment information from a file. */
- NULL,
- default_symfile_relocate, /* Relocate a debug section. */
-+ NULL, /* sym_probe_fns */
- &psym_functions
- };
++ union
++ {
++ LONGEST constant;
++ struct dwarf2_locexpr_baton *dwarf_block;
++ struct
++ {
++ struct dwarf2_loclist_baton *loclist;
++ struct type *type;
++ }
++ dwarf_loclist;
++ }
++ u;
++ enum range_bound_kind
++ {
++ RANGE_BOUND_KIND_CONSTANT,
++ RANGE_BOUND_KIND_DWARF_BLOCK,
++ RANGE_BOUND_KIND_DWARF_LOCLIST
++ }
++ kind;
++ }
+ /* Low bound of range. */
+-
+- LONGEST low;
+-
++ low,
+ /* High bound of range. */
+-
+- LONGEST high;
++ high,
++ /* Byte stride of range. */
++ byte_stride;
-diff --git a/gdb/objfiles.c b/gdb/objfiles.c
-index 1cf5aee..d1640ef 100644
---- a/gdb/objfiles.c
-+++ b/gdb/objfiles.c
-@@ -811,6 +811,11 @@ objfile_relocate1 (struct objfile *objfile,
- obj_section_addr (s));
- }
+ /* Flags indicating whether the values of low and high are
+ valid. When true, the respective range value is
+@@ -1054,9 +1147,9 @@ extern void allocate_gnat_aux_type (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, ARRAY or STRING 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
+ /* Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you want the real
+@@ -1064,11 +1157,16 @@ extern void allocate_gnat_aux_type (struct type *);
+ #define TYPE_CODE(thistype) TYPE_MAIN_TYPE(thistype)->code
+ #define TYPE_NFIELDS(thistype) TYPE_MAIN_TYPE(thistype)->nfields
+ #define TYPE_FIELDS(thistype) TYPE_MAIN_TYPE(thistype)->flds_bnds.fields
++#define TYPE_DATA_LOCATION_DWARF_BLOCK(thistype) TYPE_MAIN_TYPE (thistype)->data_location.dwarf_block
++#define TYPE_DATA_LOCATION_ADDR(thistype) TYPE_MAIN_TYPE (thistype)->data_location.addr
++#define TYPE_ALLOCATED(thistype) TYPE_MAIN_TYPE (thistype)->allocated
++#define TYPE_ASSOCIATED(thistype) TYPE_MAIN_TYPE (thistype)->associated
+
+ #define TYPE_INDEX_TYPE(type) TYPE_FIELD_TYPE (type, 0)
+ #define TYPE_RANGE_DATA(thistype) TYPE_MAIN_TYPE(thistype)->flds_bnds.bounds
+-#define TYPE_LOW_BOUND(range_type) TYPE_RANGE_DATA(range_type)->low
+-#define TYPE_HIGH_BOUND(range_type) TYPE_RANGE_DATA(range_type)->high
++#define TYPE_LOW_BOUND(range_type) TYPE_RANGE_DATA(range_type)->low.u.constant
++#define TYPE_HIGH_BOUND(range_type) TYPE_RANGE_DATA(range_type)->high.u.constant
++#define TYPE_BYTE_STRIDE(range_type) TYPE_RANGE_DATA(range_type)->byte_stride.u.constant
+ #define TYPE_LOW_BOUND_UNDEFINED(range_type) \
+ TYPE_RANGE_DATA(range_type)->low_undefined
+ #define TYPE_HIGH_BOUND_UNDEFINED(range_type) \
+@@ -1085,7 +1183,14 @@ extern void allocate_gnat_aux_type (struct type *);
+ (TYPE_HIGH_BOUND(TYPE_INDEX_TYPE((arraytype))))
-+ /* Relocating SystemTap probes. */
-+ if (objfile->sf && objfile->sf->sym_probe_fns)
-+ objfile->sf->sym_probe_fns->sym_relocate_probe (objfile,
-+ new_offsets, delta);
+ #define TYPE_ARRAY_LOWER_BOUND_VALUE(arraytype) \
+- (TYPE_LOW_BOUND(TYPE_INDEX_TYPE((arraytype))))
++ TYPE_LOW_BOUND (TYPE_INDEX_TYPE (arraytype))
+
- /* Data changed. */
- return 1;
- }
-diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
-index c5bef8a..fc3beb3 100644
---- a/gdb/p-valprint.c
-+++ b/gdb/p-valprint.c
-@@ -39,6 +39,7 @@
- #include "cp-abi.h"
- #include "cp-support.h"
- #include "exceptions.h"
-+#include "dwarf2loc.h"
- \f
++/* TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype)) with a fallback to the
++ element size if no specific stride value is known. */
++#define TYPE_ARRAY_BYTE_STRIDE_VALUE(arraytype) \
++ (TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype)) == 0 \
++ ? TYPE_LENGTH (TYPE_TARGET_TYPE (arraytype)) \
++ : TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (arraytype)))
- /* See val_print for a description of the various parameters of this
-@@ -63,8 +64,31 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
- struct type *char_type;
- LONGEST val;
- CORE_ADDR addr;
-+ struct cleanup *back_to;
-+ struct type *saved_type = type;
-+ CORE_ADDR saved_address = address;
-+
-+ back_to = make_cleanup (null_cleanup, 0);
-+ address += embedded_offset;
-+ type = object_address_get_data (type, &address);
-+ if (type == NULL)
-+ {
-+ fputs_filtered (object_address_data_not_valid (saved_type), stream);
-+ gdb_flush (stream);
-+ do_cleanups (back_to);
-+ return 0;
-+ }
-+ if (address != saved_address + embedded_offset)
-+ {
-+ size_t length = TYPE_LENGTH (type);
+ /* C++ */
-- CHECK_TYPEDEF (type);
-+ valaddr = xmalloc (length);
-+ make_cleanup (xfree, (gdb_byte *) valaddr);
-+ read_memory (address, (gdb_byte *) valaddr, length);
-+ embedded_offset = 0;
-+ }
-+ else
-+ address -= embedded_offset;
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_ARRAY:
-@@ -120,8 +144,8 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
- {
- i = 0;
- }
-- val_print_array_elements (type, valaddr, embedded_offset,
-- address, stream, recurse,
-+ val_print_array_elements (saved_type, valaddr, embedded_offset,
-+ saved_address, stream, recurse,
- original_value, options, i);
- fprintf_filtered (stream, "}");
- }
-@@ -160,6 +184,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
- /* Try to print what function it points to. */
- print_address_demangle (gdbarch, addr, stream, demangle);
- /* Return value is irrelevant except for string pointers. */
-+ do_cleanups (back_to);
- return (0);
- }
+@@ -1531,6 +1636,18 @@ extern struct type *create_array_type (struct type *, struct type *,
+ struct type *);
+ extern struct type *lookup_array_range_type (struct type *, int, int);
-@@ -251,6 +276,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
- /* Return number of characters printed, including the terminating
- '\0' if we reached the end. val_print_string takes care including
- the terminating '\0' if necessary. */
-+ do_cleanups (back_to);
- return i;
++extern CORE_ADDR type_range_any_field_internal (struct type *range_type,
++ int fieldno);
++
++extern int type_range_high_bound_internal (struct type *range_type);
++
++extern int type_range_count_bound_internal (struct type *range_type);
++
++extern CORE_ADDR type_range_byte_stride_internal (struct type *range_type,
++ struct type *element_type);
++
++extern void finalize_type (struct type *type);
++
+ extern struct type *create_string_type (struct type *, struct type *,
+ struct type *);
+ extern struct type *lookup_string_range_type (struct type *, int, int);
+@@ -1576,6 +1693,10 @@ extern int is_public_ancestor (struct type *, struct type *);
- break;
-@@ -576,6 +602,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
- TYPE_CODE (type));
- }
- gdb_flush (stream);
-+ do_cleanups (back_to);
- return (0);
- }
- \f
-diff --git a/gdb/parse.c b/gdb/parse.c
-index 32a3bd6..9eaf2de 100644
---- a/gdb/parse.c
-+++ b/gdb/parse.c
-@@ -113,8 +113,6 @@ show_parserdebug (struct ui_file *file, int from_tty,
+ extern int is_unique_ancestor (struct type *, struct value *);
- static void free_funcalls (void *ignore);
++#if 0
++extern void type_mark_used (struct type *type);
++#endif
++
+ /* Overload resolution */
--static int prefixify_expression (struct expression *);
--
- static int prefixify_subexp (struct expression *, struct expression *, int,
- int);
+ #define LENGTH_MATCH(bv) ((bv)->rank[0])
+@@ -1651,10 +1772,13 @@ extern void maintenance_print_type (char *, int);
-@@ -188,7 +186,7 @@ free_funcalls (void *ignore)
- the expout array. LANG is the language used to parse the expression.
- And GDBARCH is the gdbarch to use during parsing. */
+ extern htab_t create_copied_types_hash (struct objfile *objfile);
--static void
-+void
- initialize_expout (int initial_size, const struct language_defn *lang,
- struct gdbarch *gdbarch)
- {
-@@ -204,7 +202,7 @@ initialize_expout (int initial_size, const struct language_defn *lang,
- It is generally used when the parser has just been parsed and
- created. */
+-extern struct type *copy_type_recursive (struct objfile *objfile,
+- struct type *type,
++extern struct type *copy_type_recursive (struct type *type,
+ htab_t copied_types);
--static void
-+void
- reallocate_expout (void)
- {
- /* Record the actual number of expression elements, and then
-@@ -811,7 +809,7 @@ copy_name (struct stoken token)
- return the index of the subexpression which is the left-hand-side
- of the struct operation at EXPOUT_LAST_STRUCT. */
+ extern struct type *copy_type (const struct type *type);
--static int
-+int
- prefixify_expression (struct expression *expr)
++#if 0
++extern void free_all_types (void);
++#endif
++
+ #endif /* GDBTYPES_H */
+diff --git a/gdb/jit.c b/gdb/jit.c
+index 568d17b..cdd9f49 100644
+--- a/gdb/jit.c
++++ b/gdb/jit.c
+@@ -38,6 +38,7 @@
+ #include "gdb-dlfcn.h"
+ #include "gdb_stat.h"
+ #include "exceptions.h"
++#include "gdb_bfd.h"
+
+ static const char *jit_reader_dir = NULL;
+
+@@ -132,17 +133,16 @@ mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
+ static struct bfd *
+ bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, char *target)
{
- int len = sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
-@@ -1529,6 +1527,7 @@ parser_fprintf (FILE *x, const char *y, ...)
+- const char *filename = xstrdup ("<in-memory>");
+ struct target_buffer *buffer = xmalloc (sizeof (struct target_buffer));
+
+ buffer->base = addr;
+ buffer->size = size;
+- return bfd_openr_iovec (filename, target,
+- mem_bfd_iovec_open,
+- buffer,
+- mem_bfd_iovec_pread,
+- mem_bfd_iovec_close,
+- mem_bfd_iovec_stat);
++ return gdb_bfd_openr_iovec ("<in-memory>", target,
++ mem_bfd_iovec_open,
++ buffer,
++ mem_bfd_iovec_pread,
++ mem_bfd_iovec_close,
++ mem_bfd_iovec_stat);
+ }
- int
- operator_check_standard (struct expression *exp, int pos,
-+ int (*type_func) (struct type *type, void *data),
- int (*objfile_func) (struct objfile *objfile,
- void *data),
- void *data)
-@@ -1570,7 +1569,7 @@ operator_check_standard (struct expression *exp, int pos,
- struct type *type = elts[pos + 2 + arg].type;
- struct objfile *objfile = TYPE_OBJFILE (type);
+ /* One reader that has been loaded successfully, and can potentially be used to
+@@ -868,7 +868,7 @@ jit_bfd_try_read_symtab (struct jit_code_entry *code_entry,
+ {
+ printf_unfiltered (_("\
+ JITed symbol file is not an object file, ignoring it.\n"));
+- bfd_close (nbfd);
++ gdb_bfd_unref (nbfd);
+ return;
+ }
-- if (objfile && (*objfile_func) (objfile, data))
-+ if (objfile && objfile_func && (*objfile_func) (objfile, data))
- return 1;
- }
+@@ -896,7 +896,8 @@ JITed symbol file is not an object file, ignoring it.\n"));
+ ++i;
}
-@@ -1588,7 +1587,8 @@ operator_check_standard (struct expression *exp, int pos,
-
- /* Check objfile where the variable itself is placed.
- SYMBOL_OBJ_SECTION (symbol) may be NULL. */
-- if ((*objfile_func) (SYMBOL_SYMTAB (symbol)->objfile, data))
-+ if (objfile_func
-+ && (*objfile_func) (SYMBOL_SYMTAB (symbol)->objfile, data))
- return 1;
- /* Check objfile where is placed the code touching the variable. */
-@@ -1601,24 +1601,27 @@ operator_check_standard (struct expression *exp, int pos,
+- /* This call takes ownership of NBFD. It does not take ownership of SAI. */
++ /* This call does not take ownership of SAI. */
++ make_cleanup_bfd_unref (nbfd);
+ objfile = symbol_file_add_from_bfd (nbfd, 0, sai, OBJF_SHARED, NULL);
+
+ do_cleanups (old_cleanups);
+diff --git a/gdb/m32r-rom.c b/gdb/m32r-rom.c
+index 76e4bf1..9a2f5aa 100644
+--- a/gdb/m32r-rom.c
++++ b/gdb/m32r-rom.c
+@@ -40,6 +40,7 @@
+ #include "inferior.h"
+ #include <ctype.h>
+ #include "regcache.h"
++#include "gdb_bfd.h"
+
+ /*
+ * All this stuff just to get my host computer's IP address!
+@@ -124,13 +125,15 @@ m32r_load (char *filename, int from_tty)
+ bfd *abfd;
+ unsigned int data_count = 0;
+ struct timeval start_time, end_time;
++ struct cleanup *cleanup;
- /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL. */
+ if (filename == NULL || filename[0] == 0)
+ filename = get_exec_file (1);
+
+- abfd = bfd_openr (filename, 0);
++ abfd = gdb_bfd_openr (filename, 0);
+ if (!abfd)
+ error (_("Unable to open file %s."), filename);
++ cleanup = make_cleanup_bfd_unref (abfd);
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ error (_("File is not an object file."));
+ gettimeofday (&start_time, NULL);
+@@ -188,6 +191,7 @@ m32r_load (char *filename, int from_tty)
+ confused... */
+
+ clear_symtab_users (0);
++ do_cleanups (cleanup);
+ }
-- if (type && TYPE_OBJFILE (type)
-+ if (type && type_func && (*type_func) (type, data))
-+ return 1;
-+ if (type && TYPE_OBJFILE (type) && objfile_func
- && (*objfile_func) (TYPE_OBJFILE (type), data))
- return 1;
-- if (objfile && (*objfile_func) (objfile, data))
-+ if (objfile && objfile_func && (*objfile_func) (objfile, data))
- return 1;
+ static void
+@@ -434,6 +438,7 @@ m32r_upload_command (char *args, int from_tty)
+ char buf[1024];
+ struct hostent *hostent;
+ struct in_addr inet_addr;
++ struct cleanup *cleanup;
- return 0;
+ /* First check to see if there's an ethernet port! */
+ monitor_printf ("ust\r");
+@@ -524,7 +529,8 @@ m32r_upload_command (char *args, int from_tty)
+ printf_filtered (" -- Ethernet load complete.\n");
+
+ gettimeofday (&end_time, NULL);
+- abfd = bfd_openr (args, 0);
++ abfd = gdb_bfd_openr (args, 0);
++ cleanup = make_cleanup_bfd_unref (abfd);
+ if (abfd != NULL)
+ { /* Download is done -- print section statistics. */
+ if (bfd_check_format (abfd, bfd_object) == 0)
+@@ -565,6 +571,7 @@ m32r_upload_command (char *args, int from_tty)
+ confused... */
+
+ clear_symtab_users (0);
++ do_cleanups (cleanup);
}
--/* Call OBJFILE_FUNC for any TYPE and OBJFILE found being referenced by EXP.
-- The functions are never called with NULL OBJFILE. Functions get passed an
-- arbitrary caller supplied DATA pointer. If any of the functions returns
-- non-zero value then (any other) non-zero value is immediately returned to
-- the caller. Otherwise zero is returned after iterating through whole EXP.
-- */
-+/* Call TYPE_FUNC and OBJFILE_FUNC for any TYPE and OBJFILE found being
-+ referenced by EXP. The functions are never called with NULL TYPE or NULL
-+ OBJFILE. Functions get passed an arbitrary caller supplied DATA pointer.
-+ If any of the functions returns non-zero value then (any other) non-zero
-+ value is immediately returned to the caller. Otherwise zero is returned
-+ after iterating through whole EXP. */
-
- static int
- exp_iterate (struct expression *exp,
-+ int (*type_func) (struct type *type, void *data),
- int (*objfile_func) (struct objfile *objfile, void *data),
- void *data)
- {
-@@ -1633,7 +1636,9 @@ exp_iterate (struct expression *exp,
-
- pos = endpos - oplen;
- if (exp->language_defn->la_exp_desc->operator_check (exp, pos,
-- objfile_func, data))
-+ type_func,
-+ objfile_func,
-+ data))
- return 1;
-
- endpos = pos;
-@@ -1664,8 +1669,29 @@ exp_uses_objfile (struct expression *exp, struct objfile *objfile)
- {
- gdb_assert (objfile->separate_debug_objfile_backlink == NULL);
-
-- return exp_iterate (exp, exp_uses_objfile_iter, objfile);
-+ return exp_iterate (exp, NULL, exp_uses_objfile_iter, objfile);
-+}
-+
-+/* Helper for exp_types_mark_used. */
-+
-+#if 0
-+static int
-+exp_types_mark_used_iter (struct type *type, void *unused)
-+{
-+ type_mark_used (type);
-+
-+ /* Continue the traversal. */
-+ return 0;
-+}
-+
-+/* Call type_mark_used for any type contained in EXP. */
-+
-+void
-+exp_types_mark_used (struct expression *exp)
-+{
-+ exp_iterate (exp, exp_types_mark_used_iter, NULL, NULL);
- }
-+#endif
-
- void
- _initialize_parse (void)
-diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
-index 16b40ac..c3813ff 100644
---- a/gdb/parser-defs.h
-+++ b/gdb/parser-defs.h
-@@ -130,6 +130,24 @@ union type_stack_elt
- extern union type_stack_elt *type_stack;
- extern int type_stack_depth, type_stack_size;
-
-+/* Allocate and initialize `expout' and its related variables `expout_size'
-+ and `expout_ptr'.
-+
-+ The first argument is the initial size to be used for xmalloc. The second
-+ argument is the language related to the expression. The third argument is
-+ corresponding gdbarch. */
-+
-+extern void initialize_expout (int, const struct language_defn *,
-+ struct gdbarch *);
-+
-+/* Reallocate `expout' in order to free excessive elements that might have
-+ been created during the parsing. Set the number of elements
-+ accordingly. */
-+
-+extern void reallocate_expout (void);
-+
-+extern int prefixify_expression (struct expression *expr);
-+
- extern void write_exp_elt_opcode (enum exp_opcode);
-
- extern void write_exp_elt_sym (struct symbol *);
-@@ -191,6 +209,8 @@ extern void operator_length_standard (const struct expression *, int, int *,
- int *);
-
- extern int operator_check_standard (struct expression *exp, int pos,
-+ int (*type_func) (struct type *type,
-+ void *data),
- int (*objfile_func)
- (struct objfile *objfile, void *data),
- void *data);
-@@ -277,6 +297,7 @@ struct exp_descriptor
- value should be immediately returned to the caller. Otherwise zero
- should be returned. */
- int (*operator_check) (struct expression *exp, int pos,
-+ int (*type_func) (struct type *type, void *data),
- int (*objfile_func) (struct objfile *objfile,
- void *data),
- void *data);
-@@ -315,4 +336,10 @@ extern void parser_fprintf (FILE *, const char *, ...) ATTRIBUTE_PRINTF (2, 3);
-
- extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile);
+ /* Provide a prototype to silence -Wmissing-prototypes. */
+diff --git a/gdb/machoread.c b/gdb/machoread.c
+index 22530ab..0d7578a 100644
+--- a/gdb/machoread.c
++++ b/gdb/machoread.c
+@@ -454,6 +454,7 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd,
+ asymbol **symp;
+ struct bfd_hash_table table;
+ int nbr_sections;
++ struct cleanup *cleanup;
-+extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile);
-+
-+#if 0
-+extern void exp_types_mark_used (struct expression *exp);
-+#endif
-+
- #endif /* PARSER_DEFS_H */
-diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
-index af80919..3077c4b 100644
---- a/gdb/ppc-linux-nat.c
-+++ b/gdb/ppc-linux-nat.c
-@@ -1468,14 +1468,13 @@ ppc_linux_can_use_hw_breakpoint (int type, int cnt, int ot)
- if (!have_ptrace_booke_interface ())
+ /* Per section flag to mark which section have been rebased. */
+ unsigned char *sections_rebased;
+@@ -466,14 +467,14 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd,
{
- int tid;
-- ptid_t ptid = inferior_ptid;
-
- /* We need to know whether ptrace supports PTRACE_SET_DEBUGREG
- and whether the target has DABR. If either answer is no, the
- ptrace call will return -1. Fail in that case. */
-- tid = TIDGET (ptid);
-+ tid = TIDGET (inferior_ptid);
- if (tid == 0)
-- tid = PIDGET (ptid);
-+ tid = PIDGET (inferior_ptid);
-
- if (ptrace (PTRACE_SET_DEBUGREG, tid, 0, 0) == -1)
- return 0;
-@@ -1566,8 +1565,9 @@ booke_find_thread_points_by_tid (int tid, int alloc_new)
- /* This function is a generic wrapper that is responsible for inserting a
- *point (i.e., calling `ptrace' in order to issue the request to the
- kernel) and registering it internally in GDB. */
-+
- static void
--booke_insert_point (struct ppc_hw_breakpoint *b, int tid)
-+booke_insert_point (struct lwp_info *lp, struct ppc_hw_breakpoint *b)
- {
- int i;
- long slot;
-@@ -1580,12 +1580,12 @@ booke_insert_point (struct ppc_hw_breakpoint *b, int tid)
- memcpy (p, b, sizeof (struct ppc_hw_breakpoint));
-
- errno = 0;
-- slot = ptrace (PPC_PTRACE_SETHWDEBUG, tid, 0, p);
-+ slot = ptrace (PPC_PTRACE_SETHWDEBUG, TIDGET (lp->ptid), 0, p);
- if (slot < 0)
- perror_with_name (_("Unexpected error setting breakpoint or watchpoint"));
-
- /* Everything went fine, so we have to register this *point. */
-- t = booke_find_thread_points_by_tid (tid, 1);
-+ t = booke_find_thread_points_by_tid (TIDGET (lp->ptid), 1);
- gdb_assert (t != NULL);
- hw_breaks = t->hw_breaks;
-
-@@ -1603,17 +1603,33 @@ booke_insert_point (struct ppc_hw_breakpoint *b, int tid)
- discard_cleanups (c);
- }
-
--/* This function is a generic wrapper that is responsible for removing a
-- *point (i.e., calling `ptrace' in order to issue the request to the
-- kernel), and unregistering it internally at GDB. */
--static void
--booke_remove_point (struct ppc_hw_breakpoint *b, int tid)
-+/* Callback for linux_nat_iterate_watchpoint_lwps
-+ calling booke_insert_point. */
-+
-+static int
-+booke_insert_point_callback (struct lwp_info *lp, void *b_voidp)
- {
-+ struct ppc_hw_breakpoint *b = b_voidp;
-+
-+ booke_insert_point (lp, b);
-+
-+ /* Continue the traversal. */
-+ return 0;
-+}
-+
-+/* This function is a callback for linux_nat_iterate_watchpoint_lwps that is
-+ responsible for removing a *point (i.e., calling `ptrace' in order to issue
-+ the request to the kernel), and unregistering it internally at GDB. */
-+
-+static int
-+booke_remove_point_callback (struct lwp_info *lp, void *b_voidp)
-+{
-+ struct ppc_hw_breakpoint *b = b_voidp;
- int i;
- struct hw_break_tuple *hw_breaks;
- struct thread_points *t;
-
-- t = booke_find_thread_points_by_tid (tid, 0);
-+ t = booke_find_thread_points_by_tid (TIDGET (lp->ptid), 0);
- gdb_assert (t != NULL);
- hw_breaks = t->hw_breaks;
-
-@@ -1627,13 +1643,17 @@ booke_remove_point (struct ppc_hw_breakpoint *b, int tid)
- breakpoints/watchpoints as "one-shot", that is, they are automatically
- deleted when hit. */
- errno = 0;
-- if (ptrace (PPC_PTRACE_DELHWDEBUG, tid, 0, hw_breaks[i].slot) < 0)
-+ if (ptrace (PPC_PTRACE_DELHWDEBUG, TIDGET (lp->ptid), 0, hw_breaks[i].slot)
-+ < 0)
- if (errno != ENOENT)
- perror_with_name (_("Unexpected error deleting "
- "breakpoint or watchpoint"));
-
- xfree (hw_breaks[i].hw_break);
- hw_breaks[i].hw_break = NULL;
-+
-+ /* Continue the traversal. */
-+ return 0;
- }
-
- /* Return the number of registers needed for a ranged breakpoint. */
-@@ -1653,7 +1673,6 @@ static int
- ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
- {
-- struct lwp_info *lp;
- struct ppc_hw_breakpoint p;
-
- if (!have_ptrace_booke_interface ())
-@@ -1679,8 +1698,7 @@ ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
- p.addr2 = 0;
+ warning (_("`%s': can't read symbols: %s."), oso->name,
+ bfd_errmsg (bfd_get_error ()));
+- bfd_close (abfd);
++ gdb_bfd_unref (abfd);
+ return;
}
-- ALL_LWPS (lp)
-- booke_insert_point (&p, TIDGET (lp->ptid));
-+ linux_nat_iterate_watchpoint_lwps (booke_insert_point_callback, &p);
-
- return 0;
- }
-@@ -1689,7 +1707,6 @@ static int
- ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
- {
-- struct lwp_info *lp;
- struct ppc_hw_breakpoint p;
-
- if (!have_ptrace_booke_interface ())
-@@ -1715,8 +1732,7 @@ ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch,
- p.addr2 = 0;
+ if (abfd->my_archive == NULL && oso->mtime != bfd_get_mtime (abfd))
+ {
+ warning (_("`%s': file time stamp mismatch."), oso->name);
+- bfd_close (abfd);
++ gdb_bfd_unref (abfd);
+ return;
}
-- ALL_LWPS (lp)
-- booke_remove_point (&p, TIDGET (lp->ptid));
-+ linux_nat_iterate_watchpoint_lwps (booke_remove_point_callback, &p);
-
- return 0;
- }
-@@ -1745,7 +1761,6 @@ static int
- ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
- CORE_ADDR mask, int rw)
- {
-- struct lwp_info *lp;
- struct ppc_hw_breakpoint p;
+@@ -482,7 +483,7 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd,
+ oso->nbr_syms))
+ {
+ warning (_("`%s': can't create hash table"), oso->name);
+- bfd_close (abfd);
++ gdb_bfd_unref (abfd);
+ return;
+ }
- gdb_assert (have_ptrace_booke_interface ());
-@@ -1758,8 +1773,7 @@ ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
- p.addr2 = mask;
- p.condition_value = 0;
+@@ -629,18 +630,15 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd,
-- ALL_LWPS (lp)
-- booke_insert_point (&p, TIDGET (lp->ptid));
-+ linux_nat_iterate_watchpoint_lwps (booke_insert_point_callback, &p);
+ bfd_hash_table_free (&table);
- return 0;
+- /* Make sure that the filename was malloc'ed. The current filename comes
+- either from an OSO symbol name or from an archive name. Memory for both
+- is not managed by gdb. */
+- abfd->filename = xstrdup (abfd->filename);
+-
+ /* We need to clear SYMFILE_MAINLINE to avoid interractive question
+ from symfile.c:symbol_file_add_with_addrs_or_offsets. */
++ cleanup = make_cleanup_bfd_unref (abfd);
+ symbol_file_add_from_bfd
+ (abfd, symfile_flags & ~(SYMFILE_MAINLINE | SYMFILE_VERBOSE), NULL,
+ main_objfile->flags & (OBJF_REORDERED | OBJF_SHARED
+ | OBJF_READNOW | OBJF_USERLOADED),
+ main_objfile);
++ do_cleanups (cleanup);
}
-@@ -1773,7 +1787,6 @@ static int
- ppc_linux_remove_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
- CORE_ADDR mask, int rw)
- {
-- struct lwp_info *lp;
- struct ppc_hw_breakpoint p;
-
- gdb_assert (have_ptrace_booke_interface ());
-@@ -1786,8 +1799,7 @@ ppc_linux_remove_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
- p.addr2 = mask;
- p.condition_value = 0;
-
-- ALL_LWPS (lp)
-- booke_remove_point (&p, TIDGET (lp->ptid));
-+ linux_nat_iterate_watchpoint_lwps (booke_remove_point_callback, &p);
- return 0;
- }
-@@ -1797,10 +1809,16 @@ static int
- can_use_watchpoint_cond_accel (void)
- {
- struct thread_points *p;
-- int tid = TIDGET (inferior_ptid);
- int cnt = booke_debug_info.num_condition_regs, i;
- CORE_ADDR tmp_value;
+ /* Read symbols from the vector of oso files. */
+@@ -651,6 +649,7 @@ macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
+ int ix;
+ VEC (oso_el) *vec;
+ oso_el *oso;
++ struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
-+ /* Overload thread id onto process id. */
-+ int tid = TIDGET (inferior_ptid);
-+
-+ /* No thread id, just use process id. */
-+ if (tid == 0)
-+ tid = PIDGET (inferior_ptid);
-+
- if (!have_ptrace_booke_interface () || cnt == 0)
- return 0;
+ vec = oso_vector;
+ oso_vector = NULL;
+@@ -677,6 +676,8 @@ macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
+ memcpy (archive_name, oso->name, pfx_len);
+ archive_name[pfx_len] = '\0';
+
++ make_cleanup (xfree, archive_name);
++
+ /* Compute number of oso for this archive. */
+ for (last_ix = ix;
+ VEC_iterate (oso_el, vec, last_ix, oso2); last_ix++)
+@@ -686,7 +687,7 @@ macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
+ }
+
+ /* Open the archive and check the format. */
+- archive_bfd = bfd_openr (archive_name, gnutarget);
++ archive_bfd = gdb_bfd_openr (archive_name, gnutarget);
+ if (archive_bfd == NULL)
+ {
+ warning (_("Could not open OSO archive file \"%s\""),
+@@ -698,17 +699,18 @@ macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
+ {
+ warning (_("OSO archive file \"%s\" not an archive."),
+ archive_name);
+- bfd_close (archive_bfd);
++ gdb_bfd_unref (archive_bfd);
+ ix = last_ix;
+ continue;
+ }
+- member_bfd = bfd_openr_next_archived_file (archive_bfd, NULL);
++
++ member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, NULL);
+
+ if (member_bfd == NULL)
+ {
+ warning (_("Could not read archive members out of "
+ "OSO archive \"%s\""), archive_name);
+- bfd_close (archive_bfd);
++ gdb_bfd_unref (archive_bfd);
+ ix = last_ix;
+ continue;
+ }
+@@ -738,12 +740,12 @@ macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
+ }
+
+ prev = member_bfd;
+- member_bfd = bfd_openr_next_archived_file
+- (archive_bfd, member_bfd);
++ member_bfd = gdb_bfd_openr_next_archived_file (archive_bfd,
++ member_bfd);
+
+ /* Free previous member if not referenced by an oso. */
+ if (ix2 >= last_ix)
+- bfd_close (prev);
++ gdb_bfd_unref (prev);
+ }
+ for (ix2 = ix; ix2 < last_ix; ix2++)
+ {
+@@ -759,7 +761,7 @@ macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
+ {
+ bfd *abfd;
+
+- abfd = bfd_openr (oso->name, gnutarget);
++ abfd = gdb_bfd_openr (oso->name, gnutarget);
+ if (!abfd)
+ warning (_("`%s': can't open to read symbols: %s."), oso->name,
+ bfd_errmsg (bfd_get_error ()));
+@@ -771,6 +773,7 @@ macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
+ }
-@@ -1999,6 +2017,22 @@ ppc_linux_can_accel_watchpoint_condition (CORE_ADDR addr, int len, int rw,
- && check_condition (addr, cond, &data_value, &len));
+ VEC_free (oso_el, vec);
++ do_cleanups (cleanup);
}
-+/* Callback for linux_nat_iterate_watchpoint_lwps setting RETP_VOIDP by
-+ PTRACE_SET_DEBUGREG for LP. */
-+
-+static int
-+set_saved_dabr_value_callback (struct lwp_info *lp, void *retp_voidp)
-+{
-+ int *retp = retp_voidp;
-+
-+ if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (lp->ptid), 0, saved_dabr_value)
-+ < 0)
-+ *retp = -1;
-+
-+ /* Continue the traversal. */
-+ return 0;
-+}
-+
- /* Set up P with the parameters necessary to request a watchpoint covering
- LEN bytes starting at ADDR and if possible with condition expression COND
- evaluated by hardware. INSERT tells if we are creating a request for
-@@ -2054,7 +2088,6 @@ static int
- ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
- struct expression *cond)
- {
-- struct lwp_info *lp;
- int ret = -1;
-
- if (have_ptrace_booke_interface ())
-@@ -2063,8 +2096,7 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
-
- create_watchpoint_request (&p, addr, len, rw, cond, 1);
-
-- ALL_LWPS (lp)
-- booke_insert_point (&p, TIDGET (lp->ptid));
-+ linux_nat_iterate_watchpoint_lwps (booke_insert_point_callback, &p);
-
- ret = 0;
+ /* DSYM (debug symbols) files contain the debug info of an executable.
+@@ -808,20 +811,17 @@ macho_check_dsym (struct objfile *objfile)
+ warning (_("can't find UUID in %s"), objfile->name);
+ return NULL;
}
-@@ -2107,12 +2139,8 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
-
- saved_dabr_value = dabr_value;
-
-- ALL_LWPS (lp)
-- if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (lp->ptid), 0,
-- saved_dabr_value) < 0)
-- return -1;
--
- ret = 0;
-+ linux_nat_iterate_watchpoint_lwps (set_saved_dabr_value_callback, &ret);
+- dsym_filename = xstrdup (dsym_filename);
+- dsym_bfd = bfd_openr (dsym_filename, gnutarget);
++ dsym_bfd = gdb_bfd_openr (dsym_filename, gnutarget);
+ if (dsym_bfd == NULL)
+ {
+ warning (_("can't open dsym file %s"), dsym_filename);
+- xfree (dsym_filename);
+ return NULL;
}
- return ret;
-@@ -2122,7 +2150,6 @@ static int
- ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
- struct expression *cond)
- {
-- struct lwp_info *lp;
- int ret = -1;
-
- if (have_ptrace_booke_interface ())
-@@ -2131,20 +2158,16 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
-
- create_watchpoint_request (&p, addr, len, rw, cond, 0);
-
-- ALL_LWPS (lp)
-- booke_remove_point (&p, TIDGET (lp->ptid));
-+ linux_nat_iterate_watchpoint_lwps (booke_remove_point_callback, &p);
-
- ret = 0;
- }
- else
+ if (!bfd_check_format (dsym_bfd, bfd_object))
{
- saved_dabr_value = 0;
-- ALL_LWPS (lp)
-- if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (lp->ptid), 0,
-- saved_dabr_value) < 0)
-- return -1;
-
- ret = 0;
-+ linux_nat_iterate_watchpoint_lwps (set_saved_dabr_value_callback, &ret);
+- bfd_close (dsym_bfd);
++ gdb_bfd_unref (dsym_bfd);
+ warning (_("bad dsym file format: %s"), bfd_errmsg (bfd_get_error ()));
+- xfree (dsym_filename);
+ return NULL;
}
- return ret;
-@@ -2171,7 +2194,7 @@ ppc_linux_new_thread (struct lwp_info *lp)
- /* Copy that thread's breakpoints and watchpoints to the new thread. */
- for (i = 0; i < max_slots_number; i++)
- if (hw_breaks[i].hw_break)
-- booke_insert_point (hw_breaks[i].hw_break, tid);
-+ booke_insert_point (lp, hw_breaks[i].hw_break);
+@@ -829,16 +829,14 @@ macho_check_dsym (struct objfile *objfile)
+ BFD_MACH_O_LC_UUID, &dsym_uuid) == 0)
+ {
+ warning (_("can't find UUID in %s"), dsym_filename);
+- bfd_close (dsym_bfd);
+- xfree (dsym_filename);
++ gdb_bfd_unref (dsym_bfd);
+ return NULL;
}
- else
- ptrace (PTRACE_SET_DEBUGREG, tid, 0, saved_dabr_value);
-@@ -2229,7 +2252,14 @@ ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
- /* The index (or slot) of the *point is passed in the si_errno field. */
- int slot = siginfo_p->si_errno;
-
-- t = booke_find_thread_points_by_tid (TIDGET (inferior_ptid), 0);
-+ /* Overload thread id onto process id. */
-+ int tid = TIDGET (inferior_ptid);
-+
-+ /* No thread id, just use process id. */
-+ if (tid == 0)
-+ tid = PIDGET (inferior_ptid);
-+
-+ t = booke_find_thread_points_by_tid (tid, 0);
-
- /* Find out if this *point is a hardware breakpoint.
- If so, we should return 0. */
-diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
-index b6470fe..f871309 100644
---- a/gdb/ppc-linux-tdep.c
-+++ b/gdb/ppc-linux-tdep.c
-@@ -65,6 +65,14 @@
- #include "features/rs6000/powerpc-isa205-vsx64l.c"
- #include "features/rs6000/powerpc-e500l.c"
-
-+#include "stap-probe.h"
-+#include "ax.h"
-+#include "ax-gdb.h"
-+#include "cli/cli-utils.h"
-+#include "parser-defs.h"
-+#include "user-regs.h"
-+#include <ctype.h>
-+
- /* The syscall's XML filename for PPC and PPC64. */
- #define XML_SYSCALL_FILENAME_PPC "syscalls/ppc-linux.xml"
- #define XML_SYSCALL_FILENAME_PPC64 "syscalls/ppc64-linux.xml"
-@@ -1192,6 +1200,65 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch,
+ if (memcmp (dsym_uuid->command.uuid.uuid, main_uuid->command.uuid.uuid,
+ sizeof (main_uuid->command.uuid.uuid)))
+ {
+ warning (_("dsym file UUID doesn't match the one in %s"), objfile->name);
+- bfd_close (dsym_bfd);
+- xfree (dsym_filename);
++ gdb_bfd_unref (dsym_bfd);
+ return NULL;
}
- }
+ return dsym_bfd;
+@@ -902,6 +900,7 @@ macho_symfile_read (struct objfile *objfile, int symfile_flags)
+ int ix;
+ oso_el *oso;
+ struct bfd_section *asect, *dsect;
++ struct cleanup *cleanup;
+
+ if (mach_o_debug_level > 0)
+ printf_unfiltered (_("dsym file found\n"));
+@@ -922,7 +921,9 @@ macho_symfile_read (struct objfile *objfile, int symfile_flags)
+ }
+
+ /* Add the dsym file as a separate file. */
++ cleanup = make_cleanup_bfd_unref (dsym_bfd);
+ symbol_file_add_separate (dsym_bfd, symfile_flags, objfile);
++ do_cleanups (cleanup);
+
+ /* Don't try to read dwarf2 from main file or shared libraries. */
+ return;
+diff --git a/gdb/main.c b/gdb/main.c
+index d075694..e4da3f1 100644
+--- a/gdb/main.c
++++ b/gdb/main.c
+@@ -37,6 +37,7 @@
-+static int
-+ppc_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
-+{
-+ return (*s == 'i' /* Literal number. */
-+ || (isdigit (*s) && s[1] == '('
-+ && isdigit (s[2])) /* Displacement. */
-+ || (*s == '(' && isdigit (s[1])) /* Register indirection. */
-+ || isdigit (*s)); /* Register value. */
-+}
-+
-+static int
-+ppc_stap_parse_special_token (struct gdbarch *gdbarch,
-+ struct stap_parse_info *p)
-+{
-+ if (isdigit (*p->arg))
-+ {
-+ /* This temporary pointer is needed because we have to do a lookahead.
-+ We could be dealing with a register displacement, and in such case
-+ we would not need to do anything. */
-+ const char *s = p->arg;
-+ char *regname;
-+ int len;
-+ struct stoken str;
-+
-+ while (isdigit (*s))
-+ ++s;
-+
-+ if (*s == '(')
-+ /* It is a register displacement indeed. Returning 0 means we are
-+ deferring the treatment of this case to the generic parser. */
-+ return 0;
-+
-+ len = s - p->arg;
-+ regname = alloca (len + 2);
-+ regname[0] = 'r';
-+
-+ strncpy (regname + 1, p->arg, len);
-+ ++len;
-+ regname[len] = '\0';
-+
-+ if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
-+ error (_("Invalid register name `%s' on expression `%s'."),
-+ regname, p->saved_arg);
-+
-+ write_exp_elt_opcode (OP_REGISTER);
-+ str.ptr = regname;
-+ str.length = len;
-+ write_exp_string (str);
-+ write_exp_elt_opcode (OP_REGISTER);
-+
-+ p->arg = s;
-+ }
-+ else
-+ /* All the other tokens should be handled correctly by the generic
-+ parser. */
-+ return 0;
+ #include "interps.h"
+ #include "main.h"
++#include "python/python.h"
+ #include "source.h"
+ #include "cli/cli-cmds.h"
+ #include "python/python.h"
+@@ -283,6 +284,8 @@ captured_main (void *data)
+ char *cdarg = NULL;
+ char *ttyarg = NULL;
+
++ int python_script = 0;
+
-+ return 1;
-+}
+ /* These are static so that we can take their address in an
+ initializer. */
+ static int print_help;
+@@ -471,10 +474,14 @@ captured_main (void *data)
+ {"args", no_argument, &set_args, 1},
+ {"l", required_argument, 0, 'l'},
+ {"return-child-result", no_argument, &return_child_result, 1},
++#if HAVE_PYTHON
++ {"python", no_argument, 0, 'P'},
++ {"P", no_argument, 0, 'P'},
++#endif
+ {0, no_argument, 0, 0}
+ };
- /* Cell/B.E. active SPE context tracking support. */
+- while (1)
++ while (!python_script)
+ {
+ int option_index;
-@@ -1509,6 +1576,15 @@ ppc_linux_init_abi (struct gdbarch_info info,
- /* Get the syscall number from the arch's register. */
- set_gdbarch_get_syscall_number (gdbarch, ppc_linux_get_syscall_number);
+@@ -492,6 +499,9 @@ captured_main (void *data)
+ case 0:
+ /* Long option that just sets a flag. */
+ break;
++ case 'P':
++ python_script = 1;
++ break;
+ case OPT_SE:
+ symarg = optarg;
+ execarg = optarg;
+@@ -699,7 +709,31 @@ captured_main (void *data)
-+ /* SystemTap functions. */
-+ set_gdbarch_stap_integer_prefix (gdbarch, "i");
-+ set_gdbarch_stap_register_indirection_prefix (gdbarch, "(");
-+ set_gdbarch_stap_register_indirection_sufix (gdbarch, ")");
-+ set_gdbarch_stap_gdb_register_prefix (gdbarch, "r");
-+ set_gdbarch_stap_is_single_operand (gdbarch, ppc_stap_is_single_operand);
-+ set_gdbarch_stap_parse_special_token (gdbarch,
-+ ppc_stap_parse_special_token);
+ /* Now that gdb_init has created the initial inferior, we're in
+ position to set args for that inferior. */
+- if (set_args)
++ if (python_script)
++ {
++ /* The first argument is a python script to evaluate, and
++ subsequent arguments are passed to the script for
++ processing there. */
++ if (optind >= argc)
++ {
++ fprintf_unfiltered (gdb_stderr,
++ _("%s: Python script file name required\n"),
++ argv[0]);
++ exit (1);
++ }
+
- if (tdep->wordsize == 4)
- {
- /* Until November 2001, gcc did not comply with the 32 bit SysV
-diff --git a/gdb/printcmd.c b/gdb/printcmd.c
-index bee8a85..00f332d 100644
---- a/gdb/printcmd.c
-+++ b/gdb/printcmd.c
-@@ -49,6 +49,7 @@
- #include "charset.h"
- #include "arch-utils.h"
- #include "cli/cli-utils.h"
++ /* FIXME: should handle inferior I/O intelligently here.
++ E.g., should be possible to run gdb in pipeline and have
++ Python (and gdb) output go to stderr or file; and if a
++ prompt is needed, open the tty. */
++ quiet = 1;
++ /* FIXME: should read .gdbinit if, and only if, a prompt is
++ requested by the script. Though... maybe this is not
++ ideal? */
++ /* FIXME: likewise, reading in history. */
++ inhibit_gdbinit = 1;
++ }
++ else if (set_args)
+ {
+ /* The remaining options are the command-line options for the
+ inferior. The first one is the sym/exec file, and the rest
+@@ -979,7 +1013,8 @@ captured_main (void *data)
+
+ /* Read in the old history after all the command files have been
+ read. */
+- init_history ();
++ if (!python_script)
++ init_history ();
+
+ if (batch_flag)
+ {
+@@ -990,13 +1025,25 @@ captured_main (void *data)
+ /* Show time and/or space usage. */
+ do_cleanups (pre_stat_chain);
+
+- /* NOTE: cagney/1999-11-07: There is probably no reason for not
+- moving this loop and the code found in captured_command_loop()
+- into the command_loop() proper. The main thing holding back that
+- change - SET_TOP_LEVEL() - has been eliminated. */
+- while (1)
++#if HAVE_PYTHON
++ if (python_script)
+ {
+- catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
++ extern int pagination_enabled;
++ pagination_enabled = 0;
++ run_python_script (argc - optind, &argv[optind]);
++ return 1;
++ }
++ else
++#endif
++ {
++ /* NOTE: cagney/1999-11-07: There is probably no reason for not
++ moving this loop and the code found in captured_command_loop()
++ into the command_loop() proper. The main thing holding back that
++ change - SET_TOP_LEVEL() - has been eliminated. */
++ while (1)
++ {
++ catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
++ }
+ }
+ /* No exit -- exit is through quit_command. */
+ }
+@@ -1028,7 +1075,12 @@ print_gdb_help (struct ui_file *stream)
+ fputs_unfiltered (_("\
+ This is the GNU debugger. Usage:\n\n\
+ gdb [options] [executable-file [core-file or process-id]]\n\
+- gdb [options] --args executable-file [inferior-arguments ...]\n\n\
++ gdb [options] --args executable-file [inferior-arguments ...]\n"), stream);
++#if HAVE_PYTHON
++ fputs_unfiltered (_("\
++ gdb [options] [--python|-P] script-file [script-arguments ...]\n"), stream);
++#endif
++ fputs_unfiltered (_("\n\
+ Options:\n\n\
+ "), stream);
+ fputs_unfiltered (_("\
+@@ -1068,7 +1120,13 @@ Options:\n\n\
+ --nw Do not use a window interface.\n\
+ --nx Do not read "), stream);
+ fputs_unfiltered (gdbinit, stream);
+- fputs_unfiltered (_(" file.\n\
++ fputs_unfiltered (_(" file.\n"), stream);
++#if HAVE_PYTHON
++ fputs_unfiltered (_("\
++ --python, -P Following argument is Python script file; remaining\n\
++ arguments are passed to script.\n"), stream);
++#endif
++ fputs_unfiltered (_("\
+ --quiet Do not print version number on startup.\n\
+ --readnow Fully read symbol files on first access.\n\
+ "), stream);
+diff --git a/gdb/objfiles.c b/gdb/objfiles.c
+index f5e5c75..411618f 100644
+--- a/gdb/objfiles.c
++++ b/gdb/objfiles.c
+@@ -53,6 +53,7 @@
+ #include "complaints.h"
+ #include "psymtab.h"
+ #include "solist.h"
++#include "gdb_bfd.h"
+
+ /* Prototypes for local functions */
+
+@@ -195,7 +196,8 @@ allocate_objfile (bfd *abfd, int flags)
+ that any data that is reference is saved in the per-objfile data
+ region. */
+
+- objfile->obfd = gdb_bfd_ref (abfd);
++ objfile->obfd = abfd;
++ gdb_bfd_ref (abfd);
+ if (abfd != NULL)
+ {
+ /* Look up the gdbarch associated with the BFD. */
+@@ -1456,75 +1458,6 @@ objfiles_changed (void)
+ get_objfile_pspace_data (current_program_space)->objfiles_changed_p = 1;
+ }
+
+-/* Close ABFD, and warn if that fails. */
+-
+-int
+-gdb_bfd_close_or_warn (struct bfd *abfd)
+-{
+- int ret;
+- char *name = bfd_get_filename (abfd);
+-
+- ret = bfd_close (abfd);
+-
+- if (!ret)
+- warning (_("cannot close \"%s\": %s"),
+- name, bfd_errmsg (bfd_get_error ()));
+-
+- return ret;
+-}
+-
+-/* Add reference to ABFD. Returns ABFD. */
+-struct bfd *
+-gdb_bfd_ref (struct bfd *abfd)
+-{
+- int *p_refcount;
+-
+- if (abfd == NULL)
+- return NULL;
+-
+- p_refcount = bfd_usrdata (abfd);
+-
+- if (p_refcount != NULL)
+- {
+- *p_refcount += 1;
+- return abfd;
+- }
+-
+- p_refcount = xmalloc (sizeof (*p_refcount));
+- *p_refcount = 1;
+- bfd_usrdata (abfd) = p_refcount;
+-
+- return abfd;
+-}
+-
+-/* Unreference and possibly close ABFD. */
+-void
+-gdb_bfd_unref (struct bfd *abfd)
+-{
+- int *p_refcount;
+- char *name;
+-
+- if (abfd == NULL)
+- return;
+-
+- p_refcount = bfd_usrdata (abfd);
+-
+- /* Valid range for p_refcount: a pointer to int counter, which has a
+- value of 1 (single owner) or 2 (shared). */
+- gdb_assert (*p_refcount == 1 || *p_refcount == 2);
+-
+- *p_refcount -= 1;
+- if (*p_refcount > 0)
+- return;
+-
+- xfree (p_refcount);
+- bfd_usrdata (abfd) = NULL; /* Paranoia. */
+-
+- name = bfd_get_filename (abfd);
+- gdb_bfd_close_or_warn (abfd);
+- xfree (name);
+-}
+-
+ /* The default implementation for the "iterate_over_objfiles_in_search_order"
+ gdbarch method. It is equivalent to use the ALL_OBJFILES macro,
+ searching the objfiles in the order they are stored internally,
+diff --git a/gdb/objfiles.h b/gdb/objfiles.h
+index 01c3aea..0df5798 100644
+--- a/gdb/objfiles.h
++++ b/gdb/objfiles.h
+@@ -522,10 +522,6 @@ extern void set_objfile_data (struct objfile *objfile,
+ extern void *objfile_data (struct objfile *objfile,
+ const struct objfile_data *data);
+
+-extern struct bfd *gdb_bfd_ref (struct bfd *abfd);
+-extern void gdb_bfd_unref (struct bfd *abfd);
+-extern int gdb_bfd_close_or_warn (struct bfd *abfd);
+-
+ extern void default_iterate_over_objfiles_in_search_order
+ (struct gdbarch *gdbarch,
+ iterate_over_objfiles_in_search_order_cb_ftype *cb,
+diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
+index b8434ed..98a076d 100644
+--- a/gdb/p-valprint.c
++++ b/gdb/p-valprint.c
+@@ -39,6 +39,7 @@
+ #include "cp-abi.h"
+ #include "cp-support.h"
+ #include "exceptions.h"
+#include "dwarf2loc.h"
+ \f
- #ifdef TUI
- #include "tui/tui.h" /* For tui_active et al. */
-@@ -971,6 +972,11 @@ print_command_1 (char *exp, int inspect, int voidprint)
- else
- val = access_value_history (0);
+ /* Decorations for Pascal. */
+@@ -74,8 +75,31 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
+ struct type *char_type;
+ CORE_ADDR addr;
+ int want_space = 0;
++ struct cleanup *back_to;
++ struct type *saved_type = type;
++ CORE_ADDR saved_address = address;
++
++ back_to = make_cleanup (null_cleanup, 0);
++ address += embedded_offset;
++ type = object_address_get_data (type, &address);
++ if (type == NULL)
++ {
++ fputs_filtered (object_address_data_not_valid (saved_type), stream);
++ gdb_flush (stream);
++ do_cleanups (back_to);
++ return;
++ }
++ if (address != saved_address + embedded_offset)
++ {
++ size_t length = TYPE_LENGTH (type);
-+ /* 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))
+- CHECK_TYPEDEF (type);
++ valaddr = xmalloc (length);
++ make_cleanup (xfree, (gdb_byte *) valaddr);
++ read_memory (address, (gdb_byte *) valaddr, length);
++ embedded_offset = 0;
++ }
++ else
++ address -= embedded_offset;
+ switch (TYPE_CODE (type))
{
-@@ -1059,6 +1065,9 @@ output_command (char *exp, int from_tty)
+ case TYPE_CODE_ARRAY:
+@@ -131,8 +155,8 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
+ {
+ i = 0;
+ }
+- val_print_array_elements (type, valaddr, embedded_offset,
+- address, stream, recurse,
++ val_print_array_elements (saved_type, valaddr, embedded_offset,
++ saved_address, stream, recurse,
+ original_value, options, i);
+ fprintf_filtered (stream, "}");
+ }
+@@ -170,6 +194,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
+ {
+ /* Try to print what function it points to. */
+ print_address_demangle (options, gdbarch, addr, stream, demangle);
++ do_cleanups (back_to);
+ return;
+ }
- val = evaluate_expression (expr);
+@@ -271,6 +296,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
+ }
+ }
-+ if (VALUE_LVAL (val) == lval_memory)
-+ object_address_set (value_raw_address (val));
-+
- annotate_value_begin (value_type (val));
++ do_cleanups (back_to);
+ return;
- get_formatted_print_options (&opts, format);
-@@ -1472,6 +1481,24 @@ x_command (char *exp, int from_tty)
- set_internalvar (lookup_internalvar ("__"), last_examine_value);
+ case TYPE_CODE_REF:
+@@ -421,6 +447,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
+ TYPE_CODE (type));
}
+ gdb_flush (stream);
++ do_cleanups (back_to);
}
-+
-+#if 0
-+/* Call type_mark_used for any TYPEs referenced from this GDB source file. */
-+
-+static void
-+print_types_mark_used (void)
-+{
-+ struct display *d;
-+
-+ if (last_examine_value)
-+ type_mark_used (value_type (last_examine_value));
-+
-+ for (d = display_chain; d; d = d->next)
-+ if (d->exp)
-+ exp_types_mark_used (d->exp);
-+}
-+#endif
-+
\f
+ void
+diff --git a/gdb/parse.c b/gdb/parse.c
+index 529c517..6326a01 100644
+--- a/gdb/parse.c
++++ b/gdb/parse.c
+@@ -1708,6 +1708,7 @@ parser_fprintf (FILE *x, const char *y, ...)
- /* Add an expression to the auto-display chain.
-@@ -1971,6 +1998,10 @@ print_variable_and_value (const char *name, struct symbol *var,
- struct value_print_options opts;
+ int
+ operator_check_standard (struct expression *exp, int pos,
++ int (*type_func) (struct type *type, void *data),
+ int (*objfile_func) (struct objfile *objfile,
+ void *data),
+ void *data)
+@@ -1749,7 +1750,7 @@ operator_check_standard (struct expression *exp, int pos,
+ struct type *type = elts[pos + 2 + arg].type;
+ struct objfile *objfile = TYPE_OBJFILE (type);
- val = read_var_value (var, frame);
-+
-+ make_cleanup_restore_selected_frame ();
-+ select_frame (frame);
-+
- get_user_print_options (&opts);
- opts.deref_ref = 1;
- common_val_print (val, stream, indent, &opts, current_language);
-@@ -2884,4 +2915,8 @@ Show printing of source filename and line number with <symbol>."), NULL,
- add_com ("eval", no_class, eval_command, _("\
- Convert \"printf format string\", arg1, arg2, arg3, ..., argn to\n\
- a command line, and call it."));
-+
-+#if 0
-+ observer_attach_mark_used (print_types_mark_used);
-+#endif
- }
-diff --git a/gdb/python/lib/gdb/FrameIterator.py b/gdb/python/lib/gdb/FrameIterator.py
-new file mode 100644
-index 0000000..5654546
---- /dev/null
-+++ b/gdb/python/lib/gdb/FrameIterator.py
-@@ -0,0 +1,33 @@
-+# Iterator over frames.
-+
-+# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
-+
+- if (objfile && (*objfile_func) (objfile, data))
++ if (objfile && objfile_func && (*objfile_func) (objfile, data))
+ return 1;
+ }
+ }
+@@ -1767,7 +1768,8 @@ operator_check_standard (struct expression *exp, int pos,
+
+ /* Check objfile where the variable itself is placed.
+ SYMBOL_OBJ_SECTION (symbol) may be NULL. */
+- if ((*objfile_func) (SYMBOL_SYMTAB (symbol)->objfile, data))
++ if (objfile_func
++ && (*objfile_func) (SYMBOL_SYMTAB (symbol)->objfile, data))
+ return 1;
+
+ /* Check objfile where is placed the code touching the variable. */
+@@ -1780,24 +1782,27 @@ operator_check_standard (struct expression *exp, int pos,
+
+ /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL. */
+
+- if (type && TYPE_OBJFILE (type)
++ if (type && type_func && (*type_func) (type, data))
++ return 1;
++ if (type && TYPE_OBJFILE (type) && objfile_func
+ && (*objfile_func) (TYPE_OBJFILE (type), data))
+ return 1;
+- if (objfile && (*objfile_func) (objfile, data))
++ if (objfile && objfile_func && (*objfile_func) (objfile, data))
+ return 1;
+
+ return 0;
+ }
+
+-/* Call OBJFILE_FUNC for any TYPE and OBJFILE found being referenced by EXP.
+- The functions are never called with NULL OBJFILE. Functions get passed an
+- arbitrary caller supplied DATA pointer. If any of the functions returns
+- non-zero value then (any other) non-zero value is immediately returned to
+- the caller. Otherwise zero is returned after iterating through whole EXP.
+- */
++/* Call TYPE_FUNC and OBJFILE_FUNC for any TYPE and OBJFILE found being
++ referenced by EXP. The functions are never called with NULL TYPE or NULL
++ OBJFILE. Functions get passed an arbitrary caller supplied DATA pointer.
++ If any of the functions returns non-zero value then (any other) non-zero
++ value is immediately returned to the caller. Otherwise zero is returned
++ after iterating through whole EXP. */
+
+ static int
+ exp_iterate (struct expression *exp,
++ int (*type_func) (struct type *type, void *data),
+ int (*objfile_func) (struct objfile *objfile, void *data),
+ void *data)
+ {
+@@ -1812,7 +1817,9 @@ exp_iterate (struct expression *exp,
+
+ pos = endpos - oplen;
+ if (exp->language_defn->la_exp_desc->operator_check (exp, pos,
+- objfile_func, data))
++ type_func,
++ objfile_func,
++ data))
+ return 1;
+
+ endpos = pos;
+@@ -1843,8 +1850,29 @@ exp_uses_objfile (struct expression *exp, struct objfile *objfile)
+ {
+ gdb_assert (objfile->separate_debug_objfile_backlink == NULL);
+
+- return exp_iterate (exp, exp_uses_objfile_iter, objfile);
++ return exp_iterate (exp, NULL, exp_uses_objfile_iter, objfile);
++}
++
++/* Helper for exp_types_mark_used. */
++
++#if 0
++static int
++exp_types_mark_used_iter (struct type *type, void *unused)
++{
++ type_mark_used (type);
++
++ /* Continue the traversal. */
++ return 0;
++}
++
++/* Call type_mark_used for any type contained in EXP. */
++
++void
++exp_types_mark_used (struct expression *exp)
++{
++ exp_iterate (exp, exp_types_mark_used_iter, NULL, NULL);
+ }
++#endif
+
+ void
+ _initialize_parse (void)
+diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
+index 86f3bdf..f908a61 100644
+--- a/gdb/parser-defs.h
++++ b/gdb/parser-defs.h
+@@ -245,6 +245,8 @@ extern void operator_length_standard (const struct expression *, int, int *,
+ int *);
+
+ extern int operator_check_standard (struct expression *exp, int pos,
++ int (*type_func) (struct type *type,
++ void *data),
+ int (*objfile_func)
+ (struct objfile *objfile, void *data),
+ void *data);
+@@ -331,6 +333,7 @@ struct exp_descriptor
+ value should be immediately returned to the caller. Otherwise zero
+ should be returned. */
+ int (*operator_check) (struct expression *exp, int pos,
++ int (*type_func) (struct type *type, void *data),
+ int (*objfile_func) (struct objfile *objfile,
+ void *data),
+ void *data);
+@@ -369,4 +372,10 @@ extern void parser_fprintf (FILE *, const char *, ...) ATTRIBUTE_PRINTF (2, 3);
+
+ extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile);
+
++extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile);
++
++#if 0
++extern void exp_types_mark_used (struct expression *exp);
++#endif
++
+ #endif /* PARSER_DEFS_H */
+diff --git a/gdb/printcmd.c b/gdb/printcmd.c
+index d5b5b63..4bc2b5b 100644
+--- a/gdb/printcmd.c
++++ b/gdb/printcmd.c
+@@ -50,6 +50,7 @@
+ #include "arch-utils.h"
+ #include "cli/cli-utils.h"
+ #include "format.h"
++#include "dwarf2loc.h"
+
+ #ifdef TUI
+ #include "tui/tui.h" /* For tui_active et al. */
+@@ -968,6 +969,11 @@ print_command_1 (char *exp, int inspect, int voidprint)
+ 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))
+ {
+@@ -1056,6 +1062,9 @@ output_command (char *exp, int from_tty)
+
+ val = evaluate_expression (expr);
+
++ if (VALUE_LVAL (val) == lval_memory)
++ object_address_set (value_raw_address (val));
++
+ annotate_value_begin (value_type (val));
+
+ get_formatted_print_options (&opts, format);
+@@ -1485,6 +1494,24 @@ x_command (char *exp, int from_tty)
+ set_internalvar (lookup_internalvar ("__"), last_examine_value);
+ }
+ }
++
++#if 0
++/* Call type_mark_used for any TYPEs referenced from this GDB source file. */
++
++static void
++print_types_mark_used (void)
++{
++ struct display *d;
++
++ if (last_examine_value)
++ type_mark_used (value_type (last_examine_value));
++
++ for (d = display_chain; d; d = d->next)
++ if (d->exp)
++ exp_types_mark_used (d->exp);
++}
++#endif
++
+ \f
+
+ /* Add an expression to the auto-display chain.
+@@ -1982,6 +2009,10 @@ print_variable_and_value (const char *name, struct symbol *var,
+ struct value_print_options opts;
+
+ val = read_var_value (var, frame);
++
++ make_cleanup_restore_selected_frame ();
++ select_frame (frame);
++
+ get_user_print_options (&opts);
+ opts.deref_ref = 1;
+ common_val_print (val, stream, indent, &opts, current_language);
+@@ -2626,4 +2657,8 @@ Show printing of source filename and line number with <symbol>."), NULL,
+ add_com ("eval", no_class, eval_command, _("\
+ Convert \"printf format string\", arg1, arg2, arg3, ..., argn to\n\
+ a command line, and call it."));
++
++#if 0
++ observer_attach_mark_used (print_types_mark_used);
++#endif
+ }
+diff --git a/gdb/procfs.c b/gdb/procfs.c
+index 774df2e..4409e5b 100644
+--- a/gdb/procfs.c
++++ b/gdb/procfs.c
+@@ -3486,7 +3486,7 @@ insert_dbx_link_bpt_in_file (int fd, CORE_ADDR ignored)
+ long storage_needed;
+ CORE_ADDR sym_addr;
+
+- abfd = bfd_fdopenr ("unamed", 0, fd);
++ abfd = gdb_bfd_fdopenr ("unamed", 0, fd);
+ if (abfd == NULL)
+ {
+ warning (_("Failed to create a bfd: %s."), bfd_errmsg (bfd_get_error ()));
+@@ -3497,7 +3497,7 @@ insert_dbx_link_bpt_in_file (int fd, CORE_ADDR ignored)
+ {
+ /* Not the correct format, so we can not possibly find the dbx_link
+ symbol in it. */
+- bfd_close (abfd);
++ gdb_bfd_unref (abfd);
+ return 0;
+ }
+
+@@ -3511,14 +3511,14 @@ insert_dbx_link_bpt_in_file (int fd, CORE_ADDR ignored)
+ if (dbx_link_bpt == NULL)
+ {
+ warning (_("Failed to insert dbx_link breakpoint."));
+- bfd_close (abfd);
++ gdb_bfd_unref (abfd);
+ return 0;
+ }
+- bfd_close (abfd);
++ gdb_bfd_unref (abfd);
+ return 1;
+ }
+
+- bfd_close (abfd);
++ gdb_bfd_unref (abfd);
+ return 0;
+ }
+
+diff --git a/gdb/python/lib/gdb/FrameIterator.py b/gdb/python/lib/gdb/FrameIterator.py
+new file mode 100644
+index 0000000..5654546
+--- /dev/null
++++ b/gdb/python/lib/gdb/FrameIterator.py
+@@ -0,0 +1,33 @@
++# Iterator over frames.
++
++# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
++
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+
+InScope ()
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
-index dadb037..864da99 100644
+index 98030a6..9870eec 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -30,6 +30,8 @@
static PyTypeObject type_object_type;
/* A Field object. */
-@@ -1150,8 +1160,63 @@ typy_richcompare (PyObject *self, PyObject *other, int op)
+@@ -1166,8 +1176,63 @@ typy_richcompare (PyObject *self, PyObject *other, int op)
\f
static void
save_objfile_types (struct objfile *objfile, void *datum)
{
-@@ -1169,12 +1234,13 @@ save_objfile_types (struct objfile *objfile, void *datum)
+@@ -1185,12 +1250,13 @@ save_objfile_types (struct objfile *objfile, void *datum)
{
type_object *next = obj->next;
obj = next;
}
-@@ -1185,43 +1251,28 @@ save_objfile_types (struct objfile *objfile, void *datum)
+@@ -1201,43 +1267,28 @@ save_objfile_types (struct objfile *objfile, void *datum)
}
static void
/* Return number of fields ("length" of the field dictionary). */
-@@ -1444,7 +1495,10 @@ type_to_type_object (struct type *type)
+@@ -1457,7 +1508,10 @@ type_to_type_object (struct type *type)
type_obj = PyObject_New (type_object, &type_object_type);
if (type_obj)
return (PyObject *) type_obj;
}
-@@ -1524,6 +1578,10 @@ gdbpy_initialize_types (void)
+@@ -1537,6 +1591,10 @@ gdbpy_initialize_types (void)
Py_INCREF (&field_object_type);
PyModule_AddObject (gdb_module, "Field", (PyObject *) &field_object_type);
\f
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
-index 760360e..d935f54 100644
+index 6f67bdb..5ddd6bc 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
-@@ -28,6 +28,7 @@
- #include "infcall.h"
+@@ -29,6 +29,7 @@
#include "expression.h"
#include "cp-abi.h"
+ #include "python.h"
+#include "observer.h"
#ifdef HAVE_PYTHON
-@@ -1335,6 +1336,19 @@ gdbpy_is_value_object (PyObject *obj)
+@@ -1378,6 +1379,19 @@ gdbpy_is_value_object (PyObject *obj)
return PyObject_TypeCheck (obj, &value_object_type);
}
void
gdbpy_initialize_values (void)
{
-@@ -1345,6 +1359,10 @@ gdbpy_initialize_values (void)
+@@ -1388,6 +1402,10 @@ gdbpy_initialize_values (void)
PyModule_AddObject (gdb_module, "Value", (PyObject *) &value_object_type);
values_in_python = NULL;
\f
diff --git a/gdb/python/python.c b/gdb/python/python.c
-index 5a0d776..af01dfd 100644
+index c66efe4..0211fcb 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -66,10 +66,13 @@ static const char *gdbpy_should_print_stack = python_excp_message;
static PyMethodDef GdbMethods[];
-@@ -946,6 +949,53 @@ gdbpy_print_stack (void)
+@@ -979,6 +982,53 @@ gdbpy_print_stack (void)
/* Return the current Progspace.
There always is one. */
static PyObject *
gdbpy_get_current_progspace (PyObject *unused1, PyObject *unused2)
-@@ -1386,6 +1436,8 @@ static PyMethodDef GdbMethods[] =
+@@ -1420,6 +1470,8 @@ static PyMethodDef GdbMethods[] =
"Get a value from history" },
{ "execute", (PyCFunction) execute_gdb_command, METH_VARARGS | METH_KEYWORDS,
"Execute a gdb command" },
"Return a gdb parameter's value" },
diff --git a/gdb/python/python.h b/gdb/python/python.h
-index 9e461f7..57b21da 100644
+index dd7066f..f0f6e90 100644
--- a/gdb/python/python.h
+++ b/gdb/python/python.h
-@@ -32,6 +32,8 @@ void eval_python_from_control_command (struct command_line *);
+@@ -30,6 +30,8 @@ void eval_python_from_control_command (struct command_line *);
- void source_python_script (const char *file);
+ void source_python_script (FILE *file, const char *filename);
+void run_python_script (int argc, char **argv);
+
int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
-diff --git a/gdb/remote.c b/gdb/remote.c
-index f348536..e20f6bf 100644
---- a/gdb/remote.c
-+++ b/gdb/remote.c
-@@ -9948,7 +9948,7 @@ remote_download_tracepoint (struct bp_location *loc)
- char **stepping_actions;
- int ndx;
- struct cleanup *old_chain = NULL;
-- struct agent_expr *aexpr;
-+ struct agent_expr *aexpr = NULL;
- struct cleanup *aexpr_chain = NULL;
- char *pkt;
- struct breakpoint *b = loc->owner;
-diff --git a/gdb/s390-nat.c b/gdb/s390-nat.c
-index 2755e58..8df3fd1 100644
---- a/gdb/s390-nat.c
-+++ b/gdb/s390-nat.c
-@@ -515,6 +515,17 @@ s390_fix_watch_points (struct lwp_info *lp)
- perror_with_name (_("Couldn't modify watchpoint status"));
+diff --git a/gdb/record.c b/gdb/record.c
+index bb0fe52..ec42aac 100644
+--- a/gdb/record.c
++++ b/gdb/record.c
+@@ -32,6 +32,7 @@
+ #include "gcore.h"
+ #include "event-loop.h"
+ #include "inf-loop.h"
++#include "gdb_bfd.h"
+
+ #include <signal.h>
+
+@@ -2638,7 +2639,7 @@ record_save_cleanups (void *data)
+ bfd *obfd = data;
+ char *pathname = xstrdup (bfd_get_filename (obfd));
+
+- bfd_close (obfd);
++ gdb_bfd_unref (obfd);
+ unlink (pathname);
+ xfree (pathname);
}
+@@ -2854,7 +2855,7 @@ cmd_record_save (char *args, int from_tty)
+ }
-+/* Callback for iterate_over_lwps, to call s390_fix_watch_points. */
-+
-+static int
-+s390_fix_watch_points_iterate (struct lwp_info *lp, void *arg)
-+{
-+ s390_fix_watch_points (lp);
-+
-+ /* Continue the traversal. */
-+ return 0;
-+}
-+
- static int
- s390_insert_watchpoint (CORE_ADDR addr, int len, int type,
- struct expression *cond)
-@@ -531,8 +542,8 @@ s390_insert_watchpoint (CORE_ADDR addr, int len, int type,
- area->next = watch_base;
- watch_base = area;
-
-- ALL_LWPS (lp)
-- s390_fix_watch_points (lp);
-+ iterate_over_lwps (minus_one_ptid, s390_fix_watch_points_iterate, NULL);
-+
- return 0;
- }
+ do_cleanups (set_cleanups);
+- bfd_close (obfd);
++ gdb_bfd_unref (obfd);
+ discard_cleanups (old_cleanups);
-@@ -559,8 +570,8 @@ s390_remove_watchpoint (CORE_ADDR addr, int len, int type,
- *parea = area->next;
- xfree (area);
+ /* Succeeded. */
+diff --git a/gdb/remote-m32r-sdi.c b/gdb/remote-m32r-sdi.c
+index 47f4405..85268b6 100644
+--- a/gdb/remote-m32r-sdi.c
++++ b/gdb/remote-m32r-sdi.c
+@@ -39,6 +39,7 @@
+ #include <sys/time.h>
+ #include <signal.h>
+ #include <time.h>
++#include "gdb_bfd.h"
-- ALL_LWPS (lp)
-- s390_fix_watch_points (lp);
-+ iterate_over_lwps (minus_one_ptid, s390_fix_watch_points_iterate, NULL);
-+
- return 0;
- }
-diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
-index ac0c526..dd0e477 100644
---- a/gdb/s390-tdep.c
-+++ b/gdb/s390-tdep.c
-@@ -55,6 +55,12 @@
- #include "features/s390x-linux64v1.c"
- #include "features/s390x-linux64v2.c"
+ #include "serial.h"
+@@ -1257,13 +1258,13 @@ m32r_load (char *args, int from_tty)
+ if (!filename)
+ filename = get_exec_file (1);
-+#include "stap-probe.h"
-+#include "ax.h"
-+#include "ax-gdb.h"
-+#include "user-regs.h"
-+#include "cli/cli-utils.h"
-+#include <ctype.h>
+- pbfd = bfd_openr (filename, gnutarget);
++ pbfd = gdb_bfd_openr (filename, gnutarget);
+ if (pbfd == NULL)
+ {
+ perror_with_name (filename);
+ return;
+ }
+- old_chain = make_cleanup_bfd_close (pbfd);
++ old_chain = make_cleanup_bfd_unref (pbfd);
+
+ if (!bfd_check_format (pbfd, bfd_object))
+ error (_("\"%s\" is not an object file: %s"), filename,
+diff --git a/gdb/remote-mips.c b/gdb/remote-mips.c
+index babbf19..db4381b 100644
+--- a/gdb/remote-mips.c
++++ b/gdb/remote-mips.c
+@@ -36,6 +36,7 @@
+ #include <ctype.h>
+ #include "mips-tdep.h"
+ #include "gdbthread.h"
++#include "gdb_bfd.h"
+ \f
- /* The tdep structure. */
+ /* Breakpoint types. Values 0, 1, and 2 must agree with the watch
+@@ -2783,20 +2784,23 @@ mips_load_srec (char *args)
+ unsigned int i;
+ unsigned int srec_frame = 200;
+ int reclen;
++ struct cleanup *cleanup;
+ static int hashmark = 1;
-@@ -2953,6 +2959,15 @@ s390_address_class_name_to_type_flags (struct gdbarch *gdbarch,
- return 0;
- }
+ buffer = alloca (srec_frame * 2 + 256);
-+static int
-+s390_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
-+{
-+ return ((isdigit (*s) && s[1] == '(' && s[2] == '%') /* Displacement
-+ or indirection. */
-+ || *s == '%' /* Register access. */
-+ || isdigit (*s)); /* Literal number. */
-+}
-+
- /* Set up gdbarch struct. */
+- abfd = bfd_openr (args, 0);
++ abfd = gdb_bfd_openr (args, 0);
+ if (!abfd)
+ {
+ printf_filtered ("Unable to open file %s\n", args);
+ return;
+ }
- static struct gdbarch *
-@@ -3283,6 +3298,12 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
++ cleanup = make_cleanup_bfd_unref (abfd);
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered ("File is not an object file\n");
++ do_cleanups (cleanup);
+ return;
+ }
- set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
+@@ -2850,6 +2854,7 @@ mips_load_srec (char *args)
+ send_srec (srec, reclen, abfd->start_address);
-+ /* SystemTap functions. */
-+ set_gdbarch_stap_register_prefix (gdbarch, "%");
-+ set_gdbarch_stap_register_indirection_prefix (gdbarch, "(");
-+ set_gdbarch_stap_register_indirection_sufix (gdbarch, ")");
-+ set_gdbarch_stap_is_single_operand (gdbarch, s390_stap_is_single_operand);
-+
- return gdbarch;
+ serial_flush_input (mips_desc);
++ do_cleanups (cleanup);
}
-diff --git a/gdb/somread.c b/gdb/somread.c
-index e621cba..19a15e2 100644
---- a/gdb/somread.c
-+++ b/gdb/somread.c
-@@ -427,6 +427,7 @@ static const struct sym_fns som_sym_fns =
- default_symfile_segments, /* Get segment information from a file. */
- NULL,
- default_symfile_relocate, /* Relocate a debug section. */
-+ NULL, /* sym_get_probes */
- &psym_functions
- };
+ /*
+@@ -3366,20 +3371,23 @@ pmon_load_fast (char *file)
+ int bintotal = 0;
+ int final = 0;
+ int finished = 0;
++ struct cleanup *cleanup;
-diff --git a/gdb/stack.c b/gdb/stack.c
-index b15b5fc..b2dad29 100644
---- a/gdb/stack.c
-+++ b/gdb/stack.c
-@@ -509,6 +509,10 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
- stb = ui_out_stream_new (uiout);
- old_chain = make_cleanup_ui_out_stream_delete (stb);
+ buffer = (char *) xmalloc (MAXRECSIZE + 1);
+ binbuf = (unsigned char *) xmalloc (BINCHUNK);
-+ /* Frame may be needed for check_typedef of TYPE_DYNAMIC. */
-+ make_cleanup_restore_selected_frame ();
-+ select_frame (frame);
-+
- if (func)
+- abfd = bfd_openr (file, 0);
++ abfd = gdb_bfd_openr (file, 0);
+ if (!abfd)
{
- struct block *b = SYMBOL_BLOCK_VALUE (func);
-diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
-new file mode 100644
-index 0000000..123530f
---- /dev/null
-+++ b/gdb/stap-probe.c
-@@ -0,0 +1,1672 @@
-+/* SystemTap probe support for GDB.
-+
-+ Copyright (C) 2011 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 "stap-probe.h"
-+#include "vec.h"
-+#include "ui-out.h"
-+#include "gdb_regex.h"
-+#include "objfiles.h"
-+#include "arch-utils.h"
-+#include "command.h"
-+#include "gdbcmd.h"
-+#include "filenames.h"
-+#include "value.h"
-+#include "exceptions.h"
-+#include "ax.h"
-+#include "ax-gdb.h"
-+#include "complaints.h"
-+#include "cli/cli-utils.h"
-+#include "linespec.h"
-+#include "user-regs.h"
-+#include "parser-defs.h"
-+#include "language.h"
-+
-+#include <ctype.h>
-+
-+/* The maximum number of arguments that a probe can have,
-+ as defined in <sys/sdt.h>. */
-+
-+#define STAP_MAX_ARGS 12
-+
-+/* Should we display debug information for the probe's argument expression
-+ parsing? */
-+
-+static int stap_expression_debug = 0;
-+
-+/* The various possibilities of bitness defined for a probe's argument.
-+
-+ The relationship is:
-+
-+ - STAP_ARG_BITNESS_UNDEFINED: The user hasn't specified the bitness.
-+ - STAP_ARG_BITNESS_32BIT_UNSIGNED: argument string starts with `4@'.
-+ - STAP_ARG_BITNESS_32BIT_SIGNED: argument string starts with `-4@'.
-+ - STAP_ARG_BITNESS_64BIT_UNSIGNED: argument string starts with `8@'.
-+ - STAP_ARG_BITNESS_64BIT_SIGNED: argument string starts with `-8@'. */
-+
-+enum stap_arg_bitness
-+{
-+ STAP_ARG_BITNESS_UNDEFINED,
-+ STAP_ARG_BITNESS_32BIT_UNSIGNED,
-+ STAP_ARG_BITNESS_32BIT_SIGNED,
-+ STAP_ARG_BITNESS_64BIT_UNSIGNED,
-+ STAP_ARG_BITNESS_64BIT_SIGNED,
-+};
-+
-+/* The following structure represents a single argument for the probe. */
-+
-+struct stap_probe_arg
-+{
-+ /* The bitness of this argument. */
-+ enum stap_arg_bitness bitness;
-+
-+ /* The corresponding `struct type *' to the bitness. */
-+ struct type *atype;
-+
-+ /* The argument converted to an internal GDB expression. */
-+ struct expression *aexpr;
-+};
-+
-+/* Structure that holds information about all arguments of a probe. */
-+
-+struct stap_args_info
-+{
-+ /* The number of valid parsed arguments. */
-+ int n_args;
-+
-+ /* The probe to which these arguments belong. */
-+ struct stap_probe *probe;
-+
-+ /* Information about each argument. This is an array of `stap_probe_arg',
-+ with each entry representing one argument. */
-+ struct stap_probe_arg *args;
-+};
-+
-+/* When parsing the arguments, we have to establish different precedences
-+ for the various kinds of asm operators. This enumeration represents those
-+ precedences.
-+
-+ This logic behind this is available at
-+ <http://sourceware.org/binutils/docs/as/Infix-Ops.html#Infix-Ops>, or using
-+ the command "info '(as)Infix Ops'". */
-+
-+enum stap_operand_prec
-+{
-+ /* Lowest precedence, used for non-recognized operands or for the beginning
-+ of the parsing process. */
-+ STAP_OPERAND_PREC_NONE = 0,
-+
-+ /* Precedence of logical OR. */
-+ STAP_OPERAND_PREC_LOGICAL_OR,
-+
-+ /* Precedence of logical AND. */
-+ STAP_OPERAND_PREC_LOGICAL_AND,
-+
-+ /* Precedence of additive (plus, minus) and comparative (equal, less,
-+ greater-than, etc) operands. */
-+ STAP_OPERAND_PREC_ADD_CMP,
-+
-+ /* Precedence of bitwise operands (bitwise OR, XOR, bitwise AND,
-+ logical NOT). */
-+ STAP_OPERAND_PREC_BITWISE,
-+
-+ /* Precedence of multiplicative operands (multiplication, division,
-+ remainder, left shift and right shift). */
-+ STAP_OPERAND_PREC_MUL
-+};
-+
-+/* This dummy variable is used when parsing a probe's argument fails.
-+ In this case, the number of arguments for this probe is zero, so that's
-+ why this variable is useful. */
-+
-+static struct stap_args_info dummy_stap_args_info =
-+ { 0, NULL, NULL };
-+
-+static void stap_parse_argument_1 (struct stap_parse_info *p, int has_lhs,
-+ enum stap_operand_prec prec);
+ printf_filtered ("Unable to open file %s\n", file);
+ return;
+ }
++ cleanup = make_cleanup_bfd_unref (abfd);
+
+ if (bfd_check_format (abfd, bfd_object) == 0)
+ {
+ printf_filtered ("File is not an object file\n");
++ do_cleanups (cleanup);
+ return;
+ }
+
+@@ -3503,6 +3511,7 @@ pmon_load_fast (char *file)
+ pmon_end_download (final, bintotal);
+ }
+
++ do_cleanups (cleanup);
+ return;
+ }
+
+diff --git a/gdb/remote.c b/gdb/remote.c
+index 1c9367d..f2b5e7b 100644
+--- a/gdb/remote.c
++++ b/gdb/remote.c
+@@ -42,6 +42,7 @@
+ #include "cli/cli-decode.h"
+ #include "cli/cli-setshow.h"
+ #include "target-descriptions.h"
++#include "gdb_bfd.h"
+
+ #include <ctype.h>
+ #include <sys/time.h>
+@@ -9823,11 +9824,13 @@ remote_filename_p (const char *filename)
+ bfd *
+ remote_bfd_open (const char *remote_file, const char *target)
+ {
+- return bfd_openr_iovec (remote_file, target,
+- remote_bfd_iovec_open, NULL,
+- remote_bfd_iovec_pread,
+- remote_bfd_iovec_close,
+- remote_bfd_iovec_stat);
++ bfd *abfd = gdb_bfd_openr_iovec (remote_file, target,
++ remote_bfd_iovec_open, NULL,
++ remote_bfd_iovec_pread,
++ remote_bfd_iovec_close,
++ remote_bfd_iovec_stat);
++
++ return abfd;
+ }
+
+ void
+diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c
+index 0a2000a..9b8efd3 100644
+--- a/gdb/rs6000-nat.c
++++ b/gdb/rs6000-nat.c
+@@ -730,7 +730,7 @@ static struct vmap *
+ add_vmap (LdInfo *ldi)
+ {
+ bfd *abfd, *last;
+- char *mem, *objname, *filename;
++ char *mem, *filename;
+ struct objfile *obj;
+ struct vmap *vp;
+ int fd;
+@@ -743,19 +743,18 @@ add_vmap (LdInfo *ldi)
+ filename = LDI_FILENAME (ldi, arch64);
+ mem = filename + strlen (filename) + 1;
+ mem = xstrdup (mem);
+- objname = xstrdup (filename);
+
+ fd = LDI_FD (ldi, arch64);
+ if (fd < 0)
+ /* Note that this opens it once for every member; a possible
+ enhancement would be to only open it once for every object. */
+- abfd = bfd_openr (objname, gnutarget);
++ abfd = gdb_bfd_openr (filename, gnutarget);
+ else
+- abfd = bfd_fdopenr (objname, gnutarget, fd);
++ abfd = gdb_bfd_fdopenr (filename, gnutarget, fd);
+ if (!abfd)
+ {
+ warning (_("Could not open `%s' as an executable file: %s"),
+- objname, bfd_errmsg (bfd_get_error ()));
++ filename, bfd_errmsg (bfd_get_error ()));
+ return NULL;
+ }
+
+@@ -766,35 +765,44 @@ add_vmap (LdInfo *ldi)
+
+ else if (bfd_check_format (abfd, bfd_archive))
+ {
+- last = 0;
+- /* FIXME??? am I tossing BFDs? bfd? */
+- while ((last = bfd_openr_next_archived_file (abfd, last)))
+- if (strcmp (mem, last->filename) == 0)
+- break;
++ last = gdb_bfd_openr_next_archived_file (abfd, NULL);
++ while (last != NULL)
++ {
++ bfd *next;
+
-+static void stap_parse_argument_conditionally (struct stap_parse_info *p);
++ if (strcmp (mem, last->filename) == 0)
++ break;
+
-+/* Returns 1 if *S is an operator, zero otherwise. */
++ next = gdb_bfd_openr_next_archived_file (abfd, last);
++ gdb_bfd_unref (last);
++ }
+
+ if (!last)
+ {
+- warning (_("\"%s\": member \"%s\" missing."), objname, mem);
+- bfd_close (abfd);
++ warning (_("\"%s\": member \"%s\" missing."), filename, mem);
++ gdb_bfd_unref (abfd);
+ return NULL;
+ }
+
+ if (!bfd_check_format (last, bfd_object))
+ {
+ warning (_("\"%s\": member \"%s\" not in executable format: %s."),
+- objname, mem, bfd_errmsg (bfd_get_error ()));
+- bfd_close (last);
+- bfd_close (abfd);
++ filename, mem, bfd_errmsg (bfd_get_error ()));
++ gdb_bfd_unref (last);
++ gdb_bfd_unref (abfd);
+ return NULL;
+ }
+
+ vp = map_vmap (last, abfd);
++ /* map_vmap acquired a reference to LAST, so we can release
++ ours. */
++ gdb_bfd_unref (last);
+ }
+ else
+ {
+ warning (_("\"%s\": not in executable format: %s."),
+- objname, bfd_errmsg (bfd_get_error ()));
+- bfd_close (abfd);
++ filename, bfd_errmsg (bfd_get_error ()));
++ gdb_bfd_unref (abfd);
+ return NULL;
+ }
+ obj = allocate_objfile (vp->bfd, 0);
+@@ -803,6 +811,11 @@ add_vmap (LdInfo *ldi)
+ /* Always add symbols for the main objfile. */
+ if (vp == vmap || auto_solib_add)
+ vmap_add_symbols (vp);
+
-+static int stap_is_operator (char op);
++ /* Anything needing a reference to ABFD has already acquired it, so
++ release our local reference. */
++ gdb_bfd_unref (abfd);
+
-+static void
-+show_stapexpressiondebug (struct ui_file *file, int from_tty,
-+ struct cmd_list_element *c, const char *value)
-+{
-+ fprintf_filtered (file, _("SystemTap Probe expression debugging is %s.\n"),
-+ value);
-+}
+ return vp;
+ }
+ \f
+diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c
+index d52fb46..db8f187 100644
+--- a/gdb/solib-darwin.c
++++ b/gdb/solib-darwin.c
+@@ -28,6 +28,7 @@
+ #include "inferior.h"
+ #include "regcache.h"
+ #include "gdbthread.h"
++#include "gdb_bfd.h"
+
+ #include "gdb_assert.h"
+
+@@ -356,6 +357,7 @@ darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info)
+ gdb_byte *interp_name;
+ CORE_ADDR load_addr = 0;
+ bfd *dyld_bfd = NULL;
++ struct cleanup *cleanup;
+
+ /* This method doesn't work with an attached process. */
+ if (current_inferior ()->attach_flag)
+@@ -366,24 +368,31 @@ darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info)
+ if (!interp_name)
+ return;
+
++ cleanup = make_cleanup (null_cleanup, NULL);
+
-+/* Returns the operator precedence level of OP, or STAP_OPERAND_PREC_NONE
-+ if the operator code was not recognized. */
+ /* Create a bfd for the interpreter. */
+- dyld_bfd = bfd_openr (interp_name, gnutarget);
++ dyld_bfd = gdb_bfd_openr (interp_name, gnutarget);
+ if (dyld_bfd)
+ {
+ bfd *sub;
+
++ make_cleanup_bfd_unref (dyld_bfd);
+ sub = bfd_mach_o_fat_extract (dyld_bfd, bfd_object,
+ gdbarch_bfd_arch_info (target_gdbarch));
+ if (sub)
+- dyld_bfd = sub;
+- else
+ {
+- bfd_close (dyld_bfd);
+- dyld_bfd = NULL;
++ dyld_bfd = sub;
++ gdb_bfd_ref (sub);
++ make_cleanup_bfd_unref (sub);
+ }
++ else
++ dyld_bfd = NULL;
+ }
+ if (!dyld_bfd)
+- return;
++ {
++ do_cleanups (cleanup);
++ return;
++ }
+
+ /* We find the dynamic linker's base address by examining
+ the current pc (which should point at the entry point for the
+@@ -395,7 +404,7 @@ darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info)
+ info->all_image_addr =
+ lookup_symbol_from_bfd (dyld_bfd, "_dyld_all_image_infos");
+
+- bfd_close (dyld_bfd);
++ do_cleanups (cleanup);
+
+ if (info->all_image_addr == 0)
+ return;
+@@ -509,17 +518,10 @@ darwin_bfd_open (char *pathname)
+ gdbarch_bfd_arch_info (target_gdbarch));
+ if (!res)
+ {
+- bfd_close (abfd);
+- make_cleanup (xfree, found_pathname);
++ make_cleanup_bfd_unref (abfd);
+ error (_("`%s': not a shared-library: %s"),
+- found_pathname, bfd_errmsg (bfd_get_error ()));
++ bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
+ }
+-
+- /* Make sure that the filename is malloc'ed. The current filename
+- for fat-binaries BFDs is a name that was generated by BFD, usually
+- a static string containing the name of the architecture. */
+- res->filename = xstrdup (pathname);
+-
+ return res;
+ }
+
+diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c
+index 2500c1f..fcc01a8 100644
+--- a/gdb/solib-dsbt.c
++++ b/gdb/solib-dsbt.c
+@@ -30,6 +30,7 @@
+ #include "gdbcmd.h"
+ #include "elf-bfd.h"
+ #include "exceptions.h"
++#include "gdb_bfd.h"
+
+ #define GOT_MODULE_OFFSET 4
+
+@@ -899,7 +900,7 @@ enable_break2 (void)
+ {
+ warning (_("Could not find symbol _dl_debug_addr in dynamic linker"));
+ enable_break_failure_warning ();
+- bfd_close (tmp_bfd);
++ gdb_bfd_unref (tmp_bfd);
+ return 0;
+ }
+
+@@ -948,13 +949,13 @@ enable_break2 (void)
+ "(at address %s) from dynamic linker"),
+ hex_string_custom (addr + 8, 8));
+ enable_break_failure_warning ();
+- bfd_close (tmp_bfd);
++ gdb_bfd_unref (tmp_bfd);
+ return 0;
+ }
+ addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
+
+ /* We're done with the temporary bfd. */
+- bfd_close (tmp_bfd);
++ gdb_bfd_unref (tmp_bfd);
+
+ /* We're also done with the loadmap. */
+ xfree (ldm);
+diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c
+index 2f2c8b0..0f59535 100644
+--- a/gdb/solib-frv.c
++++ b/gdb/solib-frv.c
+@@ -31,6 +31,7 @@
+ #include "gdbcmd.h"
+ #include "elf/frv.h"
+ #include "exceptions.h"
++#include "gdb_bfd.h"
+
+ /* Flag which indicates whether internal debug messages should be printed. */
+ static int solib_frv_debug;
+@@ -574,7 +575,7 @@ enable_break2 (void)
+ {
+ warning (_("Unable to determine dynamic linker loadmap address."));
+ enable_break_failure_warning ();
+- bfd_close (tmp_bfd);
++ gdb_bfd_unref (tmp_bfd);
+ return 0;
+ }
+
+@@ -589,7 +590,7 @@ enable_break2 (void)
+ warning (_("Unable to load dynamic linker loadmap at address %s."),
+ hex_string_custom (interp_loadmap_addr, 8));
+ enable_break_failure_warning ();
+- bfd_close (tmp_bfd);
++ gdb_bfd_unref (tmp_bfd);
+ return 0;
+ }
+
+@@ -623,7 +624,7 @@ enable_break2 (void)
+ warning (_("Could not find symbol _dl_debug_addr "
+ "in dynamic linker"));
+ enable_break_failure_warning ();
+- bfd_close (tmp_bfd);
++ gdb_bfd_unref (tmp_bfd);
+ return 0;
+ }
+
+@@ -674,7 +675,7 @@ enable_break2 (void)
+ "(at address %s) from dynamic linker"),
+ hex_string_custom (addr + 8, 8));
+ enable_break_failure_warning ();
+- bfd_close (tmp_bfd);
++ gdb_bfd_unref (tmp_bfd);
+ return 0;
+ }
+ addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
+@@ -686,13 +687,13 @@ enable_break2 (void)
+ "(at address %s) from dynamic linker"),
+ hex_string_custom (addr, 8));
+ enable_break_failure_warning ();
+- bfd_close (tmp_bfd);
++ gdb_bfd_unref (tmp_bfd);
+ return 0;
+ }
+ addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
+
+ /* We're done with the temporary bfd. */
+- bfd_close (tmp_bfd);
++ gdb_bfd_unref (tmp_bfd);
+
+ /* We're also done with the loadmap. */
+ xfree (ldm);
+diff --git a/gdb/solib-pa64.c b/gdb/solib-pa64.c
+index 2b8d061..00ed8a5 100644
+--- a/gdb/solib-pa64.c
++++ b/gdb/solib-pa64.c
+@@ -362,7 +362,7 @@ manpage for methods to privately map shared library text."));
+ to find any magic formula to find it for Solaris (appears to
+ be trivial on GNU/Linux). Therefore, we have to try an alternate
+ mechanism to find the dynamic linker's base address. */
+- tmp_bfd = bfd_openr (buf, gnutarget);
++ tmp_bfd = gdb_bfd_openr (buf, gnutarget);
+ if (tmp_bfd == NULL)
+ return;
+
+@@ -371,7 +371,7 @@ manpage for methods to privately map shared library text."));
+ {
+ warning (_("Unable to grok dynamic linker %s as an object file"),
+ buf);
+- bfd_close (tmp_bfd);
++ gdb_bfd_unref (tmp_bfd);
+ return;
+ }
+
+@@ -401,7 +401,7 @@ manpage for methods to privately map shared library text."));
+ }
+
+ /* We're done with the temporary bfd. */
+- bfd_close (tmp_bfd);
++ gdb_bfd_unref (tmp_bfd);
+ }
+ }
+
+diff --git a/gdb/solib-spu.c b/gdb/solib-spu.c
+index b5454e7..f62d96c 100644
+--- a/gdb/solib-spu.c
++++ b/gdb/solib-spu.c
+@@ -36,6 +36,7 @@
+ #include "breakpoint.h"
+ #include "gdbthread.h"
+ #include "exceptions.h"
++#include "gdb_bfd.h"
+
+ #include "spu-tdep.h"
+
+@@ -325,16 +326,16 @@ spu_bfd_fopen (char *name, CORE_ADDR addr)
+ CORE_ADDR *open_closure = xmalloc (sizeof (CORE_ADDR));
+ *open_closure = addr;
+
+- nbfd = bfd_openr_iovec (xstrdup (name), "elf32-spu",
+- spu_bfd_iovec_open, open_closure,
+- spu_bfd_iovec_pread, spu_bfd_iovec_close,
+- spu_bfd_iovec_stat);
++ nbfd = gdb_bfd_openr_iovec (name, "elf32-spu",
++ spu_bfd_iovec_open, open_closure,
++ spu_bfd_iovec_pread, spu_bfd_iovec_close,
++ spu_bfd_iovec_stat);
+ if (!nbfd)
+ return NULL;
+
+ if (!bfd_check_format (nbfd, bfd_object))
+ {
+- bfd_close (nbfd);
++ gdb_bfd_unref (nbfd);
+ return NULL;
+ }
+
+diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
+index 307e483..76bd872 100644
+--- a/gdb/solib-svr4.c
++++ b/gdb/solib-svr4.c
+@@ -46,6 +46,7 @@
+ #include "exec.h"
+ #include "auxv.h"
+ #include "exceptions.h"
++#include "gdb_bfd.h"
+
+ static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
+ static int svr4_have_link_map_offsets (void);
+@@ -1558,9 +1559,11 @@ enable_break (struct svr4_info *info, int from_tty)
+ goto bkpt_at_symbol;
+
+ /* Now convert the TMP_BFD into a target. That way target, as
+- well as BFD operations can be used. Note that closing the
+- target will also close the underlying bfd. */
++ well as BFD operations can be used. */
+ tmp_bfd_target = target_bfd_reopen (tmp_bfd);
++ /* target_bfd_reopen acquired its own reference, so we can
++ release ours now. */
++ gdb_bfd_unref (tmp_bfd);
+
+ /* On a running target, we can get the dynamic linker's base
+ address from the shared library table. */
+@@ -1670,8 +1673,9 @@ enable_break (struct svr4_info *info, int from_tty)
+ sym_addr,
+ tmp_bfd_target);
+
+- /* We're done with both the temporary bfd and target. Remember,
+- closing the target closes the underlying bfd. */
++ /* We're done with both the temporary bfd and target. Closing
++ the target closes the underlying bfd, because it holds the
++ only remaining reference. */
+ target_close (tmp_bfd_target, 0);
+
+ if (sym_addr != 0)
+diff --git a/gdb/solib.c b/gdb/solib.c
+index 90439ba..73773f1 100644
+--- a/gdb/solib.c
++++ b/gdb/solib.c
+@@ -46,6 +46,7 @@
+ #include "solib.h"
+ #include "interps.h"
+ #include "filesystem.h"
++#include "gdb_bfd.h"
+
+ /* Architecture-specific operations. */
+
+@@ -360,9 +361,9 @@ solib_find (char *in_pathname, int *fd)
+ it is used as file handle to open the file. Throws an error if the file
+ could not be opened. Handles both local and remote file access.
+
+- PATHNAME must be malloc'ed by the caller. If successful, the new BFD's
+- name will point to it. If unsuccessful, PATHNAME will be freed and the
+- FD will be closed (unless FD was -1). */
++ PATHNAME must be malloc'ed by the caller. It will be freed by this
++ function. If unsuccessful, the FD will be closed (unless FD was
++ -1). */
+
+ bfd *
+ solib_bfd_fopen (char *pathname, int fd)
+@@ -376,7 +377,7 @@ solib_bfd_fopen (char *pathname, int fd)
+ }
+ else
+ {
+- abfd = bfd_fopen (pathname, gnutarget, FOPEN_RB, fd);
++ abfd = gdb_bfd_fopen (pathname, gnutarget, FOPEN_RB, fd);
+
+ if (abfd)
+ bfd_set_cacheable (abfd, 1);
+@@ -389,6 +390,8 @@ solib_bfd_fopen (char *pathname, int fd)
+ pathname, bfd_errmsg (bfd_get_error ()));
+ }
+
++ xfree (pathname);
+
-+static enum stap_operand_prec
-+stap_get_operator_prec (enum exp_opcode op)
-+{
-+ switch (op)
+ return abfd;
+ }
+
+@@ -420,17 +423,16 @@ solib_bfd_open (char *pathname)
+ /* Check bfd format. */
+ if (!bfd_check_format (abfd, bfd_object))
+ {
+- bfd_close (abfd);
+- make_cleanup (xfree, found_pathname);
++ make_cleanup_bfd_unref (abfd);
+ error (_("`%s': not in executable format: %s"),
+- found_pathname, bfd_errmsg (bfd_get_error ()));
++ bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
+ }
+
+ /* Check bfd arch. */
+ b = gdbarch_bfd_arch_info (target_gdbarch);
+ if (!b->compatible (b, bfd_get_arch_info (abfd)))
+ warning (_("`%s': Shared library architecture %s is not compatible "
+- "with target architecture %s."), found_pathname,
++ "with target architecture %s."), bfd_get_filename (abfd),
+ bfd_get_arch_info (abfd)->printable_name, b->printable_name);
+
+ return abfd;
+@@ -466,7 +468,7 @@ solib_map_sections (struct so_list *so)
+ return 0;
+
+ /* Leave bfd open, core_xfer_memory and "info files" need it. */
+- so->abfd = gdb_bfd_ref (abfd);
++ so->abfd = abfd;
+
+ /* copy full path name into so_name, so that later symbol_file_add
+ can find it. */
+@@ -1233,7 +1235,7 @@ reload_shared_libraries_1 (int from_tty)
+ {
+ found_pathname = xstrdup (bfd_get_filename (abfd));
+ make_cleanup (xfree, found_pathname);
+- gdb_bfd_close_or_warn (abfd);
++ gdb_bfd_unref (abfd);
+ }
+
+ /* If this shared library is no longer associated with its previous
+diff --git a/gdb/spu-linux-nat.c b/gdb/spu-linux-nat.c
+index 2dfec8c..999f1ab 100644
+--- a/gdb/spu-linux-nat.c
++++ b/gdb/spu-linux-nat.c
+@@ -315,16 +315,16 @@ spu_bfd_open (ULONGEST addr)
+ ULONGEST *open_closure = xmalloc (sizeof (ULONGEST));
+ *open_closure = addr;
+
+- nbfd = bfd_openr_iovec (xstrdup ("<in-memory>"), "elf32-spu",
+- spu_bfd_iovec_open, open_closure,
+- spu_bfd_iovec_pread, spu_bfd_iovec_close,
+- spu_bfd_iovec_stat);
++ nbfd = gdb_bfd_openr_iovec ("<in-memory>", "elf32-spu",
++ spu_bfd_iovec_open, open_closure,
++ spu_bfd_iovec_pread, spu_bfd_iovec_close,
++ spu_bfd_iovec_stat);
+ if (!nbfd)
+ return NULL;
+
+ if (!bfd_check_format (nbfd, bfd_object))
+ {
+- bfd_close (nbfd);
++ gdb_bfd_unref (nbfd);
+ return NULL;
+ }
+
+@@ -374,8 +374,13 @@ spu_symbol_file_add_from_memory (int inferior_fd)
+ /* Open BFD representing SPE executable and read its symbols. */
+ nbfd = spu_bfd_open (addr);
+ if (nbfd)
+- symbol_file_add_from_bfd (nbfd, SYMFILE_VERBOSE | SYMFILE_MAINLINE,
+- NULL, 0, NULL);
+ {
-+ case BINOP_LOGICAL_OR:
-+ return STAP_OPERAND_PREC_LOGICAL_OR;
-+
-+ case BINOP_LOGICAL_AND:
-+ return STAP_OPERAND_PREC_LOGICAL_AND;
-+
-+ case BINOP_ADD:
-+ case BINOP_SUB:
-+ case BINOP_EQUAL:
-+ case BINOP_NOTEQUAL:
-+ case BINOP_LESS:
-+ case BINOP_LEQ:
-+ case BINOP_GTR:
-+ case BINOP_GEQ:
-+ return STAP_OPERAND_PREC_ADD_CMP;
-+
-+ case BINOP_BITWISE_IOR:
-+ case BINOP_BITWISE_AND:
-+ case BINOP_BITWISE_XOR:
-+ case UNOP_LOGICAL_NOT:
-+ return STAP_OPERAND_PREC_BITWISE;
-+
-+ case BINOP_MUL:
-+ case BINOP_DIV:
-+ case BINOP_REM:
-+ case BINOP_LSH:
-+ case BINOP_RSH:
-+ return STAP_OPERAND_PREC_MUL;
++ struct cleanup *cleanup = make_cleanup_bfd_unref (nbfd);
+
-+ default:
-+ return STAP_OPERAND_PREC_NONE;
++ symbol_file_add_from_bfd (nbfd, SYMFILE_VERBOSE | SYMFILE_MAINLINE,
++ NULL, 0, NULL);
++ do_cleanups (cleanup);
+ }
-+}
+ }
+
+
+diff --git a/gdb/stack.c b/gdb/stack.c
+index 35d379d..04aab5e 100644
+--- a/gdb/stack.c
++++ b/gdb/stack.c
+@@ -509,6 +509,10 @@ print_frame_args (struct symbol *func, struct frame_info *frame,
+ stb = mem_fileopen ();
+ old_chain = make_cleanup_ui_file_delete (stb);
+
++ /* Frame may be needed for check_typedef of TYPE_DYNAMIC. */
++ make_cleanup_restore_selected_frame ();
++ select_frame (frame);
+
-+/* Given S, read the operator in it and fills the OP pointer with its code.
-+ Return 1 on success, zero if the operator was not recognized. */
+ if (func)
+ {
+ struct block *b = SYMBOL_BLOCK_VALUE (func);
+diff --git a/gdb/symfile-mem.c b/gdb/symfile-mem.c
+index e80fd25..2e53be0 100644
+--- a/gdb/symfile-mem.c
++++ b/gdb/symfile-mem.c
+@@ -54,6 +54,7 @@
+ #include "observer.h"
+ #include "auxv.h"
+ #include "elf/common.h"
++#include "gdb_bfd.h"
+
+ /* Verify parameters of target_read_memory_bfd and target_read_memory are
+ compatible. */
+@@ -100,23 +101,24 @@ symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
+ if (nbfd == NULL)
+ error (_("Failed to read a valid object file image from memory."));
+
++ gdb_bfd_ref (nbfd);
+ if (name == NULL)
+- nbfd->filename = xstrdup ("shared object read from target memory");
++ nbfd->filename = "shared object read from target memory";
+ else
+- nbfd->filename = name;
+-
+- if (!bfd_check_format (nbfd, bfd_object))
+ {
+- /* FIXME: should be checking for errors from bfd_close (for one thing,
+- on error it does not free all the storage associated with the
+- bfd). */
+- bfd_close (nbfd);
+- error (_("Got object file from memory but can't read symbols: %s."),
+- bfd_errmsg (bfd_get_error ()));
++ nbfd->filename = name;
++ gdb_bfd_stash_filename (nbfd);
++ xfree (name);
+ }
+
++ cleanup = make_cleanup_bfd_unref (nbfd);
++
++ if (!bfd_check_format (nbfd, bfd_object))
++ error (_("Got object file from memory but can't read symbols: %s."),
++ bfd_errmsg (bfd_get_error ()));
++
+ sai = alloc_section_addr_info (bfd_count_sections (nbfd));
+- cleanup = make_cleanup (xfree, sai);
++ make_cleanup (xfree, sai);
+ i = 0;
+ for (sec = nbfd->sections; sec != NULL; sec = sec->next)
+ if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
+diff --git a/gdb/symfile.c b/gdb/symfile.c
+index 01252e2..95ed480 100644
+--- a/gdb/symfile.c
++++ b/gdb/symfile.c
+@@ -55,6 +55,7 @@
+ #include "solib.h"
+ #include "remote.h"
+ #include "stack.h"
++#include "gdb_bfd.h"
+
+ #include <sys/types.h>
+ #include <fcntl.h>
+@@ -1036,7 +1037,7 @@ new_symfile_objfile (struct objfile *objfile, int add_flags)
+ loaded file.
+
+ ABFD is a BFD already open on the file, as from symfile_bfd_open.
+- This BFD will be closed on error, and is always consumed by this function.
++ A new reference is acquired by this function.
+
+ ADD_FLAGS encodes verbosity, whether this is main symbol file or
+ extra, such as dynamically loaded code, and what to do with breakpoins.
+@@ -1060,7 +1061,6 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
+ int flags, struct objfile *parent)
+ {
+ struct objfile *objfile;
+- struct cleanup *my_cleanups;
+ const char *name = bfd_get_filename (abfd);
+ const int from_tty = add_flags & SYMFILE_VERBOSE;
+ const int mainline = add_flags & SYMFILE_MAINLINE;
+@@ -1074,8 +1074,6 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
+ add_flags &= ~SYMFILE_NO_READ;
+ }
+
+- my_cleanups = make_cleanup_bfd_close (abfd);
+-
+ /* Give user a chance to burp if we'd be
+ interactively wiping out any existing symbols. */
+
+@@ -1086,7 +1084,6 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
+ error (_("Not confirmed."));
+
+ objfile = allocate_objfile (abfd, flags | (mainline ? OBJF_MAINLINE : 0));
+- discard_cleanups (my_cleanups);
+
+ if (parent)
+ add_separate_debug_objfile (objfile, parent);
+@@ -1207,8 +1204,13 @@ struct objfile *
+ symbol_file_add (char *name, int add_flags, struct section_addr_info *addrs,
+ int flags)
+ {
+- return symbol_file_add_from_bfd (symfile_bfd_open (name), add_flags, addrs,
+- flags, NULL);
++ bfd *bfd = symfile_bfd_open (name);
++ struct cleanup *cleanup = make_cleanup_bfd_unref (bfd);
++ struct objfile *objf;
+
-+static int
-+stap_get_opcode (const char **s, enum exp_opcode *op)
-+{
-+ const char c = **s;
-+ int ret = 1;
++ objf = symbol_file_add_from_bfd (bfd, add_flags, addrs, flags, NULL);
++ do_cleanups (cleanup);
++ return objf;
+ }
+
+
+@@ -1350,7 +1352,7 @@ separate_debug_file_exists (const char *name, unsigned long crc,
+ if (filename_cmp (name, parent_objfile->name) == 0)
+ return 0;
+
+- abfd = bfd_open_maybe_remote (name);
++ abfd = gdb_bfd_open_maybe_remote (name);
+
+ if (!abfd)
+ return 0;
+@@ -1372,7 +1374,7 @@ separate_debug_file_exists (const char *name, unsigned long crc,
+ if (abfd_stat.st_dev == parent_stat.st_dev
+ && abfd_stat.st_ino == parent_stat.st_ino)
+ {
+- bfd_close (abfd);
++ gdb_bfd_unref (abfd);
+ return 0;
+ }
+ verified_as_different = 1;
+@@ -1382,7 +1384,7 @@ separate_debug_file_exists (const char *name, unsigned long crc,
+
+ file_crc_p = get_file_crc (abfd, &file_crc);
+
+- bfd_close (abfd);
++ gdb_bfd_unref (abfd);
+
+ if (!file_crc_p)
+ return 0;
+@@ -1690,15 +1692,20 @@ set_initial_language (void)
+ }
+
+ /* If NAME is a remote name open the file using remote protocol, otherwise
+- open it normally. */
++ open it normally. Returns a new reference to the BFD. On error,
++ returns NULL with the BFD error set. */
+
+ bfd *
+-bfd_open_maybe_remote (const char *name)
++gdb_bfd_open_maybe_remote (const char *name)
+ {
++ bfd *result;
+
-+ *s += 1;
+ if (remote_filename_p (name))
+- return remote_bfd_open (name, gnutarget);
++ result = remote_bfd_open (name, gnutarget);
+ else
+- return bfd_openr (name, gnutarget);
++ result = gdb_bfd_openr (name, gnutarget);
+
-+ switch (c)
-+ {
-+ case '*':
-+ *op = BINOP_MUL;
-+ break;
-+
-+ case '/':
-+ *op = BINOP_DIV;
-+ break;
-+
-+ case '%':
-+ *op = BINOP_REM;
-+ break;
-+
-+ case '<':
-+ *op = BINOP_LESS;
-+ if (**s == '<')
-+ {
-+ *s += 1;
-+ *op = BINOP_LSH;
-+ }
-+ else if (**s == '=')
-+ {
-+ *s += 1;
-+ *op = BINOP_LEQ;
-+ }
-+ else if (**s == '>')
-+ {
-+ *s += 1;
-+ *op = BINOP_NOTEQUAL;
-+ }
-+ break;
-+
-+ case '>':
-+ *op = BINOP_GTR;
-+ if (**s == '>')
-+ {
-+ *s += 1;
-+ *op = BINOP_RSH;
-+ }
-+ else if (**s == '=')
-+ {
-+ *s += 1;
-+ *op = BINOP_GEQ;
-+ }
-+ break;
-+
-+ case '|':
-+ *op = BINOP_BITWISE_IOR;
-+ if (**s == '|')
-+ {
-+ *s += 1;
-+ *op = BINOP_LOGICAL_OR;
-+ }
-+ break;
-+
-+ case '&':
-+ *op = BINOP_BITWISE_AND;
-+ if (**s == '&')
-+ {
-+ *s += 1;
-+ *op = BINOP_LOGICAL_AND;
-+ }
-+ break;
-+
-+ case '^':
-+ *op = BINOP_BITWISE_XOR;
-+ break;
-+
-+ case '!':
-+ *op = UNOP_LOGICAL_NOT;
-+ break;
-+
-+ case '+':
-+ *op = BINOP_ADD;
-+ break;
-+
-+ case '-':
-+ *op = BINOP_SUB;
-+ break;
-+
-+ case '=':
-+ if (**s != '=')
-+ {
-+ ret = 0;
-+ break;
-+ }
-+ *op = BINOP_EQUAL;
-+ break;
-+
-+ default:
-+ /* We didn't find any operator. */
-+ *s -= 1;
-+ return 0;
-+ }
-+
-+ return ret;
-+}
-+
-+/* Given the bitness of the argument, represented by B, return the
-+ corresponding `struct type *'. */
-+
-+static struct type *
-+stap_get_expected_argument_type (struct gdbarch *gdbarch,
-+ enum stap_arg_bitness b)
-+{
-+ switch (b)
-+ {
-+ case STAP_ARG_BITNESS_UNDEFINED:
-+ if (gdbarch_addr_bit (gdbarch) == 32)
-+ return builtin_type (gdbarch)->builtin_uint32;
-+ else
-+ return builtin_type (gdbarch)->builtin_uint64;
-+
-+ case STAP_ARG_BITNESS_32BIT_SIGNED:
-+ return builtin_type (gdbarch)->builtin_int32;
-+
-+ case STAP_ARG_BITNESS_32BIT_UNSIGNED:
-+ return builtin_type (gdbarch)->builtin_uint32;
-+
-+ case STAP_ARG_BITNESS_64BIT_SIGNED:
-+ return builtin_type (gdbarch)->builtin_int64;
-+
-+ case STAP_ARG_BITNESS_64BIT_UNSIGNED:
-+ return builtin_type (gdbarch)->builtin_uint64;
-+
-+ default:
-+ internal_error (__FILE__, __LINE__,
-+ _("Undefined bitness for probe."));
-+ break;
-+ }
-+}
-+
-+static void
-+stap_parse_register_operand (struct stap_parse_info *p)
-+{
-+ /* Simple flag to indicate whether we have seen a minus signal before
-+ certain number. */
-+ int got_minus = 0;
-+ /* Flags to indicate whether this register access is being displaced and/or
-+ indirected. */
-+ int disp_p = 0, indirect_p = 0;
-+ struct gdbarch *gdbarch = p->gdbarch;
-+ /* Needed to generate the register name as a part of an expression. */
-+ struct stoken str;
-+ /* Variables used to extract the register name from the probe's
-+ argument. */
-+ const char *start;
-+ char *regname;
-+ int len;
-+
-+ /* Prefixes for the parser. */
-+ const char *reg_prefix = gdbarch_stap_register_prefix (gdbarch);
-+ const char *reg_ind_prefix
-+ = gdbarch_stap_register_indirection_prefix (gdbarch);
-+ const char *gdb_reg_prefix = gdbarch_stap_gdb_register_prefix (gdbarch);
-+ int reg_prefix_len = reg_prefix ? strlen (reg_prefix) : 0;
-+ int reg_ind_prefix_len = reg_ind_prefix ? strlen (reg_ind_prefix) : 0;
-+ int gdb_reg_prefix_len = gdb_reg_prefix ? strlen (gdb_reg_prefix) : 0;
-+
-+ /* Sufixes for the parser. */
-+ const char *reg_sufix = gdbarch_stap_register_sufix (gdbarch);
-+ const char *reg_ind_sufix
-+ = gdbarch_stap_register_indirection_sufix (gdbarch);
-+ const char *gdb_reg_sufix = gdbarch_stap_gdb_register_sufix (gdbarch);
-+ int reg_sufix_len = reg_sufix ? strlen (reg_sufix) : 0;
-+ int reg_ind_sufix_len = reg_ind_sufix ? strlen (reg_ind_sufix) : 0;
-+ int gdb_reg_sufix_len = gdb_reg_sufix ? strlen (gdb_reg_sufix) : 0;
-+
-+ /* Checking for a displacement argument. */
-+ if (*p->arg == '+')
-+ /* If it's a plus sign, we don't need to do anything, just advance the
-+ pointer. */
-+ ++p->arg;
-+
-+ if (*p->arg == '-')
-+ {
-+ got_minus = 1;
-+ ++p->arg;
-+ }
-+
-+ if (isdigit (*p->arg))
-+ {
-+ /* The value of the displacement. */
-+ long displacement;
-+
-+ disp_p = 1;
-+ displacement = strtol (p->arg, (char **) &p->arg, 10);
-+
-+ /* Generating the expression for the displacement. */
-+ write_exp_elt_opcode (OP_LONG);
-+ write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
-+ write_exp_elt_longcst (displacement);
-+ write_exp_elt_opcode (OP_LONG);
-+ if (got_minus)
-+ write_exp_elt_opcode (UNOP_NEG);
-+ }
-+
-+ /* Getting rid of register indirection prefix. */
-+ if (reg_ind_prefix
-+ && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0)
-+ {
-+ indirect_p = 1;
-+ p->arg += reg_ind_prefix_len;
-+ }
-+
-+ if (disp_p && !indirect_p)
-+ error (_("Invalid register displacement syntax on expression `%s'."),
-+ p->saved_arg);
-+
-+ /* Getting rid of register prefix. */
-+ if (reg_prefix && strncmp (p->arg, reg_prefix, reg_prefix_len) == 0)
-+ p->arg += reg_prefix_len;
-+
-+ /* Now we should have only the register name. Let's extract it and get
-+ the associated number. */
-+ start = p->arg;
-+
-+ /* We assume the register name is composed by letters and numbers. */
-+ while (isalnum (*p->arg))
-+ ++p->arg;
-+
-+ len = p->arg - start;
-+
-+ regname = alloca (len + gdb_reg_prefix_len + gdb_reg_sufix_len + 1);
-+ regname[0] = '\0';
-+
-+ /* We only add the GDB's register prefix/sufix if we are dealing with
-+ a numeric register. */
-+ if (gdb_reg_prefix && isdigit (*start))
-+ {
-+ strncpy (regname, gdb_reg_prefix, gdb_reg_prefix_len);
-+ strncpy (regname + gdb_reg_prefix_len, start, len);
-+
-+ if (gdb_reg_sufix)
-+ strncpy (regname + gdb_reg_prefix_len + len,
-+ gdb_reg_sufix, gdb_reg_sufix_len);
-+
-+ len += gdb_reg_prefix_len + gdb_reg_sufix_len;
-+ }
-+ else
-+ strncpy (regname, start, len);
-+
-+ regname[len] = '\0';
-+ /* Is this a valid register name? */
-+ if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
-+ error (_("Invalid register name `%s' on expression `%s'."),
-+ regname, p->saved_arg);
-+
-+ write_exp_elt_opcode (OP_REGISTER);
-+ str.ptr = regname;
-+ str.length = len;
-+ write_exp_string (str);
-+ write_exp_elt_opcode (OP_REGISTER);
-+
-+ if (indirect_p)
-+ {
-+ if (disp_p)
-+ write_exp_elt_opcode (BINOP_ADD);
-+
-+ /* Casting to the expected type. */
-+ write_exp_elt_opcode (UNOP_CAST);
-+ write_exp_elt_type (lookup_pointer_type (p->arg_type));
-+ write_exp_elt_opcode (UNOP_CAST);
-+
-+ write_exp_elt_opcode (UNOP_IND);
-+ }
-+
-+ /* Getting rid of the register name sufix. */
-+ if (reg_sufix)
-+ {
-+ if (strncmp (p->arg, reg_sufix, reg_sufix_len) != 0)
-+ error (_("Missing register name sufix `%s' on expression `%s'."),
-+ reg_sufix, p->saved_arg);
-+
-+ p->arg += reg_sufix_len;
-+ }
-+
-+ /* Getting rid of the register indirection sufix. */
-+ if (indirect_p && reg_ind_sufix)
-+ {
-+ if (strncmp (p->arg, reg_ind_sufix, reg_ind_sufix_len) != 0)
-+ error (_("Missing indirection sufix `%s' on expression `%s'."),
-+ reg_ind_sufix, p->saved_arg);
-+
-+ p->arg += reg_ind_sufix_len;
-+ }
-+}
-+
-+static void
-+stap_parse_single_operand (struct stap_parse_info *p)
-+{
-+ struct gdbarch *gdbarch = p->gdbarch;
-+ /* Prefixes for the parser. */
-+ const char *const_prefix = gdbarch_stap_integer_prefix (gdbarch);
-+ const char *reg_prefix = gdbarch_stap_register_prefix (gdbarch);
-+ const char *reg_ind_prefix
-+ = gdbarch_stap_register_indirection_prefix (gdbarch);
-+ int const_prefix_len = const_prefix ? strlen (const_prefix) : 0;
-+ int reg_prefix_len = reg_prefix ? strlen (reg_prefix) : 0;
-+ int reg_ind_prefix_len = reg_ind_prefix ? strlen (reg_ind_prefix) : 0;
-+
-+ /* Sufixes for the parser. */
-+ const char *const_sufix = gdbarch_stap_integer_sufix (gdbarch);
-+ const char *reg_sufix = gdbarch_stap_register_sufix (gdbarch);
-+ const char *reg_ind_sufix
-+ = gdbarch_stap_register_indirection_sufix (gdbarch);
-+ int const_sufix_len = const_sufix ? strlen (const_sufix) : 0;
-+ int reg_sufix_len = reg_sufix ? strlen (reg_sufix) : 0;
-+ int reg_ind_sufix_len = reg_ind_sufix ? strlen (reg_ind_sufix) : 0;
-+
-+ /* We first try to parse this token as a "special token". */
-+ if (gdbarch_stap_parse_special_token_p (gdbarch))
-+ {
-+ int ret = gdbarch_stap_parse_special_token (gdbarch, p);
-+
-+ if (ret)
-+ /* If the return value of the above function is not zero,
-+ it means it successfully parsed the special token.
-+
-+ If it is NULL, we try to parse it using our method. */
-+ return;
-+ }
-+
-+ if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+')
-+ {
-+ char c = *p->arg;
-+ /* We use this variable to do a lookahead. */
-+ const char *tmp = p->arg;
-+
-+ ++tmp;
-+
-+ /* This is an unary operation. Here is a list of allowed tokens
-+ here:
-+
-+ - numeric literal;
-+ - number (from register displacement)
-+ - subexpression (beginning with `(')
-+
-+ We handle the register displacement here, and the other cases
-+ recursively. */
-+ if (isdigit (*tmp))
-+ {
-+ int number = strtol (tmp, (char **) &tmp, 10);
-+
-+ if (p->inside_paren_p)
-+ tmp = skip_spaces_const (tmp);
-+ if (!reg_ind_prefix
-+ || strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) != 0)
-+ goto not_displacement;
-+
-+ /* If we are here, it means it is a displacement. The only
-+ operations allowed here are `-' and `+'. */
-+ if (c == '~')
-+ error (_("Invalid operator `%c' for register displacement "
-+ "on expression `%s'."), c, p->saved_arg);
-+
-+ stap_parse_register_operand (p);
-+ }
-+ else
-+not_displacement:
-+ {
-+ p->arg = tmp;
-+ stap_parse_argument_conditionally (p);
-+ if (c == '-')
-+ write_exp_elt_opcode (UNOP_NEG);
-+ else if (c == '~')
-+ write_exp_elt_opcode (UNOP_COMPLEMENT);
-+ }
-+ }
-+ else if (isdigit (*p->arg))
-+ {
-+ /* A temporary variable, needed for lookahead. */
-+ const char *tmp = p->arg;
-+ long number;
-+
-+ /* We can be dealing with a numeric constant (if `const_prefix' is
-+ NULL), or with a register displacement. */
-+ number = strtol (tmp, (char **) &tmp, 10);
-+
-+ if (p->inside_paren_p)
-+ tmp = skip_spaces_const (tmp);
-+ if (!const_prefix && reg_ind_prefix
-+ && strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) != 0)
-+ {
-+ /* We are dealing with a numeric constant. */
-+ write_exp_elt_opcode (OP_LONG);
-+ write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
-+ write_exp_elt_longcst (number);
-+ write_exp_elt_opcode (OP_LONG);
-+
-+ p->arg = tmp;
-+
-+ if (const_sufix)
-+ {
-+ if (strncmp (p->arg, const_sufix, const_sufix_len) == 0)
-+ p->arg += const_sufix_len;
-+ else
-+ error (_("Invalid constant sufix on expression `%s'."),
-+ p->saved_arg);
-+ }
-+ }
-+ else if (reg_ind_prefix
-+ && strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) == 0)
-+ stap_parse_register_operand (p);
-+ else
-+ error (_("Unknown numeric token on expression `%s'."),
-+ p->saved_arg);
-+ }
-+ else if (const_prefix
-+ && strncmp (p->arg, const_prefix, const_prefix_len) == 0)
-+ {
-+ /* We are dealing with a numeric constant. */
-+ long number;
-+
-+ p->arg += const_prefix_len;
-+ number = strtol (p->arg, (char **) &p->arg, 10);
-+
-+ write_exp_elt_opcode (OP_LONG);
-+ write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
-+ write_exp_elt_longcst (number);
-+ write_exp_elt_opcode (OP_LONG);
-+
-+ if (const_sufix)
-+ {
-+ if (strncmp (p->arg, const_sufix, const_sufix_len) == 0)
-+ p->arg += const_sufix_len;
-+ else
-+ error (_("Invalid constant sufix on expression `%s'."),
-+ p->saved_arg);
-+ }
-+ }
-+ else if ((reg_prefix
-+ && strncmp (p->arg, reg_prefix, reg_prefix_len) == 0)
-+ || (reg_ind_prefix
-+ && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0))
-+ stap_parse_register_operand (p);
-+ else
-+ error (_("Operator `%c' not recognized on expression `%s'."),
-+ *p->arg, p->saved_arg);
-+}
-+
-+static void
-+stap_parse_argument_conditionally (struct stap_parse_info *p)
-+{
-+ if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+' /* Unary. */
-+ || isdigit (*p->arg)
-+ || gdbarch_stap_is_single_operand (p->gdbarch, p->arg))
-+ stap_parse_single_operand (p);
-+ else if (*p->arg == '(')
-+ {
-+ /* We are dealing with a parenthesized operand. It means we
-+ have to parse it as it was a separate expression, without
-+ left-side or precedence. */
-+ ++p->arg;
-+ p->arg = skip_spaces_const (p->arg);
-+ ++p->inside_paren_p;
-+
-+ stap_parse_argument_1 (p, 0, STAP_OPERAND_PREC_NONE);
-+
-+ --p->inside_paren_p;
-+ if (*p->arg != ')')
-+ error (_("Missign close-paren on expression `%s'."),
-+ p->saved_arg);
-+
-+ ++p->arg;
-+ if (p->inside_paren_p)
-+ p->arg = skip_spaces_const (p->arg);
-+ }
-+ else
-+ error (_("Cannot parse expression `%s'."), p->saved_arg);
-+}
-+
-+static void
-+stap_parse_argument_1 (struct stap_parse_info *p, int has_lhs,
-+ enum stap_operand_prec prec)
-+{
-+ /* This is an operator-precedence parser.
-+
-+ We work with left- and right-sides of expressions, and
-+ parse them depending on the precedence of the operators
-+ we find. */
-+
-+ if (p->inside_paren_p)
-+ p->arg = skip_spaces_const (p->arg);
-+
-+ if (!has_lhs)
-+ /* We were called without a left-side, either because this is the
-+ first call, or because we were called to parse a parenthesized
-+ expression. It doesn't really matter; we have to parse the
-+ left-side in order to continue the process. */
-+ stap_parse_argument_conditionally (p);
-+
-+ /* Start to parse the right-side, and to "join" left and right sides
-+ depending on the operation specified.
-+
-+ This loop shall continue until we run out of characters in the input,
-+ or until we find a close-parenthesis, which means that we've reached
-+ the end of a sub-expression. */
-+ while (p->arg && *p->arg && *p->arg != ')' && !isspace (*p->arg))
-+ {
-+ const char *tmp_exp_buf;
-+ enum exp_opcode opcode;
-+ enum stap_operand_prec cur_prec;
-+
-+ if (!stap_is_operator (*p->arg))
-+ error (_("Invalid operator `%c' on expression `%s'."), *p->arg,
-+ p->saved_arg);
-+
-+ /* We have to save the current value of the expression buffer because
-+ the `stap_get_opcode' modifies it in order to get the current
-+ operator. If this operator's precedence is lower than PREC, we
-+ should return and not advance the expression buffer pointer. */
-+ tmp_exp_buf = p->arg;
-+ stap_get_opcode (&tmp_exp_buf, &opcode);
-+
-+ cur_prec = stap_get_operator_prec (opcode);
-+ if (cur_prec < prec)
-+ /* If the precedence of the operator that we are seeing now is
-+ lower than the precedence of the first operator seen before
-+ this parsing process began, it means we should stop parsing
-+ and return. */
-+ break;
-+
-+ p->arg = tmp_exp_buf;
-+ if (p->inside_paren_p)
-+ p->arg = skip_spaces_const (p->arg);
-+
-+ /* Parse the right-side of the expression. */
-+ stap_parse_argument_conditionally (p);
-+
-+ /* While we still have operators, try to parse another
-+ right-side, but using the current right-side as a left-side. */
-+ while (*p->arg && stap_is_operator (*p->arg))
-+ {
-+ enum exp_opcode lookahead_opcode;
-+ enum stap_operand_prec lookahead_prec;
-+
-+ /* Saving the current expression buffer position. The explanation
-+ is the same as above. */
-+ tmp_exp_buf = p->arg;
-+ stap_get_opcode (&tmp_exp_buf, &lookahead_opcode);
-+ lookahead_prec = stap_get_operator_prec (lookahead_opcode);
-+
-+ if (lookahead_prec <= prec)
-+ /* If we are dealing with an operator whose precedence is lower
-+ than the first one, just abandon the attempt. */
-+ break;
-+
-+ /* Parse the right-side of the expression, but since we already
-+ have a left-side at this point, set `has_lhs' to 1. */
-+ stap_parse_argument_1 (p, 1, lookahead_prec);
-+ }
-+
-+ write_exp_elt_opcode (opcode);
-+ }
-+}
-+
-+/* Parse a probe's argument.
-+
-+ Assuming that:
-+
-+ LP = literal integer prefix
-+ LS = literal integer sufix
-+
-+ RP = register prefix
-+ RS = register sufix
-+
-+ RIP = register indirection prefix
-+ RIS = register indirection sufix
-+
-+ This routine assumes that arguments' tokens are of the form:
-+
-+ - [LP] NUMBER [LS]
-+ - [RP] REGISTER [RS]
-+ - [RIP] [RP] REGISTER [RS] [RIS]
-+ - If we find a number without LP, we try to parse it as a literal integer
-+ constant (if LP == NULL), or as a register displacement.
-+ - We count parenthesis, and only skip whitespaces if we are inside them.
-+ - If we find an operator, we skip it.
-+
-+ This function can also call a special function that will try to match
-+ unknown tokens. It will return 1 if the argument has been parsed
-+ successfully, or zero otherwise. */
-+
-+static int
-+stap_parse_argument (const char **arg, struct type *atype,
-+ struct gdbarch *gdbarch)
-+{
-+ struct stap_parse_info p;
-+ volatile struct gdb_exception e;
-+
-+ /* We need to initialize the expression buffer, in order to begin
-+ our parsing efforts. The language here does not matter, since we
-+ are using our own parser. */
-+ initialize_expout (10, current_language, gdbarch);
++ return result;
+ }
+
+
+@@ -1716,19 +1723,14 @@ symfile_bfd_open (char *name)
+
+ if (remote_filename_p (name))
+ {
+- name = xstrdup (name);
+ sym_bfd = remote_bfd_open (name, gnutarget);
+ if (!sym_bfd)
+- {
+- make_cleanup (xfree, name);
+- error (_("`%s': can't open to read symbols: %s."), name,
+- bfd_errmsg (bfd_get_error ()));
+- }
++ error (_("`%s': can't open to read symbols: %s."), name,
++ bfd_errmsg (bfd_get_error ()));
+
+ if (!bfd_check_format (sym_bfd, bfd_object))
+ {
+- bfd_close (sym_bfd);
+- make_cleanup (xfree, name);
++ make_cleanup_bfd_unref (sym_bfd);
+ error (_("`%s': can't read symbols: %s."), name,
+ bfd_errmsg (bfd_get_error ()));
+ }
+@@ -1757,12 +1759,11 @@ symfile_bfd_open (char *name)
+ perror_with_name (name);
+ }
+
+- /* Free 1st new malloc'd copy, but keep the 2nd malloc'd copy in
+- bfd. It'll be freed in free_objfile(). */
+ xfree (name);
+ name = absolute_name;
++ make_cleanup (xfree, name);
+
+- sym_bfd = bfd_fopen (name, gnutarget, FOPEN_RB, desc);
++ sym_bfd = gdb_bfd_fopen (name, gnutarget, FOPEN_RB, desc);
+ if (!sym_bfd)
+ {
+ make_cleanup (xfree, name);
+@@ -1773,18 +1774,11 @@ symfile_bfd_open (char *name)
+
+ if (!bfd_check_format (sym_bfd, bfd_object))
+ {
+- /* FIXME: should be checking for errors from bfd_close (for one
+- thing, on error it does not free all the storage associated
+- with the bfd). */
+- bfd_close (sym_bfd); /* This also closes desc. */
+- make_cleanup (xfree, name);
++ make_cleanup_bfd_unref (sym_bfd);
+ error (_("`%s': can't read symbols: %s."), name,
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+- /* bfd_usrdata exists for applications and libbfd must not touch it. */
+- gdb_assert (bfd_usrdata (sym_bfd) == NULL);
+-
+ return sym_bfd;
+ }
+
+@@ -2109,17 +2103,14 @@ generic_load (char *args, int from_tty)
+ }
+
+ /* Open the file for loading. */
+- loadfile_bfd = bfd_openr (filename, gnutarget);
++ loadfile_bfd = gdb_bfd_openr (filename, gnutarget);
+ if (loadfile_bfd == NULL)
+ {
+ perror_with_name (filename);
+ return;
+ }
+
+- /* FIXME: should be checking for errors from bfd_close (for one thing,
+- on error it does not free all the storage associated with the
+- bfd). */
+- make_cleanup_bfd_close (loadfile_bfd);
++ make_cleanup_bfd_unref (loadfile_bfd);
+
+ if (!bfd_check_format (loadfile_bfd, bfd_object))
+ {
+@@ -2518,15 +2509,18 @@ reread_symbols (void)
+ /* Clean up any state BFD has sitting around. We don't need
+ to close the descriptor but BFD lacks a way of closing the
+ BFD without closing the descriptor. */
+- obfd_filename = bfd_get_filename (objfile->obfd);
+- if (!bfd_close (objfile->obfd))
+- error (_("Can't close BFD for %s: %s"), objfile->name,
+- bfd_errmsg (bfd_get_error ()));
+- objfile->obfd = bfd_open_maybe_remote (obfd_filename);
++ {
++ struct bfd *obfd = objfile->obfd;
+
-+ p.saved_arg = *arg;
-+ p.arg = *arg;
-+ p.arg_type = atype;
-+ p.gdbarch = gdbarch;
-+ p.inside_paren_p = 0;
++ obfd_filename = bfd_get_filename (objfile->obfd);
++ /* Open the new BFD before freeing the old one, so that
++ the filename remains live. */
++ objfile->obfd = gdb_bfd_open_maybe_remote (obfd_filename);
++ gdb_bfd_unref (obfd);
++ }
+
-+ TRY_CATCH (e, RETURN_MASK_ERROR)
-+ {
-+ stap_parse_argument_1 (&p, 0, STAP_OPERAND_PREC_NONE);
-+ }
-+ if (e.reason < 0)
-+ {
-+ xfree (expout);
-+ return 0;
+ if (objfile->obfd == NULL)
+ error (_("Can't open %s to read symbols."), objfile->name);
+- else
+- objfile->obfd = gdb_bfd_ref (objfile->obfd);
+ /* bfd_openr sets cacheable to true, which is what we want. */
+ if (!bfd_check_format (objfile->obfd, bfd_object))
+ error (_("Can't read symbols from %s: %s."), objfile->name,
+diff --git a/gdb/symfile.h b/gdb/symfile.h
+index aca7359..184a83e 100644
+--- a/gdb/symfile.h
++++ b/gdb/symfile.h
+@@ -553,7 +553,7 @@ extern void find_lowest_section (bfd *, asection *, void *);
+
+ extern bfd *symfile_bfd_open (char *);
+
+-extern bfd *bfd_open_maybe_remote (const char *);
++extern bfd *gdb_bfd_open_maybe_remote (const char *);
+
+ extern int get_section_index (struct objfile *, char *);
+
+diff --git a/gdb/testsuite/gdb.ada/packed_array.exp b/gdb/testsuite/gdb.ada/packed_array.exp
+index 678639c..47a2202 100644
+--- a/gdb/testsuite/gdb.ada/packed_array.exp
++++ b/gdb/testsuite/gdb.ada/packed_array.exp
+@@ -60,5 +60,11 @@ gdb_test_multiple "$test" "$test" {
+ # are. Observed with (FSF GNU Ada 4.5.3 20110124).
+ xfail $test
+ }
++ -re "= \\(\\)\[\r\n\]+$gdb_prompt $" {
++ # archer-jankratochvil-vla resolves it as a dynamic type resolved as an
++ # empty array [0..-1].
++ # DW_AT_upper_bound : (DW_OP_fbreg: -48; DW_OP_deref)
++ xfail $test
+ }
-+
-+ gdb_assert (p.inside_paren_p == 0);
-+
-+ /* Casting the final expression to the appropriate type. */
-+ write_exp_elt_opcode (UNOP_CAST);
-+ write_exp_elt_type (atype);
-+ write_exp_elt_opcode (UNOP_CAST);
-+
-+ reallocate_expout ();
-+
-+ p.arg = skip_spaces_const (p.arg);
-+ *arg = p.arg;
-+
-+ return 1;
-+}
-+
-+/* Helper function which is responsible for freeing the space allocated to
-+ hold information about a probe's arguments. */
-+
-+static void
-+stap_free_args_info (void *args_info_ptr)
-+{
-+ struct stap_args_info *a = (struct stap_args_info *) args_info_ptr;
-+ int i;
-+
-+ for (i = 0; i < a->n_args; i++)
-+ xfree (a->args[i].aexpr);
-+
-+ xfree (a->args);
-+ xfree (a);
-+}
-+
-+/* Function which parses an argument string from PROBE, correctly splitting
-+ the arguments and storing their information in properly ways.
-+
-+ Consider the following argument string (x86 syntax):
-+
-+ `4@%eax 4@$10'
-+
-+ We have two arguments, `%eax' and `$10', both with 32-bit unsigned bitness.
-+ This function basically handles them, properly filling some structures with
-+ this information. */
-+
-+static void
-+stap_parse_probe_arguments (struct stap_probe *probe)
-+{
-+ struct stap_args_info *args_info;
-+ struct cleanup *back_to;
-+ const char *cur = probe->args;
-+ int current_arg = -1;
-+ /* This is a state-machine parser, which means we will always be
-+ in a known state when parsing an argument. The state could be
-+ either `NEW_ARG' if we are parsing a new argument, `BITNESS' if
-+ we are parsing the bitness-definition part (i.e., `4@'), or
-+ `PARSE_ARG' if we are actually parsing the argument part. */
-+ enum
-+ {
-+ NEW_ARG,
-+ BITNESS,
-+ PARSE_ARG,
-+ } current_state;
-+
-+ /* For now, we assume everything is not going to work. */
-+ probe->parsed_args = &dummy_stap_args_info;
-+
-+ if (!cur || !*cur || *cur == ':')
-+ return;
-+
-+ args_info = xmalloc (sizeof (struct stap_args_info));
-+ args_info->n_args = 0;
-+ back_to = make_cleanup (stap_free_args_info, args_info);
-+ args_info->args = xcalloc (STAP_MAX_ARGS, sizeof (struct stap_probe_arg));
-+
-+ /* Ok, let's start. */
-+ current_state = NEW_ARG;
-+
-+ while (*cur)
-+ {
-+ switch (current_state)
-+ {
-+ case NEW_ARG:
-+ ++current_arg;
-+
-+ if (current_arg >= STAP_MAX_ARGS)
-+ {
-+ complaint (&symfile_complaints,
-+ _("probe `%s' has more arguments than the maximum "
-+ "allowed"), probe->name);
-+ do_cleanups (back_to);
-+ return;
-+ }
-+
-+ current_state = BITNESS;
-+ break;
-+
-+ case BITNESS:
-+ {
-+ enum stap_arg_bitness b;
-+ int got_minus = 0;
-+
-+ /* We expect to find something like:
-+
-+ N@OP
-+
-+ Where `N' can be [+,-][4,8]. This is not mandatory, so
-+ we check it here. If we don't find it, go to the next
-+ state. */
-+ if ((*cur == '-' && cur[1] && cur[2] != '@')
-+ && cur[1] != '@')
-+ {
-+ current_state = PARSE_ARG;
-+ args_info->args[current_arg].bitness
-+ = STAP_ARG_BITNESS_UNDEFINED;
-+ break;
-+ }
-+
-+ if (*cur == '-')
-+ {
-+ /* Discard the `-'. */
-+ ++cur;
-+ got_minus = 1;
-+ }
-+
-+ if (*cur == '4')
-+ b = got_minus ? STAP_ARG_BITNESS_32BIT_SIGNED
-+ : STAP_ARG_BITNESS_32BIT_UNSIGNED;
-+ else if (*cur == '8')
-+ b = got_minus ? STAP_ARG_BITNESS_64BIT_SIGNED
-+ : STAP_ARG_BITNESS_64BIT_UNSIGNED;
-+ else
-+ {
-+ /* We have an error, because we don't expect anything
-+ except 4 and 8. */
-+ complaint (&symfile_complaints,
-+ _("unrecognized bitness `%c' for probe `%s'"),
-+ *cur, probe->name);
-+ do_cleanups (back_to);
-+ return;
-+ }
-+
-+ args_info->args[current_arg].bitness = b;
-+ args_info->args[current_arg].atype
-+ = stap_get_expected_argument_type (probe->gdbarch, b);
-+ /* Discard the number and the `@' sign. */
-+ cur += 2;
-+ /* Move on. */
-+ current_state = PARSE_ARG;
-+ }
-+ break;
-+
-+ case PARSE_ARG:
-+ {
-+ if (!stap_parse_argument (&cur,
-+ args_info->args[current_arg].atype,
-+ probe->gdbarch))
-+ {
-+ /* We have tried to parse this argument, but it's
-+ malformed. This is an error. */
-+ complaint (&symfile_complaints,
-+ _("malformed argument for probe `%s'"),
-+ probe->name);
-+ do_cleanups (back_to);
-+ return;
-+ }
-+
-+ if (stap_expression_debug)
-+ dump_raw_expression (expout, gdb_stdlog,
-+ "before conversion to prefix form");
-+
-+ prefixify_expression (expout);
-+
-+ if (stap_expression_debug)
-+ dump_prefix_expression (expout, gdb_stdlog);
-+
-+ args_info->args[current_arg].aexpr = expout;
-+ expout = NULL;
-+
-+ ++args_info->n_args;
-+ /* Start it over again. */
-+ cur = skip_spaces_const (cur);
-+ current_state = NEW_ARG;
-+ }
-+ break;
-+ }
-+
-+ if (!*cur && current_state != NEW_ARG)
-+ {
-+ /* We reached the end of the argument string, but we're
-+ still in the middle of the process of parsing an argument.
-+ It means the argument string is malformed. */
-+ complaint (&symfile_complaints,
-+ _("malformed argument for probe `%s'"),
-+ probe->name);
-+ do_cleanups (back_to);
-+ return;
-+ }
-+ }
-+
-+ args_info->args = xrealloc (args_info->args,
-+ args_info->n_args
-+ * sizeof (struct stap_probe_arg));
-+ args_info->probe = probe;
-+
-+ probe->parsed_args = args_info;
-+
-+ discard_cleanups (back_to);
-+}
-+
-+/* See definition in stap-probe.h. */
-+
-+int
-+stap_get_probe_argument_count (struct stap_probe *probe)
-+{
-+ if (!probe->parsed_args)
-+ stap_parse_probe_arguments (probe);
-+
-+ return probe->parsed_args->n_args;
-+}
-+
-+/* Return 1 if OP is a valid operator inside a probe argument, or zero
-+ otherwise. */
-+
-+static int
-+stap_is_operator (char op)
-+{
-+ return (op == '+' || op == '-' || op == '*' || op == '/'
-+ || op == '>' || op == '<' || op == '!' || op == '^'
-+ || op == '|' || op == '&' || op == '%' || op == '=');
-+}
-+
-+/* See definition in stap-probe.h. */
-+
-+struct value *
-+stap_evaluate_probe_argument (struct objfile *objfile,
-+ struct stap_probe *probe,
-+ struct frame_info *frame,
-+ int n)
-+{
-+ int pos = 0;
-+
-+ if (!probe->parsed_args)
-+ stap_parse_probe_arguments (probe);
-+
-+ if (!probe->parsed_args->args
-+ || n >= probe->parsed_args->n_args)
-+ return NULL;
-+
-+ /* This is needed because on some architectures (e.g., ARM) we need
-+ the frame's gdbarch in order to compute the value of the frame
-+ pointer. */
-+ probe->parsed_args->args[n].aexpr->gdbarch = get_frame_arch (frame);
-+
-+ return evaluate_subexp_standard (probe->parsed_args->args[n].atype,
-+ probe->parsed_args->args[n].aexpr,
-+ &pos, EVAL_NORMAL);
-+}
-+
-+/* See definition in stap-probe.h. */
-+
-+void
-+stap_compile_to_ax (struct objfile *objfile,
-+ struct stap_probe *probe,
-+ struct agent_expr *expr,
-+ struct axs_value *value,
-+ int n)
-+{
-+ union exp_element *pc;
-+
-+ if (!probe->parsed_args)
-+ stap_parse_probe_arguments (probe);
-+
-+ if (!probe->parsed_args->args
-+ || n >= probe->parsed_args->n_args)
-+ return;
-+
-+ pc = probe->parsed_args->args[n].aexpr->elts;
-+ gen_expr (probe->parsed_args->args[n].aexpr, &pc, expr, value);
-+
-+ require_rvalue (expr, value);
-+ value->type = probe->parsed_args->args[n].atype;
-+}
-+
-+struct value *
-+stap_safe_evaluate_at_pc (struct frame_info *frame, int n)
-+{
-+ struct stap_probe *probe;
-+ struct objfile *objfile;
-+ int n_probes;
-+
-+ probe = find_probe_by_pc (get_frame_pc (frame), &objfile);
-+ if (!probe)
-+ return NULL;
-+ gdb_assert (objfile->sf && objfile->sf->sym_probe_fns);
-+
-+ n_probes
-+ = objfile->sf->sym_probe_fns->sym_get_probe_argument_count (objfile,
-+ probe);
-+ if (n >= n_probes)
-+ return NULL;
-+
-+ return objfile->sf->sym_probe_fns->sym_evaluate_probe_argument (objfile,
-+ probe,
-+ frame,
-+ n);
-+}
-+
-+/* This function frees the space allocated to hold information about
-+ the probe's parsed arguments. */
-+
-+void
-+stap_free_parsed_args (struct stap_args_info *parsed_args)
-+{
-+ int i;
-+
-+ if (!parsed_args
-+ || parsed_args == &dummy_stap_args_info
-+ || parsed_args->n_args == 0)
-+ return;
-+
-+ for (i = 0; i < parsed_args->n_args; i++)
-+ xfree (parsed_args->args[i].aexpr);
-+
-+ xfree (parsed_args->args);
-+ xfree (parsed_args);
-+}
-+
-+/* A utility structure. A VEC of these is built when handling "info
-+ probes". */
-+
-+struct stap_probe_and_objfile
-+{
-+ /* The probe. */
-+ struct stap_probe *probe;
-+ /* The probe's objfile. */
-+ struct objfile *objfile;
-+};
-+
-+typedef struct stap_probe_and_objfile stap_entry;
-+DEF_VEC_O (stap_entry);
-+
-+/* A helper function for collect_probes that compiles a regexp and
-+ throws an exception on error. This installs a cleanup to free the
-+ resulting pattern on success. If RX is NULL, this does nothing. */
-+
-+static void
-+compile_rx_or_error (regex_t *pattern, const char *rx, const char *message)
-+{
-+ int code;
-+
-+ if (!rx)
-+ return;
-+
-+ code = regcomp (pattern, rx, REG_NOSUB);
-+ if (code == 0)
-+ make_regfree_cleanup (pattern);
-+ else
-+ {
-+ char *err = get_regcomp_error (code, pattern);
-+
-+ make_cleanup (xfree, err);
-+ error (_("%s: %s"), message, err);
-+ }
-+}
-+
-+/* Make a vector of probes matching OBJNAME, PROVIDER, and PROBE.
-+ Each argument is a regexp, or NULL, which matches anything. */
-+
-+static VEC (stap_entry) *
-+collect_probes (char *objname, char *provider, char *probe)
-+{
-+ struct objfile *objfile;
-+ VEC (stap_entry) *result = NULL;
-+ struct cleanup *cleanup;
-+ regex_t obj_pat, prov_pat, probe_pat;
-+
-+ cleanup = make_cleanup (VEC_cleanup (stap_entry), &result);
-+
-+ compile_rx_or_error (&prov_pat, provider, _("Invalid provider regexp"));
-+ compile_rx_or_error (&probe_pat, probe, _("Invalid probe regexp"));
-+ compile_rx_or_error (&obj_pat, objname, _("Invalid object file regexp"));
-+
-+ ALL_OBJFILES (objfile)
-+ {
-+ struct stap_probe *probes;
-+ int i, num_probes;
-+
-+ if (! objfile->sf || ! objfile->sf->sym_probe_fns)
-+ continue;
-+
-+ if (objname)
-+ {
-+ if (regexec (&obj_pat, objfile->name, 0, NULL, 0) != 0)
-+ continue;
-+ }
-+
-+ probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile, &num_probes);
-+ for (i = 0; i < num_probes; ++i)
-+ {
-+ stap_entry entry;
-+
-+ if (provider)
-+ {
-+ if (regexec (&prov_pat, probes[i].provider, 0, NULL, 0) != 0)
-+ continue;
-+ }
-+
-+ if (probe)
-+ {
-+ if (regexec (&probe_pat, probes[i].name, 0, NULL, 0) != 0)
-+ continue;
-+ }
-+
-+ entry.probe = &probes[i];
-+ entry.objfile = objfile;
-+ VEC_safe_push (stap_entry, result, &entry);
-+ }
-+ }
-+
-+ discard_cleanups (cleanup);
-+ return result;
-+}
-+
-+/* A qsort comparison function for stap_entry objects. */
-+
-+static int
-+compare_entries (const void *a, const void *b)
-+{
-+ const stap_entry *ea = a;
-+ const stap_entry *eb = b;
-+ int v;
-+
-+ v = strcmp (ea->probe->provider, eb->probe->provider);
-+ if (v)
-+ return v;
-+
-+ v = strcmp (ea->probe->name, eb->probe->name);
-+ if (v)
-+ return v;
-+
-+ if (ea->probe->address < eb->probe->address)
-+ return -1;
-+ if (ea->probe->address > eb->probe->address)
-+ return 1;
-+
-+ return strcmp (ea->objfile->name, eb->objfile->name);
-+}
-+
-+/* Implementation of the "info probes" command. */
-+
-+static void
-+info_probes_command (char *arg, int from_tty)
-+{
-+ char *provider, *probe = NULL, *objname = NULL;
-+ struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
-+ VEC (stap_entry) *items;
-+ int i, addr_width, any_found;
-+ stap_entry *entry;
-+
-+ provider = extract_arg (&arg);
-+ if (provider)
-+ {
-+ make_cleanup (xfree, provider);
-+
-+ probe = extract_arg (&arg);
-+ if (probe)
-+ {
-+ make_cleanup (xfree, probe);
-+
-+ objname = extract_arg (&arg);
-+ if (objname)
-+ make_cleanup (xfree, objname);
-+ }
-+ }
-+
-+ items = collect_probes (objname, provider, probe);
-+ make_cleanup (VEC_cleanup (stap_entry), &items);
-+ make_cleanup_ui_out_table_begin_end (current_uiout, 5,
-+ VEC_length (stap_entry, items),
-+ "SystemTapProbes");
-+
-+ if (! VEC_empty (stap_entry, items))
-+ qsort (VEC_address (stap_entry, items),
-+ VEC_length (stap_entry, items),
-+ sizeof (stap_entry),
-+ compare_entries);
-+
-+ addr_width = 4 + (gdbarch_ptr_bit (get_current_arch ()) / 4);
-+
-+ ui_out_table_header (current_uiout, 10, ui_left, "provider", _("Provider"));
-+ ui_out_table_header (current_uiout, 10, ui_left, "name", _("Name"));
-+ ui_out_table_header (current_uiout, addr_width - 1, ui_left, "addr", _("Where"));
-+ ui_out_table_header (current_uiout, addr_width - 1, ui_left, "semaphore",
-+ _("Semaphore"));
-+ ui_out_table_header (current_uiout, 30, ui_left, "object", _("Object"));
-+ ui_out_table_body (current_uiout);
-+
-+ for (i = 0; VEC_iterate (stap_entry, items, i, entry); ++i)
-+ {
-+ struct cleanup *inner;
-+
-+ inner = make_cleanup_ui_out_tuple_begin_end (current_uiout, "probe");
-+
-+ ui_out_field_string (current_uiout, "provider", entry->probe->provider);
-+ ui_out_field_string (current_uiout, "name", entry->probe->name);
-+ ui_out_field_core_addr (current_uiout, "addr", get_current_arch (),
-+ entry->probe->address);
-+ if (entry->probe->sem_addr == 0)
-+ ui_out_field_skip (current_uiout, "semaphore");
-+ else
-+ ui_out_field_core_addr (current_uiout, "semaphore", get_current_arch (),
-+ entry->probe->sem_addr);
-+ ui_out_field_string (current_uiout, "object", entry->objfile->name);
-+ ui_out_text (current_uiout, "\n");
-+
-+ do_cleanups (inner);
-+ }
-+
-+ any_found = ! VEC_empty (stap_entry, items);
-+ do_cleanups (cleanup);
-+
-+ if (! any_found)
-+ ui_out_message (current_uiout, 0, _("No probes matched.\n"));
-+}
-+
-+\f
-+
-+/* See definition in stap-probe.h. */
-+
-+VEC (stap_probe_p) *
-+find_probes_in_objfile (struct objfile *objfile,
-+ const char *provider,
-+ const char *name)
-+{
-+ struct stap_probe *probes;
-+ int i, num_probes;
-+ VEC (stap_probe_p) *result = NULL;
-+
-+ if (! objfile->sf || ! objfile->sf->sym_probe_fns)
-+ return NULL;
-+
-+ probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile, &num_probes);
-+ for (i = 0; i < num_probes; ++i)
-+ {
-+ if (strcmp (probes[i].provider, provider) != 0)
-+ continue;
-+
-+ if (strcmp (probes[i].name, name) != 0)
-+ continue;
-+
-+ VEC_safe_push (stap_probe_p, result, &probes[i]);
-+ }
-+
-+ return result;
-+}
-+
-+/* See definition in stap-probe.h. */
-+
-+struct symtabs_and_lines
-+parse_stap_probe (char **argptr, struct linespec_result *canonical)
-+{
-+ char *arg_start, *arg_end, *arg;
-+ char *objfile_name = NULL, *provider = NULL, *name, *p;
-+ struct cleanup *cleanup;
-+ struct symtabs_and_lines result;
-+ struct objfile *objfile;
-+
-+ result.sals = NULL;
-+ result.nelts = 0;
-+
-+ arg_start = *argptr;
-+ /* The caller ensured that this starts with '-p'. */
-+ gdb_assert (arg_start && strncmp (arg_start, "-p", 2) == 0);
-+ arg_end = arg_start + 2;
-+ arg_end = skip_spaces (arg_end);
-+
-+ if (!*arg_end)
-+ error (_("argument to `-p' missing"));
-+
-+ arg = arg_end;
-+ arg_end = skip_to_space (arg_end);
-+
-+ /* We make a copy here so we can write over parts with impunity. */
-+ arg = savestring (arg, arg_end - arg);
-+ cleanup = make_cleanup (xfree, arg);
-+
-+ /* Extract each word from the argument, separated by ":"s. */
-+ p = strchr (arg, ':');
-+ if (p == NULL)
-+ {
-+ /* This is `-p name'. */
-+ name = arg;
-+ }
-+ else
-+ {
-+ char *hold = p + 1;
-+
-+ *p = '\0';
-+ p = strchr (hold, ':');
-+ if (p == NULL)
-+ {
-+ /* This is `-p provider:name'. */
-+ provider = arg;
-+ name = hold;
-+ }
-+ else
-+ {
-+ /* This is `-p objfile:provider:name'. */
-+ *p = '\0';
-+ objfile_name = arg;
-+ provider = hold;
-+ name = p + 1;
-+ }
-+ }
-+
-+ if (*name == '\0')
-+ error (_("no probe name specified"));
-+ if (provider && *provider == '\0')
-+ error (_("invalid provider name"));
-+ if (objfile_name && *objfile_name == '\0')
-+ error (_("invalid objfile name"));
-+
-+ ALL_OBJFILES (objfile)
-+ {
-+ struct stap_probe *probes;
-+ int i, num_probes;
-+
-+ if (! objfile->sf || ! objfile->sf->sym_probe_fns)
-+ continue;
-+
-+ if (objfile_name
-+ && FILENAME_CMP (objfile->name, objfile_name) != 0
-+ && FILENAME_CMP (lbasename (objfile->name), objfile_name) != 0)
-+ continue;
-+
-+ probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile, &num_probes);
-+ for (i = 0; i < num_probes; ++i)
-+ {
-+ struct symtab_and_line *sal;
-+
-+ if (provider && strcmp (probes[i].provider, provider) != 0)
-+ continue;
-+
-+ if (strcmp (probes[i].name, name) != 0)
-+ continue;
-+
-+ ++result.nelts;
-+ result.sals = xrealloc (result.sals,
-+ result.nelts * sizeof (struct symtab_and_line));
-+ sal = &result.sals[result.nelts - 1];
-+
-+ init_sal (sal);
-+
-+ sal->pc = probes[i].address;
-+ sal->explicit_pc = 1;
-+ sal->section = find_pc_overlay (sal->pc);
-+ sal->pspace = current_program_space;
-+ sal->semaphore = probes[i].sem_addr;
-+ }
-+ }
-+
-+ if (result.nelts == 0)
-+ {
-+ throw_error (NOT_FOUND_ERROR,
-+ _("No probe matching objfile=`%s', provider=`%s', name=`%s'"),
-+ objfile_name ? objfile_name : _("<any>"),
-+ provider ? provider : _("<any>"),
-+ name);
-+ }
-+
-+ if (canonical)
-+ {
-+ canonical->special_display = 1;
-+ canonical->pre_expanded = 1;
-+ canonical->addr_string = savestring (*argptr, arg_end - *argptr);
-+ }
-+
-+ *argptr = arg_end;
-+ do_cleanups (cleanup);
-+
-+ return result;
-+}
-+
-+\f
-+
-+/* See definition in stap-probe.h. */
-+
-+struct stap_probe *
-+find_probe_by_pc (CORE_ADDR pc, struct objfile **objfile_out)
-+{
-+ struct objfile *objfile;
-+
-+ ALL_OBJFILES (objfile)
-+ {
-+ struct stap_probe *probes;
-+ int i, num_probes;
-+ stap_entry entry;
-+
-+ if (! objfile->sf || ! objfile->sf->sym_probe_fns)
-+ continue;
-+
-+ /* If this proves too inefficient, we can replace with a hash. */
-+ probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile, &num_probes);
-+ for (i = 0; i < num_probes; ++i)
-+ {
-+ if (probes[i].address == pc)
-+ {
-+ *objfile_out = objfile;
-+ return &probes[i];
-+ }
-+ }
-+ }
-+
-+ return NULL;
-+}
-+
-+/* This is called to compute the value of one of the $_probe_arg*
-+ convenience variables. */
-+
-+static struct value *
-+compute_probe_arg (struct gdbarch *arch, struct internalvar *ivar,
-+ void *data)
-+{
-+ struct frame_info *frame = get_selected_frame (_("No frame selected"));
-+ CORE_ADDR pc = get_frame_pc (frame);
-+ int sel = (int) (uintptr_t) data;
-+ struct objfile *objfile;
-+ struct stap_probe *pc_probe;
-+ int n_probes;
-+
-+ /* SEL==-1 means "_probe_argc". */
-+ gdb_assert (sel >= -1 && sel <= STAP_MAX_ARGS);
-+
-+ pc_probe = find_probe_by_pc (pc, &objfile);
-+ if (pc_probe == NULL)
-+ error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc));
-+
-+ n_probes
-+ = objfile->sf->sym_probe_fns->sym_get_probe_argument_count (objfile,
-+ pc_probe);
-+ if (sel == -1)
-+ return value_from_longest (builtin_type (arch)->builtin_int, n_probes);
-+
-+ if (sel >= n_probes)
-+ error (_("Invalid probe argument %d -- probe has %d arguments available"),
-+ sel, n_probes);
-+
-+ return objfile->sf->sym_probe_fns->sym_evaluate_probe_argument (objfile,
-+ pc_probe,
-+ frame, sel);
-+}
-+
-+/* This is called to compile one of the $_probe_arg* convenience
-+ variables into an agent expression. */
-+
-+static void
-+compile_probe_arg (struct internalvar *ivar, struct agent_expr *expr,
-+ struct axs_value *value, void *data)
-+{
-+ CORE_ADDR pc = expr->scope;
-+ int sel = (int) (uintptr_t) data;
-+ struct objfile *objfile;
-+ struct stap_probe *pc_probe;
-+ int n_probes;
-+
-+ /* SEL==-1 means "_probe_argc". */
-+ gdb_assert (sel >= -1 && sel <= STAP_MAX_ARGS);
-+
-+ pc_probe = find_probe_by_pc (pc, &objfile);
-+ if (pc_probe == NULL)
-+ error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc));
-+
-+ n_probes
-+ = objfile->sf->sym_probe_fns->sym_get_probe_argument_count (objfile,
-+ pc_probe);
-+ if (sel == -1)
-+ {
-+ value->kind = axs_rvalue;
-+ value->type = builtin_type (expr->gdbarch)->builtin_int;
-+ ax_const_l (expr, n_probes);
-+ return;
-+ }
-+
-+ gdb_assert (sel >= 0);
-+ if (sel >= n_probes)
-+ error (_("Invalid probe argument %d -- probe has %d arguments available"),
-+ sel, n_probes);
-+
-+ objfile->sf->sym_probe_fns->sym_compile_to_ax (objfile, pc_probe,
-+ expr, value, sel);
-+}
-+
-+\f
-+
-+/* Implementation of `$_probe_arg*' set of variables. */
-+
-+static const struct internalvar_funcs probe_funcs =
-+{
-+ compute_probe_arg,
-+ compile_probe_arg,
-+ NULL
-+};
-+
-+void
-+_initialize_stap_probe (void)
-+{
-+ add_info ("probes", info_probes_command, _("\
-+Show available static probes.\n\
-+Usage: info probes [PROVIDER [NAME [OBJECT]]]\n\
-+Each argument is a regular expression, used to select probes.\n\
-+PROVIDER matches probe provider names.\n\
-+NAME matches the probe names.\n\
-+OBJECT match the executable or shared library name."));
-+
-+ add_setshow_zinteger_cmd ("stap-expression", class_maintenance,
-+ &stap_expression_debug,
-+ _("Set SystemTap expression debugging."),
-+ _("Show SystemTap expression debugging."),
-+ _("When non-zero, the internal representation "
-+ "of SystemTap expressions will be printed."),
-+ NULL,
-+ show_stapexpressiondebug,
-+ &setdebuglist, &showdebuglist);
-+
-+ create_internalvar_type_lazy ("_probe_argc", &probe_funcs,
-+ (void *) (uintptr_t) -1);
-+ create_internalvar_type_lazy ("_probe_arg0", &probe_funcs,
-+ (void *) (uintptr_t) 0);
-+ create_internalvar_type_lazy ("_probe_arg1", &probe_funcs,
-+ (void *) (uintptr_t) 1);
-+ create_internalvar_type_lazy ("_probe_arg2", &probe_funcs,
-+ (void *) (uintptr_t) 2);
-+ create_internalvar_type_lazy ("_probe_arg3", &probe_funcs,
-+ (void *) (uintptr_t) 3);
-+ create_internalvar_type_lazy ("_probe_arg4", &probe_funcs,
-+ (void *) (uintptr_t) 4);
-+ create_internalvar_type_lazy ("_probe_arg5", &probe_funcs,
-+ (void *) (uintptr_t) 5);
-+ create_internalvar_type_lazy ("_probe_arg6", &probe_funcs,
-+ (void *) (uintptr_t) 6);
-+ create_internalvar_type_lazy ("_probe_arg7", &probe_funcs,
-+ (void *) (uintptr_t) 7);
-+ create_internalvar_type_lazy ("_probe_arg8", &probe_funcs,
-+ (void *) (uintptr_t) 8);
-+ create_internalvar_type_lazy ("_probe_arg9", &probe_funcs,
-+ (void *) (uintptr_t) 9);
-+ create_internalvar_type_lazy ("_probe_arg10", &probe_funcs,
-+ (void *) (uintptr_t) 10);
-+ create_internalvar_type_lazy ("_probe_arg11", &probe_funcs,
-+ (void *) (uintptr_t) 11);
-+}
-diff --git a/gdb/stap-probe.h b/gdb/stap-probe.h
-new file mode 100644
-index 0000000..9b6dc7a
---- /dev/null
-+++ b/gdb/stap-probe.h
-@@ -0,0 +1,144 @@
-+/* SystemTap probe support for GDB.
-+
-+ Copyright (C) 2011 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 (STAP_PROBE_H)
-+#define STAP_PROBE_H 1
-+
-+#include "vec.h"
-+
-+struct stap_args_info;
-+struct axs_value;
-+struct linespec_result;
-+
-+/* Main structure which holds information about a SystemTap probe. */
-+
-+struct stap_probe
-+{
-+ /* The provider of this probe. */
-+ const char *provider;
-+
-+ /* The name of the probe. */
-+ const char *name;
-+
-+ /* The address where the probe is inserted. */
-+ CORE_ADDR address;
-+
-+ /* The address of the probe's semaphore, or 0 if this probe does not
-+ have an associated semaphore. */
-+ CORE_ADDR sem_addr;
-+
-+ /* Probe's arguments. Users should generally not examine this, but
-+ should instead extract information about the arguments using the
-+ methods provided in sym_probe_fns. */
-+ const char *args;
-+
-+ /* Probe's arguments after parsing. This is an opaque structure that
-+ will hold information about the arguments pointed by ARGS. */
-+ struct stap_args_info *parsed_args;
-+
-+ /* gdbarch structure associated with this probe. */
-+ struct gdbarch *gdbarch;
-+};
-+
-+/* Structure which holds information about the parsing process of one probe's
-+ argument. */
-+
-+struct stap_parse_info
-+{
-+ /* The probe's argument in a string format. */
-+ const char *arg;
-+
-+ /* A pointer to the full chain of arguments. This is useful for printing
-+ error messages. The parser functions should not modify this argument
-+ directly; instead, they should use the ARG pointer above. */
-+ const char *saved_arg;
-+
-+ /* The expected argument type (bitness), as defined in the probe's
-+ argument. For instance, if the argument begins with `-8@', it means
-+ the bitness is 64-bit signed. In this case, ARG_TYPE would represent
-+ the type `int64_t'. */
-+ struct type *arg_type;
-+
-+ /* A pointer to the current gdbarch. */
-+ struct gdbarch *gdbarch;
-+
-+ /* Greater than zero if we are inside a parenthesized expression. Useful
-+ for knowing when to skip spaces or not. */
-+ int inside_paren_p;
-+};
-+
-+typedef struct stap_probe *stap_probe_p;
-+DEF_VEC_P (stap_probe_p);
-+
-+/* A helper for linespec that decodes a stap probe specification. It
-+ returns a symtabs_and_lines object and updates *ARGPTR or throws an
-+ error. */
-+
-+extern struct symtabs_and_lines parse_stap_probe (char **argptr,
-+ struct linespec_result *canon);
-+
-+/* Search OBJFILE for a probe with the given PROVIDER and NAME.
-+ Return a VEC of all probes that were found. If no matching probe
-+ is found, return NULL. The caller must free the VEC. */
-+
-+extern VEC (stap_probe_p) *find_probes_in_objfile (struct objfile *objfile,
-+ const char *provider,
-+ const char *name);
-+
-+/* Given a PC, find an associated SystemTap probe. If a probe is
-+ found, set *OBJFILE_OUT to the probe's objfile, and return the
-+ probe. If no probe is found, return NULL. */
-+
-+extern struct stap_probe *find_probe_by_pc (CORE_ADDR pc,
-+ struct objfile **objfile_out);
-+
-+/* Given PROBE, returns the number of arguments present in that probe's
-+ argument string. */
-+
-+extern int stap_get_probe_argument_count (struct stap_probe *probe);
-+
-+/* Given PARSED_ARGS, frees the space allocated to hold information about
-+ the probe's parsed arguments. */
-+
-+extern void stap_free_parsed_args (struct stap_args_info *parsed_args);
-+
-+/* Evaluate the probe's argument N, returning a value corresponding
-+ to it. */
-+
-+extern struct value *stap_evaluate_probe_argument (struct objfile *objfile,
-+ struct stap_probe *probe,
-+ struct frame_info *frame,
-+ int n);
-+
-+/* Compile the probe's argument N to agent expression. */
-+
-+extern void stap_compile_to_ax (struct objfile *objfile,
-+ struct stap_probe *probe,
-+ struct agent_expr *expr,
-+ struct axs_value *value,
-+ int n);
-+
-+/* A convenience function that finds a probe at the PC in FRAME and
-+ evaluates argument N. If there is no probe at that location, or if
-+ the probe does not have enough arguments, this returns NULL. */
-+
-+extern struct value *stap_safe_evaluate_at_pc (struct frame_info *frame,
-+ int n);
-+
-+#endif /* !defined (STAP_PROBE_H) */
-diff --git a/gdb/symfile.h b/gdb/symfile.h
-index 6b664cd..6ca797d 100644
---- a/gdb/symfile.h
-+++ b/gdb/symfile.h
-@@ -29,6 +29,11 @@ struct objfile;
- struct obj_section;
- struct obstack;
- struct block;
-+struct stap_probe;
-+struct value;
-+struct frame_info;
-+struct agent_expr;
-+struct axs_value;
-
- /* Comparison function for symbol look ups. */
-
-@@ -299,6 +304,52 @@ struct quick_symbol_functions
- int need_fullname);
- };
-
-+/* Structure of functions used for SystemTap probe support. If one of
-+ these functions is provided, all must be. */
-+
-+struct sym_probe_fns
-+{
-+ /* If non-NULL, return an array of SystemTap probe objects. The
-+ number of objects is returned in *NUM_PROBES. */
-+ struct stap_probe *(*sym_get_probes) (struct objfile *,
-+ int *num_probes);
-+
-+ /* Return the number of arguments available to PROBE. PROBE will
-+ have come from a call to this objfile's sym_get_probes method.
-+ If you provide an implementation of sym_get_probes, you must
-+ implement this method as well. */
-+ int (*sym_get_probe_argument_count) (struct objfile *objfile,
-+ struct stap_probe *probe);
-+
-+ /* Evaluate the Nth argument available to PROBE. PROBE will have
-+ come from a call to this objfile's sym_get_probes method. N will
-+ be between 0 and the number of arguments available to this probe.
-+ FRAME is the frame in which the evaluation is done; the frame's
-+ PC will match the address of the probe. If you provide an
-+ implementation of sym_get_probes, you must implement this method
-+ as well. */
-+ struct value *(*sym_evaluate_probe_argument) (struct objfile *objfile,
-+ struct stap_probe *probe,
-+ struct frame_info *frame,
-+ int n);
-+
-+ /* Compile the Nth probe argument to an agent expression. PROBE
-+ will have come from a call to this objfile's sym_get_probes
-+ method. N will be between 0 and the number of arguments
-+ available to this probe. EXPR and VALUE are the agent expression
-+ that is being updated. */
-+ void (*sym_compile_to_ax) (struct objfile *objfile,
-+ struct stap_probe *probe,
-+ struct agent_expr *expr,
-+ struct axs_value *value,
-+ int n);
-+
-+ /* Relocate the probe section of OBJFILE. */
-+ void (*sym_relocate_probe) (struct objfile *objfile,
-+ struct section_offsets *new_offsets,
-+ struct section_offsets *delta);
-+};
-+
- /* Structure to keep track of symbol reading functions for various
- object file types. */
-
-@@ -369,6 +420,10 @@ struct sym_fns
-
- bfd_byte *(*sym_relocate) (struct objfile *, asection *sectp, bfd_byte *buf);
-
-+ /* If non-NULL, this objfile has probe support, and all the probe
-+ functions referred to here will be non-NULL. */
-+ const struct sym_probe_fns *sym_probe_fns;
-+
- /* The "quick" (aka partial) symbol functions for this symbol
- reader. */
- const struct quick_symbol_functions *qf;
-diff --git a/gdb/symtab.c b/gdb/symtab.c
-index 1746d69..2abc17f 100644
---- a/gdb/symtab.c
-+++ b/gdb/symtab.c
-@@ -869,6 +869,7 @@ init_sal (struct symtab_and_line *sal)
- sal->end = 0;
- sal->explicit_pc = 0;
- sal->explicit_line = 0;
-+ sal->semaphore = 0;
- }
- \f
-
-diff --git a/gdb/symtab.h b/gdb/symtab.h
-index 4836dd6..668a22b 100644
---- a/gdb/symtab.h
-+++ b/gdb/symtab.h
-@@ -1056,6 +1056,10 @@ struct symtab_and_line
- CORE_ADDR end;
- int explicit_pc;
- int explicit_line;
-+
-+ /* If non-zero, the semaphore location associated with a SystemTap
-+ probe. */
-+ CORE_ADDR semaphore;
- };
-
- extern void init_sal (struct symtab_and_line *sal);
-diff --git a/gdb/testsuite/gdb.ada/packed_array.exp b/gdb/testsuite/gdb.ada/packed_array.exp
-index 678639c..47a2202 100644
---- a/gdb/testsuite/gdb.ada/packed_array.exp
-+++ b/gdb/testsuite/gdb.ada/packed_array.exp
-@@ -60,5 +60,11 @@ gdb_test_multiple "$test" "$test" {
- # are. Observed with (FSF GNU Ada 4.5.3 20110124).
- xfail $test
- }
-+ -re "= \\(\\)\[\r\n\]+$gdb_prompt $" {
-+ # archer-jankratochvil-vla resolves it as a dynamic type resolved as an
-+ # empty array [0..-1].
-+ # DW_AT_upper_bound : (DW_OP_fbreg: -48; DW_OP_deref)
-+ xfail $test
-+ }
- }
-
-diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-pointer-foo.S b/gdb/testsuite/gdb.arch/x86_64-vla-pointer-foo.S
-new file mode 100644
-index 0000000..83faaf6
---- /dev/null
-+++ b/gdb/testsuite/gdb.arch/x86_64-vla-pointer-foo.S
-@@ -0,0 +1,457 @@
-+ .file "x86_64-vla-pointer.c"
-+ .section .debug_abbrev,"",@progbits
-+.Ldebug_abbrev0:
-+ .section .debug_info,"",@progbits
-+.Ldebug_info0:
-+ .section .debug_line,"",@progbits
-+.Ldebug_line0:
-+ .text
-+.Ltext0:
-+.globl foo
-+ .type foo, @function
-+foo:
-+.LFB2:
-+ .file 1 "x86_64-vla-pointer.c"
-+ .loc 1 22 0
-+ pushq %rbp
-+.LCFI0:
-+ movq %rsp, %rbp
-+.LCFI1:
-+ subq $64, %rsp
-+.LCFI2:
-+ movl %edi, -36(%rbp)
-+ .loc 1 22 0
-+ movq %rsp, %rax
-+ movq %rax, -48(%rbp)
-+ .loc 1 23 0
-+ movl -36(%rbp), %edx
-+ movslq %edx,%rax
-+ subq $1, %rax
-+ movq %rax, -24(%rbp)
-+ .loc 1 24 0
-+ movslq %edx,%rax
-+ addq $15, %rax
-+ addq $15, %rax
-+ shrq $4, %rax
-+ salq $4, %rax
-+ subq %rax, %rsp
-+ movq %rsp, -56(%rbp)
-+ movq -56(%rbp), %rax
-+ addq $15, %rax
-+ shrq $4, %rax
-+ salq $4, %rax
-+ movq %rax, -56(%rbp)
-+ movq -56(%rbp), %rax
-+ movq %rax, -16(%rbp)
-+ .loc 1 27 0
-+ movl $0, -4(%rbp)
-+ jmp .L2
-+.L3:
-+ .loc 1 28 0
-+ movl -4(%rbp), %esi
-+ movl -4(%rbp), %eax
-+ movl %eax, %ecx
-+ movq -16(%rbp), %rdx
-+ movslq %esi,%rax
-+ movb %cl, (%rdx,%rax)
-+ .loc 1 27 0
-+ addl $1, -4(%rbp)
-+.L2:
-+ movl -4(%rbp), %eax
-+ cmpl -36(%rbp), %eax
-+ jl .L3
-+ .loc 1 30 0
-+ .globl break_here
-+break_here:
-+ movq -16(%rbp), %rax
-+ movb $0, (%rax)
-+ movq -48(%rbp), %rsp
-+ .loc 1 31 0
-+ leave
-+ ret
-+.LFE2:
-+ .size foo, .-foo
-+ .section .debug_frame,"",@progbits
-+.Lframe0:
-+ .long .LECIE0-.LSCIE0
-+.LSCIE0:
-+ .long 0xffffffff
-+ .byte 0x1
-+ .string ""
-+ .uleb128 0x1
-+ .sleb128 -8
-+ .byte 0x10
-+ .byte 0xc
-+ .uleb128 0x7
-+ .uleb128 0x8
-+ .byte 0x90
-+ .uleb128 0x1
-+ .align 8
-+.LECIE0:
-+.LSFDE0:
-+ .long .LEFDE0-.LASFDE0
-+.LASFDE0:
-+ .long .Lframe0
-+ .quad .LFB2
-+ .quad .LFE2-.LFB2
-+ .byte 0x4
-+ .long .LCFI0-.LFB2
-+ .byte 0xe
-+ .uleb128 0x10
-+ .byte 0x86
-+ .uleb128 0x2
-+ .byte 0x4
-+ .long .LCFI1-.LCFI0
-+ .byte 0xd
-+ .uleb128 0x6
-+ .align 8
-+.LEFDE0:
-+ .section .eh_frame,"a",@progbits
-+.Lframe1:
-+ .long .LECIE1-.LSCIE1
-+.LSCIE1:
-+ .long 0x0
-+ .byte 0x1
-+ .string "zR"
-+ .uleb128 0x1
-+ .sleb128 -8
-+ .byte 0x10
-+ .uleb128 0x1
-+ .byte 0x3
-+ .byte 0xc
-+ .uleb128 0x7
-+ .uleb128 0x8
-+ .byte 0x90
-+ .uleb128 0x1
-+ .align 8
-+.LECIE1:
-+.LSFDE1:
-+ .long .LEFDE1-.LASFDE1
-+.LASFDE1:
-+ .long .LASFDE1-.Lframe1
-+ .long .LFB2
-+ .long .LFE2-.LFB2
-+ .uleb128 0x0
-+ .byte 0x4
-+ .long .LCFI0-.LFB2
-+ .byte 0xe
-+ .uleb128 0x10
-+ .byte 0x86
-+ .uleb128 0x2
-+ .byte 0x4
-+ .long .LCFI1-.LCFI0
-+ .byte 0xd
-+ .uleb128 0x6
-+ .align 8
-+.LEFDE1:
-+ .text
-+.Letext0:
-+ .section .debug_loc,"",@progbits
-+.Ldebug_loc0:
-+.LLST0:
-+ .quad .LFB2-.Ltext0
-+ .quad .LCFI0-.Ltext0
-+ .value 0x2
-+ .byte 0x77
-+ .sleb128 8
-+ .quad .LCFI0-.Ltext0
-+ .quad .LCFI1-.Ltext0
-+ .value 0x2
-+ .byte 0x77
-+ .sleb128 16
-+ .quad .LCFI1-.Ltext0
-+ .quad .LFE2-.Ltext0
-+ .value 0x2
-+ .byte 0x76
-+ .sleb128 16
-+ .quad 0x0
-+ .quad 0x0
-+ .section .debug_info
-+.Ldebug_relative:
-+ .long .Ldebug_end - .Ldebug_start
-+.Ldebug_start:
-+ .value 0x2
-+ .long .Ldebug_abbrev0
-+ .byte 0x8
-+ .uleb128 0x1
-+ .long .LASF2
-+ .byte 0x1
-+ .long .LASF3
-+ .long .LASF4
-+ .quad .Ltext0
-+ .quad .Letext0
-+ .long .Ldebug_line0
-+ .uleb128 0x2
-+ .byte 0x1
-+ .string "foo"
-+ .byte 0x1
-+ .byte 0x16
-+ .byte 0x1
-+ .quad .LFB2
-+ .quad .LFE2
-+ .long .LLST0
-+ .long .Ltype_int - .Ldebug_relative
-+ .uleb128 0x3
-+ .long .LASF5
-+ .byte 0x1
-+ .byte 0x15
-+ .long .Ltype_int - .Ldebug_relative
-+ .byte 0x2
-+ .byte 0x91
-+ .sleb128 -52
-+.Ltag_pointer:
-+ .uleb128 0x4
-+ .byte 0x8 /* DW_AT_byte_size */
-+ .long .Ltag_array_type - .debug_info /* DW_AT_type */
-+ .uleb128 0x5 /* Abbrev Number: 5 (DW_TAG_variable) */
-+ .long .LASF0
-+ .byte 0x1
-+ .byte 0x18
-+#if 1
-+ .long .Ltag_pointer - .debug_info
-+#else
-+ /* Debugging only: Skip the typedef indirection. */
-+ .long .Ltag_array_type - .debug_info
-+#endif
-+ /* DW_AT_location: DW_FORM_block1: start */
-+ .byte 0x3
-+ .byte 0x91
-+ .sleb128 -32
-+#if 0
-+ .byte 0x6 /* DW_OP_deref */
-+#else
-+ .byte 0x96 /* DW_OP_nop */
-+#endif
-+ /* DW_AT_location: DW_FORM_block1: end */
-+ .uleb128 0x6
-+ .string "i"
-+ .byte 0x1
-+ .byte 0x19
-+ .long .Ltype_int - .Ldebug_relative
-+ .byte 0x2
-+ .byte 0x91
-+ .sleb128 -20
-+ .byte 0x0
-+.Ltype_int:
-+ .uleb128 0x7
-+ .byte 0x4
-+ .byte 0x5
-+ .string "int"
-+.Ltag_array_type:
-+ .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */
-+ .long .Ltype_char - .Ldebug_relative
-+ .long .Ltype_ulong - .Ldebug_relative /* DW_AT_sibling: DW_FORM_ref4 */
-+1: /* DW_AT_data_location: DW_FORM_block1: start */
-+ .byte 2f - 3f /* length */
-+3:
-+ .byte 0x97 /* DW_OP_push_object_address */
-+#if 1
-+ .byte 0x6 /* DW_OP_deref */
-+#else
-+ .byte 0x96 /* DW_OP_nop */
-+#endif
-+2: /* DW_AT_data_location: DW_FORM_block1: end */
-+ .uleb128 0x9
-+ .long .Ltype_char - .Ldebug_relative /* DW_AT_type: DW_FORM_ref4 */
-+ .byte 0x3
-+ .byte 0x91
-+ .sleb128 -40
-+ .byte 0x6
-+ .byte 0x0
-+.Ltype_ulong:
-+ .uleb128 0xa
-+ .byte 0x8
-+ .byte 0x7
-+.Ltype_char:
-+ .uleb128 0xb
-+ .byte 0x1
-+ .byte 0x6
-+ .long .LASF1
-+ .byte 0x0
-+.Ldebug_end:
-+ .section .debug_abbrev
-+ .uleb128 0x1
-+ .uleb128 0x11
-+ .byte 0x1
-+ .uleb128 0x25
-+ .uleb128 0xe
-+ .uleb128 0x13
-+ .uleb128 0xb
-+ .uleb128 0x3
-+ .uleb128 0xe
-+ .uleb128 0x1b
-+ .uleb128 0xe
-+ .uleb128 0x11
-+ .uleb128 0x1
-+ .uleb128 0x12
-+ .uleb128 0x1
-+ .uleb128 0x10
-+ .uleb128 0x6
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x2
-+ .uleb128 0x2e
-+ .byte 0x1
-+ .uleb128 0x3f
-+ .uleb128 0xc
-+ .uleb128 0x3
-+ .uleb128 0x8
-+ .uleb128 0x3a
-+ .uleb128 0xb
-+ .uleb128 0x3b
-+ .uleb128 0xb
-+ .uleb128 0x27
-+ .uleb128 0xc
-+ .uleb128 0x11
-+ .uleb128 0x1
-+ .uleb128 0x12
-+ .uleb128 0x1
-+ .uleb128 0x40
-+ .uleb128 0x6
-+ .uleb128 0x1
-+ .uleb128 0x13
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x3
-+ .uleb128 0x5
-+ .byte 0x0
-+ .uleb128 0x3
-+ .uleb128 0xe
-+ .uleb128 0x3a
-+ .uleb128 0xb
-+ .uleb128 0x3b
-+ .uleb128 0xb
-+ .uleb128 0x49
-+ .uleb128 0x13
-+ .uleb128 0x2
-+ .uleb128 0xa
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x4 /* .Ltag_pointer abbrev */
-+ .uleb128 0x0f /* DW_TAG_pointer_type */
-+ .byte 0x0
-+ .uleb128 0x0b
-+ .uleb128 0xb
-+ .uleb128 0x49
-+ .uleb128 0x13
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x5
-+ .uleb128 0x34
-+ .byte 0x0
-+ .uleb128 0x3
-+ .uleb128 0xe
-+ .uleb128 0x3a
-+ .uleb128 0xb
-+ .uleb128 0x3b
-+ .uleb128 0xb
-+ .uleb128 0x49
-+ .uleb128 0x13
-+ .uleb128 0x2
-+ .uleb128 0xa
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x6
-+ .uleb128 0x34
-+ .byte 0x0
-+ .uleb128 0x3
-+ .uleb128 0x8
-+ .uleb128 0x3a
-+ .uleb128 0xb
-+ .uleb128 0x3b
-+ .uleb128 0xb
-+ .uleb128 0x49
-+ .uleb128 0x13
-+ .uleb128 0x2
-+ .uleb128 0xa
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x7
-+ .uleb128 0x24
-+ .byte 0x0
-+ .uleb128 0xb
-+ .uleb128 0xb
-+ .uleb128 0x3e
-+ .uleb128 0xb
-+ .uleb128 0x3
-+ .uleb128 0x8
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */
-+ .uleb128 0x1
-+ .byte 0x1
-+ .uleb128 0x49 /* DW_AT_type */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .uleb128 0x1 /* DW_AT_sibling */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .uleb128 0x50 /* DW_AT_data_location */
-+ .uleb128 0xa /* DW_FORM_block1 */
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x9
-+ .uleb128 0x21
-+ .byte 0x0
-+ .uleb128 0x49 /* DW_AT_type */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .uleb128 0x2f
-+ .uleb128 0xa
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0xa
-+ .uleb128 0x24
-+ .byte 0x0
-+ .uleb128 0xb
-+ .uleb128 0xb
-+ .uleb128 0x3e
-+ .uleb128 0xb
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0xb
-+ .uleb128 0x24
-+ .byte 0x0
-+ .uleb128 0xb
-+ .uleb128 0xb
-+ .uleb128 0x3e
-+ .uleb128 0xb
-+ .uleb128 0x3
-+ .uleb128 0xe
-+ .byte 0x0
-+ .byte 0x0
-+ .byte 0x0
-+ .section .debug_pubnames,"",@progbits
-+ .long 0x16
-+ .value 0x2
-+ .long .Ldebug_info0
-+ .long 0xa8
-+ .long 0x2d
-+ .string "foo"
-+ .long 0x0
-+ .section .debug_aranges,"",@progbits
-+ .long 0x2c
-+ .value 0x2
-+ .long .Ldebug_info0
-+ .byte 0x8
-+ .byte 0x0
-+ .value 0x0
-+ .value 0x0
-+ .quad .Ltext0
-+ .quad .Letext0-.Ltext0
-+ .quad 0x0
-+ .quad 0x0
-+ .section .debug_str,"MS",@progbits,1
-+.LASF0:
-+ .string "array"
-+.LASF5:
-+ .string "size"
-+.LASF3:
-+ .string "x86_64-vla-pointer.c"
-+.LASF6:
-+ .string "array_t"
-+.LASF1:
-+ .string "char"
-+.LASF4:
-+ .string "gdb.arch"
-+.LASF2:
-+ .string "GNU C 4.3.2 20081105 (Red Hat 4.3.2-7)"
-+ .ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)"
-+ .section .note.GNU-stack,"",@progbits
-diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-pointer.c b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.c
-new file mode 100644
-index 0000000..fe2c8f7
---- /dev/null
-+++ b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.c
-@@ -0,0 +1,43 @@
-+/* This testcase is part of GDB, the GNU debugger.
-+
-+ Copyright 2009 Free Software Foundation, Inc.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 3 of the License, or
-+ (at your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
-+
-+#if 0
-+
-+void
-+foo (int size)
-+{
-+ typedef char array_t[size];
-+ array_t array;
-+ int i;
-+
-+ for (i = 0; i < size; i++)
-+ array[i] = i;
-+
-+ array[0] = 0; /* break-here */
-+}
-+
-+#else
-+
-+int
-+main (void)
-+{
-+ foo (26);
-+ foo (78);
-+ return 0;
-+}
-+
-+#endif
-diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-pointer.exp b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.exp
-new file mode 100644
-index 0000000..d243cf1
---- /dev/null
-+++ b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.exp
-@@ -0,0 +1,66 @@
-+# Copyright 2009 Free Software Foundation, Inc.
-+
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 3 of the License, or
-+# (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program. If not, see <http://www.gnu.org/licenses/>.
-+
-+if ![istarget "x86_64-*-*"] then {
-+ verbose "Skipping over gdb.arch/x86_64-vla-pointer.exp test made only for x86_64."
-+ return
-+}
-+
-+set testfile x86_64-vla-pointer
-+set srcasmfile ${testfile}-foo.S
-+set srcfile ${testfile}.c
-+set binfile ${objdir}/${subdir}/${testfile}
-+set binobjfile ${objdir}/${subdir}/${testfile}-foo.o
-+if { [gdb_compile "${srcdir}/${subdir}/${srcasmfile}" "${binobjfile}" object {}] != "" } {
-+ untested "Couldn't compile test program"
-+ return -1
-+}
-+if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${binobjfile}" "${binfile}" executable {debug}] != "" } {
-+ untested "Couldn't compile test program"
-+ return -1
-+}
-+
-+gdb_exit
-+gdb_start
-+gdb_reinitialize_dir $srcdir/$subdir
-+gdb_load ${binfile}
-+
-+if ![runto_main] {
-+ untested x86_64-vla-pointer
-+ return -1
-+}
-+
-+gdb_breakpoint "break_here"
-+
-+gdb_continue_to_breakpoint "break_here"
-+
-+gdb_test "whatis array" "type = char \\(\\*\\)\\\[variable\\\]" "first: whatis array"
-+gdb_test "ptype array" "type = char \\(\\*\\)\\\[26\\\]" "first: ptype array"
-+
-+gdb_test "whatis *array" "type = char \\\[26\\\]" "first: whatis *array"
-+gdb_test "ptype *array" "type = char \\\[26\\\]" "first: ptype *array"
-+
-+gdb_test "p (*array)\[1\]" "\\$\[0-9\] = 1 '\\\\001'"
-+gdb_test "p (*array)\[2\]" "\\$\[0-9\] = 2 '\\\\002'"
-+gdb_test "p (*array)\[3\]" "\\$\[0-9\] = 3 '\\\\003'"
-+gdb_test "p (*array)\[4\]" "\\$\[0-9\] = 4 '\\\\004'"
-+
-+gdb_continue_to_breakpoint "break_here"
-+
-+gdb_test "whatis array" "type = char \\(\\*\\)\\\[variable\\\]" "second: whatis array"
-+gdb_test "ptype array" "type = char \\(\\*\\)\\\[78\\\]" "second: ptype array"
-+
-+gdb_test "whatis *array" "type = char \\\[78\\\]" "second: whatis *array"
-+gdb_test "ptype *array" "type = char \\\[78\\\]" "second: ptype *array"
-diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S
-new file mode 100644
-index 0000000..66f7a39
---- /dev/null
-+++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S
-@@ -0,0 +1,455 @@
-+ .file "x86_64-vla-typedef.c"
-+ .section .debug_abbrev,"",@progbits
-+.Ldebug_abbrev0:
-+ .section .debug_info,"",@progbits
-+.Ldebug_info0:
-+ .section .debug_line,"",@progbits
-+.Ldebug_line0:
-+ .text
-+.Ltext0:
-+.globl foo
-+ .type foo, @function
-+foo:
-+.LFB2:
-+ .file 1 "x86_64-vla-typedef.c"
-+ .loc 1 22 0
-+ pushq %rbp
-+.LCFI0:
-+ movq %rsp, %rbp
-+.LCFI1:
-+ subq $64, %rsp
-+.LCFI2:
-+ movl %edi, -36(%rbp)
-+ .loc 1 22 0
-+ movq %rsp, %rax
-+ movq %rax, -48(%rbp)
-+ .loc 1 23 0
-+ movl -36(%rbp), %edx
-+ movslq %edx,%rax
-+ subq $1, %rax
-+ movq %rax, -24(%rbp)
-+ .loc 1 24 0
-+ movslq %edx,%rax
-+ addq $15, %rax
-+ addq $15, %rax
-+ shrq $4, %rax
-+ salq $4, %rax
-+ subq %rax, %rsp
-+ movq %rsp, -56(%rbp)
-+ movq -56(%rbp), %rax
-+ addq $15, %rax
-+ shrq $4, %rax
-+ salq $4, %rax
-+ movq %rax, -56(%rbp)
-+ movq -56(%rbp), %rax
-+ movq %rax, -16(%rbp)
-+ .loc 1 27 0
-+ movl $0, -4(%rbp)
-+ jmp .L2
-+.L3:
-+ .loc 1 28 0
-+ movl -4(%rbp), %esi
-+ movl -4(%rbp), %eax
-+ movl %eax, %ecx
-+ movq -16(%rbp), %rdx
-+ movslq %esi,%rax
-+ movb %cl, (%rdx,%rax)
-+ .loc 1 27 0
-+ addl $1, -4(%rbp)
-+.L2:
-+ movl -4(%rbp), %eax
-+ cmpl -36(%rbp), %eax
-+ jl .L3
-+ .loc 1 30 0
-+ .globl break_here
-+break_here:
-+ movq -16(%rbp), %rax
-+ movb $0, (%rax)
-+ movq -48(%rbp), %rsp
-+ .loc 1 31 0
-+ leave
-+ ret
-+.LFE2:
-+ .size foo, .-foo
-+ .section .debug_frame,"",@progbits
-+.Lframe0:
-+ .long .LECIE0-.LSCIE0
-+.LSCIE0:
-+ .long 0xffffffff
-+ .byte 0x1
-+ .string ""
-+ .uleb128 0x1
-+ .sleb128 -8
-+ .byte 0x10
-+ .byte 0xc
-+ .uleb128 0x7
-+ .uleb128 0x8
-+ .byte 0x90
-+ .uleb128 0x1
-+ .align 8
-+.LECIE0:
-+.LSFDE0:
-+ .long .LEFDE0-.LASFDE0
-+.LASFDE0:
-+ .long .Lframe0
-+ .quad .LFB2
-+ .quad .LFE2-.LFB2
-+ .byte 0x4
-+ .long .LCFI0-.LFB2
-+ .byte 0xe
-+ .uleb128 0x10
-+ .byte 0x86
-+ .uleb128 0x2
-+ .byte 0x4
-+ .long .LCFI1-.LCFI0
-+ .byte 0xd
-+ .uleb128 0x6
-+ .align 8
-+.LEFDE0:
-+ .section .eh_frame,"a",@progbits
-+.Lframe1:
-+ .long .LECIE1-.LSCIE1
-+.LSCIE1:
-+ .long 0x0
-+ .byte 0x1
-+ .string "zR"
-+ .uleb128 0x1
-+ .sleb128 -8
-+ .byte 0x10
-+ .uleb128 0x1
-+ .byte 0x3
-+ .byte 0xc
-+ .uleb128 0x7
-+ .uleb128 0x8
-+ .byte 0x90
-+ .uleb128 0x1
-+ .align 8
-+.LECIE1:
-+.LSFDE1:
-+ .long .LEFDE1-.LASFDE1
-+.LASFDE1:
-+ .long .LASFDE1-.Lframe1
-+ .long .LFB2
-+ .long .LFE2-.LFB2
-+ .uleb128 0x0
-+ .byte 0x4
-+ .long .LCFI0-.LFB2
-+ .byte 0xe
-+ .uleb128 0x10
-+ .byte 0x86
-+ .uleb128 0x2
-+ .byte 0x4
-+ .long .LCFI1-.LCFI0
-+ .byte 0xd
-+ .uleb128 0x6
-+ .align 8
-+.LEFDE1:
-+ .text
-+.Letext0:
-+ .section .debug_loc,"",@progbits
-+.Ldebug_loc0:
-+.LLST0:
-+ .quad .LFB2-.Ltext0
-+ .quad .LCFI0-.Ltext0
-+ .value 0x2
-+ .byte 0x77
-+ .sleb128 8
-+ .quad .LCFI0-.Ltext0
-+ .quad .LCFI1-.Ltext0
-+ .value 0x2
-+ .byte 0x77
-+ .sleb128 16
-+ .quad .LCFI1-.Ltext0
-+ .quad .LFE2-.Ltext0
-+ .value 0x2
-+ .byte 0x76
-+ .sleb128 16
-+ .quad 0x0
-+ .quad 0x0
-+ .section .debug_info
-+ .long .Ldebug_end - .Ldebug_start
-+.Ldebug_start:
-+ .value 0x2
-+ .long .Ldebug_abbrev0
-+ .byte 0x8
-+ .uleb128 0x1
-+ .long .LASF2
-+ .byte 0x1
-+ .long .LASF3
-+ .long .LASF4
-+ .quad .Ltext0
-+ .quad .Letext0
-+ .long .Ldebug_line0
-+ .uleb128 0x2
-+ .byte 0x1
-+ .string "foo"
-+ .byte 0x1
-+ .byte 0x16
-+ .byte 0x1
-+ .quad .LFB2
-+ .quad .LFE2
-+ .long .LLST0
-+ .long 0x83
-+ .uleb128 0x3
-+ .long .LASF5
-+ .byte 0x1
-+ .byte 0x15
-+ .long 0x83
-+ .byte 0x2
-+ .byte 0x91
-+ .sleb128 -52
-+.Ltag_typedef:
-+ .uleb128 0x4
-+ .long .LASF6
-+ .byte 0x1
-+ .byte 0x17
-+ .long .Ltag_array_type - .debug_info
-+ .uleb128 0x5 /* Abbrev Number: 5 (DW_TAG_variable) */
-+ .long .LASF0
-+ .byte 0x1
-+ .byte 0x18
-+#if 1
-+ .long .Ltag_typedef - .debug_info
-+#else
-+ /* Debugging only: Skip the typedef indirection. */
-+ .long .Ltag_array_type - .debug_info
-+#endif
-+ /* DW_AT_location: DW_FORM_block1: start */
-+ .byte 0x3
-+ .byte 0x91
-+ .sleb128 -32
-+#if 0
-+ .byte 0x6 /* DW_OP_deref */
-+#else
-+ .byte 0x96 /* DW_OP_nop */
-+#endif
-+ /* DW_AT_location: DW_FORM_block1: end */
-+ .uleb128 0x6
-+ .string "i"
-+ .byte 0x1
-+ .byte 0x19
-+ .long 0x83
-+ .byte 0x2
-+ .byte 0x91
-+ .sleb128 -20
-+ .byte 0x0
-+ .uleb128 0x7
-+ .byte 0x4
-+ .byte 0x5
-+ .string "int"
-+.Ltag_array_type:
-+ .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */
-+ .long 0xa0 + (2f - 1f) /* DW_AT_type: DW_FORM_ref4 */
-+ .long 0x9d + (2f - 1f) /* DW_AT_sibling: DW_FORM_ref4 */
-+1: /* DW_AT_data_location: DW_FORM_block1: start */
-+ .byte 2f - 3f /* length */
-+3:
-+ .byte 0x97 /* DW_OP_push_object_address */
-+ .byte 0x6 /* DW_OP_deref */
-+2: /* DW_AT_data_location: DW_FORM_block1: end */
-+ .uleb128 0x9
-+ .long 0x9d + (2b - 1b) /* DW_AT_type: DW_FORM_ref4 */
-+ .byte 0x3
-+ .byte 0x91
-+ .sleb128 -40
-+ .byte 0x6
-+ .byte 0x0
-+ .uleb128 0xa
-+ .byte 0x8
-+ .byte 0x7
-+ .uleb128 0xb
-+ .byte 0x1
-+ .byte 0x6
-+ .long .LASF1
-+ .byte 0x0
-+.Ldebug_end:
-+ .section .debug_abbrev
-+ .uleb128 0x1
-+ .uleb128 0x11
-+ .byte 0x1
-+ .uleb128 0x25
-+ .uleb128 0xe
-+ .uleb128 0x13
-+ .uleb128 0xb
-+ .uleb128 0x3
-+ .uleb128 0xe
-+ .uleb128 0x1b
-+ .uleb128 0xe
-+ .uleb128 0x11
-+ .uleb128 0x1
-+ .uleb128 0x12
-+ .uleb128 0x1
-+ .uleb128 0x10
-+ .uleb128 0x6
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x2
-+ .uleb128 0x2e
-+ .byte 0x1
-+ .uleb128 0x3f
-+ .uleb128 0xc
-+ .uleb128 0x3
-+ .uleb128 0x8
-+ .uleb128 0x3a
-+ .uleb128 0xb
-+ .uleb128 0x3b
-+ .uleb128 0xb
-+ .uleb128 0x27
-+ .uleb128 0xc
-+ .uleb128 0x11
-+ .uleb128 0x1
-+ .uleb128 0x12
-+ .uleb128 0x1
-+ .uleb128 0x40
-+ .uleb128 0x6
-+ .uleb128 0x1
-+ .uleb128 0x13
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x3
-+ .uleb128 0x5
-+ .byte 0x0
-+ .uleb128 0x3
-+ .uleb128 0xe
-+ .uleb128 0x3a
-+ .uleb128 0xb
-+ .uleb128 0x3b
-+ .uleb128 0xb
-+ .uleb128 0x49
-+ .uleb128 0x13
-+ .uleb128 0x2
-+ .uleb128 0xa
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x4
-+ .uleb128 0x16
-+ .byte 0x0
-+ .uleb128 0x3
-+ .uleb128 0xe
-+ .uleb128 0x3a
-+ .uleb128 0xb
-+ .uleb128 0x3b
-+ .uleb128 0xb
-+ .uleb128 0x49
-+ .uleb128 0x13
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x5
-+ .uleb128 0x34
-+ .byte 0x0
-+ .uleb128 0x3
-+ .uleb128 0xe
-+ .uleb128 0x3a
-+ .uleb128 0xb
-+ .uleb128 0x3b
-+ .uleb128 0xb
-+ .uleb128 0x49
-+ .uleb128 0x13
-+ .uleb128 0x2
-+ .uleb128 0xa
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x6
-+ .uleb128 0x34
-+ .byte 0x0
-+ .uleb128 0x3
-+ .uleb128 0x8
-+ .uleb128 0x3a
-+ .uleb128 0xb
-+ .uleb128 0x3b
-+ .uleb128 0xb
-+ .uleb128 0x49
-+ .uleb128 0x13
-+ .uleb128 0x2
-+ .uleb128 0xa
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x7
-+ .uleb128 0x24
-+ .byte 0x0
-+ .uleb128 0xb
-+ .uleb128 0xb
-+ .uleb128 0x3e
-+ .uleb128 0xb
-+ .uleb128 0x3
-+ .uleb128 0x8
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */
-+ .uleb128 0x1
-+ .byte 0x1
-+ .uleb128 0x49 /* DW_AT_type */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .uleb128 0x1 /* DW_AT_sibling */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .uleb128 0x50 /* DW_AT_data_location */
-+ .uleb128 0xa /* DW_FORM_block1 */
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0x9
-+ .uleb128 0x21
-+ .byte 0x0
-+ .uleb128 0x49 /* DW_AT_type */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .uleb128 0x2f
-+ .uleb128 0xa
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0xa
-+ .uleb128 0x24
-+ .byte 0x0
-+ .uleb128 0xb
-+ .uleb128 0xb
-+ .uleb128 0x3e
-+ .uleb128 0xb
-+ .byte 0x0
-+ .byte 0x0
-+ .uleb128 0xb
-+ .uleb128 0x24
-+ .byte 0x0
-+ .uleb128 0xb
-+ .uleb128 0xb
-+ .uleb128 0x3e
-+ .uleb128 0xb
-+ .uleb128 0x3
-+ .uleb128 0xe
-+ .byte 0x0
-+ .byte 0x0
-+ .byte 0x0
-+ .section .debug_pubnames,"",@progbits
-+ .long 0x16
-+ .value 0x2
-+ .long .Ldebug_info0
-+ .long 0xa8
-+ .long 0x2d
-+ .string "foo"
-+ .long 0x0
-+ .section .debug_aranges,"",@progbits
-+ .long 0x2c
-+ .value 0x2
-+ .long .Ldebug_info0
-+ .byte 0x8
-+ .byte 0x0
-+ .value 0x0
-+ .value 0x0
-+ .quad .Ltext0
-+ .quad .Letext0-.Ltext0
-+ .quad 0x0
-+ .quad 0x0
-+ .section .debug_str,"MS",@progbits,1
-+.LASF0:
-+ .string "array"
-+.LASF5:
-+ .string "size"
-+.LASF3:
-+ .string "x86_64-vla-typedef.c"
-+.LASF6:
-+ .string "array_t"
-+.LASF1:
-+ .string "char"
-+.LASF4:
-+ .string "gdb.arch"
-+.LASF2:
-+ .string "GNU C 4.3.2 20081105 (Red Hat 4.3.2-7)"
-+ .ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)"
-+ .section .note.GNU-stack,"",@progbits
-diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c
-new file mode 100644
-index 0000000..b809c4e
---- /dev/null
-+++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c
-@@ -0,0 +1,43 @@
-+/* This testcase is part of GDB, the GNU debugger.
-+
-+ 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 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 0
-+
-+void
-+foo (int size)
-+{
-+ typedef char array_t[size];
-+ array_t array;
-+ int i;
-+
-+ for (i = 0; i < size; i++)
-+ array[i] = i;
-+
-+ array[0] = 0; /* break-here */
-+}
-+
-+#else
-+
-+int
-+main (void)
-+{
-+ foo (26);
-+ foo (78);
-+ return 0;
-+}
-+
-+#endif
-diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp
-new file mode 100644
-index 0000000..b05411e
---- /dev/null
-+++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp
-@@ -0,0 +1,64 @@
-+# Copyright 2009 Free Software Foundation, Inc.
-+
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 3 of the License, or
-+# (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program. If not, see <http://www.gnu.org/licenses/>.
-+
-+# Test DW_AT_data_location accessed through DW_TAG_typedef intermediate.
-+
-+if ![istarget "x86_64-*-*"] then {
-+ verbose "Skipping over gdb.arch/x86_64-vla-typedef.exp test made only for x86_64."
-+ return
-+}
-+
-+set testfile x86_64-vla-typedef
-+set srcasmfile ${testfile}-foo.S
-+set srcfile ${testfile}.c
-+set binfile ${objdir}/${subdir}/${testfile}
-+set binobjfile ${objdir}/${subdir}/${testfile}-foo.o
-+if { [gdb_compile "${srcdir}/${subdir}/${srcasmfile}" "${binobjfile}" object {}] != "" } {
-+ untested "Couldn't compile test program"
-+ return -1
-+}
-+if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${binobjfile}" "${binfile}" executable {debug}] != "" } {
-+ untested "Couldn't compile test program"
-+ return -1
-+}
-+
-+gdb_exit
-+gdb_start
-+gdb_reinitialize_dir $srcdir/$subdir
-+gdb_load ${binfile}
-+
-+if ![runto_main] {
-+ untested x86_64-vla-typedef
-+ return -1
-+}
-+
-+gdb_breakpoint "break_here"
-+
-+gdb_continue_to_breakpoint "break_here"
-+
-+gdb_test "whatis array" "type = array_t" "first: whatis array"
-+
-+gdb_test "ptype array" "type = char \\\[26\\\]" "first: ptype array"
-+
-+gdb_test "p array\[1\]" "\\$\[0-9\] = 1 '\\\\001'"
-+gdb_test "p array\[2\]" "\\$\[0-9\] = 2 '\\\\002'"
-+gdb_test "p array\[3\]" "\\$\[0-9\] = 3 '\\\\003'"
-+gdb_test "p array\[4\]" "\\$\[0-9\] = 4 '\\\\004'"
-+
-+gdb_continue_to_breakpoint "break_here"
-+
-+gdb_test "whatis array" "type = array_t" "second: whatis array"
-+
-+gdb_test "ptype array" "type = char \\\[78\\\]" "second: ptype array"
-diff --git a/gdb/testsuite/gdb.base/arrayidx.c b/gdb/testsuite/gdb.base/arrayidx.c
-index a99137e..c3dc2d9 100644
---- a/gdb/testsuite/gdb.base/arrayidx.c
-+++ b/gdb/testsuite/gdb.base/arrayidx.c
-@@ -17,6 +17,13 @@
-
- int array[] = {1, 2, 3, 4};
-
-+#ifdef __GNUC__
-+struct
-+ {
-+ int a[0];
-+ } unbound;
-+#endif
-+
- int
- main (void)
- {
-diff --git a/gdb/testsuite/gdb.base/arrayidx.exp b/gdb/testsuite/gdb.base/arrayidx.exp
-index cba0024..0dc0e46 100644
---- a/gdb/testsuite/gdb.base/arrayidx.exp
-+++ b/gdb/testsuite/gdb.base/arrayidx.exp
-@@ -53,4 +53,12 @@ gdb_test "print array" \
- "\\{\\\[0\\\] = 1, \\\[1\\\] = 2, \\\[2\\\] = 3, \\\[3\\\] = 4\\}" \
- "Print array with array-indexes on"
-
--
-+set test "p unbound.a == &unbound.a\[0\]"
-+gdb_test_multiple $test $test {
-+ -re " = 1\r\n$gdb_prompt $" {
-+ pass $test
-+ }
-+ -re "No symbol \"unbound\" in current context.\r\n$gdb_prompt $" {
-+ unsupported "$test (no GCC)"
-+ }
-+}
-diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp
-index 9677396..55d03a9 100644
---- a/gdb/testsuite/gdb.base/default.exp
-+++ b/gdb/testsuite/gdb.base/default.exp
-@@ -610,6 +610,19 @@ gdb_test_list_exact "show convenience" "show convenience" \
- {$_sdata = void} \
- {$_siginfo = void} \
- {$_thread = 0} \
-+ {$_probe_argc = <error: No frame selected>} \
-+ {$_probe_arg0 = <error: No frame selected>} \
-+ {$_probe_arg1 = <error: No frame selected>} \
-+ {$_probe_arg2 = <error: No frame selected>} \
-+ {$_probe_arg3 = <error: No frame selected>} \
-+ {$_probe_arg4 = <error: No frame selected>} \
-+ {$_probe_arg5 = <error: No frame selected>} \
-+ {$_probe_arg6 = <error: No frame selected>} \
-+ {$_probe_arg7 = <error: No frame selected>} \
-+ {$_probe_arg8 = <error: No frame selected>} \
-+ {$_probe_arg9 = <error: No frame selected>} \
-+ {$_probe_arg10 = <error: No frame selected>} \
-+ {$_probe_arg11 = <error: No frame selected>} \
- }
-
- #test show directories
-diff --git a/gdb/testsuite/gdb.base/internal-var-field-address.c b/gdb/testsuite/gdb.base/internal-var-field-address.c
-new file mode 100644
-index 0000000..eeb7b85
---- /dev/null
-+++ b/gdb/testsuite/gdb.base/internal-var-field-address.c
-@@ -0,0 +1,20 @@
-+/* This testcase is part of GDB, the GNU debugger.
-+
-+ Copyright 2009 Free Software Foundation, Inc.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 3 of the License, or
-+ (at your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
-+
-+struct {
-+ int field;
-+} staticstruct = { 1 };
-diff --git a/gdb/testsuite/gdb.base/internal-var-field-address.exp b/gdb/testsuite/gdb.base/internal-var-field-address.exp
-new file mode 100644
-index 0000000..6d82e73
---- /dev/null
-+++ b/gdb/testsuite/gdb.base/internal-var-field-address.exp
-@@ -0,0 +1,26 @@
-+# Copyright 2009 Free Software Foundation, Inc.
-+
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 3 of the License, or
-+# (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program. If not, see <http://www.gnu.org/licenses/>.
-+
-+set test internal-var-field-address
-+set binfile ${test}.x
-+if { [gdb_compile "${srcdir}/${subdir}/${test}.c" "${objdir}/${subdir}/${binfile}" object {debug}] != "" } {
-+ untested "Couldn't compile test program"
-+ return -1
-+}
-+
-+clean_restart $binfile
-+
-+gdb_test {set $varstruct = staticstruct}
-+gdb_test {p $varstruct.field} " = 1"
-diff --git a/gdb/testsuite/gdb.base/stap-probe.c b/gdb/testsuite/gdb.base/stap-probe.c
-new file mode 100644
-index 0000000..236da96
---- /dev/null
-+++ b/gdb/testsuite/gdb.base/stap-probe.c
-@@ -0,0 +1,108 @@
-+/* This testcase is part of GDB, the GNU debugger.
-+
-+ Copyright 2011 Free Software Foundation, Inc.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 3 of the License, or
-+ (at your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
-+
-+#if USE_PROBES
-+
-+#define _SDT_HAS_SEMAPHORES
-+__extension__ unsigned short teste_user_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
-+#define TEST teste_user_semaphore
-+
-+__extension__ unsigned short teste_two_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
-+#define TEST2 teste_two_semaphore
-+
-+__extension__ unsigned short teste_m4_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
-+
-+__extension__ unsigned short teste_pstr_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
-+
-+__extension__ unsigned short teste_ps_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
-+#else
-+
-+#define TEST 1
-+#define TEST2 1
-+
-+#endif
-+
-+#include <sys/sdt.h>
-+
-+/* We only support SystemTap and only the v3 form. */
-+#if _SDT_NOTE_TYPE != 3
-+#error "not using SystemTap v3 probes"
-+#endif
-+
-+struct funcs
-+{
-+ int val;
-+
-+ const char *(*ps) (int);
-+};
-+
-+static void
-+m1 (void)
-+{
-+ if (TEST2)
-+ STAP_PROBE (teste, two);
-+}
-+
-+static void
-+m2 (void)
-+{
-+ if (TEST2)
-+ STAP_PROBE (teste, two);
-+}
-+
-+static int
-+f (int x)
-+{
-+ if (TEST)
-+ STAP_PROBE1 (teste, user, x);
-+ return x+5;
-+}
-+
-+static const char *
-+pstr (int val)
-+{
-+ const char *a = "This is a test message.";
-+ const char *b = "This is another test message.";
-+
-+ STAP_PROBE3 (teste, ps, a, b, val);
-+
-+ return val == 0 ? a : b;
-+}
-+
-+static void
-+m4 (const struct funcs *fs, int v)
-+{
-+ STAP_PROBE3 (teste, m4, fs->val, fs->ps (v), v);
-+}
-+
-+int
-+main()
-+{
-+ struct funcs fs;
-+
-+ fs.val = 42;
-+ fs.ps = pstr;
-+
-+ f (f (23));
-+ m1 ();
-+ m2 ();
-+
-+ m4 (&fs, 0);
-+ m4 (&fs, 1);
-+
-+ return 0; /* last break here */
-+}
-diff --git a/gdb/testsuite/gdb.base/stap-probe.exp b/gdb/testsuite/gdb.base/stap-probe.exp
-new file mode 100644
-index 0000000..468efb9
---- /dev/null
-+++ b/gdb/testsuite/gdb.base/stap-probe.exp
-@@ -0,0 +1,187 @@
-+# Copyright (C) 2011 Free Software Foundation, Inc.
-+
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 3 of the License, or
-+# (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program. If not, see <http://www.gnu.org/licenses/>.
-+
-+set testfile stap-probe
-+
-+# Run the tests. We run the tests two different ways: once with a
-+# plain probe, and once with a probe that has an associated semaphore.
-+# This returns -1 on failure to compile or start, 0 otherwise.
-+proc stap_test {{arg ""}} {
-+ global testfile hex
-+
-+ if {$arg != ""} {
-+ set arg "additional_flags=$arg"
-+ set addendum ", with semaphore, not optimized"
-+ } else {
-+ set addendum ", no semaphore, not optimized"
-+ }
-+
-+ if {[prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c \
-+ [concat $arg debug]]} {
-+ return -1
-+ }
-+
-+ if ![runto_main] {
-+ return -1
-+ }
-+
-+ gdb_test "print \$_probe_argc" "No SystemTap probe at PC $hex" \
-+ "check argument not at probe point$addendum"
-+
-+ gdb_test "info probes" \
-+ "teste *user *$hex .*" \
-+ "info probes$addendum"
-+
-+ if {[runto "-p teste:user"]} {
-+ pass "run to -p teste:user$addendum"
-+ } else {
-+ fail "run to -p teste:user$addendum"
-+ }
-+
-+ # Test probe arguments.
-+ gdb_test "print \$_probe_argc" " = 1" \
-+ "print \$_probe_argc for probe user$addendum"
-+ gdb_test "print \$_probe_arg0 == x" " = 1" \
-+ "check \$_probe_arg0 for probe user$addendum"
-+ gdb_test "print \$_probe_arg1" \
-+ "Invalid probe argument 1 -- probe has 1 arguments available" \
-+ "check \$_probe_arg1 for probe user$addendum"
-+
-+ # Set a breakpoint with multiple probe locations.
-+ gdb_test "break -p teste:two" \
-+ "Breakpoint \[0-9\]+ at $hex.*2 locations.*" \
-+ "set multi-location probe breakpoint (probe two)$addendum"
-+
-+ # Reinit GDB, set a breakpoint on probe m4.
-+ delete_breakpoints
-+ rerun_to_main
-+ if {[runto "-p teste:m4"]} {
-+ pass "run to -p teste:m4$addendum"
-+ } else {
-+ fail "run to -p teste:m4$addendum"
-+ }
-+
-+ # Testing probe arguments.
-+ gdb_test "print \$_probe_argc" " = 3" \
-+ "print \$_probe_argc for probe m4$addendum"
-+ gdb_test "print \$_probe_arg0" " = 42" \
-+ "check \$_probe_arg0 for probe m4$addendum"
-+ gdb_test "print (const char *) \$_probe_arg1" \
-+ " = $hex .This is a test message.*" \
-+ "check \$_probe_arg1 for probe m4$addendum"
-+ gdb_test "print \$_probe_arg2 == v" " = 1" \
-+ "check \$_probe_arg2 for probe m4$addendum"
-+
-+ # Reinit GDB, set a breakpoint on probe ps.
-+ delete_breakpoints
-+ rerun_to_main
-+ if {[runto "-p teste:ps"]} {
-+ pass "run to -p teste:m4$addendum"
-+ } else {
-+ fail "run to -p teste:m4$addendum"
-+ }
-+
-+ gdb_test "print \$_probe_argc" " = 3" \
-+ "print \$_probe_argc for probe ps$addendum"
-+ gdb_test "print (const char *) \$_probe_arg1" \
-+ " = $hex .This is another test message.*" \
-+ "print \$_probe_arg1 for probe ps$addendum"
-+
-+ return 0
-+}
-+
-+proc stap_test_no_debuginfo {{ arg "" }} {
-+ global testfile hex
-+
-+ if {$arg != ""} {
-+ set arg "additional_flags=$arg"
-+ set addendum ", with semaphore, optimized"
-+ } else {
-+ set addendum ", no semaphore, optimized"
-+ }
-+
-+ if {[prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c \
-+ {$arg nodebug optimize=-O2}]} {
-+ return -1
-+ }
-+
-+ if {[runto "-p teste:user"]} {
-+ pass "run to -p teste:user$addendum"
-+ } else {
-+ fail "run to -p teste:user$addendum"
-+ }
-+
-+ # Test probe arguments.
-+ gdb_test "print \$_probe_argc" " = 1" \
-+ "print \$_probe_argc for probe user$addendum"
-+ gdb_test "print \$_probe_arg0 == 23" " = 1" \
-+ "check \$_probe_arg0 for probe user$addendum"
-+ gdb_test "print \$_probe_arg1" \
-+ "Invalid probe argument 1 -- probe has 1 arguments available" \
-+ "check \$_probe_arg1 for probe user$addendum"
-+
-+ # Set a breakpoint with multiple probe locations.
-+ # In this scenario, we may expect more than 2 locations because of
-+ # the optimizations (inlining, loop unrolling, etc).
-+ gdb_test "break -p teste:two" \
-+ "Breakpoint .* at $hex.*\[0-9\]+ locations.*" \
-+ "set multi-location probe breakpoint (probe two)$addendum"
-+
-+ # Reinit GDB, set a breakpoint on probe m4.
-+ delete_breakpoints
-+ rerun_to_main
-+ if {[runto "-p teste:m4"]} {
-+ pass "run to -p teste:m4$addendum"
-+ } else {
-+ fail "run to -p teste:m4$addendum"
-+ }
-+
-+ # Testing probe arguments.
-+ gdb_test "print \$_probe_argc" " = 3" \
-+ "print \$_probe_argc for probe m4$addendum"
-+ gdb_test "print \$_probe_arg0" " = 42" \
-+ "check \$_probe_arg0 for probe m4$addendum"
-+ gdb_test "print (const char *) \$_probe_arg1" \
-+ " = $hex .This is a test message.*" \
-+ "check \$_probe_arg1 for probe m4$addendum"
-+ gdb_test "print \$_probe_arg2 == 0" " = 1" \
-+ "check \$_probe_arg2 for probe m4$addendum"
-+
-+ # Reinit GDB, set a breakpoint on probe ps.
-+ delete_breakpoints
-+ rerun_to_main
-+ if {[runto "-p teste:ps"]} {
-+ pass "run to -p teste:m4$addendum"
-+ } else {
-+ fail "run to -p teste:m4$addendum"
-+ }
-+
-+ gdb_test "print \$_probe_argc" " = 3" \
-+ "print \$_probe_argc for probe ps$addendum"
-+ gdb_test "print (const char *) \$_probe_arg1" \
-+ " = $hex .This is another test message.*" \
-+ "print \$_probe_arg1 for probe ps$addendum"
-+
-+ return 0
-+}
-+
-+if {[stap_test] == -1} {
-+ untested stap-probe.exp
-+ return -1
-+}
-+
-+stap_test "-DUSE_PROBES"
-+stap_test_no_debuginfo
-+stap_test_no_debuginfo "-DUSE_PROBES"
-diff --git a/gdb/testsuite/gdb.base/vla-frame.c b/gdb/testsuite/gdb.base/vla-frame.c
-new file mode 100644
-index 0000000..5750f68
---- /dev/null
-+++ b/gdb/testsuite/gdb.base/vla-frame.c
-@@ -0,0 +1,31 @@
-+/* This testcase is part of GDB, the GNU debugger.
-+
-+ Copyright 2011 Free Software Foundation, Inc.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 3 of the License, or
-+ (at your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
-+
-+#include <string.h>
-+
-+int
-+main (int argc, char **argv)
-+{
-+ char s[2 + argc];
-+ void (*f) (char *) = 0;
-+
-+ memset (s, 0, sizeof (s));
-+ s[0] = 'X';
-+
-+ f (s);
-+ return 0;
-+}
-diff --git a/gdb/testsuite/gdb.base/vla-frame.exp b/gdb/testsuite/gdb.base/vla-frame.exp
-new file mode 100644
-index 0000000..47736c7
---- /dev/null
-+++ b/gdb/testsuite/gdb.base/vla-frame.exp
-@@ -0,0 +1,38 @@
-+# Copyright 2011 Free Software Foundation, Inc.
-+#
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 3 of the License, or
-+# (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program. If not, see <http://www.gnu.org/licenses/>.
-+
-+set testfile vla-frame
-+set executable ${testfile}
-+
-+if { [prepare_for_testing ${testfile}.exp ${executable}] } {
-+ return -1
-+}
-+
-+if ![runto_main] {
-+ return -1
-+}
-+
-+set test "continue"
-+gdb_test_multiple $test $test {
-+ -re "Continuing\\.\r\n\r\nProgram received signal SIGSEGV, Segmentation fault\\.\r\n0x0+ in \\?\\? \\(\\)\r\n$gdb_prompt $" {
-+ pass $test
-+ }
-+ -re "\r\n$gdb_prompt $" {
-+ untested ${testfile}.exp
-+ return
-+ }
-+}
-+
-+gdb_test "bt full" "\r\n +s = \"X\\\\000\"\r\n.*"
-diff --git a/gdb/testsuite/gdb.base/vla-overflow.c b/gdb/testsuite/gdb.base/vla-overflow.c
-new file mode 100644
-index 0000000..c5d5ee0
---- /dev/null
-+++ b/gdb/testsuite/gdb.base/vla-overflow.c
-@@ -0,0 +1,30 @@
-+/* This testcase is part of GDB, the GNU debugger.
-+
-+ 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 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 <stdlib.h>
-+
-+int
-+main (int argc, char **argv)
-+{
-+ int array[argc];
-+
-+ array[0] = array[0];
-+
-+ abort ();
-+
-+ return 0;
-+}
-diff --git a/gdb/testsuite/gdb.base/vla-overflow.exp b/gdb/testsuite/gdb.base/vla-overflow.exp
+ }
+
+diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-pointer-foo.S b/gdb/testsuite/gdb.arch/x86_64-vla-pointer-foo.S
new file mode 100644
-index 0000000..24a608f
---- /dev/null
-+++ b/gdb/testsuite/gdb.base/vla-overflow.exp
-@@ -0,0 +1,109 @@
-+# 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 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/>.
-+
-+# We could crash in:
-+# #0 block_linkage_function (bl=0x0) at ../../gdb/block.c:69
-+# #1 in dwarf_block_get_frame_base (...) at ../../gdb/dwarf2block.c:97
-+# 97 framefunc = block_linkage_function (get_frame_block (frame, NULL));
-+# #2 in execute_stack_op (...) at ../../gdb/dwarf2expr.c:496
-+# #3 in dwarf_block_exec_core () at ../../gdb/dwarf2block.c:156
-+# #4 dwarf_block_exec (...) at ../../gdb/dwarf2block.c:206
-+# #5 in range_type_count_bound_internal (...) at ../../gdb/gdbtypes.c:1430
-+# #6 in create_array_type (...) at ../../gdb/gdbtypes.c:840
-+# ...
-+# #21 in psymtab_to_symtab (...) at ../../gdb/symfile.c:292
-+# ...
-+# #29 in backtrace_command_1 () at ../../gdb/stack.c:1273
-+
-+set testfile vla-overflow
-+set shfile ${objdir}/${subdir}/${testfile}-gdb.sh
-+set srcfile ${testfile}.c
-+set binfile ${objdir}/${subdir}/${testfile}
-+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
-+ untested "Couldn't compile test program"
-+ return -1
-+}
-+
-+set f [open "|getconf PAGESIZE" "r"]
-+gets $f pagesize
-+close $f
-+
-+gdb_exit
-+gdb_start
-+gdb_reinitialize_dir $srcdir/$subdir
-+gdb_load ${binfile}
-+
-+set pid_of_gdb [exp_pid -i [board_info host fileid]]
-+
-+if { [runto_main] < 0 } {
-+ untested vla-overflow
-+ return -1
-+}
-+
-+# Get the GDB memory size when we stay at main.
-+
-+proc memory_v_pages_get {} {
-+ global pid_of_gdb pagesize
-+ set fd [open "/proc/$pid_of_gdb/statm"]
-+ gets $fd line
-+ close $fd
-+ # number of pages of virtual memory
-+ scan $line "%d" drs
-+ return $drs
-+}
-+
-+set pages_found [memory_v_pages_get]
-+
-+# s390x with glibc-debuginfo.s390x installed used approx. 16MB.
-+set mb_reserve 40
-+verbose -log "pages_found = $pages_found, mb_reserve = $mb_reserve"
-+set kb_found [expr $pages_found * $pagesize / 1024]
-+set kb_permit [expr $kb_found + 1 * 1024 + $mb_reserve * 1024]
-+verbose -log "kb_found = $kb_found, kb_permit = $kb_permit"
-+
-+# Create the ulimit wrapper.
-+set f [open $shfile "w"]
-+puts $f "#! /bin/sh"
-+puts $f "ulimit -v $kb_permit"
-+puts $f "exec $GDB \"\$@\""
-+close $f
-+remote_exec host "chmod +x $shfile"
-+
-+gdb_exit
-+set GDBold $GDB
-+set GDB "$shfile"
-+gdb_start
-+set GDB $GDBold
-+
-+gdb_reinitialize_dir $srcdir/$subdir
-+gdb_load ${binfile}
-+
-+set pid_of_gdb [exp_pid -i [board_info host fileid]]
-+
-+# Check the size again after the second run.
-+# We must not stop in main as it would cache `array' and never crash later.
-+
-+gdb_run_cmd
-+
-+verbose -log "kb_found before abort() = [expr [memory_v_pages_get] * $pagesize / 1024]"
-+
-+gdb_test "" "Program received signal SIGABRT, Aborted..*" "Enter abort()"
-+
-+verbose -log "kb_found in abort() = [expr [memory_v_pages_get] * $pagesize / 1024]"
-+
-+# `abort' can get expressed as `*__GI_abort'.
-+gdb_test "bt" "in \[^ \]*abort \\(.* in main \\(.*" "Backtrace after abort()"
-+
-+verbose -log "kb_found in bt after abort() = [expr [memory_v_pages_get] * $pagesize / 1024]"
-diff --git a/gdb/testsuite/gdb.base/vla.c b/gdb/testsuite/gdb.base/vla.c
+index 0000000..83faaf6
+--- /dev/null
++++ b/gdb/testsuite/gdb.arch/x86_64-vla-pointer-foo.S
+@@ -0,0 +1,457 @@
++ .file "x86_64-vla-pointer.c"
++ .section .debug_abbrev,"",@progbits
++.Ldebug_abbrev0:
++ .section .debug_info,"",@progbits
++.Ldebug_info0:
++ .section .debug_line,"",@progbits
++.Ldebug_line0:
++ .text
++.Ltext0:
++.globl foo
++ .type foo, @function
++foo:
++.LFB2:
++ .file 1 "x86_64-vla-pointer.c"
++ .loc 1 22 0
++ pushq %rbp
++.LCFI0:
++ movq %rsp, %rbp
++.LCFI1:
++ subq $64, %rsp
++.LCFI2:
++ movl %edi, -36(%rbp)
++ .loc 1 22 0
++ movq %rsp, %rax
++ movq %rax, -48(%rbp)
++ .loc 1 23 0
++ movl -36(%rbp), %edx
++ movslq %edx,%rax
++ subq $1, %rax
++ movq %rax, -24(%rbp)
++ .loc 1 24 0
++ movslq %edx,%rax
++ addq $15, %rax
++ addq $15, %rax
++ shrq $4, %rax
++ salq $4, %rax
++ subq %rax, %rsp
++ movq %rsp, -56(%rbp)
++ movq -56(%rbp), %rax
++ addq $15, %rax
++ shrq $4, %rax
++ salq $4, %rax
++ movq %rax, -56(%rbp)
++ movq -56(%rbp), %rax
++ movq %rax, -16(%rbp)
++ .loc 1 27 0
++ movl $0, -4(%rbp)
++ jmp .L2
++.L3:
++ .loc 1 28 0
++ movl -4(%rbp), %esi
++ movl -4(%rbp), %eax
++ movl %eax, %ecx
++ movq -16(%rbp), %rdx
++ movslq %esi,%rax
++ movb %cl, (%rdx,%rax)
++ .loc 1 27 0
++ addl $1, -4(%rbp)
++.L2:
++ movl -4(%rbp), %eax
++ cmpl -36(%rbp), %eax
++ jl .L3
++ .loc 1 30 0
++ .globl break_here
++break_here:
++ movq -16(%rbp), %rax
++ movb $0, (%rax)
++ movq -48(%rbp), %rsp
++ .loc 1 31 0
++ leave
++ ret
++.LFE2:
++ .size foo, .-foo
++ .section .debug_frame,"",@progbits
++.Lframe0:
++ .long .LECIE0-.LSCIE0
++.LSCIE0:
++ .long 0xffffffff
++ .byte 0x1
++ .string ""
++ .uleb128 0x1
++ .sleb128 -8
++ .byte 0x10
++ .byte 0xc
++ .uleb128 0x7
++ .uleb128 0x8
++ .byte 0x90
++ .uleb128 0x1
++ .align 8
++.LECIE0:
++.LSFDE0:
++ .long .LEFDE0-.LASFDE0
++.LASFDE0:
++ .long .Lframe0
++ .quad .LFB2
++ .quad .LFE2-.LFB2
++ .byte 0x4
++ .long .LCFI0-.LFB2
++ .byte 0xe
++ .uleb128 0x10
++ .byte 0x86
++ .uleb128 0x2
++ .byte 0x4
++ .long .LCFI1-.LCFI0
++ .byte 0xd
++ .uleb128 0x6
++ .align 8
++.LEFDE0:
++ .section .eh_frame,"a",@progbits
++.Lframe1:
++ .long .LECIE1-.LSCIE1
++.LSCIE1:
++ .long 0x0
++ .byte 0x1
++ .string "zR"
++ .uleb128 0x1
++ .sleb128 -8
++ .byte 0x10
++ .uleb128 0x1
++ .byte 0x3
++ .byte 0xc
++ .uleb128 0x7
++ .uleb128 0x8
++ .byte 0x90
++ .uleb128 0x1
++ .align 8
++.LECIE1:
++.LSFDE1:
++ .long .LEFDE1-.LASFDE1
++.LASFDE1:
++ .long .LASFDE1-.Lframe1
++ .long .LFB2
++ .long .LFE2-.LFB2
++ .uleb128 0x0
++ .byte 0x4
++ .long .LCFI0-.LFB2
++ .byte 0xe
++ .uleb128 0x10
++ .byte 0x86
++ .uleb128 0x2
++ .byte 0x4
++ .long .LCFI1-.LCFI0
++ .byte 0xd
++ .uleb128 0x6
++ .align 8
++.LEFDE1:
++ .text
++.Letext0:
++ .section .debug_loc,"",@progbits
++.Ldebug_loc0:
++.LLST0:
++ .quad .LFB2-.Ltext0
++ .quad .LCFI0-.Ltext0
++ .value 0x2
++ .byte 0x77
++ .sleb128 8
++ .quad .LCFI0-.Ltext0
++ .quad .LCFI1-.Ltext0
++ .value 0x2
++ .byte 0x77
++ .sleb128 16
++ .quad .LCFI1-.Ltext0
++ .quad .LFE2-.Ltext0
++ .value 0x2
++ .byte 0x76
++ .sleb128 16
++ .quad 0x0
++ .quad 0x0
++ .section .debug_info
++.Ldebug_relative:
++ .long .Ldebug_end - .Ldebug_start
++.Ldebug_start:
++ .value 0x2
++ .long .Ldebug_abbrev0
++ .byte 0x8
++ .uleb128 0x1
++ .long .LASF2
++ .byte 0x1
++ .long .LASF3
++ .long .LASF4
++ .quad .Ltext0
++ .quad .Letext0
++ .long .Ldebug_line0
++ .uleb128 0x2
++ .byte 0x1
++ .string "foo"
++ .byte 0x1
++ .byte 0x16
++ .byte 0x1
++ .quad .LFB2
++ .quad .LFE2
++ .long .LLST0
++ .long .Ltype_int - .Ldebug_relative
++ .uleb128 0x3
++ .long .LASF5
++ .byte 0x1
++ .byte 0x15
++ .long .Ltype_int - .Ldebug_relative
++ .byte 0x2
++ .byte 0x91
++ .sleb128 -52
++.Ltag_pointer:
++ .uleb128 0x4
++ .byte 0x8 /* DW_AT_byte_size */
++ .long .Ltag_array_type - .debug_info /* DW_AT_type */
++ .uleb128 0x5 /* Abbrev Number: 5 (DW_TAG_variable) */
++ .long .LASF0
++ .byte 0x1
++ .byte 0x18
++#if 1
++ .long .Ltag_pointer - .debug_info
++#else
++ /* Debugging only: Skip the typedef indirection. */
++ .long .Ltag_array_type - .debug_info
++#endif
++ /* DW_AT_location: DW_FORM_block1: start */
++ .byte 0x3
++ .byte 0x91
++ .sleb128 -32
++#if 0
++ .byte 0x6 /* DW_OP_deref */
++#else
++ .byte 0x96 /* DW_OP_nop */
++#endif
++ /* DW_AT_location: DW_FORM_block1: end */
++ .uleb128 0x6
++ .string "i"
++ .byte 0x1
++ .byte 0x19
++ .long .Ltype_int - .Ldebug_relative
++ .byte 0x2
++ .byte 0x91
++ .sleb128 -20
++ .byte 0x0
++.Ltype_int:
++ .uleb128 0x7
++ .byte 0x4
++ .byte 0x5
++ .string "int"
++.Ltag_array_type:
++ .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */
++ .long .Ltype_char - .Ldebug_relative
++ .long .Ltype_ulong - .Ldebug_relative /* DW_AT_sibling: DW_FORM_ref4 */
++1: /* DW_AT_data_location: DW_FORM_block1: start */
++ .byte 2f - 3f /* length */
++3:
++ .byte 0x97 /* DW_OP_push_object_address */
++#if 1
++ .byte 0x6 /* DW_OP_deref */
++#else
++ .byte 0x96 /* DW_OP_nop */
++#endif
++2: /* DW_AT_data_location: DW_FORM_block1: end */
++ .uleb128 0x9
++ .long .Ltype_char - .Ldebug_relative /* DW_AT_type: DW_FORM_ref4 */
++ .byte 0x3
++ .byte 0x91
++ .sleb128 -40
++ .byte 0x6
++ .byte 0x0
++.Ltype_ulong:
++ .uleb128 0xa
++ .byte 0x8
++ .byte 0x7
++.Ltype_char:
++ .uleb128 0xb
++ .byte 0x1
++ .byte 0x6
++ .long .LASF1
++ .byte 0x0
++.Ldebug_end:
++ .section .debug_abbrev
++ .uleb128 0x1
++ .uleb128 0x11
++ .byte 0x1
++ .uleb128 0x25
++ .uleb128 0xe
++ .uleb128 0x13
++ .uleb128 0xb
++ .uleb128 0x3
++ .uleb128 0xe
++ .uleb128 0x1b
++ .uleb128 0xe
++ .uleb128 0x11
++ .uleb128 0x1
++ .uleb128 0x12
++ .uleb128 0x1
++ .uleb128 0x10
++ .uleb128 0x6
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x2
++ .uleb128 0x2e
++ .byte 0x1
++ .uleb128 0x3f
++ .uleb128 0xc
++ .uleb128 0x3
++ .uleb128 0x8
++ .uleb128 0x3a
++ .uleb128 0xb
++ .uleb128 0x3b
++ .uleb128 0xb
++ .uleb128 0x27
++ .uleb128 0xc
++ .uleb128 0x11
++ .uleb128 0x1
++ .uleb128 0x12
++ .uleb128 0x1
++ .uleb128 0x40
++ .uleb128 0x6
++ .uleb128 0x1
++ .uleb128 0x13
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x3
++ .uleb128 0x5
++ .byte 0x0
++ .uleb128 0x3
++ .uleb128 0xe
++ .uleb128 0x3a
++ .uleb128 0xb
++ .uleb128 0x3b
++ .uleb128 0xb
++ .uleb128 0x49
++ .uleb128 0x13
++ .uleb128 0x2
++ .uleb128 0xa
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x4 /* .Ltag_pointer abbrev */
++ .uleb128 0x0f /* DW_TAG_pointer_type */
++ .byte 0x0
++ .uleb128 0x0b
++ .uleb128 0xb
++ .uleb128 0x49
++ .uleb128 0x13
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x5
++ .uleb128 0x34
++ .byte 0x0
++ .uleb128 0x3
++ .uleb128 0xe
++ .uleb128 0x3a
++ .uleb128 0xb
++ .uleb128 0x3b
++ .uleb128 0xb
++ .uleb128 0x49
++ .uleb128 0x13
++ .uleb128 0x2
++ .uleb128 0xa
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x6
++ .uleb128 0x34
++ .byte 0x0
++ .uleb128 0x3
++ .uleb128 0x8
++ .uleb128 0x3a
++ .uleb128 0xb
++ .uleb128 0x3b
++ .uleb128 0xb
++ .uleb128 0x49
++ .uleb128 0x13
++ .uleb128 0x2
++ .uleb128 0xa
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x7
++ .uleb128 0x24
++ .byte 0x0
++ .uleb128 0xb
++ .uleb128 0xb
++ .uleb128 0x3e
++ .uleb128 0xb
++ .uleb128 0x3
++ .uleb128 0x8
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */
++ .uleb128 0x1
++ .byte 0x1
++ .uleb128 0x49 /* DW_AT_type */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .uleb128 0x1 /* DW_AT_sibling */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .uleb128 0x50 /* DW_AT_data_location */
++ .uleb128 0xa /* DW_FORM_block1 */
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x9
++ .uleb128 0x21
++ .byte 0x0
++ .uleb128 0x49 /* DW_AT_type */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .uleb128 0x2f
++ .uleb128 0xa
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0xa
++ .uleb128 0x24
++ .byte 0x0
++ .uleb128 0xb
++ .uleb128 0xb
++ .uleb128 0x3e
++ .uleb128 0xb
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0xb
++ .uleb128 0x24
++ .byte 0x0
++ .uleb128 0xb
++ .uleb128 0xb
++ .uleb128 0x3e
++ .uleb128 0xb
++ .uleb128 0x3
++ .uleb128 0xe
++ .byte 0x0
++ .byte 0x0
++ .byte 0x0
++ .section .debug_pubnames,"",@progbits
++ .long 0x16
++ .value 0x2
++ .long .Ldebug_info0
++ .long 0xa8
++ .long 0x2d
++ .string "foo"
++ .long 0x0
++ .section .debug_aranges,"",@progbits
++ .long 0x2c
++ .value 0x2
++ .long .Ldebug_info0
++ .byte 0x8
++ .byte 0x0
++ .value 0x0
++ .value 0x0
++ .quad .Ltext0
++ .quad .Letext0-.Ltext0
++ .quad 0x0
++ .quad 0x0
++ .section .debug_str,"MS",@progbits,1
++.LASF0:
++ .string "array"
++.LASF5:
++ .string "size"
++.LASF3:
++ .string "x86_64-vla-pointer.c"
++.LASF6:
++ .string "array_t"
++.LASF1:
++ .string "char"
++.LASF4:
++ .string "gdb.arch"
++.LASF2:
++ .string "GNU C 4.3.2 20081105 (Red Hat 4.3.2-7)"
++ .ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)"
++ .section .note.GNU-stack,"",@progbits
+diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-pointer.c b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.c
new file mode 100644
-index 0000000..e1f3ed1
+index 0000000..fe2c8f7
--- /dev/null
-+++ b/gdb/testsuite/gdb.base/vla.c
-@@ -0,0 +1,55 @@
++++ b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.c
+@@ -0,0 +1,43 @@
+/* This testcase is part of GDB, the GNU debugger.
+
-+ Copyright 2008 Free Software Foundation, Inc.
++ Copyright 2009 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 <string.h>
-+
-+void
-+marker (void)
-+{
-+}
-+
-+void
-+bar (char *a, char *b, char *c, int size)
-+{
-+ memset (a, '1', size);
-+ memset (b, '2', size);
-+ memset (c, '3', 48);
-+}
++#if 0
+
+void
+foo (int size)
+{
-+ char temp1[size];
-+ char temp3[48];
-+
-+ temp1[size - 1] = '\0';
-+ {
-+ char temp2[size];
++ typedef char array_t[size];
++ array_t array;
++ int i;
+
-+ bar (temp1, temp2, temp3, size);
++ for (i = 0; i < size; i++)
++ array[i] = i;
+
-+ marker (); /* break-here */
-+ }
++ array[0] = 0; /* break-here */
+}
+
++#else
++
+int
+main (void)
+{
+ foo (78);
+ return 0;
+}
-diff --git a/gdb/testsuite/gdb.base/vla.exp b/gdb/testsuite/gdb.base/vla.exp
++
++#endif
+diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-pointer.exp b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.exp
new file mode 100644
-index 0000000..5da7378
+index 0000000..d243cf1
--- /dev/null
-+++ b/gdb/testsuite/gdb.base/vla.exp
-@@ -0,0 +1,62 @@
-+# Copyright 2008 Free Software Foundation, Inc.
++++ b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.exp
+@@ -0,0 +1,66 @@
++# Copyright 2009 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
-+set testfile vla
++if ![istarget "x86_64-*-*"] then {
++ verbose "Skipping over gdb.arch/x86_64-vla-pointer.exp test made only for x86_64."
++ return
++}
++
++set testfile x86_64-vla-pointer
++set srcasmfile ${testfile}-foo.S
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
-+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
++set binobjfile ${objdir}/${subdir}/${testfile}-foo.o
++if { [gdb_compile "${srcdir}/${subdir}/${srcasmfile}" "${binobjfile}" object {}] != "" } {
++ untested "Couldn't compile test program"
++ return -1
++}
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${binobjfile}" "${binfile}" executable {debug}] != "" } {
+ untested "Couldn't compile test program"
+ return -1
+}
+gdb_load ${binfile}
+
+if ![runto_main] {
-+ untested vla
++ untested x86_64-vla-pointer
+ return -1
+}
+
-+gdb_breakpoint [gdb_get_line_number "break-here"]
-+
-+gdb_continue_to_breakpoint "break-here"
-+
-+gdb_test "whatis temp1" "type = char \\\[variable\\\]" "first: whatis temp1"
-+gdb_test "whatis temp2" "type = char \\\[variable\\\]" "first: whatis temp2"
-+gdb_test "whatis temp3" "type = char \\\[48\\\]" "first: whatis temp3"
++gdb_breakpoint "break_here"
+
-+gdb_test "ptype temp1" "type = char \\\[26\\\]" "first: ptype temp1"
-+gdb_test "ptype temp2" "type = char \\\[26\\\]" "first: ptype temp2"
-+gdb_test "ptype temp3" "type = char \\\[48\\\]" "first: ptype temp3"
++gdb_continue_to_breakpoint "break_here"
+
-+gdb_test "p temp1" " = '1' <repeats 26 times>" "first: print temp1"
-+gdb_test "p temp2" " = '2' <repeats 26 times>" "first: print temp2"
-+gdb_test "p temp3" " = '3' <repeats 48 times>" "first: print temp3"
++gdb_test "whatis array" "type = char \\(\\*\\)\\\[variable\\\]" "first: whatis array"
++gdb_test "ptype array" "type = char \\(\\*\\)\\\[26\\\]" "first: ptype array"
+
-+gdb_continue_to_breakpoint "break-here"
++gdb_test "whatis *array" "type = char \\\[26\\\]" "first: whatis *array"
++gdb_test "ptype *array" "type = char \\\[26\\\]" "first: ptype *array"
+
-+gdb_test "whatis temp1" "type = char \\\[variable\\\]" "second: whatis temp1"
-+gdb_test "whatis temp2" "type = char \\\[variable\\\]" "second: whatis temp2"
-+gdb_test "whatis temp3" "type = char \\\[48\\\]" "second: whatis temp3"
++gdb_test "p (*array)\[1\]" "\\$\[0-9\] = 1 '\\\\001'"
++gdb_test "p (*array)\[2\]" "\\$\[0-9\] = 2 '\\\\002'"
++gdb_test "p (*array)\[3\]" "\\$\[0-9\] = 3 '\\\\003'"
++gdb_test "p (*array)\[4\]" "\\$\[0-9\] = 4 '\\\\004'"
+
-+gdb_test "ptype temp1" "type = char \\\[78\\\]" "second: ptype temp1"
-+gdb_test "ptype temp2" "type = char \\\[78\\\]" "second: ptype temp2"
-+gdb_test "ptype temp3" "type = char \\\[48\\\]" "second: ptype temp3"
++gdb_continue_to_breakpoint "break_here"
+
-+gdb_test "p temp1" " = '1' <repeats 78 times>" "second: print temp1"
-+gdb_test "p temp2" " = '2' <repeats 78 times>" "second: print temp2"
-+gdb_test "p temp3" " = '3' <repeats 48 times>" "second: print temp3"
-diff --git a/gdb/testsuite/gdb.cp/nextoverthrow.exp b/gdb/testsuite/gdb.cp/nextoverthrow.exp
-index 7d4a0c5..2dafcab 100644
---- a/gdb/testsuite/gdb.cp/nextoverthrow.exp
-+++ b/gdb/testsuite/gdb.cp/nextoverthrow.exp
-@@ -54,6 +54,17 @@ gdb_test_multiple "print _Unwind_DebugHook" "check for unwinder hook" {
- }
- }
- if {!$ok} {
-+ gdb_test_multiple "info probe" "check for stap probe in unwinder" {
-+ -re ".*libgcc.*unwind.*\r\n$gdb_prompt $" {
-+ pass "check for stap probe in unwinder"
-+ set ok 1
-+ }
-+ -re "\r\n$gdb_prompt $" {
-+ }
-+ }
-+}
++gdb_test "whatis array" "type = char \\(\\*\\)\\\[variable\\\]" "second: whatis array"
++gdb_test "ptype array" "type = char \\(\\*\\)\\\[78\\\]" "second: ptype array"
+
-+if {!$ok} {
- unsupported "nextoverthrow.exp could not find _Unwind_DebugHook"
- return -1
- }
-diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.S b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.S
++gdb_test "whatis *array" "type = char \\\[78\\\]" "second: whatis *array"
++gdb_test "ptype *array" "type = char \\\[78\\\]" "second: ptype *array"
+diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S
+new file mode 100644
+index 0000000..66f7a39
+--- /dev/null
++++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S
+@@ -0,0 +1,455 @@
++ .file "x86_64-vla-typedef.c"
++ .section .debug_abbrev,"",@progbits
++.Ldebug_abbrev0:
++ .section .debug_info,"",@progbits
++.Ldebug_info0:
++ .section .debug_line,"",@progbits
++.Ldebug_line0:
++ .text
++.Ltext0:
++.globl foo
++ .type foo, @function
++foo:
++.LFB2:
++ .file 1 "x86_64-vla-typedef.c"
++ .loc 1 22 0
++ pushq %rbp
++.LCFI0:
++ movq %rsp, %rbp
++.LCFI1:
++ subq $64, %rsp
++.LCFI2:
++ movl %edi, -36(%rbp)
++ .loc 1 22 0
++ movq %rsp, %rax
++ movq %rax, -48(%rbp)
++ .loc 1 23 0
++ movl -36(%rbp), %edx
++ movslq %edx,%rax
++ subq $1, %rax
++ movq %rax, -24(%rbp)
++ .loc 1 24 0
++ movslq %edx,%rax
++ addq $15, %rax
++ addq $15, %rax
++ shrq $4, %rax
++ salq $4, %rax
++ subq %rax, %rsp
++ movq %rsp, -56(%rbp)
++ movq -56(%rbp), %rax
++ addq $15, %rax
++ shrq $4, %rax
++ salq $4, %rax
++ movq %rax, -56(%rbp)
++ movq -56(%rbp), %rax
++ movq %rax, -16(%rbp)
++ .loc 1 27 0
++ movl $0, -4(%rbp)
++ jmp .L2
++.L3:
++ .loc 1 28 0
++ movl -4(%rbp), %esi
++ movl -4(%rbp), %eax
++ movl %eax, %ecx
++ movq -16(%rbp), %rdx
++ movslq %esi,%rax
++ movb %cl, (%rdx,%rax)
++ .loc 1 27 0
++ addl $1, -4(%rbp)
++.L2:
++ movl -4(%rbp), %eax
++ cmpl -36(%rbp), %eax
++ jl .L3
++ .loc 1 30 0
++ .globl break_here
++break_here:
++ movq -16(%rbp), %rax
++ movb $0, (%rax)
++ movq -48(%rbp), %rsp
++ .loc 1 31 0
++ leave
++ ret
++.LFE2:
++ .size foo, .-foo
++ .section .debug_frame,"",@progbits
++.Lframe0:
++ .long .LECIE0-.LSCIE0
++.LSCIE0:
++ .long 0xffffffff
++ .byte 0x1
++ .string ""
++ .uleb128 0x1
++ .sleb128 -8
++ .byte 0x10
++ .byte 0xc
++ .uleb128 0x7
++ .uleb128 0x8
++ .byte 0x90
++ .uleb128 0x1
++ .align 8
++.LECIE0:
++.LSFDE0:
++ .long .LEFDE0-.LASFDE0
++.LASFDE0:
++ .long .Lframe0
++ .quad .LFB2
++ .quad .LFE2-.LFB2
++ .byte 0x4
++ .long .LCFI0-.LFB2
++ .byte 0xe
++ .uleb128 0x10
++ .byte 0x86
++ .uleb128 0x2
++ .byte 0x4
++ .long .LCFI1-.LCFI0
++ .byte 0xd
++ .uleb128 0x6
++ .align 8
++.LEFDE0:
++ .section .eh_frame,"a",@progbits
++.Lframe1:
++ .long .LECIE1-.LSCIE1
++.LSCIE1:
++ .long 0x0
++ .byte 0x1
++ .string "zR"
++ .uleb128 0x1
++ .sleb128 -8
++ .byte 0x10
++ .uleb128 0x1
++ .byte 0x3
++ .byte 0xc
++ .uleb128 0x7
++ .uleb128 0x8
++ .byte 0x90
++ .uleb128 0x1
++ .align 8
++.LECIE1:
++.LSFDE1:
++ .long .LEFDE1-.LASFDE1
++.LASFDE1:
++ .long .LASFDE1-.Lframe1
++ .long .LFB2
++ .long .LFE2-.LFB2
++ .uleb128 0x0
++ .byte 0x4
++ .long .LCFI0-.LFB2
++ .byte 0xe
++ .uleb128 0x10
++ .byte 0x86
++ .uleb128 0x2
++ .byte 0x4
++ .long .LCFI1-.LCFI0
++ .byte 0xd
++ .uleb128 0x6
++ .align 8
++.LEFDE1:
++ .text
++.Letext0:
++ .section .debug_loc,"",@progbits
++.Ldebug_loc0:
++.LLST0:
++ .quad .LFB2-.Ltext0
++ .quad .LCFI0-.Ltext0
++ .value 0x2
++ .byte 0x77
++ .sleb128 8
++ .quad .LCFI0-.Ltext0
++ .quad .LCFI1-.Ltext0
++ .value 0x2
++ .byte 0x77
++ .sleb128 16
++ .quad .LCFI1-.Ltext0
++ .quad .LFE2-.Ltext0
++ .value 0x2
++ .byte 0x76
++ .sleb128 16
++ .quad 0x0
++ .quad 0x0
++ .section .debug_info
++ .long .Ldebug_end - .Ldebug_start
++.Ldebug_start:
++ .value 0x2
++ .long .Ldebug_abbrev0
++ .byte 0x8
++ .uleb128 0x1
++ .long .LASF2
++ .byte 0x1
++ .long .LASF3
++ .long .LASF4
++ .quad .Ltext0
++ .quad .Letext0
++ .long .Ldebug_line0
++ .uleb128 0x2
++ .byte 0x1
++ .string "foo"
++ .byte 0x1
++ .byte 0x16
++ .byte 0x1
++ .quad .LFB2
++ .quad .LFE2
++ .long .LLST0
++ .long 0x83
++ .uleb128 0x3
++ .long .LASF5
++ .byte 0x1
++ .byte 0x15
++ .long 0x83
++ .byte 0x2
++ .byte 0x91
++ .sleb128 -52
++.Ltag_typedef:
++ .uleb128 0x4
++ .long .LASF6
++ .byte 0x1
++ .byte 0x17
++ .long .Ltag_array_type - .debug_info
++ .uleb128 0x5 /* Abbrev Number: 5 (DW_TAG_variable) */
++ .long .LASF0
++ .byte 0x1
++ .byte 0x18
++#if 1
++ .long .Ltag_typedef - .debug_info
++#else
++ /* Debugging only: Skip the typedef indirection. */
++ .long .Ltag_array_type - .debug_info
++#endif
++ /* DW_AT_location: DW_FORM_block1: start */
++ .byte 0x3
++ .byte 0x91
++ .sleb128 -32
++#if 0
++ .byte 0x6 /* DW_OP_deref */
++#else
++ .byte 0x96 /* DW_OP_nop */
++#endif
++ /* DW_AT_location: DW_FORM_block1: end */
++ .uleb128 0x6
++ .string "i"
++ .byte 0x1
++ .byte 0x19
++ .long 0x83
++ .byte 0x2
++ .byte 0x91
++ .sleb128 -20
++ .byte 0x0
++ .uleb128 0x7
++ .byte 0x4
++ .byte 0x5
++ .string "int"
++.Ltag_array_type:
++ .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */
++ .long 0xa0 + (2f - 1f) /* DW_AT_type: DW_FORM_ref4 */
++ .long 0x9d + (2f - 1f) /* DW_AT_sibling: DW_FORM_ref4 */
++1: /* DW_AT_data_location: DW_FORM_block1: start */
++ .byte 2f - 3f /* length */
++3:
++ .byte 0x97 /* DW_OP_push_object_address */
++ .byte 0x6 /* DW_OP_deref */
++2: /* DW_AT_data_location: DW_FORM_block1: end */
++ .uleb128 0x9
++ .long 0x9d + (2b - 1b) /* DW_AT_type: DW_FORM_ref4 */
++ .byte 0x3
++ .byte 0x91
++ .sleb128 -40
++ .byte 0x6
++ .byte 0x0
++ .uleb128 0xa
++ .byte 0x8
++ .byte 0x7
++ .uleb128 0xb
++ .byte 0x1
++ .byte 0x6
++ .long .LASF1
++ .byte 0x0
++.Ldebug_end:
++ .section .debug_abbrev
++ .uleb128 0x1
++ .uleb128 0x11
++ .byte 0x1
++ .uleb128 0x25
++ .uleb128 0xe
++ .uleb128 0x13
++ .uleb128 0xb
++ .uleb128 0x3
++ .uleb128 0xe
++ .uleb128 0x1b
++ .uleb128 0xe
++ .uleb128 0x11
++ .uleb128 0x1
++ .uleb128 0x12
++ .uleb128 0x1
++ .uleb128 0x10
++ .uleb128 0x6
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x2
++ .uleb128 0x2e
++ .byte 0x1
++ .uleb128 0x3f
++ .uleb128 0xc
++ .uleb128 0x3
++ .uleb128 0x8
++ .uleb128 0x3a
++ .uleb128 0xb
++ .uleb128 0x3b
++ .uleb128 0xb
++ .uleb128 0x27
++ .uleb128 0xc
++ .uleb128 0x11
++ .uleb128 0x1
++ .uleb128 0x12
++ .uleb128 0x1
++ .uleb128 0x40
++ .uleb128 0x6
++ .uleb128 0x1
++ .uleb128 0x13
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x3
++ .uleb128 0x5
++ .byte 0x0
++ .uleb128 0x3
++ .uleb128 0xe
++ .uleb128 0x3a
++ .uleb128 0xb
++ .uleb128 0x3b
++ .uleb128 0xb
++ .uleb128 0x49
++ .uleb128 0x13
++ .uleb128 0x2
++ .uleb128 0xa
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x4
++ .uleb128 0x16
++ .byte 0x0
++ .uleb128 0x3
++ .uleb128 0xe
++ .uleb128 0x3a
++ .uleb128 0xb
++ .uleb128 0x3b
++ .uleb128 0xb
++ .uleb128 0x49
++ .uleb128 0x13
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x5
++ .uleb128 0x34
++ .byte 0x0
++ .uleb128 0x3
++ .uleb128 0xe
++ .uleb128 0x3a
++ .uleb128 0xb
++ .uleb128 0x3b
++ .uleb128 0xb
++ .uleb128 0x49
++ .uleb128 0x13
++ .uleb128 0x2
++ .uleb128 0xa
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x6
++ .uleb128 0x34
++ .byte 0x0
++ .uleb128 0x3
++ .uleb128 0x8
++ .uleb128 0x3a
++ .uleb128 0xb
++ .uleb128 0x3b
++ .uleb128 0xb
++ .uleb128 0x49
++ .uleb128 0x13
++ .uleb128 0x2
++ .uleb128 0xa
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x7
++ .uleb128 0x24
++ .byte 0x0
++ .uleb128 0xb
++ .uleb128 0xb
++ .uleb128 0x3e
++ .uleb128 0xb
++ .uleb128 0x3
++ .uleb128 0x8
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */
++ .uleb128 0x1
++ .byte 0x1
++ .uleb128 0x49 /* DW_AT_type */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .uleb128 0x1 /* DW_AT_sibling */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .uleb128 0x50 /* DW_AT_data_location */
++ .uleb128 0xa /* DW_FORM_block1 */
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0x9
++ .uleb128 0x21
++ .byte 0x0
++ .uleb128 0x49 /* DW_AT_type */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .uleb128 0x2f
++ .uleb128 0xa
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0xa
++ .uleb128 0x24
++ .byte 0x0
++ .uleb128 0xb
++ .uleb128 0xb
++ .uleb128 0x3e
++ .uleb128 0xb
++ .byte 0x0
++ .byte 0x0
++ .uleb128 0xb
++ .uleb128 0x24
++ .byte 0x0
++ .uleb128 0xb
++ .uleb128 0xb
++ .uleb128 0x3e
++ .uleb128 0xb
++ .uleb128 0x3
++ .uleb128 0xe
++ .byte 0x0
++ .byte 0x0
++ .byte 0x0
++ .section .debug_pubnames,"",@progbits
++ .long 0x16
++ .value 0x2
++ .long .Ldebug_info0
++ .long 0xa8
++ .long 0x2d
++ .string "foo"
++ .long 0x0
++ .section .debug_aranges,"",@progbits
++ .long 0x2c
++ .value 0x2
++ .long .Ldebug_info0
++ .byte 0x8
++ .byte 0x0
++ .value 0x0
++ .value 0x0
++ .quad .Ltext0
++ .quad .Letext0-.Ltext0
++ .quad 0x0
++ .quad 0x0
++ .section .debug_str,"MS",@progbits,1
++.LASF0:
++ .string "array"
++.LASF5:
++ .string "size"
++.LASF3:
++ .string "x86_64-vla-typedef.c"
++.LASF6:
++ .string "array_t"
++.LASF1:
++ .string "char"
++.LASF4:
++ .string "gdb.arch"
++.LASF2:
++ .string "GNU C 4.3.2 20081105 (Red Hat 4.3.2-7)"
++ .ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)"
++ .section .note.GNU-stack,"",@progbits
+diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c
new file mode 100644
-index 0000000..aac3baa
+index 0000000..b809c4e
--- /dev/null
-+++ b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.S
-@@ -0,0 +1,246 @@
++++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c
+@@ -0,0 +1,43 @@
+/* This testcase is part of GDB, the GNU debugger.
+
-+ Copyright 2010 Free Software Foundation, Inc.
++ 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
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
-+/* Debug information */
-+
-+/* We will `break *main' at the very first instruction. */
-+#define main_length 1
-+
-+ .section .data
-+vardata:
-+ /* See DW_OP_lit3 + 1 (0-based). */
-+ .string "seennotseen"
-+
-+ .section .debug_info
-+.Lcu1_begin:
-+ .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */
-+.Lcu1_start:
-+ .2byte 2 /* DWARF version number */
-+ .4byte .Ldebug_abbrev0 /* Offset Into Abbrev. Section */
-+ .byte 4 /* Pointer Size (in bytes) */
-+
-+ /* CU die */
-+ .uleb128 1 /* Abbrev: DW_TAG_compile_unit */
-+ .4byte .Lproducer /* DW_AT_producer */
-+ /* Use C++ to exploit a bug in parsing DW_AT_name "". */
-+ .byte 4 /* DW_AT_language (C++) - */
-+ .4byte main /* DW_AT_low_pc */
-+ .byte main_length /* DW_AT_high_pc */
-+
-+.Larray_type:
-+ .uleb128 2 /* Abbrev: DW_TAG_array_type */
-+ .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */
-+
-+ .uleb128 3 /* Abbrev: DW_TAG_subrange_type */
-+ .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */
-+ .byte 0 /* DW_AT_lower_bound */
-+ .4byte .Llen_var-.Lcu1_begin /* DW_AT_upper_bound */
-+ .byte 0 /* End of children of die */
-+
-+ /* DW_AT_upper_bound is referencing an optimized-out variable. */
-+.Larrayb_type:
-+ .uleb128 2 /* Abbrev: DW_TAG_array_type */
-+ .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */
-+
-+ .uleb128 3 /* Abbrev: DW_TAG_subrange_type */
-+ .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */
-+ .byte 0 /* DW_AT_lower_bound */
-+ .4byte .Llenb_var-.Lcu1_begin /* DW_AT_upper_bound */
-+ .byte 0 /* End of children of die */
-+
-+ /* DW_AT_upper_bound is referencing register. */
-+.Larrayreg_type:
-+ .uleb128 2 /* Abbrev: DW_TAG_array_type */
-+ .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */
-+
-+ .uleb128 8 /* Abbrev: DW_TAG_subrange_type with block */
-+ .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */
-+ .byte 0 /* DW_AT_lower_bound */
-+ .byte 2f - 1f /* DW_AT_upper_bound */
-+1: .byte 0x50 /* DW_OP_reg0 */
-+2:
-+ .byte 0 /* End of children of die */
-+
-+.Luint_type:
-+ .uleb128 4 /* Abbrev: DW_TAG_base_type */
-+ .4byte .Luint_str /* DW_AT_name */
-+ .byte 4 /* DW_AT_byte_size */
-+ .byte 7 /* DW_AT_encoding */
-+
-+.Lchar_type:
-+ .uleb128 4 /* Abbrev: DW_TAG_base_type */
-+ .4byte .Lchar_str /* DW_AT_name */
-+ .byte 1 /* DW_AT_byte_size */
-+ .byte 6 /* DW_AT_encoding */
-+
-+.Llen_var:
-+ .uleb128 5 /* Abbrev: DW_TAG_variable artificial */
-+ .byte 1 /* DW_AT_artificial */
-+ .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */
-+ .4byte .Llen_loclist-.Lloclist /* DW_AT_location */
-+
-+ /* optimized-out variable for b_string. */
-+.Llenb_var:
-+ .uleb128 7 /* Abbrev: DW_TAG_variable artificial no DW_AT_location */
-+ .byte 1 /* DW_AT_artificial */
-+ .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */
-+
-+ .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */
-+ .string "a_string" /* DW_AT_name */
-+ .4byte .Larray_type-.Lcu1_begin /* DW_AT_type */
-+ .byte 2f - 1f /* DW_AT_location */
-+1: .byte 3 /* DW_OP_addr */
-+ .4byte vardata /* <addr> */
-+2:
-+
-+ /* DW_AT_upper_bound is referencing an optimized-out variable. */
-+ .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */
-+ .string "b_string" /* DW_AT_name */
-+ .4byte .Larrayb_type-.Lcu1_begin /* DW_AT_type */
-+ .byte 2f - 1f /* DW_AT_location */
-+1: .byte 3 /* DW_OP_addr */
-+ .4byte vardata /* <addr> */
-+2:
-+
-+ /* DW_AT_upper_bound is referencing register. */
-+ .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */
-+ .string "reg_string" /* DW_AT_name */
-+ .4byte .Larrayreg_type-.Lcu1_begin /* DW_AT_type */
-+ .byte 2f - 1f /* DW_AT_location */
-+1: .byte 3 /* DW_OP_addr */
-+ .4byte vardata /* <addr> */
-+2:
-+
-+ .byte 0 /* End of children of CU */
-+.Lcu1_end:
-+
-+ .section .debug_loc
-+.Lloclist:
-+.Llen_loclist:
-+ .4byte 0 # Location list begin address
-+ .4byte main_length # Location list end address
-+ .value 2f-1f # Location expression size
-+1: .byte 0x33 # DW_OP_lit3
-+ .byte 0x9f # DW_OP_stack_value
-+2:
-+ .quad 0x0 # Location list terminator begin (*.LLST2)
-+ .quad 0x0 # Location list terminator end (*.LLST2)
-+
-+ .section .debug_abbrev
-+.Ldebug_abbrev0:
-+ .uleb128 1 /* Abbrev code */
-+ .uleb128 0x11 /* DW_TAG_compile_unit */
-+ .byte 0x1 /* has_children */
-+ .uleb128 0x25 /* DW_AT_producer */
-+ .uleb128 0xe /* DW_FORM_strp */
-+ .uleb128 0x13 /* DW_AT_language */
-+ .uleb128 0xb /* DW_FORM_data1 */
-+ .uleb128 0x11 /* DW_AT_low_pc */
-+ .uleb128 0x1 /* DW_FORM_addr */
-+ .uleb128 0x12 /* DW_AT_high_pc */
-+ .uleb128 0xb /* DW_FORM_data1 */
-+ .byte 0x0 /* Terminator */
-+ .byte 0x0 /* Terminator */
-+
-+ .uleb128 2 /* Abbrev code */
-+ .uleb128 0x1 /* TAG: DW_TAG_array_type */
-+ .byte 0x1 /* DW_children_yes */
-+ .uleb128 0x49 /* DW_AT_type */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .byte 0x0 /* Terminator */
-+ .byte 0x0 /* Terminator */
-+
-+ .uleb128 3 /* Abbrev code */
-+ .uleb128 0x21 /* DW_TAG_subrange_type */
-+ .byte 0x0 /* no children */
-+ .uleb128 0x49 /* DW_AT_type */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .uleb128 0x22 /* DW_AT_lower_bound */
-+ .uleb128 0xb /* DW_FORM_data1 */
-+ .uleb128 0x2f /* DW_AT_upper_bound */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .byte 0x0 /* Terminator */
-+ .byte 0x0 /* Terminator */
-+
-+ .uleb128 4 /* Abbrev code */
-+ .uleb128 0x24 /* DW_TAG_base_type */
-+ .byte 0x0 /* no_children */
-+ .uleb128 0x3 /* DW_AT_name */
-+ .uleb128 0xe /* DW_FORM_strp */
-+ .uleb128 0xb /* DW_AT_byte_size */
-+ .uleb128 0xb /* DW_FORM_data1 */
-+ .uleb128 0x3e /* DW_AT_encoding */
-+ .uleb128 0xb /* DW_FORM_data1 */
-+ .byte 0x0 /* Terminator */
-+ .byte 0x0 /* Terminator */
++#if 0
+
-+ .uleb128 5 /* Abbrev code */
-+ .uleb128 0x34 /* DW_TAG_variable */
-+ .byte 0x0 /* no_children */
-+ .uleb128 0x34 /* DW_AT_artificial */
-+ .uleb128 0x0c /* DW_FORM_flag */
-+ .uleb128 0x49 /* DW_AT_type */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .uleb128 0x02 /* DW_AT_location */
-+ .uleb128 0x06 /* DW_FORM_data4 */
-+ .byte 0x0 /* Terminator */
-+ .byte 0x0 /* Terminator */
++void
++foo (int size)
++{
++ typedef char array_t[size];
++ array_t array;
++ int i;
+
-+ .uleb128 6 /* Abbrev code */
-+ .uleb128 0x34 /* DW_TAG_variable */
-+ .byte 0x0 /* no_children */
-+ .uleb128 0x3 /* DW_AT_name */
-+ .uleb128 0x8 /* DW_FORM_string */
-+ .uleb128 0x49 /* DW_AT_type */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .uleb128 0x2 /* DW_AT_location */
-+ .uleb128 0xa /* DW_FORM_block1 */
-+ .byte 0x0 /* Terminator */
-+ .byte 0x0 /* Terminator */
++ for (i = 0; i < size; i++)
++ array[i] = i;
+
-+ .uleb128 7 /* Abbrev code */
-+ .uleb128 0x34 /* DW_TAG_variable */
-+ .byte 0x0 /* no_children */
-+ .uleb128 0x34 /* DW_AT_artificial */
-+ .uleb128 0x0c /* DW_FORM_flag */
-+ .uleb128 0x49 /* DW_AT_type */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .byte 0x0 /* Terminator */
-+ .byte 0x0 /* Terminator */
++ array[0] = 0; /* break-here */
++}
+
-+ .uleb128 8 /* Abbrev code */
-+ .uleb128 0x21 /* DW_TAG_subrange_type with block */
-+ .byte 0x0 /* no children */
-+ .uleb128 0x49 /* DW_AT_type */
-+ .uleb128 0x13 /* DW_FORM_ref4 */
-+ .uleb128 0x22 /* DW_AT_lower_bound */
-+ .uleb128 0xb /* DW_FORM_data1 */
-+ .uleb128 0x2f /* DW_AT_upper_bound */
-+ .uleb128 0xa /* DW_FORM_block1 */
-+ .byte 0x0 /* Terminator */
-+ .byte 0x0 /* Terminator */
++#else
+
-+ .byte 0x0 /* Terminator */
++int
++main (void)
++{
++ foo (26);
++ foo (78);
++ return 0;
++}
+
-+/* String table */
-+ .section .debug_str
-+.Lproducer:
-+ .string "GNU C 3.3.3"
-+.Lchar_str:
-+ .string "char"
-+.Luint_str:
-+ .string "unsigned int"
-diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.exp b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.exp
++#endif
+diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp
new file mode 100644
-index 0000000..815ed93
+index 0000000..b05411e
--- /dev/null
-+++ b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.exp
-@@ -0,0 +1,54 @@
-+# Copyright 2010 Free Software Foundation, Inc.
++++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp
+@@ -0,0 +1,64 @@
++# Copyright 2009 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
-+# Test printing variable with dynamic bounds which reference a different
-+# (artificial in the GCC case) variable containing loclist as its location.
-+# This testcase uses value (not address) of the referenced variable:
-+# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43762
++# Test DW_AT_data_location accessed through DW_TAG_typedef intermediate.
+
-+# This test can only be run on targets which support DWARF-2 and use gas.
-+# For now pick a sampling of likely targets.
-+if {![istarget *-*-linux*]
-+ && ![istarget *-*-gnu*]
-+ && ![istarget *-*-elf*]
-+ && ![istarget *-*-openbsd*]
-+ && ![istarget arm-*-eabi*]
-+ && ![istarget powerpc-*-eabi*]} {
-+ return 0
++if ![istarget "x86_64-*-*"] then {
++ verbose "Skipping over gdb.arch/x86_64-vla-typedef.exp test made only for x86_64."
++ return
+}
+
-+set testfile dw2-bound-loclist
-+if { [prepare_for_testing ${testfile}.exp ${testfile} [list ${testfile}.S main.c] {}] } {
++set testfile x86_64-vla-typedef
++set srcasmfile ${testfile}-foo.S
++set srcfile ${testfile}.c
++set binfile ${objdir}/${subdir}/${testfile}
++set binobjfile ${objdir}/${subdir}/${testfile}-foo.o
++if { [gdb_compile "${srcdir}/${subdir}/${srcasmfile}" "${binobjfile}" object {}] != "" } {
++ untested "Couldn't compile test program"
++ return -1
++}
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${binobjfile}" "${binfile}" executable {debug}] != "" } {
++ untested "Couldn't compile test program"
+ return -1
+}
+
-+# Verify it behaves at least as an unbound array without inferior.
-+
-+gdb_test "p a_string" { = 0x[0-9a-f]+ "seennotseen"}
-+gdb_test "ptype a_string" {type = char \[\]}
++gdb_exit
++gdb_start
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_load ${binfile}
+
-+# Not runto_main as dw2-bound-loclist.S handles only the first byte of main.
-+if ![runto "*main"] {
++if ![runto_main] {
++ untested x86_64-vla-typedef
+ return -1
+}
+
-+gdb_test "p a_string" { = "seen"}
-+gdb_test "ptype a_string" {type = char \[4\]}
++gdb_breakpoint "break_here"
+
-+gdb_test "p b_string" { = (0x[0-9a-f]+ )?"seennotseen"}
-+gdb_test "ptype b_string" {type = char \[\]}
++gdb_continue_to_breakpoint "break_here"
+
-+# The register contains unpredictable value - the array size.
-+gdb_test "ptype reg_string" {type = char \[-?[0-9]+\]}
-diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.c b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c
++gdb_test "whatis array" "type = array_t" "first: whatis array"
++
++gdb_test "ptype array" "type = char \\\[26\\\]" "first: ptype array"
++
++gdb_test "p array\[1\]" "\\$\[0-9\] = 1 '\\\\001'"
++gdb_test "p array\[2\]" "\\$\[0-9\] = 2 '\\\\002'"
++gdb_test "p array\[3\]" "\\$\[0-9\] = 3 '\\\\003'"
++gdb_test "p array\[4\]" "\\$\[0-9\] = 4 '\\\\004'"
++
++gdb_continue_to_breakpoint "break_here"
++
++gdb_test "whatis array" "type = array_t" "second: whatis array"
++
++gdb_test "ptype array" "type = char \\\[78\\\]" "second: ptype array"
+diff --git a/gdb/testsuite/gdb.base/arrayidx.c b/gdb/testsuite/gdb.base/arrayidx.c
+index a99137e..c3dc2d9 100644
+--- a/gdb/testsuite/gdb.base/arrayidx.c
++++ b/gdb/testsuite/gdb.base/arrayidx.c
+@@ -17,6 +17,13 @@
+
+ int array[] = {1, 2, 3, 4};
+
++#ifdef __GNUC__
++struct
++ {
++ int a[0];
++ } unbound;
++#endif
++
+ int
+ main (void)
+ {
+diff --git a/gdb/testsuite/gdb.base/arrayidx.exp b/gdb/testsuite/gdb.base/arrayidx.exp
+index cba0024..0dc0e46 100644
+--- a/gdb/testsuite/gdb.base/arrayidx.exp
++++ b/gdb/testsuite/gdb.base/arrayidx.exp
+@@ -53,4 +53,12 @@ gdb_test "print array" \
+ "\\{\\\[0\\\] = 1, \\\[1\\\] = 2, \\\[2\\\] = 3, \\\[3\\\] = 4\\}" \
+ "Print array with array-indexes on"
+
+-
++set test "p unbound.a == &unbound.a\[0\]"
++gdb_test_multiple $test $test {
++ -re " = 1\r\n$gdb_prompt $" {
++ pass $test
++ }
++ -re "No symbol \"unbound\" in current context.\r\n$gdb_prompt $" {
++ unsupported "$test (no GCC)"
++ }
++}
+diff --git a/gdb/testsuite/gdb.base/internal-var-field-address.c b/gdb/testsuite/gdb.base/internal-var-field-address.c
new file mode 100644
-index 0000000..1f02d90
+index 0000000..eeb7b85
--- /dev/null
-+++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c
-@@ -0,0 +1,42 @@
++++ b/gdb/testsuite/gdb.base/internal-var-field-address.c
+@@ -0,0 +1,20 @@
+/* This testcase is part of GDB, the GNU debugger.
+
-+ Copyright 2004 Free Software Foundation, Inc.
++ Copyright 2009 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2 of the License, or
++ 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, write to the Free Software
-+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ USA. */
++ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
++struct {
++ int field;
++} staticstruct = { 1 };
+diff --git a/gdb/testsuite/gdb.base/internal-var-field-address.exp b/gdb/testsuite/gdb.base/internal-var-field-address.exp
+new file mode 100644
+index 0000000..6d82e73
+--- /dev/null
++++ b/gdb/testsuite/gdb.base/internal-var-field-address.exp
+@@ -0,0 +1,26 @@
++# Copyright 2009 Free Software Foundation, Inc.
+
-+/* The function `func1' traced into must have debug info on offset > 0;
-+ (DW_UNSND (attr)). This is the reason of `func0' existence. */
++# 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/>.
+
-+void
-+func0(int a, int b)
-+{
++set test internal-var-field-address
++set binfile ${test}.x
++if { [gdb_compile "${srcdir}/${subdir}/${test}.c" "${objdir}/${subdir}/${binfile}" object {debug}] != "" } {
++ untested "Couldn't compile test program"
++ return -1
+}
+
-+/* `func1' being traced into must have some arguments to dump. */
++clean_restart $binfile
+
-+void
-+func1(int a, int b)
-+{
-+ func0 (a,b);
-+}
++gdb_test {set $varstruct = staticstruct}
++gdb_test {p $varstruct.field} " = 1"
+diff --git a/gdb/testsuite/gdb.base/vla-frame.c b/gdb/testsuite/gdb.base/vla-frame.c
+new file mode 100644
+index 0000000..5750f68
+--- /dev/null
++++ b/gdb/testsuite/gdb.base/vla-frame.c
+@@ -0,0 +1,31 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++ Copyright 2011 Free Software Foundation, Inc.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 3 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program. If not, see <http://www.gnu.org/licenses/>. */
++
++#include <string.h>
+
+int
-+main(void)
++main (int argc, char **argv)
+{
-+ func1 (1, 2);
++ char s[2 + argc];
++ void (*f) (char *) = 0;
++
++ memset (s, 0, sizeof (s));
++ s[0] = 'X';
++
++ f (s);
+ return 0;
+}
-diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp
+diff --git a/gdb/testsuite/gdb.base/vla-frame.exp b/gdb/testsuite/gdb.base/vla-frame.exp
new file mode 100644
-index 0000000..1c6e84a
+index 0000000..47736c7
--- /dev/null
-+++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp
-@@ -0,0 +1,79 @@
-+# Copyright 2006 Free Software Foundation, Inc.
-+
++++ b/gdb/testsuite/gdb.base/vla-frame.exp
+@@ -0,0 +1,38 @@
++# Copyright 2011 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
++# 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, write to the Free Software
-+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+# Minimal DWARF-2 unit test
-+
-+# This test can only be run on targets which support DWARF-2.
-+# For now pick a sampling of likely targets.
-+if {![istarget *-*-linux*]
-+ && ![istarget *-*-gnu*]
-+ && ![istarget *-*-elf*]
-+ && ![istarget *-*-openbsd*]
-+ && ![istarget arm-*-eabi*]
-+ && ![istarget powerpc-*-eabi*]} {
-+ return 0
-+}
-+
-+set testfile "dw2-stripped"
-+set srcfile ${testfile}.c
-+set binfile ${objdir}/${subdir}/${testfile}.x
-+
-+remote_exec build "rm -f ${binfile}"
-+
-+# get the value of gcc_compiled
-+if [get_compiler_info ${binfile}] {
-+ return -1
-+}
++# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
-+# This test can only be run on gcc as we use additional_flags=FIXME
-+if {$gcc_compiled == 0} {
-+ return 0
-+}
++set testfile vla-frame
++set executable ${testfile}
+
-+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-ggdb3}] != "" } {
++if { [prepare_for_testing ${testfile}.exp ${executable}] } {
+ return -1
+}
+
-+remote_exec build "objcopy -R .debug_loc ${binfile}"
-+set strip_output [remote_exec build "objdump -h ${binfile}"]
-+
-+set test "stripping test file preservation"
-+if [ regexp ".debug_info " $strip_output] {
-+ pass "$test (.debug_info preserved)"
-+} else {
-+ fail "$test (.debug_info got also stripped)"
++if ![runto_main] {
++ return -1
+}
+
-+set test "stripping test file functionality"
-+if [ regexp ".debug_loc " $strip_output] {
-+ fail "$test (.debug_loc still present)"
-+} else {
-+ pass "$test (.debug_loc stripped)"
++set test "continue"
++gdb_test_multiple $test $test {
++ -re "Continuing\\.\r\n\r\nProgram received signal SIGSEGV, Segmentation fault\\.\r\n0x0+ in \\?\\? \\(\\)\r\n$gdb_prompt $" {
++ pass $test
++ }
++ -re "\r\n$gdb_prompt $" {
++ untested ${testfile}.exp
++ return
++ }
+}
+
-+gdb_exit
-+gdb_start
-+gdb_reinitialize_dir $srcdir/$subdir
-+gdb_load ${binfile}
-+
-+# For C programs, "start" should stop in main().
-+
-+gdb_test "start" \
-+ ".*main \\(\\) at .*" \
-+ "start"
-+gdb_test "step" \
-+ "func.* \\(.*\\) at .*" \
-+ "step"
-diff --git a/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S
++gdb_test "bt full" "\r\n +s = \"X\\\\000\"\r\n.*"
+diff --git a/gdb/testsuite/gdb.base/vla-overflow.c b/gdb/testsuite/gdb.base/vla-overflow.c
new file mode 100644
-index 0000000..5fcdd84
+index 0000000..c5d5ee0
--- /dev/null
-+++ b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S
-@@ -0,0 +1,83 @@
++++ b/gdb/testsuite/gdb.base/vla-overflow.c
+@@ -0,0 +1,30 @@
+/* This testcase is part of GDB, the GNU debugger.
+
-+ Copyright 2009 Free Software Foundation, Inc.
++ 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
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
-+/* Debug information */
-+
-+ .section .debug_info
-+.Lcu1_begin:
-+ /* CU header */
-+ .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */
-+.Lcu1_start:
-+ .2byte 2 /* DWARF Version */
-+ .4byte .Labbrev1_begin /* Offset into abbrev section */
-+ .byte 4 /* Pointer size */
-+
-+ /* CU die */
-+ .uleb128 1 /* Abbrev: DW_TAG_compile_unit */
-+ .ascii "dw2-struct-member-data-location.c\0" /* DW_AT_name */
-+ .ascii "GNU C 4.3.2\0" /* DW_AT_producer */
-+ .byte 1 /* DW_AT_language (C) */
-+
-+.Ltype_uchar:
-+ .uleb128 2 /* Abbrev: DW_TAG_structure_type */
-+ .ascii "some_struct\0" /* DW_AT_name */
-+
-+ .uleb128 3 /* Abbrev: DW_TAG_member */
-+ .ascii "field\0" /* DW_AT_name */
-+ .byte 0 /* DW_AT_data_member_location */
-+
-+ .byte 0 /* End of children of some_struct */
-+
-+ .byte 0 /* End of children of CU */
-+
-+.Lcu1_end:
++#include <stdlib.h>
+
-+/* Abbrev table */
-+ .section .debug_abbrev
-+.Labbrev1_begin:
-+ .uleb128 1 /* Abbrev code */
-+ .uleb128 0x11 /* DW_TAG_compile_unit */
-+ .byte 1 /* has_children */
-+ .uleb128 0x3 /* DW_AT_name */
-+ .uleb128 0x8 /* DW_FORM_string */
-+ .uleb128 0x25 /* DW_AT_producer */
-+ .uleb128 0x8 /* DW_FORM_string */
-+ .uleb128 0x13 /* DW_AT_language */
-+ .uleb128 0xb /* DW_FORM_data1 */
-+ .byte 0x0 /* Terminator */
-+ .byte 0x0 /* Terminator */
++int
++main (int argc, char **argv)
++{
++ int array[argc];
+
-+ .uleb128 2 /* Abbrev code */
-+ .uleb128 0x13 /* DW_TAG_structure_type */
-+ .byte 1 /* has_children */
-+ .uleb128 0x3 /* DW_AT_name */
-+ .uleb128 0x8 /* DW_FORM_string */
-+ .byte 0x0 /* Terminator */
-+ .byte 0x0 /* Terminator */
++ array[0] = array[0];
+
-+ .uleb128 3 /* Abbrev code */
-+ .uleb128 0x0d /* DW_TAG_member */
-+ .byte 0 /* has_children */
-+ .uleb128 0x3 /* DW_AT_name */
-+ .uleb128 0x8 /* DW_FORM_string */
-+ .uleb128 0x38 /* DW_AT_data_member_location */
-+ .uleb128 0x0b /* DW_FORM_data1 */
-+ .byte 0x0 /* Terminator */
-+ .byte 0x0 /* Terminator */
++ abort ();
+
-+ .byte 0x0 /* Terminator */
-+ .byte 0x0 /* Terminator */
-diff --git a/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp
++ return 0;
++}
+diff --git a/gdb/testsuite/gdb.base/vla-overflow.exp b/gdb/testsuite/gdb.base/vla-overflow.exp
new file mode 100644
-index 0000000..c41151c
+index 0000000..24a608f
--- /dev/null
-+++ b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp
-@@ -0,0 +1,37 @@
-+# Copyright 2009 Free Software Foundation, Inc.
++++ b/gdb/testsuite/gdb.base/vla-overflow.exp
+@@ -0,0 +1,109 @@
++# 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
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
-+# This test can only be run on targets which support DWARF-2 and use gas.
-+# For now pick a sampling of likely targets.
-+if {![istarget *-*-linux*]
-+ && ![istarget *-*-gnu*]
-+ && ![istarget *-*-elf*]
-+ && ![istarget *-*-openbsd*]
-+ && ![istarget arm-*-eabi*]
-+ && ![istarget powerpc-*-eabi*]} {
-+ return 0
++# We could crash in:
++# #0 block_linkage_function (bl=0x0) at ../../gdb/block.c:69
++# #1 in dwarf_block_get_frame_base (...) at ../../gdb/dwarf2block.c:97
++# 97 framefunc = block_linkage_function (get_frame_block (frame, NULL));
++# #2 in execute_stack_op (...) at ../../gdb/dwarf2expr.c:496
++# #3 in dwarf_block_exec_core () at ../../gdb/dwarf2block.c:156
++# #4 dwarf_block_exec (...) at ../../gdb/dwarf2block.c:206
++# #5 in range_type_count_bound_internal (...) at ../../gdb/gdbtypes.c:1430
++# #6 in create_array_type (...) at ../../gdb/gdbtypes.c:840
++# ...
++# #21 in psymtab_to_symtab (...) at ../../gdb/symfile.c:292
++# ...
++# #29 in backtrace_command_1 () at ../../gdb/stack.c:1273
++
++set testfile vla-overflow
++set shfile ${objdir}/${subdir}/${testfile}-gdb.sh
++set srcfile ${testfile}.c
++set binfile ${objdir}/${subdir}/${testfile}
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
++ untested "Couldn't compile test program"
++ return -1
+}
+
-+set testfile "dw2-struct-member-data-location"
-+set srcfile ${testfile}.S
-+set binfile ${testfile}.x
++set f [open "|getconf PAGESIZE" "r"]
++gets $f pagesize
++close $f
+
-+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${binfile}" object {nodebug}] != "" } {
++gdb_exit
++gdb_start
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_load ${binfile}
++
++set pid_of_gdb [exp_pid -i [board_info host fileid]]
++
++if { [runto_main] < 0 } {
++ untested vla-overflow
+ return -1
+}
+
-+clean_restart $binfile
++# Get the GDB memory size when we stay at main.
+
-+gdb_test "ptype struct some_struct" "type = struct some_struct {\[\r\n \t\]*void field;\[\r\n \t\]*}"
-diff --git a/gdb/testsuite/gdb.fortran/dwarf-stride.exp b/gdb/testsuite/gdb.fortran/dwarf-stride.exp
-new file mode 100644
-index 0000000..d7b8bea
---- /dev/null
-+++ b/gdb/testsuite/gdb.fortran/dwarf-stride.exp
-@@ -0,0 +1,42 @@
-+# Copyright 2009 Free Software Foundation, Inc.
++proc memory_v_pages_get {} {
++ global pid_of_gdb pagesize
++ set fd [open "/proc/$pid_of_gdb/statm"]
++ gets $fd line
++ close $fd
++ # number of pages of virtual memory
++ scan $line "%d" drs
++ return $drs
++}
+
-+# 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.
++set pages_found [memory_v_pages_get]
+
-+# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
++# s390x with glibc-debuginfo.s390x installed used approx. 16MB.
++set mb_reserve 40
++verbose -log "pages_found = $pages_found, mb_reserve = $mb_reserve"
++set kb_found [expr $pages_found * $pagesize / 1024]
++set kb_permit [expr $kb_found + 1 * 1024 + $mb_reserve * 1024]
++verbose -log "kb_found = $kb_found, kb_permit = $kb_permit"
+
-+# This file is part of the gdb testsuite. Array element stride must not be
-+# specified in the number of elements but in a number of bytes instead.
-+# Original problem:
-+# (gdb) p c40pt(1)
-+# $1 = '0-hello', ' ' <repeats 33 times>
-+# (gdb) p c40pt(2)
-+# warning: Fortran array stride not divisible by the element size
++# Create the ulimit wrapper.
++set f [open $shfile "w"]
++puts $f "#! /bin/sh"
++puts $f "ulimit -v $kb_permit"
++puts $f "exec $GDB \"\$@\""
++close $f
++remote_exec host "chmod +x $shfile"
++
++gdb_exit
++set GDBold $GDB
++set GDB "$shfile"
++gdb_start
++set GDB $GDBold
++
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_load ${binfile}
++
++set pid_of_gdb [exp_pid -i [board_info host fileid]]
++
++# Check the size again after the second run.
++# We must not stop in main as it would cache `array' and never crash later.
++
++gdb_run_cmd
++
++verbose -log "kb_found before abort() = [expr [memory_v_pages_get] * $pagesize / 1024]"
+
-+set testfile dwarf-stride
-+set srcfile ${testfile}.f90
++gdb_test "" "Program received signal SIGABRT, Aborted..*" "Enter abort()"
+
-+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f90}] } {
-+ return -1
-+}
++verbose -log "kb_found in abort() = [expr [memory_v_pages_get] * $pagesize / 1024]"
+
-+if ![runto MAIN__] then {
-+ perror "couldn't run to breakpoint MAIN__"
-+ continue
-+}
++# `abort' can get expressed as `*__GI_abort'.
++gdb_test "bt" "in \[^ \]*abort \\(.* in main \\(.*" "Backtrace after abort()"
+
-+gdb_breakpoint [gdb_get_line_number "break-here"]
-+gdb_continue_to_breakpoint "break-here" ".*break-here.*"
-+gdb_test "p c40pt(1)" " = '0-hello.*"
-+gdb_test "p c40pt(2)" " = '1-hello.*"
-diff --git a/gdb/testsuite/gdb.fortran/dwarf-stride.f90 b/gdb/testsuite/gdb.fortran/dwarf-stride.f90
++verbose -log "kb_found in bt after abort() = [expr [memory_v_pages_get] * $pagesize / 1024]"
+diff --git a/gdb/testsuite/gdb.base/vla.c b/gdb/testsuite/gdb.base/vla.c
new file mode 100644
-index 0000000..e492b3a
+index 0000000..e1f3ed1
--- /dev/null
-+++ b/gdb/testsuite/gdb.fortran/dwarf-stride.f90
-@@ -0,0 +1,40 @@
-+! Copyright 2009 Free Software Foundation, Inc.
-+!
-+! This program is free software; you can redistribute it and/or modify
-+! it under the terms of the GNU General Public License as published by
-+! the Free Software Foundation; either version 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.
-+!
-+! File written by Alan Matsuoka.
++++ b/gdb/testsuite/gdb.base/vla.c
+@@ -0,0 +1,55 @@
++/* This testcase is part of GDB, the GNU debugger.
+
-+program repro
++ Copyright 2008 Free Software Foundation, Inc.
+
-+ type small_stride
-+ character*40 long_string
-+ integer small_pad
-+ end type small_stride
++ 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.
+
-+ type(small_stride), dimension (20), target :: unpleasant
-+ character*40, pointer, dimension(:):: c40pt
++ 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.
+
-+ integer i
++ You should have received a copy of the GNU General Public License
++ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
-+ do i = 0,19
-+ unpleasant(i+1)%small_pad = i+1
-+ unpleasant(i+1)%long_string = char (ichar('0') + i) // '-hello'
-+ end do
++#include <string.h>
+
-+ c40pt => unpleasant%long_string
++void
++marker (void)
++{
++}
+
-+ print *, c40pt ! break-here
++void
++bar (char *a, char *b, char *c, int size)
++{
++ memset (a, '1', size);
++ memset (b, '2', size);
++ memset (c, '3', 48);
++}
+
-+end program repro
-diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90 b/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90
-new file mode 100644
-index 0000000..261ce17
---- /dev/null
-+++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90
-@@ -0,0 +1,24 @@
-+! Copyright 2010 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>.
++void
++foo (int size)
++{
++ char temp1[size];
++ char temp3[48];
+
-+subroutine bar
-+ real :: dummy
-+ dummy = 1
-+end subroutine bar
-diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp b/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp
++ temp1[size - 1] = '\0';
++ {
++ char temp2[size];
++
++ bar (temp1, temp2, temp3, size);
++
++ marker (); /* break-here */
++ }
++}
++
++int
++main (void)
++{
++ foo (26);
++ foo (78);
++ return 0;
++}
+diff --git a/gdb/testsuite/gdb.base/vla.exp b/gdb/testsuite/gdb.base/vla.exp
new file mode 100644
-index 0000000..fa41b80
+index 0000000..5da7378
--- /dev/null
-+++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp
-@@ -0,0 +1,37 @@
-+# Copyright 2010 Free Software Foundation, Inc.
++++ b/gdb/testsuite/gdb.base/vla.exp
+@@ -0,0 +1,62 @@
++# 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
++# 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, write to the Free Software
-+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+set testfile "dynamic-other-frame"
-+set srcfile1 ${testfile}.f90
-+set srcfile2 ${testfile}-stub.f90
-+set objfile2 ${objdir}/${subdir}/${testfile}-stub.o
-+set executable ${testfile}
-+set binfile ${objdir}/${subdir}/${executable}
++# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
-+if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${objfile2}" object {f90}] != ""
-+ || [gdb_compile "${srcdir}/${subdir}/${srcfile1} ${objfile2}" "${binfile}" executable {debug f90}] != "" } {
-+ untested "Couldn't compile ${srcfile1} or ${srcfile2}"
++set testfile vla
++set srcfile ${testfile}.c
++set binfile ${objdir}/${subdir}/${testfile}
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
++ untested "Couldn't compile test program"
+ return -1
+}
+
-+clean_restart ${executable}
++gdb_exit
++gdb_start
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_load ${binfile}
+
-+if ![runto bar_] then {
-+ perror "couldn't run to bar_"
-+ continue
++if ![runto_main] {
++ untested vla
++ return -1
+}
+
-+gdb_test "bt" {foo \(string='hello'.*}
-diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90 b/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90
-new file mode 100644
-index 0000000..2bc637d
---- /dev/null
-+++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90
-@@ -0,0 +1,36 @@
-+! Copyright 2010 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>.
++gdb_breakpoint [gdb_get_line_number "break-here"]
+
-+subroutine foo (string)
-+ interface
-+ subroutine bar
-+ end subroutine
-+ end interface
-+ character string*(*)
-+ call bar ! stop-here
-+end subroutine foo
-+program test
-+ interface
-+ subroutine foo (string)
-+ character string*(*)
-+ end subroutine
-+ end interface
-+ call foo ('hello')
-+end
-diff --git a/gdb/testsuite/gdb.fortran/dynamic.exp b/gdb/testsuite/gdb.fortran/dynamic.exp
++gdb_continue_to_breakpoint "break-here"
++
++gdb_test "whatis temp1" "type = char \\\[variable\\\]" "first: whatis temp1"
++gdb_test "whatis temp2" "type = char \\\[variable\\\]" "first: whatis temp2"
++gdb_test "whatis temp3" "type = char \\\[48\\\]" "first: whatis temp3"
++
++gdb_test "ptype temp1" "type = char \\\[26\\\]" "first: ptype temp1"
++gdb_test "ptype temp2" "type = char \\\[26\\\]" "first: ptype temp2"
++gdb_test "ptype temp3" "type = char \\\[48\\\]" "first: ptype temp3"
++
++gdb_test "p temp1" " = '1' <repeats 26 times>" "first: print temp1"
++gdb_test "p temp2" " = '2' <repeats 26 times>" "first: print temp2"
++gdb_test "p temp3" " = '3' <repeats 48 times>" "first: print temp3"
++
++gdb_continue_to_breakpoint "break-here"
++
++gdb_test "whatis temp1" "type = char \\\[variable\\\]" "second: whatis temp1"
++gdb_test "whatis temp2" "type = char \\\[variable\\\]" "second: whatis temp2"
++gdb_test "whatis temp3" "type = char \\\[48\\\]" "second: whatis temp3"
++
++gdb_test "ptype temp1" "type = char \\\[78\\\]" "second: ptype temp1"
++gdb_test "ptype temp2" "type = char \\\[78\\\]" "second: ptype temp2"
++gdb_test "ptype temp3" "type = char \\\[48\\\]" "second: ptype temp3"
++
++gdb_test "p temp1" " = '1' <repeats 78 times>" "second: print temp1"
++gdb_test "p temp2" " = '2' <repeats 78 times>" "second: print temp2"
++gdb_test "p temp3" " = '3' <repeats 48 times>" "second: print temp3"
+diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.S b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.S
new file mode 100644
-index 0000000..e79e94a
---- /dev/null
-+++ b/gdb/testsuite/gdb.fortran/dynamic.exp
-@@ -0,0 +1,152 @@
-+# Copyright 2007 Free Software Foundation, Inc.
+index 0000000..aac3baa
+--- /dev/null
++++ b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.S
+@@ -0,0 +1,246 @@
++/* This testcase is part of GDB, the GNU debugger.
+
-+# 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.
++ Copyright 2010 Free Software Foundation, Inc.
+
-+# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
++ 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 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
++ 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.
+
-+set testfile "dynamic"
-+set srcfile ${testfile}.f90
-+set binfile ${objdir}/${subdir}/${testfile}
++ 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 { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f90 quiet}] != "" } {
-+ untested "Couldn't compile ${srcfile}"
-+ return -1
-+}
++/* Debug information */
+
-+gdb_exit
-+gdb_start
-+gdb_reinitialize_dir $srcdir/$subdir
-+gdb_load ${binfile}
++/* We will `break *main' at the very first instruction. */
++#define main_length 1
+
-+if ![runto MAIN__] then {
-+ perror "couldn't run to breakpoint MAIN__"
-+ continue
-+}
++ .section .data
++vardata:
++ /* See DW_OP_lit3 + 1 (0-based). */
++ .string "seennotseen"
+
-+gdb_breakpoint [gdb_get_line_number "varx-init"]
-+gdb_continue_to_breakpoint "varx-init"
-+gdb_test "p varx" "\\$\[0-9\]* = <(object|the array) is not allocated>" "p varx unallocated"
-+gdb_test "ptype varx" "type = <(object|the array) is not allocated>" "ptype varx unallocated"
-+gdb_test "p varx(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "p varx(1,5,17) unallocated"
-+gdb_test "p varx(1,5,17)=1" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "p varx(1,5,17)=1 unallocated"
-+gdb_test "ptype varx(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "ptype varx(1,5,17) unallocated"
++ .section .debug_info
++.Lcu1_begin:
++ .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */
++.Lcu1_start:
++ .2byte 2 /* DWARF version number */
++ .4byte .Ldebug_abbrev0 /* Offset Into Abbrev. Section */
++ .byte 4 /* Pointer Size (in bytes) */
+
-+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\\)" "ptype varx allocated"
-+# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1.
-+gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)" "p l if varx allocated"
++ /* CU die */
++ .uleb128 1 /* Abbrev: DW_TAG_compile_unit */
++ .4byte .Lproducer /* DW_AT_producer */
++ /* Use C++ to exploit a bug in parsing DW_AT_name "". */
++ .byte 4 /* DW_AT_language (C++) - */
++ .4byte main /* DW_AT_low_pc */
++ .byte main_length /* DW_AT_high_pc */
+
-+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\]* = (<(object|the array) is not associated>|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "p varv unassociated"
-+gdb_test "ptype varv" "type = (<(object|the array) is not associated>|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "ptype varv unassociated"
++.Larray_type:
++ .uleb128 2 /* Abbrev: DW_TAG_array_type */
++ .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */
+
-+set test "output varx"
-+gdb_test_multiple $test $test {
-+ -re "^output varx\r\n\[() ,6789.\]*$gdb_prompt $" {
-+ pass $test
-+ }
-+}
++ .uleb128 3 /* Abbrev: DW_TAG_subrange_type */
++ .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */
++ .byte 0 /* DW_AT_lower_bound */
++ .4byte .Llen_var-.Lcu1_begin /* DW_AT_upper_bound */
++ .byte 0 /* End of children of die */
+
-+gdb_breakpoint [gdb_get_line_number "varv-associated"]
-+gdb_continue_to_breakpoint "varv-associated"
-+gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 6" "p varx(3, 7, 19) with varv associated"
-+gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 6" "p varv(3, 7, 19) associated"
-+# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1.
-+gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)" "p l if varv associated"
-+gdb_test "ptype varx" "type = real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)" "ptype varx with varv associated"
-+# 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\\)\\)?" "ptype varv associated"
++ /* DW_AT_upper_bound is referencing an optimized-out variable. */
++.Larrayb_type:
++ .uleb128 2 /* Abbrev: DW_TAG_array_type */
++ .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */
+
-+gdb_breakpoint [gdb_get_line_number "varv-filled"]
-+gdb_continue_to_breakpoint "varv-filled"
-+gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 10" "p varx(3, 7, 19) with varv filled"
-+gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 10" "p varv(3, 7, 19) filled"
++ .uleb128 3 /* Abbrev: DW_TAG_subrange_type */
++ .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */
++ .byte 0 /* DW_AT_lower_bound */
++ .4byte .Llenb_var-.Lcu1_begin /* DW_AT_upper_bound */
++ .byte 0 /* End of children of die */
+
-+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\]* = (<(object|the array) is not associated>|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "p varv deassociated"
-+gdb_test "ptype varv" "type = (<(object|the array) is not associated>|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "ptype varv deassociated"
-+gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\." "p l if varv deassociated"
-+gdb_test "p varv(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not associated\\."
-+gdb_test "ptype varv(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not associated\\."
++ /* DW_AT_upper_bound is referencing register. */
++.Larrayreg_type:
++ .uleb128 2 /* Abbrev: DW_TAG_array_type */
++ .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */
+
-+gdb_breakpoint [gdb_get_line_number "varx-deallocated"]
-+gdb_continue_to_breakpoint "varx-deallocated"
-+gdb_test "p varx" "\\$\[0-9\]* = <(object|the array) is not allocated>" "p varx deallocated"
-+gdb_test "ptype varx" "type = <(object|the array) is not allocated>" "ptype varx deallocated"
-+gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\." "p l if varx deallocated"
-+gdb_test "p varx(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "p varx(1,5,17) deallocated"
-+gdb_test "ptype varx(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "ptype varx(1,5,17) deallocated"
++ .uleb128 8 /* Abbrev: DW_TAG_subrange_type with block */
++ .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */
++ .byte 0 /* DW_AT_lower_bound */
++ .byte 2f - 1f /* DW_AT_upper_bound */
++1: .byte 0x50 /* DW_OP_reg0 */
++2:
++ .byte 0 /* End of children of die */
+
-+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, .\]*\\)"
++.Luint_type:
++ .uleb128 4 /* Abbrev: DW_TAG_base_type */
++ .4byte .Luint_str /* DW_AT_name */
++ .byte 4 /* DW_AT_byte_size */
++ .byte 7 /* DW_AT_encoding */
+
-+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, .\]*\\)"
++.Lchar_type:
++ .uleb128 4 /* Abbrev: DW_TAG_base_type */
++ .4byte .Lchar_str /* DW_AT_name */
++ .byte 1 /* DW_AT_byte_size */
++ .byte 6 /* DW_AT_encoding */
+
-+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, .\]*\\)" "p varw filled"
-+# "up" works with GCC but other Fortran compilers may copy the values into the
-+# outer function only on the exit of the inner function.
-+# We need both variants as depending on the arch we optionally may still be
-+# executing the caller line or not after `finish'.
-+gdb_test "finish" ".*(call bar \\(y, x\\)|call foo \\(x, z\\(2:6, 4:7, 6:8\\)\\))"
-+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"
++.Llen_var:
++ .uleb128 5 /* Abbrev: DW_TAG_variable artificial */
++ .byte 1 /* DW_AT_artificial */
++ .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */
++ .4byte .Llen_loclist-.Lloclist /* DW_AT_location */
+
-+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" "\\$\[0-9\]* = \\(\\)"
-+gdb_test "p vart" "\\$\[0-9\]* = \\(\\)"
-+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 --git a/gdb/testsuite/gdb.fortran/dynamic.f90 b/gdb/testsuite/gdb.fortran/dynamic.f90
-new file mode 100644
-index 0000000..0f43564
---- /dev/null
-+++ b/gdb/testsuite/gdb.fortran/dynamic.f90
-@@ -0,0 +1,98 @@
-+! 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>.
++ /* optimized-out variable for b_string. */
++.Llenb_var:
++ .uleb128 7 /* Abbrev: DW_TAG_variable artificial no DW_AT_location */
++ .byte 1 /* DW_AT_artificial */
++ .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */
++
++ .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */
++ .string "a_string" /* DW_AT_name */
++ .4byte .Larray_type-.Lcu1_begin /* DW_AT_type */
++ .byte 2f - 1f /* DW_AT_location */
++1: .byte 3 /* DW_OP_addr */
++ .4byte vardata /* <addr> */
++2:
++
++ /* DW_AT_upper_bound is referencing an optimized-out variable. */
++ .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */
++ .string "b_string" /* DW_AT_name */
++ .4byte .Larrayb_type-.Lcu1_begin /* DW_AT_type */
++ .byte 2f - 1f /* DW_AT_location */
++1: .byte 3 /* DW_OP_addr */
++ .4byte vardata /* <addr> */
++2:
+
-+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
-+ vart(2,7) = vart(2,7)
-+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 --git a/gdb/testsuite/gdb.fortran/string.exp b/gdb/testsuite/gdb.fortran/string.exp
-new file mode 100644
-index 0000000..39de2c4
---- /dev/null
-+++ b/gdb/testsuite/gdb.fortran/string.exp
-@@ -0,0 +1,59 @@
-+# Copyright 2008 Free Software Foundation, Inc.
++ /* DW_AT_upper_bound is referencing register. */
++ .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */
++ .string "reg_string" /* DW_AT_name */
++ .4byte .Larrayreg_type-.Lcu1_begin /* DW_AT_type */
++ .byte 2f - 1f /* DW_AT_location */
++1: .byte 3 /* DW_OP_addr */
++ .4byte vardata /* <addr> */
++2:
+
-+# 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.
++ .byte 0 /* End of children of CU */
++.Lcu1_end:
+
-+# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
++ .section .debug_loc
++.Lloclist:
++.Llen_loclist:
++ .4byte 0 # Location list begin address
++ .4byte main_length # Location list end address
++ .value 2f-1f # Location expression size
++1: .byte 0x33 # DW_OP_lit3
++ .byte 0x9f # DW_OP_stack_value
++2:
++ .quad 0x0 # Location list terminator begin (*.LLST2)
++ .quad 0x0 # Location list terminator end (*.LLST2)
+
-+# This file is part of the gdb testsuite. It contains tests for Fortran
-+# strings with dynamic length.
++ .section .debug_abbrev
++.Ldebug_abbrev0:
++ .uleb128 1 /* Abbrev code */
++ .uleb128 0x11 /* DW_TAG_compile_unit */
++ .byte 0x1 /* has_children */
++ .uleb128 0x25 /* DW_AT_producer */
++ .uleb128 0xe /* DW_FORM_strp */
++ .uleb128 0x13 /* DW_AT_language */
++ .uleb128 0xb /* DW_FORM_data1 */
++ .uleb128 0x11 /* DW_AT_low_pc */
++ .uleb128 0x1 /* DW_FORM_addr */
++ .uleb128 0x12 /* DW_AT_high_pc */
++ .uleb128 0xb /* DW_FORM_data1 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+
-+set testfile "string"
-+set srcfile ${testfile}.f90
-+set binfile ${objdir}/${subdir}/${testfile}
++ .uleb128 2 /* Abbrev code */
++ .uleb128 0x1 /* TAG: DW_TAG_array_type */
++ .byte 0x1 /* DW_children_yes */
++ .uleb128 0x49 /* DW_AT_type */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+
-+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f90 quiet}] != "" } {
-+ untested "Couldn't compile ${srcfile}"
-+ return -1
-+}
++ .uleb128 3 /* Abbrev code */
++ .uleb128 0x21 /* DW_TAG_subrange_type */
++ .byte 0x0 /* no children */
++ .uleb128 0x49 /* DW_AT_type */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .uleb128 0x22 /* DW_AT_lower_bound */
++ .uleb128 0xb /* DW_FORM_data1 */
++ .uleb128 0x2f /* DW_AT_upper_bound */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+
-+gdb_exit
-+gdb_start
-+gdb_reinitialize_dir $srcdir/$subdir
-+gdb_load ${binfile}
++ .uleb128 4 /* Abbrev code */
++ .uleb128 0x24 /* DW_TAG_base_type */
++ .byte 0x0 /* no_children */
++ .uleb128 0x3 /* DW_AT_name */
++ .uleb128 0xe /* DW_FORM_strp */
++ .uleb128 0xb /* DW_AT_byte_size */
++ .uleb128 0xb /* DW_FORM_data1 */
++ .uleb128 0x3e /* DW_AT_encoding */
++ .uleb128 0xb /* DW_FORM_data1 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+
-+if ![runto MAIN__] then {
-+ perror "couldn't run to breakpoint MAIN__"
-+ continue
-+}
++ .uleb128 5 /* Abbrev code */
++ .uleb128 0x34 /* DW_TAG_variable */
++ .byte 0x0 /* no_children */
++ .uleb128 0x34 /* DW_AT_artificial */
++ .uleb128 0x0c /* DW_FORM_flag */
++ .uleb128 0x49 /* DW_AT_type */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .uleb128 0x02 /* DW_AT_location */
++ .uleb128 0x06 /* DW_FORM_data4 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+
-+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 = character(\\(kind=4\\)|\\*4)"
-+gdb_test "ptype f" "type = character(\\(kind=4\\)|\\*4) \\(7,8:10\\)"
-+gdb_test "ptype *e" "Attempt to take contents of a non-pointer value."
-+gdb_test "ptype *f" "type = character(\\(kind=4\\)|\\*4) \\(7\\)"
-+gdb_test "p c" "\\$\[0-9\]* = 'c'"
-+gdb_test "p d" "\\$\[0-9\]* = 'd '"
-+gdb_test "p e" "\\$\[0-9\]* = 'g '"
-+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_test "p *e" "Attempt to take contents of a non-pointer value."
-+gdb_test "p *f" "Attempt to take contents of a non-pointer value."
++ .uleb128 6 /* Abbrev code */
++ .uleb128 0x34 /* DW_TAG_variable */
++ .byte 0x0 /* no_children */
++ .uleb128 0x3 /* DW_AT_name */
++ .uleb128 0x8 /* DW_FORM_string */
++ .uleb128 0x49 /* DW_AT_type */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .uleb128 0x2 /* DW_AT_location */
++ .uleb128 0xa /* DW_FORM_block1 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+
-+gdb_breakpoint [gdb_get_line_number "var-finish"]
-+gdb_continue_to_breakpoint "var-finish"
-+gdb_test "p e" "\\$\[0-9\]* = '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 --git a/gdb/testsuite/gdb.fortran/string.f90 b/gdb/testsuite/gdb.fortran/string.f90
-new file mode 100644
-index 0000000..226dc5d
---- /dev/null
-+++ b/gdb/testsuite/gdb.fortran/string.f90
-@@ -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>.
++ .uleb128 7 /* Abbrev code */
++ .uleb128 0x34 /* DW_TAG_variable */
++ .byte 0x0 /* no_children */
++ .uleb128 0x34 /* DW_AT_artificial */
++ .uleb128 0x0c /* DW_FORM_flag */
++ .uleb128 0x49 /* DW_AT_type */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+
-+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 --git a/gdb/testsuite/gdb.fortran/subrange.exp b/gdb/testsuite/gdb.fortran/subrange.exp
++ .uleb128 8 /* Abbrev code */
++ .uleb128 0x21 /* DW_TAG_subrange_type with block */
++ .byte 0x0 /* no children */
++ .uleb128 0x49 /* DW_AT_type */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .uleb128 0x22 /* DW_AT_lower_bound */
++ .uleb128 0xb /* DW_FORM_data1 */
++ .uleb128 0x2f /* DW_AT_upper_bound */
++ .uleb128 0xa /* DW_FORM_block1 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
++
++ .byte 0x0 /* Terminator */
++
++/* String table */
++ .section .debug_str
++.Lproducer:
++ .string "GNU C 3.3.3"
++.Lchar_str:
++ .string "char"
++.Luint_str:
++ .string "unsigned int"
+diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.exp b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.exp
new file mode 100644
-index 0000000..c819e23
+index 0000000..815ed93
--- /dev/null
-+++ b/gdb/testsuite/gdb.fortran/subrange.exp
-@@ -0,0 +1,60 @@
-+# Copyright 2011 Free Software Foundation, Inc.
++++ b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.exp
+@@ -0,0 +1,54 @@
++# Copyright 2010 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
+# 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 { [skip_fortran_tests] } { return -1 }
++# Test printing variable with dynamic bounds which reference a different
++# (artificial in the GCC case) variable containing loclist as its location.
++# This testcase uses value (not address) of the referenced variable:
++# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43762
+
-+set testfile "subrange"
-+set srcfile ${testfile}.f90
-+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f90}] } {
-+ return -1
++# This test can only be run on targets which support DWARF-2 and use gas.
++# For now pick a sampling of likely targets.
++if {![istarget *-*-linux*]
++ && ![istarget *-*-gnu*]
++ && ![istarget *-*-elf*]
++ && ![istarget *-*-openbsd*]
++ && ![istarget arm-*-eabi*]
++ && ![istarget powerpc-*-eabi*]} {
++ return 0
+}
+
-+if ![runto MAIN__] {
-+ perror "Couldn't run to MAIN__"
-+ continue
++set testfile dw2-bound-loclist
++if { [prepare_for_testing ${testfile}.exp ${testfile} [list ${testfile}.S main.c] {}] } {
++ return -1
+}
+
-+# Depending on the compiler version being used, the name of the 4-byte integer
-+# and real types can be printed differently. For instance, gfortran-4.1 uses
-+# "int4" whereas gfortran-4.3 uses "int(kind=4)".
-+set int4 "(int4|integer\\(kind=4\\))"
-+
-+gdb_breakpoint [gdb_get_line_number "break-static"]
-+gdb_continue_to_breakpoint "break-static" ".*break-static.*"
-+
-+foreach var {a alloc ptr} {
-+ global pf_prefix
-+ set old_prefix $pf_prefix
-+ lappend pf_prefix "$var:"
++# Verify it behaves at least as an unbound array without inferior.
+
-+ gdb_test "p $var (2, 2:3)" { = \(22, 32\)}
-+ gdb_test "p $var (2:3, 3)" { = \(32, 33\)}
-+ gdb_test "p $var (1, 2:)" { = \(21, 31\)}
-+ gdb_test "p $var (2, :2)" { = \(12, 22\)}
-+ gdb_test "p $var (3, 2:2)" { = \(23\)}
-+ gdb_test "ptype $var (3, 2:2)" " = $int4 \\(2:2\\)"
-+ gdb_test "p $var (4, :)" { = \(14, 24, 34\)}
-+ gdb_test "p $var (:, :)" { = \(\( *11, 12, 13, 14\) \( *21, 22, 23, 24\) \( *31, 32, 33, 34\) *\)}
-+ gdb_test "ptype $var (:, :)" " = $int4 \\(4,3\\)"
-+ gdb_test "p $var (:)" "Wrong number of subscripts"
-+ gdb_test "p $var (:, :, :)" "Wrong number of subscripts"
++gdb_test "p a_string" { = 0x[0-9a-f]+ "seennotseen"}
++gdb_test "ptype a_string" {type = char \[\]}
+
-+ set pf_prefix $old_prefix
++# Not runto_main as dw2-bound-loclist.S handles only the first byte of main.
++if ![runto "*main"] {
++ return -1
+}
+
-+gdb_test_no_output {set $a=a}
-+delete_breakpoints
-+gdb_unload
-+gdb_test {p $a (3, 2:2)} { = \(23\)}
-diff --git a/gdb/testsuite/gdb.fortran/subrange.f90 b/gdb/testsuite/gdb.fortran/subrange.f90
-new file mode 100644
-index 0000000..4747ea9
---- /dev/null
-+++ b/gdb/testsuite/gdb.fortran/subrange.f90
-@@ -0,0 +1,28 @@
-+! Copyright 2011 Free Software Foundation, Inc.
-+!
-+! This program is free software; you can redistribute it and/or modify
-+! it under the terms of the GNU General Public License as published by
-+! the Free Software Foundation; either version 3 of the License, or
-+! (at your option) any later version.
-+!
-+! This program is distributed in the hope that it will be useful,
-+! but WITHOUT ANY WARRANTY; without even the implied warranty of
-+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+! GNU General Public License for more details.
-+!
-+! You should have received a copy of the GNU General Public License
-+! along with this program. If not, see <http://www.gnu.org/licenses/>.
++gdb_test "p a_string" { = "seen"}
++gdb_test "ptype a_string" {type = char \[4\]}
+
-+program test
-+ integer, target :: a (4, 3)
-+ integer, allocatable :: alloc (:, :)
-+ integer, pointer :: ptr (:, :)
-+ do 1 i = 1, 4
-+ do 1 j = 1, 3
-+ a (i, j) = j * 10 + i
-+1 continue
-+ allocate (alloc (4, 3))
-+ alloc = a
-+ ptr => a
-+ write (*,*) a ! break-static
-+end
-diff --git a/gdb/testsuite/gdb.gdb/selftest.exp b/gdb/testsuite/gdb.gdb/selftest.exp
-index 21798bc..111f692 100644
---- a/gdb/testsuite/gdb.gdb/selftest.exp
-+++ b/gdb/testsuite/gdb.gdb/selftest.exp
-@@ -88,6 +88,10 @@ proc do_steps_and_nexts {} {
- set description "step over ttyarg initialization"
- set command "step"
- }
-+ -re ".*python_script = 0.*$gdb_prompt $" {
-+ set description "step over python_script initialization"
-+ set command "step"
-+ }
- -re ".*pre_stat_chain = make_command_stats_cleanup.*$gdb_prompt $" {
- set description "next over make_command_stats_cleanup and everything it calls"
- set command "next"
-diff --git a/gdb/testsuite/gdb.mi/mi2-var-stale-type.c b/gdb/testsuite/gdb.mi/mi2-var-stale-type.c
++gdb_test "p b_string" { = (0x[0-9a-f]+ )?"seennotseen"}
++gdb_test "ptype b_string" {type = char \[\]}
++
++# The register contains unpredictable value - the array size.
++gdb_test "ptype reg_string" {type = char \[-?[0-9]+\]}
+diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.c b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c
new file mode 100644
-index 0000000..ebced3c
+index 0000000..1f02d90
--- /dev/null
-+++ b/gdb/testsuite/gdb.mi/mi2-var-stale-type.c
-@@ -0,0 +1,26 @@
-+/* Copyright 2011 Free Software Foundation, Inc.
++++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c
+@@ -0,0 +1,42 @@
++/* This testcase is part of GDB, the GNU debugger.
+
-+ This file is part of GDB.
++ Copyright 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 3 of the License, or
++ 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, see <http://www.gnu.org/licenses/>. */
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++ USA. */
+
-+int
-+main (int argc, char **argv)
++
++/* The function `func1' traced into must have debug info on offset > 0;
++ (DW_UNSND (attr)). This is the reason of `func0' existence. */
++
++void
++func0(int a, int b)
+{
-+ char vla[argc];
++}
+
-+ vla[0] = 0; /* break-here */
++/* `func1' being traced into must have some arguments to dump. */
+
++void
++func1(int a, int b)
++{
++ func0 (a,b);
++}
++
++int
++main(void)
++{
++ func1 (1, 2);
+ return 0;
+}
-diff --git a/gdb/testsuite/gdb.mi/mi2-var-stale-type.exp b/gdb/testsuite/gdb.mi/mi2-var-stale-type.exp
+diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp
new file mode 100644
-index 0000000..74a104e
+index 0000000..1c6e84a
--- /dev/null
-+++ b/gdb/testsuite/gdb.mi/mi2-var-stale-type.exp
-@@ -0,0 +1,57 @@
-+# Copyright 2011 Free Software Foundation, Inc.
-+#
++++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp
+@@ -0,0 +1,79 @@
++# Copyright 2006 Free Software Foundation, Inc.
++
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 3 of the License, or
++# 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, see <http://www.gnu.org/licenses/>.
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
-+load_lib mi-support.exp
-+set MIFLAGS "-i=mi2"
++# Minimal DWARF-2 unit test
+
-+gdb_exit
-+if [mi_gdb_start] {
-+ continue
++# This test can only be run on targets which support DWARF-2.
++# For now pick a sampling of likely targets.
++if {![istarget *-*-linux*]
++ && ![istarget *-*-gnu*]
++ && ![istarget *-*-elf*]
++ && ![istarget *-*-openbsd*]
++ && ![istarget arm-*-eabi*]
++ && ![istarget powerpc-*-eabi*]} {
++ return 0
+}
+
-+set testfile "mi2-var-stale-type"
++set testfile "dw2-stripped"
+set srcfile ${testfile}.c
-+set binfile ${objdir}/${subdir}/${testfile}
-+if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} {
-+ return -1
-+}
++set binfile ${objdir}/${subdir}/${testfile}.x
+
-+mi_delete_breakpoints
-+mi_gdb_reinitialize_dir $srcdir/$subdir
-+mi_gdb_load ${binfile}
++remote_exec build "rm -f ${binfile}"
+
-+mi_gdb_test {-interpreter-exec console "maintenance set internal-error quit yes"} \
-+ {\^done} \
-+ "maintenance set internal-error quit yes"
++# get the value of gcc_compiled
++if [get_compiler_info ${binfile}] {
++ return -1
++}
+
-+mi_gdb_test {-interpreter-exec console "maintenance set internal-error corefile yes"} \
-+ {\^done} \
-+ "maintenance set internal-error corefile yes"
++# This test can only be run on gcc as we use additional_flags=FIXME
++if {$gcc_compiled == 0} {
++ return 0
++}
+
-+set line [gdb_get_line_number "break-here"]
-+set func "main"
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-ggdb3}] != "" } {
++ return -1
++}
+
-+mi_gdb_test "-break-insert -t $srcfile:$line" \
-+ "\\^done,bkpt=\{number=\"\[0-9\]+\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"$func\(\\\(.*\\\)\)?\",file=\".*\",line=\"$line\",times=\"0\",original-location=\".*\"\}" \
-+ "breakpoint at $func"
++remote_exec build "objcopy -R .debug_loc ${binfile}"
++set strip_output [remote_exec build "objdump -h ${binfile}"]
+
-+if { [mi_run_cmd] < 0 } {
-+ return -1
++set test "stripping test file preservation"
++if [ regexp ".debug_info " $strip_output] {
++ pass "$test (.debug_info preserved)"
++} else {
++ fail "$test (.debug_info got also stripped)"
+}
-+mi_expect_stop "breakpoint-hit" $func ".*" ".*" "\[0-9\]+" { "" "disp=\"del\"" } "stop after initializing vla"
+
-+mi_create_varobj "vla" "vla" "create local variable vla"
++set test "stripping test file functionality"
++if [ regexp ".debug_loc " $strip_output] {
++ fail "$test (.debug_loc still present)"
++} else {
++ pass "$test (.debug_loc stripped)"
++}
+
-+mi_gdb_test "-var-update *" "\\^done,changelist=.*" "-var-update *"
-diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi.c b/gdb/testsuite/gdb.multi/watchpoint-multi.c
++gdb_exit
++gdb_start
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_load ${binfile}
++
++# For C programs, "start" should stop in main().
++
++gdb_test "start" \
++ ".*main \\(\\) at .*" \
++ "start"
++gdb_test "step" \
++ "func.* \\(.*\\) at .*" \
++ "step"
+diff --git a/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S
new file mode 100644
-index 0000000..51697b0
+index 0000000..5fcdd84
--- /dev/null
-+++ b/gdb/testsuite/gdb.multi/watchpoint-multi.c
-@@ -0,0 +1,51 @@
++++ b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S
+@@ -0,0 +1,83 @@
+/* This testcase is part of GDB, the GNU debugger.
+
-+ Copyright 2012 Free Software Foundation, Inc.
++ Copyright 2009 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 <pthread.h>
-+#include <assert.h>
++/* Debug information */
+
-+static volatile int a, b, c;
++ .section .debug_info
++.Lcu1_begin:
++ /* CU header */
++ .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */
++.Lcu1_start:
++ .2byte 2 /* DWARF Version */
++ .4byte .Labbrev1_begin /* Offset into abbrev section */
++ .byte 4 /* Pointer size */
+
-+static void
-+marker_exit (void)
-+{
-+ a = 1;
-+}
++ /* CU die */
++ .uleb128 1 /* Abbrev: DW_TAG_compile_unit */
++ .ascii "dw2-struct-member-data-location.c\0" /* DW_AT_name */
++ .ascii "GNU C 4.3.2\0" /* DW_AT_producer */
++ .byte 1 /* DW_AT_language (C) */
+
-+static void *
-+start (void *arg)
-+{
-+ b = 2;
-+ c = 3;
++.Ltype_uchar:
++ .uleb128 2 /* Abbrev: DW_TAG_structure_type */
++ .ascii "some_struct\0" /* DW_AT_name */
+
-+ return NULL;
-+}
++ .uleb128 3 /* Abbrev: DW_TAG_member */
++ .ascii "field\0" /* DW_AT_name */
++ .byte 0 /* DW_AT_data_member_location */
+
-+int
-+main (void)
-+{
-+ pthread_t thread;
-+ int i;
++ .byte 0 /* End of children of some_struct */
++
++ .byte 0 /* End of children of CU */
+
-+ i = pthread_create (&thread, NULL, start, NULL);
-+ assert (i == 0);
-+ i = pthread_join (thread, NULL);
-+ assert (i == 0);
++.Lcu1_end:
+
-+ marker_exit ();
-+ return 0;
-+}
-diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi.exp b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
++/* Abbrev table */
++ .section .debug_abbrev
++.Labbrev1_begin:
++ .uleb128 1 /* Abbrev code */
++ .uleb128 0x11 /* DW_TAG_compile_unit */
++ .byte 1 /* has_children */
++ .uleb128 0x3 /* DW_AT_name */
++ .uleb128 0x8 /* DW_FORM_string */
++ .uleb128 0x25 /* DW_AT_producer */
++ .uleb128 0x8 /* DW_FORM_string */
++ .uleb128 0x13 /* DW_AT_language */
++ .uleb128 0xb /* DW_FORM_data1 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
++
++ .uleb128 2 /* Abbrev code */
++ .uleb128 0x13 /* DW_TAG_structure_type */
++ .byte 1 /* has_children */
++ .uleb128 0x3 /* DW_AT_name */
++ .uleb128 0x8 /* DW_FORM_string */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
++
++ .uleb128 3 /* Abbrev code */
++ .uleb128 0x0d /* DW_TAG_member */
++ .byte 0 /* has_children */
++ .uleb128 0x3 /* DW_AT_name */
++ .uleb128 0x8 /* DW_FORM_string */
++ .uleb128 0x38 /* DW_AT_data_member_location */
++ .uleb128 0x0b /* DW_FORM_data1 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
++
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+diff --git a/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp
new file mode 100644
-index 0000000..d7daeec
+index 0000000..c41151c
--- /dev/null
-+++ b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
-@@ -0,0 +1,92 @@
-+# Copyright 2012 Free Software Foundation, Inc.
-+#
++++ b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp
+@@ -0,0 +1,37 @@
++# Copyright 2009 Free Software Foundation, Inc.
++
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# 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 [is_remote target] {
-+ # It is KFAIL.
-+ continue
++# This test can only be run on targets which support DWARF-2 and use gas.
++# For now pick a sampling of likely targets.
++if {![istarget *-*-linux*]
++ && ![istarget *-*-gnu*]
++ && ![istarget *-*-elf*]
++ && ![istarget *-*-openbsd*]
++ && ![istarget arm-*-eabi*]
++ && ![istarget powerpc-*-eabi*]} {
++ return 0
+}
+
-+set testfile "watchpoint-multi"
-+
-+set executable ${testfile}
-+set srcfile ${testfile}.c
-+set binfile ${objdir}/${subdir}/${executable}
++set testfile "dw2-struct-member-data-location"
++set srcfile ${testfile}.S
++set binfile ${testfile}.x
+
-+if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
-+ untested ${testfile}.exp
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${binfile}" object {nodebug}] != "" } {
+ return -1
+}
+
-+clean_restart $executable
-+
-+if ![runto_main] {
-+ return
-+}
-+# Never keep/use any non-hw breakpoints to workaround a multi-inferior bug.
-+delete_breakpoints
-+
-+gdb_test "add-inferior" "Added inferior 2"
-+gdb_test "inferior 2" "witching to inferior 2 .*"
-+gdb_load $binfile
-+
-+if ![runto_main] {
-+ return
-+}
-+delete_breakpoints
-+
-+# Simulate non-stop+target-async which also uses breakpoint always-inserted.
-+gdb_test_no_output "set breakpoint always-inserted on"
-+# displaced-stepping is also needed as other GDB sometimes still removes the
-+# breakpoints, even with always-inserted on.
-+gdb_test_no_output "set displaced-stepping on"
-+
-+# Debugging of this testcase:
-+#gdb_test_no_output "maintenance set show-debug-regs on"
-+#gdb_test_no_output "set debug infrun 1"
-+
-+# Do not use simple hardware watchpoint ("watch") as its false hit may be
-+# unnoticed by GDB if it reads it still has the same value.
-+gdb_test "awatch c" "Hardware access \\(read/write\\) watchpoint \[0-9\]+: c"
-+
-+gdb_breakpoint "marker_exit"
-+
-+gdb_test "inferior 1" "witching to inferior 1 .*"
-+
-+set have_awatch_b 0
-+set test "awatch b"
-+gdb_test_multiple $test $test {
-+ -re "Hardware access \\(read/write\\) watchpoint \[0-9\]+: b\r\n$gdb_prompt $" {
-+ pass $test
-+ set have_awatch_b 1
-+ }
-+ -re "There are not enough available hardware resources for this watchpoint\\.\r\n$gdb_prompt $" {
-+ untested $test
-+ return
-+ }
-+}
-+
-+gdb_test "inferior 2" "witching to inferior 2 .*"
-+
-+# FAIL would be a hit on watchpoint for `b' - that one is for the other
-+# inferior.
-+gdb_test "continue" "Hardware access \\(read/write\\) watchpoint \[0-9\]+: c\r\n\r\nOld value = 0\r\nNew value = 3\r\n.*" "catch c"
-+
-+gdb_test "continue" "Breakpoint \[0-9\]+, marker_exit .*" "catch marker_exit in inferior 2"
-+
-+gdb_test "inferior 1" "witching to inferior 1 .*"
-+
-+gdb_test "continue" "Hardware access \\(read/write\\) watchpoint \[0-9\]+: b\r\n\r\nOld value = 0\r\nNew value = 2\r\n.*" "catch b"
++clean_restart $binfile
+
-+gdb_test "continue" "Breakpoint \[0-9\]+, marker_exit .*" "catch marker_exit in inferior 1"
-diff --git a/gdb/testsuite/gdb.opt/array-from-register-func.c b/gdb/testsuite/gdb.opt/array-from-register-func.c
++gdb_test "ptype struct some_struct" "type = struct some_struct {\[\r\n \t\]*void field;\[\r\n \t\]*}"
+diff --git a/gdb/testsuite/gdb.dwarf2/dw2-subrange-no-type.S b/gdb/testsuite/gdb.dwarf2/dw2-subrange-no-type.S
new file mode 100644
-index 0000000..729f457
+index 0000000..9dbbf3c
--- /dev/null
-+++ b/gdb/testsuite/gdb.opt/array-from-register-func.c
-@@ -0,0 +1,22 @@
-+/* This file is part of GDB, the GNU debugger.
++++ b/gdb/testsuite/gdb.dwarf2/dw2-subrange-no-type.S
+@@ -0,0 +1,121 @@
++/* This testcase is part of GDB, the GNU debugger.
+
-+ Copyright 2009 Free Software Foundation, Inc.
++ Copyright 2012 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
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
-+int
-+func (int *arr)
-+{
-+ return arr[0];
-+}
-diff --git a/gdb/testsuite/gdb.opt/array-from-register.c b/gdb/testsuite/gdb.opt/array-from-register.c
-new file mode 100644
-index 0000000..3090e7e
---- /dev/null
-+++ b/gdb/testsuite/gdb.opt/array-from-register.c
-@@ -0,0 +1,28 @@
-+/* This file is part of GDB, the GNU debugger.
++/* Debug information */
+
-+ Copyright 2009 Free Software Foundation, Inc.
++ .section .data
++vardata:
++ .rept 129
++ .ascii "x"
++ .endr
++ .ascii "UNSEEN\0"
+
-+ 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.
++ .section .debug_info
++.Lcu1_begin:
++ .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */
++.Lcu1_start:
++ .2byte 2 /* DWARF version number */
++ .4byte .Ldebug_abbrev0 /* Offset Into Abbrev. Section */
++ .byte 4 /* Pointer Size (in bytes) */
+
-+ 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.
++ /* CU die */
++ .uleb128 1 /* Abbrev: DW_TAG_compile_unit */
++ .ascii "GNU C 3.3.3\0" /* DW_AT_producer */
++ .byte 2 /* DW_AT_language (C) - */
++
++.Larray_type:
++ .uleb128 2 /* Abbrev: DW_TAG_array_type */
++ .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */
++
++ .uleb128 8 /* Abbrev: DW_TAG_subrange_type without DW_AT_type */
++ .byte 0 /* DW_AT_lower_bound */
++ .byte 128 /* DW_AT_upper_bound */
++
++ .byte 0 /* End of children of die */
++
++.Lchar_type:
++ .uleb128 4 /* Abbrev: DW_TAG_base_type */
++ .ascii "char\0" /* DW_AT_name */
++ .byte 1 /* DW_AT_byte_size */
++ .byte 6 /* DW_AT_encoding */
++
++ .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */
++ .ascii "notype_string\0" /* DW_AT_name */
++ .4byte .Larray_type-.Lcu1_begin /* DW_AT_type */
++ .byte 2f - 1f /* DW_AT_location */
++1: .byte 3 /* DW_OP_addr */
++ .4byte vardata /* <addr> */
++2:
++
++ .byte 0 /* End of children of CU */
++.Lcu1_end:
++
++ .section .debug_abbrev
++.Ldebug_abbrev0:
++ .uleb128 1 /* Abbrev code */
++ .uleb128 0x11 /* DW_TAG_compile_unit */
++ .byte 0x1 /* has_children */
++ .uleb128 0x25 /* DW_AT_producer */
++ .uleb128 0x8 /* DW_FORM_string */
++ .uleb128 0x13 /* DW_AT_language */
++ .uleb128 0xb /* DW_FORM_data1 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+
-+ You should have received a copy of the GNU General Public License
-+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
++ .uleb128 2 /* Abbrev code */
++ .uleb128 0x1 /* TAG: DW_TAG_array_type */
++ .byte 0x1 /* DW_children_yes */
++ .uleb128 0x49 /* DW_AT_type */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+
-+extern int func (int *arr);
++ .uleb128 4 /* Abbrev code */
++ .uleb128 0x24 /* DW_TAG_base_type */
++ .byte 0x0 /* no_children */
++ .uleb128 0x3 /* DW_AT_name */
++ .uleb128 0x8 /* DW_FORM_string */
++ .uleb128 0xb /* DW_AT_byte_size */
++ .uleb128 0xb /* DW_FORM_data1 */
++ .uleb128 0x3e /* DW_AT_encoding */
++ .uleb128 0xb /* DW_FORM_data1 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+
-+int
-+main (void)
-+{
-+ int arr[] = { 42 };
++ .uleb128 6 /* Abbrev code */
++ .uleb128 0x34 /* DW_TAG_variable */
++ .byte 0x0 /* no_children */
++ .uleb128 0x3 /* DW_AT_name */
++ .uleb128 0x8 /* DW_FORM_string */
++ .uleb128 0x49 /* DW_AT_type */
++ .uleb128 0x13 /* DW_FORM_ref4 */
++ .uleb128 0x2 /* DW_AT_location */
++ .uleb128 0xa /* DW_FORM_block1 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+
-+ func (arr);
++ .uleb128 8 /* Abbrev code */
++ .uleb128 0x21 /* DW_TAG_subrange_type without DW_AT_type */
++ .byte 0x0 /* no children */
++ .uleb128 0x22 /* DW_AT_lower_bound */
++ .uleb128 0xb /* DW_FORM_data1 */
++ .uleb128 0x2f /* DW_AT_upper_bound */
++ .uleb128 0xb /* DW_FORM_data1 */
++ .byte 0x0 /* Terminator */
++ .byte 0x0 /* Terminator */
+
-+ return 0;
-+}
-diff --git a/gdb/testsuite/gdb.opt/array-from-register.exp b/gdb/testsuite/gdb.opt/array-from-register.exp
++ .byte 0x0 /* Terminator */
+diff --git a/gdb/testsuite/gdb.dwarf2/dw2-subrange-no-type.exp b/gdb/testsuite/gdb.dwarf2/dw2-subrange-no-type.exp
new file mode 100644
-index 0000000..f2de718
+index 0000000..a13e346
--- /dev/null
-+++ b/gdb/testsuite/gdb.opt/array-from-register.exp
-@@ -0,0 +1,33 @@
-+# Copyright 2009 Free Software Foundation, Inc.
-+#
++++ b/gdb/testsuite/gdb.dwarf2/dw2-subrange-no-type.exp
+@@ -0,0 +1,39 @@
++# Copyright 2012 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
++# 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,
+# 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 is part of the gdb testsuite.
++# along with this program. If not, see <http://www.gnu.org/licenses/>.
++load_lib dwarf.exp
+
-+if { [prepare_for_testing array-from-register.exp "array-from-register" \
-+ {array-from-register.c array-from-register-func.c} \
-+ {debug optimize=-O2}] } {
-+ return -1
++# https://bugzilla.redhat.com/show_bug.cgi?id=806920
++# read_subrange_type <TYPE_CODE (base_type) == TYPE_CODE_VOID> reinitialization
++# of BASE_TYPE was done too late, it affects DW_TAG_subrange_type without
++# specified DW_AT_type, present only in XLF produced code.
++
++# This test can only be run on targets which support DWARF-2 and use gas.
++if {![dwarf2_support]} {
++ return 0
+}
+
-+if ![runto func] then {
++set testfile dw2-subrange-no-type
++set srcfile ${testfile}.S
++set executable ${testfile}.x
++set binfile ${objdir}/${subdir}/${executable}
++
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {}] != "" } {
+ return -1
+}
+
-+gdb_test "p arr" "\\$\[0-9\]+ = \\(int \\*\\) *0x\[0-9a-f\]+"
++clean_restart $executable
+
-+# Seen regression:
-+# Address requested for identifier "arr" which is in register $rdi
-+gdb_test "p arr\[0\]" "\\$\[0-9\]+ = 42"
-diff --git a/gdb/testsuite/gdb.pascal/arrays.exp b/gdb/testsuite/gdb.pascal/arrays.exp
++gdb_test "ptype notype_string" {type = char \[129\]}
++gdb_test "p notype_string" " = 'x' <repeats 129 times>"
+diff --git a/gdb/testsuite/gdb.fortran/dwarf-stride.exp b/gdb/testsuite/gdb.fortran/dwarf-stride.exp
new file mode 100644
-index 0000000..ccc6e1e
+index 0000000..d7b8bea
--- /dev/null
-+++ b/gdb/testsuite/gdb.pascal/arrays.exp
-@@ -0,0 +1,104 @@
-+# Copyright 2008, 2009 Free Software Foundation, Inc.
-+#
++++ b/gdb/testsuite/gdb.fortran/dwarf-stride.exp
+@@ -0,0 +1,42 @@
++# Copyright 2009 Free Software Foundation, Inc.
++
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 3 of the License, or
++# 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, see <http://www.gnu.org/licenses/>.
-+
-+if $tracelevel then {
-+ strace $tracelevel
-+}
-+
-+load_lib "pascal.exp"
-+
-+set testfile "arrays"
-+set srcfile ${testfile}.pas
-+set binfile ${objdir}/${subdir}/${testfile}$EXEEXT
-+
-+# These tests only work with fpc, using the -gw3 compile-option
-+pascal_init
-+if { $pascal_compiler_is_fpc != 1 } {
-+ return -1
-+}
-+
-+# Detect if the fpc version is below 2.3.0
-+set fpc_generates_dwarf_for_dynamic_arrays 1
-+if { ($fpcversion_major < 2) || ( ($fpcversion_major == 2) && ($fpcversion_minor < 3))} {
-+ set fpc_generates_dwarf_for_dynamic_arrays 0
-+}
-+
-+
-+if {[gdb_compile_pascal "-gw3 ${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug ]] != "" } {
-+ return -1
-+}
-+
-+gdb_exit
-+gdb_start
-+gdb_reinitialize_dir $srcdir/$subdir
-+gdb_load ${binfile}
-+set bp_location1 [gdb_get_line_number "set breakpoint 1 here"]
-+set bp_location2 [gdb_get_line_number "set breakpoint 2 here"]
-+
-+
-+if { [gdb_breakpoint ${srcfile}:${bp_location1}] } {
-+ pass "setting breakpoint 1"
-+}
-+if { [gdb_breakpoint ${srcfile}:${bp_location2}] } {
-+ pass "setting breakpoint 2"
-+}
-+
-+# Verify that "start" lands inside the right procedure.
-+if { [gdb_start_cmd] < 0 } {
-+ untested start
-+ return -1
-+}
-+
-+gdb_test "" ".* at .*${srcfile}.*" "start"
-+
-+gdb_test "cont" "Breakpoint .*:${bp_location1}.*" "Going to first breakpoint"
-+
-+gdb_test "print StatArrInt" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61\\}" "Print static array of integer type"
-+gdb_test "print StatArrInt_" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61\\}" "Print static array of integer"
-+
-+gdb_test "cont" "Breakpoint .*:${bp_location2}.*" "Going to second breakpoint"
-+
-+gdb_test "print StatArrChar" ".* = 'abcdefghijkl'" "Print static array of char"
-+gdb_test "print Stat2dArrInt" ".* = \\{\\{0, 1, 2, 3, 4\\}, \\{1, 2, 3, 4, 5\\}, \\{2, 3, 4, 5, 6\\}, \\{3, 4, 5, 6, 7\\}, \\{4, 5, 6, 7, 8\\}, \\{5, 6, 7, 8, 9\\}, \\{6, 7, 8, 9, 10\\}, \\{7, 8, 9, 10, 11\\}, \\{8, 9, 10, 11, 12\\}, \\{9, 10, 11, 12, 13\\}, \\{10, 11, 12, 13, 14\\}, \\{11, 12, 13, 14, 15\\}\\}" "Print static 2-dimensional array of integer"
-+
-+if { $fpc_generates_dwarf_for_dynamic_arrays == 0} {
-+ setup_xfail "*-*-*"
-+}
-+gdb_test "print DynArrInt" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62\\}" "Print dynamic array of integer type"
-+if { $fpc_generates_dwarf_for_dynamic_arrays == 0} {
-+ setup_xfail "*-*-*"
-+}
-+gdb_test "print DynArrInt_" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62\\}" "Print dynamic array of integer"
-+
-+if { $fpc_generates_dwarf_for_dynamic_arrays == 0} {
-+ setup_xfail "*-*-*"
-+}
-+gdb_test "print s" ".* = 'test'#0'string'" "Print string containing null-char"
-+
-+if { $fpc_generates_dwarf_for_dynamic_arrays == 0} {
-+ setup_xfail "*-*-*"
-+}
-+gdb_test "print DynArrStr" ".* = \\{'dstr0', 'dstr1', 'dstr2', 'dstr3', 'dstr4', 'dstr5', 'dstr6', 'dstr7', 'dstr8', 'dstr9', 'dstr10', 'dstr11', 'dstr12'\\}" "Print dynamic array of string"
-+
-+if { $fpc_generates_dwarf_for_dynamic_arrays == 0} {
-+ setup_xfail "*-*-*"
-+}
-+gdb_test "print StatArrStr" ".* = \\{'str0', 'str1', 'str2', 'str3', 'str4', 'str5', 'str6', 'str7', 'str8', 'str9', 'str10', 'str11', 'str12'\\}" "Print static array of string"
-+
-+if { $fpc_generates_dwarf_for_dynamic_arrays == 0} {
-+ setup_xfail "*-*-*"
-+}
-+gdb_test "print DynArrChar" ".* = 'abcdefghijklm'" "Print dynamic array of char"
-+
-diff --git a/gdb/testsuite/gdb.pascal/arrays.pas b/gdb/testsuite/gdb.pascal/arrays.pas
-new file mode 100644
-index 0000000..295602d
---- /dev/null
-+++ b/gdb/testsuite/gdb.pascal/arrays.pas
-@@ -0,0 +1,82 @@
-+{
-+ Copyright 2008, 2009 Free Software Foundation, Inc.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 3 of the License, or
-+ (at your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program. If not, see <http://www.gnu.org/licenses/>.
-+}
-+
-+program arrays;
-+
-+{$mode objfpc}{$h+}
-+
-+uses sysutils;
-+
-+type TStatArrInt= array[0..11] of integer;
-+ TDynArrInt= array of integer;
-+ TStatArrStr= array[0..12] of string;
-+ TDynArrStr= array of string;
-+ TDynArrChar = array of char;
-+ TStatArrChar = array [0..11] of char;
-+
-+ TStat2dArrInt = array[0..11,0..4] of integer;
-+
-+var StatArrInt: TStatArrInt;
-+ StatArrInt_: Array[0..11] of integer;
-+ DynArrInt: TDynArrInt;
-+ DynArrInt_: Array of integer;
-+ StatArrStr: TStatArrStr;
-+ DynArrStr: TDynArrStr;
-+ StatArrChar: TStatArrChar;
-+ DynArrChar: TDynArrChar;
-+
-+ Stat2dArrInt: TStat2dArrInt;
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
-+ s: string;
-+
-+ i,j : integer;
++# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
+
-+begin
-+ for i := 0 to 11 do
-+ begin
-+ StatArrInt[i]:= i+50;
-+ StatArrInt_[i]:= i+50;
-+ StatArrChar[i]:= chr(ord('a')+i);
-+ for j := 0 to 4 do
-+ Stat2dArrInt[i,j]:=i+j;
-+ end;
-+ writeln(StatArrInt_[0]);
-+ writeln(StatArrInt[0]); { set breakpoint 1 here }
-+ writeln(StatArrChar[0]);
-+ writeln(Stat2dArrInt[0,0]);
++# This file is part of the gdb testsuite. Array element stride must not be
++# specified in the number of elements but in a number of bytes instead.
++# Original problem:
++# (gdb) p c40pt(1)
++# $1 = '0-hello', ' ' <repeats 33 times>
++# (gdb) p c40pt(2)
++# warning: Fortran array stride not divisible by the element size
+
-+ setlength(DynArrInt,13);
-+ setlength(DynArrInt_,13);
-+ setlength(DynArrStr,13);
-+ setlength(DynArrChar,13);
-+ for i := 0 to 12 do
-+ begin
-+ DynArrInt[i]:= i+50;
-+ DynArrInt_[i]:= i+50;
-+ DynArrChar[i]:= chr(ord('a')+i);
-+ StatArrStr[i]:='str'+inttostr(i);
-+ DynArrStr[i]:='dstr'+inttostr(i);
-+ end;
-+ writeln(DynArrInt_[1]);
-+ writeln(DynArrInt[1]);
-+ writeln(DynArrStr[1]);
-+ writeln(StatArrStr[1]);
-+ writeln(DynArrChar[1]);
++set testfile dwarf-stride
++set srcfile ${testfile}.f90
+
-+ s := 'test'#0'string';
-+ writeln(s); { set breakpoint 2 here }
-+end.
-diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp
-index 83ff8fe..bddbf9f 100644
---- a/gdb/testsuite/gdb.python/py-frame.exp
-+++ b/gdb/testsuite/gdb.python/py-frame.exp
-@@ -74,8 +74,6 @@ gdb_test "python print bframe == gdb.newest_frame()" True \
-
- gdb_test "python print 'result =', f0 == f1" " = False" "test equality comparison (false)"
- gdb_test "python print 'result =', f0 == f0" " = True" "test equality comparison (true)"
--gdb_test "python print 'result =', f0 != f1" " = True" "test inequality comparison (true)"
--gdb_test "python print 'result =', f0 != f0" " = False" "test inequality comparison (false)"
- gdb_test "python print 'result =', f0.is_valid ()" " = True" "test Frame.is_valid"
- gdb_test "python print 'result =', f0.name ()" " = f2" "test Frame.name"
- gdb_test "python print 'result =', f0.type () == gdb.NORMAL_FRAME" " = True" "test Frame.type"
-@@ -90,3 +88,5 @@ gdb_test "python print 'result =', f0.read_var ('variable_which_surely_doesnt_ex
- gdb_test "python print 'result =', f0.read_var ('a')" " = 1" "test Frame.read_var - success"
-
- gdb_test "python print 'result =', gdb.selected_frame () == f1" " = True" "test gdb.selected_frame"
++if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f90}] } {
++ return -1
++}
+
-+gdb_test "python print 'result =', f0.block ()" "<gdb.Block object at 0x\[\[:xdigit:\]\]+>" "test Frame.block"
-diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp
-index c9d8c97..4324db0 100644
---- a/gdb/testsuite/gdb.python/py-value.exp
-+++ b/gdb/testsuite/gdb.python/py-value.exp
-@@ -360,6 +360,15 @@ proc test_value_after_death {} {
- "print value's type"
- }
-
-+# Regression test for a cast failure. The bug was that if we cast a
-+# value to its own type, gdb could crash. This happened because we
-+# could end up double-freeing a struct value.
-+proc test_cast_regression {} {
-+ gdb_test "python v = gdb.Value(5)" "" "create value for cast test"
-+ gdb_test "python v = v.cast(v.type)" "" "cast value for cast test"
-+ gdb_test "python print v" "5" "print value for cast test"
++if ![runto MAIN__] then {
++ perror "couldn't run to breakpoint MAIN__"
++ continue
+}
+
- # Regression test for invalid subscript operations. The bug was that
- # the type of the value was not being checked before allowing a
- # subscript operation to proceed.
-@@ -496,6 +505,7 @@ test_value_in_inferior
- test_inferior_function_call
- test_lazy_strings
- test_value_after_death
-+test_cast_regression
-
- # Test either C or C++ values.
- test_subscript_regression "${binfile}" "c"
-diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork-child.c b/gdb/testsuite/gdb.threads/watchpoint-fork-child.c
++gdb_breakpoint [gdb_get_line_number "break-here"]
++gdb_continue_to_breakpoint "break-here" ".*break-here.*"
++gdb_test "p c40pt(1)" " = '0-hello.*"
++gdb_test "p c40pt(2)" " = '1-hello.*"
+diff --git a/gdb/testsuite/gdb.fortran/dwarf-stride.f90 b/gdb/testsuite/gdb.fortran/dwarf-stride.f90
new file mode 100644
-index 0000000..7a7e07f
+index 0000000..e492b3a
--- /dev/null
-+++ b/gdb/testsuite/gdb.threads/watchpoint-fork-child.c
-@@ -0,0 +1,129 @@
-+/* Test case for forgotten hw-watchpoints after fork()-off of a process.
++++ b/gdb/testsuite/gdb.fortran/dwarf-stride.f90
+@@ -0,0 +1,40 @@
++! Copyright 2009 Free Software Foundation, Inc.
++!
++! This program is free software; you can redistribute it and/or modify
++! it under the terms of the GNU General Public License as published by
++! the Free Software Foundation; either version 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.
++!
++! File written by Alan Matsuoka.
+
-+ Copyright 2012 Free Software Foundation, Inc.
++program repro
+
-+ This file is part of GDB.
++ type small_stride
++ character*40 long_string
++ integer small_pad
++ end type small_stride
+
-+ 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.
++ type(small_stride), dimension (20), target :: unpleasant
++ character*40, pointer, dimension(:):: c40pt
+
-+ 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.
++ integer i
+
-+ 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. */
++ do i = 0,19
++ unpleasant(i+1)%small_pad = i+1
++ unpleasant(i+1)%long_string = char (ichar('0') + i) // '-hello'
++ end do
+
-+#include <string.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <assert.h>
-+#include <signal.h>
-+#include <stdio.h>
++ c40pt => unpleasant%long_string
++
++ print *, c40pt ! break-here
+
-+#include "watchpoint-fork.h"
++end program repro
+diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90 b/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90
+new file mode 100644
+index 0000000..261ce17
+--- /dev/null
++++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90
+@@ -0,0 +1,24 @@
++! Copyright 2010 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 bar
++ real :: dummy
++ dummy = 1
++end subroutine bar
+diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp b/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp
+new file mode 100644
+index 0000000..fa41b80
+--- /dev/null
++++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp
+@@ -0,0 +1,37 @@
++# Copyright 2010 Free Software Foundation, Inc.
+
-+/* `pid_t' may not be available. */
++# 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.
+
-+static volatile int usr1_got;
++set testfile "dynamic-other-frame"
++set srcfile1 ${testfile}.f90
++set srcfile2 ${testfile}-stub.f90
++set objfile2 ${objdir}/${subdir}/${testfile}-stub.o
++set executable ${testfile}
++set binfile ${objdir}/${subdir}/${executable}
+
-+static void
-+handler_usr1 (int signo)
-+{
-+ usr1_got++;
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${objfile2}" object {f90}] != ""
++ || [gdb_compile "${srcdir}/${subdir}/${srcfile1} ${objfile2}" "${binfile}" executable {debug f90}] != "" } {
++ untested "Couldn't compile ${srcfile1} or ${srcfile2}"
++ return -1
+}
+
-+void
-+forkoff (int nr)
-+{
-+ int child, save_parent = getpid ();
-+ int i;
-+ struct sigaction act, oldact;
-+#ifdef THREAD
-+ void *thread_result;
-+#endif
++clean_restart ${executable}
++
++if ![runto bar_] then {
++ perror "couldn't run to bar_"
++ continue
++}
++
++gdb_test "bt" {foo \(string='hello'.*}
+diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90 b/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90
+new file mode 100644
+index 0000000..2bc637d
+--- /dev/null
++++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90
+@@ -0,0 +1,36 @@
++! Copyright 2010 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 (string)
++ interface
++ subroutine bar
++ end subroutine
++ end interface
++ character string*(*)
++ call bar ! stop-here
++end subroutine foo
++program test
++ interface
++ subroutine foo (string)
++ character string*(*)
++ end subroutine
++ end interface
++ call foo ('hello')
++end
+diff --git a/gdb/testsuite/gdb.fortran/dynamic.exp b/gdb/testsuite/gdb.fortran/dynamic.exp
+new file mode 100644
+index 0000000..e79e94a
+--- /dev/null
++++ b/gdb/testsuite/gdb.fortran/dynamic.exp
+@@ -0,0 +1,152 @@
++# Copyright 2007 Free Software Foundation, Inc.
+
-+ memset (&act, 0, sizeof act);
-+ act.sa_flags = SA_RESTART;
-+ act.sa_handler = handler_usr1;
-+ sigemptyset (&act.sa_mask);
-+ i = sigaction (SIGUSR1, &act, &oldact);
-+ assert (i == 0);
++# 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.
+
-+ child = fork ();
-+ switch (child)
-+ {
-+ case -1:
-+ assert (0);
-+ default:
-+ printf ("parent%d: %d\n", nr, (int) child);
++# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
+
-+ /* Sleep for a while to possibly get incorrectly ATTACH_THREADed by GDB
-+ tracing the child fork with no longer valid thread/lwp entries of the
-+ parent. */
++# 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
+
-+ i = sleep (2);
-+ assert (i == 0);
++set testfile "dynamic"
++set srcfile ${testfile}.f90
++set binfile ${objdir}/${subdir}/${testfile}
+
-+ /* We must not get caught here (against a forgotten breakpoint). */
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f90 quiet}] != "" } {
++ untested "Couldn't compile ${srcfile}"
++ return -1
++}
+
-+ var++;
-+ marker ();
++gdb_exit
++gdb_start
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_load ${binfile}
+
-+#ifdef THREAD
-+ /* And neither got caught our thread. */
++if ![runto MAIN__] then {
++ perror "couldn't run to breakpoint MAIN__"
++ continue
++}
+
-+ step = 99;
-+ i = pthread_join (thread, &thread_result);
-+ assert (i == 0);
-+ assert (thread_result == (void *) 99UL);
-+#endif
++gdb_breakpoint [gdb_get_line_number "varx-init"]
++gdb_continue_to_breakpoint "varx-init"
++gdb_test "p varx" "\\$\[0-9\]* = <(object|the array) is not allocated>" "p varx unallocated"
++gdb_test "ptype varx" "type = <(object|the array) is not allocated>" "ptype varx unallocated"
++gdb_test "p varx(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "p varx(1,5,17) unallocated"
++gdb_test "p varx(1,5,17)=1" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "p varx(1,5,17)=1 unallocated"
++gdb_test "ptype varx(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "ptype varx(1,5,17) unallocated"
+
-+ /* Be sure our child knows we did not get caught above. */
++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\\)" "ptype varx allocated"
++# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1.
++gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)" "p l if varx allocated"
+
-+ i = kill (child, SIGUSR1);
-+ assert (i == 0);
++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\]* = (<(object|the array) is not associated>|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "p varv unassociated"
++gdb_test "ptype varv" "type = (<(object|the array) is not associated>|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "ptype varv unassociated"
+
-+ /* Sleep for a while to check GDB's `info threads' no longer tracks us in
-+ the child fork. */
++set test "output varx"
++gdb_test_multiple $test $test {
++ -re "^output varx\r\n\[() ,6789.\]*$gdb_prompt $" {
++ pass $test
++ }
++}
+
-+ i = sleep (2);
-+ assert (i == 0);
++gdb_breakpoint [gdb_get_line_number "varv-associated"]
++gdb_continue_to_breakpoint "varv-associated"
++gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 6" "p varx(3, 7, 19) with varv associated"
++gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 6" "p varv(3, 7, 19) associated"
++# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1.
++gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)" "p l if varv associated"
++gdb_test "ptype varx" "type = real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)" "ptype varx with varv associated"
++# 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\\)\\)?" "ptype varv associated"
+
-+ _exit (0);
-+ case 0:
-+ printf ("child%d: %d\n", nr, (int) getpid ());
++gdb_breakpoint [gdb_get_line_number "varv-filled"]
++gdb_continue_to_breakpoint "varv-filled"
++gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 10" "p varx(3, 7, 19) with varv filled"
++gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 10" "p varv(3, 7, 19) filled"
+
-+ /* Let the parent signal us about its success. Be careful of races. */
++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\]* = (<(object|the array) is not associated>|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "p varv deassociated"
++gdb_test "ptype varv" "type = (<(object|the array) is not associated>|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "ptype varv deassociated"
++gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\." "p l if varv deassociated"
++gdb_test "p varv(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not associated\\."
++gdb_test "ptype varv(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not associated\\."
+
-+ for (;;)
-+ {
-+ /* Parent either died (and USR1_GOT is zero) or it succeeded. */
-+ if (getppid () != save_parent)
-+ break;
-+ if (kill (getppid (), 0) != 0)
-+ break;
-+ /* Parent succeeded? */
-+ if (usr1_got)
-+ break;
++gdb_breakpoint [gdb_get_line_number "varx-deallocated"]
++gdb_continue_to_breakpoint "varx-deallocated"
++gdb_test "p varx" "\\$\[0-9\]* = <(object|the array) is not allocated>" "p varx deallocated"
++gdb_test "ptype varx" "type = <(object|the array) is not allocated>" "ptype varx deallocated"
++gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\." "p l if varx deallocated"
++gdb_test "p varx(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "p varx(1,5,17) deallocated"
++gdb_test "ptype varx(1,5,17)" "(Cannot access it|Unable to access the object) because the (object|array) is not allocated\\." "ptype varx(1,5,17) deallocated"
+
-+#ifdef THREAD
-+ i = pthread_yield ();
-+ assert (i == 0);
-+#endif
-+ }
-+ assert (usr1_got);
++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, .\]*\\)"
+
-+ /* We must get caught here (against a false watchpoint removal). */
++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, .\]*\\)"
+
-+ marker ();
-+ }
++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, .\]*\\)" "p varw filled"
++# "up" works with GCC but other Fortran compilers may copy the values into the
++# outer function only on the exit of the inner function.
++# We need both variants as depending on the arch we optionally may still be
++# executing the caller line or not after `finish'.
++gdb_test "finish" ".*(call bar \\(y, x\\)|call foo \\(x, z\\(2:6, 4:7, 6:8\\)\\))"
++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"
+
-+ i = sigaction (SIGUSR1, &oldact, NULL);
-+ assert (i == 0);
-+}
-diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c b/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c
++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" "\\$\[0-9\]* = \\(\\)"
++gdb_test "p vart" "\\$\[0-9\]* = \\(\\)"
++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 --git a/gdb/testsuite/gdb.fortran/dynamic.f90 b/gdb/testsuite/gdb.fortran/dynamic.f90
new file mode 100644
-index 0000000..bfdd89f
+index 0000000..0f43564
--- /dev/null
-+++ b/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c
-@@ -0,0 +1,174 @@
-+/* Test case for forgotten hw-watchpoints after fork()-off of a process.
-+
-+ Copyright 2012 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 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. */
++++ b/gdb/testsuite/gdb.fortran/dynamic.f90
+@@ -0,0 +1,98 @@
++! 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>.
+
-+#include <assert.h>
-+#include <unistd.h>
-+#include <sys/wait.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <pthread.h>
++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
++ vart(2,7) = vart(2,7)
++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 --git a/gdb/testsuite/gdb.fortran/string.exp b/gdb/testsuite/gdb.fortran/string.exp
+new file mode 100644
+index 0000000..39de2c4
+--- /dev/null
++++ b/gdb/testsuite/gdb.fortran/string.exp
+@@ -0,0 +1,59 @@
++# Copyright 2008 Free Software Foundation, Inc.
+
-+#include <asm/unistd.h>
-+#include <unistd.h>
-+#define gettid() syscall (__NR_gettid)
++# 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.
+
-+#include "watchpoint-fork.h"
++# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
+
-+/* Non-atomic `var++' should not hurt as we synchronize the threads by the STEP
-+ variable. Hit-comments need to be duplicite there to catch both at-stops
-+ and behind-stops, depending on the target. */
++# This file is part of the gdb testsuite. It contains tests for Fortran
++# strings with dynamic length.
+
-+volatile int var;
++set testfile "string"
++set srcfile ${testfile}.f90
++set binfile ${objdir}/${subdir}/${testfile}
+
-+void
-+marker (void)
-+{
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f90 quiet}] != "" } {
++ untested "Couldn't compile ${srcfile}"
++ return -1
+}
+
-+static void
-+empty (void)
-+{
-+}
++gdb_exit
++gdb_start
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_load ${binfile}
+
-+static void
-+mark_exit (void)
-+{
++if ![runto MAIN__] then {
++ perror "couldn't run to breakpoint MAIN__"
++ continue
+}
+
-+pthread_t thread;
-+volatile int step;
-+
-+static void *
-+start (void *arg)
-+{
-+ int i;
-+
-+ if (step >= 3)
-+ goto step_3;
-+
-+ while (step != 1)
-+ {
-+ i = pthread_yield ();
-+ assert (i == 0);
-+ }
-+
-+ var++; /* validity-thread-B */
-+ empty (); /* validity-thread-B */
-+ step = 2;
-+ while (step != 3)
-+ {
-+ if (step == 99)
-+ goto step_99;
-+
-+ i = pthread_yield ();
-+ assert (i == 0);
-+ }
++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 = character(\\(kind=4\\)|\\*4)"
++gdb_test "ptype f" "type = character(\\(kind=4\\)|\\*4) \\(7,8:10\\)"
++gdb_test "ptype *e" "Attempt to take contents of a non-pointer value."
++gdb_test "ptype *f" "type = character(\\(kind=4\\)|\\*4) \\(7\\)"
++gdb_test "p c" "\\$\[0-9\]* = 'c'"
++gdb_test "p d" "\\$\[0-9\]* = 'd '"
++gdb_test "p e" "\\$\[0-9\]* = 'g '"
++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_test "p *e" "Attempt to take contents of a non-pointer value."
++gdb_test "p *f" "Attempt to take contents of a non-pointer value."
+
-+step_3:
-+ if (step >= 5)
-+ goto step_5;
++gdb_breakpoint [gdb_get_line_number "var-finish"]
++gdb_continue_to_breakpoint "var-finish"
++gdb_test "p e" "\\$\[0-9\]* = '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 --git a/gdb/testsuite/gdb.fortran/string.f90 b/gdb/testsuite/gdb.fortran/string.f90
+new file mode 100644
+index 0000000..226dc5d
+--- /dev/null
++++ b/gdb/testsuite/gdb.fortran/string.f90
+@@ -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>.
+
-+ var++; /* after-fork1-B */
-+ empty (); /* after-fork1-B */
-+ step = 4;
-+ while (step != 5)
-+ {
-+ if (step == 99)
-+ goto step_99;
++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 --git a/gdb/testsuite/gdb.fortran/subrange.exp b/gdb/testsuite/gdb.fortran/subrange.exp
+new file mode 100644
+index 0000000..c819e23
+--- /dev/null
++++ b/gdb/testsuite/gdb.fortran/subrange.exp
+@@ -0,0 +1,60 @@
++# Copyright 2011 Free Software Foundation, Inc.
+
-+ i = pthread_yield ();
-+ assert (i == 0);
-+ }
++# 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/>.
+
-+step_5:
-+ var++; /* after-fork2-B */
-+ empty (); /* after-fork2-B */
-+ return (void *) 5UL;
++if { [skip_fortran_tests] } { return -1 }
+
-+step_99:
-+ /* We must not get caught here (against a forgotten breakpoint). */
-+ var++;
-+ marker ();
-+ return (void *) 99UL;
++set testfile "subrange"
++set srcfile ${testfile}.f90
++if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f90}] } {
++ return -1
+}
+
-+int
-+main (void)
-+{
-+ int i;
-+ void *thread_result;
-+
-+ setbuf (stdout, NULL);
-+ printf ("main: %d\n", (int) gettid ());
-+
-+ /* General hardware breakpoints and watchpoints validity. */
-+ marker ();
-+ var++; /* validity-first */
-+ empty (); /* validity-first */
-+
-+ i = pthread_create (&thread, NULL, start, NULL);
-+ assert (i == 0);
-+
-+ var++; /* validity-thread-A */
-+ empty (); /* validity-thread-A */
-+ step = 1;
-+ while (step != 2)
-+ {
-+ i = pthread_yield ();
-+ assert (i == 0);
-+ }
-+
-+ /* Hardware watchpoints got disarmed here. */
-+ forkoff (1);
++if ![runto MAIN__] {
++ perror "Couldn't run to MAIN__"
++ continue
++}
+
-+ var++; /* after-fork1-A */
-+ empty (); /* after-fork1-A */
-+ step = 3;
-+#ifdef FOLLOW_CHILD
-+ /* Spawn new thread as it was deleted in the child of FORK. */
-+ i = pthread_create (&thread, NULL, start, NULL);
-+ assert (i == 0);
-+#endif
-+ while (step != 4)
-+ {
-+ i = pthread_yield ();
-+ assert (i == 0);
-+ }
++# Depending on the compiler version being used, the name of the 4-byte integer
++# and real types can be printed differently. For instance, gfortran-4.1 uses
++# "int4" whereas gfortran-4.3 uses "int(kind=4)".
++set int4 "(int4|integer\\(kind=4\\))"
+
-+ /* A sanity check for double hardware watchpoints removal. */
-+ forkoff (2);
++gdb_breakpoint [gdb_get_line_number "break-static"]
++gdb_continue_to_breakpoint "break-static" ".*break-static.*"
+
-+ var++; /* after-fork2-A */
-+ empty (); /* after-fork2-A */
-+ step = 5;
-+#ifdef FOLLOW_CHILD
-+ /* Spawn new thread as it was deleted in the child of FORK. */
-+ i = pthread_create (&thread, NULL, start, NULL);
-+ assert (i == 0);
-+#endif
++foreach var {a alloc ptr} {
++ global pf_prefix
++ set old_prefix $pf_prefix
++ lappend pf_prefix "$var:"
+
-+ i = pthread_join (thread, &thread_result);
-+ assert (i == 0);
-+ assert (thread_result == (void *) 5UL);
++ gdb_test "p $var (2, 2:3)" { = \(22, 32\)}
++ gdb_test "p $var (2:3, 3)" { = \(32, 33\)}
++ gdb_test "p $var (1, 2:)" { = \(21, 31\)}
++ gdb_test "p $var (2, :2)" { = \(12, 22\)}
++ gdb_test "p $var (3, 2:2)" { = \(23\)}
++ gdb_test "ptype $var (3, 2:2)" " = $int4 \\(2:2\\)"
++ gdb_test "p $var (4, :)" { = \(14, 24, 34\)}
++ gdb_test "p $var (:, :)" { = \(\( *11, 12, 13, 14\) \( *21, 22, 23, 24\) \( *31, 32, 33, 34\) *\)}
++ gdb_test "ptype $var (:, :)" " = $int4 \\(4,3\\)"
++ gdb_test "p $var (:)" "Wrong number of subscripts"
++ gdb_test "p $var (:, :, :)" "Wrong number of subscripts"
+
-+ mark_exit ();
-+ return 0;
++ set pf_prefix $old_prefix
+}
-diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork-parent.c b/gdb/testsuite/gdb.threads/watchpoint-fork-parent.c
++
++gdb_test_no_output {set $a=a}
++delete_breakpoints
++gdb_unload
++gdb_test {p $a (3, 2:2)} { = \(23\)}
+diff --git a/gdb/testsuite/gdb.fortran/subrange.f90 b/gdb/testsuite/gdb.fortran/subrange.f90
new file mode 100644
-index 0000000..9bbf438
+index 0000000..4747ea9
--- /dev/null
-+++ b/gdb/testsuite/gdb.threads/watchpoint-fork-parent.c
-@@ -0,0 +1,74 @@
-+/* Test case for forgotten hw-watchpoints after fork()-off of a process.
-+
-+ Copyright 2012 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 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. */
-+
-+#include <string.h>
-+#include <errno.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+#include <assert.h>
-+#include <stdio.h>
-+#include <sys/wait.h>
-+
-+#include "watchpoint-fork.h"
-+
-+void
-+forkoff (int nr)
-+{
-+ pid_t child, pid_got;
-+ int exit_code = 42 + nr;
-+ int status, i;
++++ b/gdb/testsuite/gdb.fortran/subrange.f90
+@@ -0,0 +1,28 @@
++! Copyright 2011 Free Software Foundation, Inc.
++!
++! This program is free software; you can redistribute it and/or modify
++! it under the terms of the GNU General Public License as published by
++! the Free Software Foundation; either version 3 of the License, or
++! (at your option) any later version.
++!
++! This program is distributed in the hope that it will be useful,
++! but WITHOUT ANY WARRANTY; without even the implied warranty of
++! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++! GNU General Public License for more details.
++!
++! You should have received a copy of the GNU General Public License
++! along with this program. If not, see <http://www.gnu.org/licenses/>.
+
-+ child = fork ();
-+ switch (child)
-+ {
-+ case -1:
-+ assert (0);
-+ case 0:
-+ printf ("child%d: %d\n", nr, (int) getpid ());
-+ /* Delay to get both the "child%d" and "parent%d" message printed without
-+ a race breaking expect by its endless wait on `$gdb_prompt$':
-+ Breakpoint 3, marker () at ../../../gdb/testsuite/gdb.threads/watchpoint-fork.c:33
-+ 33 }
-+ (gdb) parent2: 14223 */
-+ i = sleep (1);
-+ assert (i == 0);
-+
-+ /* We must not get caught here (against a forgotten breakpoint). */
-+ var++;
-+ marker ();
-+
-+ _exit (exit_code);
-+ default:
-+ printf ("parent%d: %d\n", nr, (int) child);
-+ /* Delay to get both the "child%d" and "parent%d" message printed, see
-+ above. */
-+ i = sleep (1);
-+ assert (i == 0);
-+
-+ pid_got = wait (&status);
-+ assert (pid_got == child);
-+ assert (WIFEXITED (status));
-+ assert (WEXITSTATUS (status) == exit_code);
-+
-+ /* We must get caught here (against a false watchpoint removal). */
-+ marker ();
-+ }
-+}
-diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork-st.c b/gdb/testsuite/gdb.threads/watchpoint-fork-st.c
++program test
++ integer, target :: a (4, 3)
++ integer, allocatable :: alloc (:, :)
++ integer, pointer :: ptr (:, :)
++ do 1 i = 1, 4
++ do 1 j = 1, 3
++ a (i, j) = j * 10 + i
++1 continue
++ allocate (alloc (4, 3))
++ alloc = a
++ ptr => a
++ write (*,*) a ! break-static
++end
+diff --git a/gdb/testsuite/gdb.gdb/selftest.exp b/gdb/testsuite/gdb.gdb/selftest.exp
+index 7645caf..f4f9c1f 100644
+--- a/gdb/testsuite/gdb.gdb/selftest.exp
++++ b/gdb/testsuite/gdb.gdb/selftest.exp
+@@ -92,6 +92,10 @@ proc do_steps_and_nexts {} {
+ set description "step over cmdarg_vec initialization"
+ set command "step"
+ }
++ -re ".*python_script = 0.*$gdb_prompt $" {
++ set description "step over python_script initialization"
++ set command "step"
++ }
+ -re ".*pre_stat_chain = make_command_stats_cleanup.*$gdb_prompt $" {
+ set description "next over make_command_stats_cleanup and everything it calls"
+ set command "next"
+diff --git a/gdb/testsuite/gdb.mi/mi2-var-stale-type.c b/gdb/testsuite/gdb.mi/mi2-var-stale-type.c
new file mode 100644
-index 0000000..17cc058
+index 0000000..ebced3c
--- /dev/null
-+++ b/gdb/testsuite/gdb.threads/watchpoint-fork-st.c
-@@ -0,0 +1,61 @@
-+/* Test case for forgotten hw-watchpoints after fork()-off of a process.
-+
-+ Copyright 2012 Free Software Foundation, Inc.
++++ b/gdb/testsuite/gdb.mi/mi2-var-stale-type.c
+@@ -0,0 +1,26 @@
++/* Copyright 2011 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 2 of the License, or
++ 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,
+ 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. */
-+
-+#include <assert.h>
-+#include <unistd.h>
-+#include <sys/wait.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+
-+#include "watchpoint-fork.h"
-+
-+volatile int var;
++ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
-+void
-+marker (void)
++int
++main (int argc, char **argv)
+{
-+}
++ char vla[argc];
+
-+static void
-+mark_exit (void)
-+{
-+}
++ vla[0] = 0; /* break-here */
+
-+int
-+main (void)
-+{
-+ setbuf (stdout, NULL);
-+ printf ("main: %d\n", (int) getpid ());
-+
-+ /* General hardware breakpoints and watchpoints validity. */
-+ marker ();
-+ var++;
-+ /* Hardware watchpoints got disarmed here. */
-+ forkoff (1);
-+ /* This watchpoint got lost before. */
-+ var++;
-+ /* A sanity check for double hardware watchpoints removal. */
-+ forkoff (2);
-+ var++;
-+
-+ mark_exit ();
+ return 0;
+}
-diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork.exp b/gdb/testsuite/gdb.threads/watchpoint-fork.exp
+diff --git a/gdb/testsuite/gdb.mi/mi2-var-stale-type.exp b/gdb/testsuite/gdb.mi/mi2-var-stale-type.exp
new file mode 100644
-index 0000000..2e01344
+index 0000000..74a104e
--- /dev/null
-+++ b/gdb/testsuite/gdb.threads/watchpoint-fork.exp
-@@ -0,0 +1,149 @@
-+# Copyright 2012 Free Software Foundation, Inc.
++++ b/gdb/testsuite/gdb.mi/mi2-var-stale-type.exp
+@@ -0,0 +1,57 @@
++# Copyright 2011 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
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
-+# Test case for forgotten hw-watchpoints after fork()-off of a process.
-+
-+proc test {type symbol} {
-+ global objdir subdir srcdir gdb_prompt
-+
-+ set testfile watchpoint-fork
-+
-+ global pf_prefix
-+ set prefix_test $pf_prefix
-+ lappend pf_prefix "$type:"
-+ set prefix_mt $pf_prefix
-+
-+ set srcfile_type ${srcdir}/${subdir}/${testfile}-${type}.c
-+
-+
-+ # no threads
-+
-+ set pf_prefix $prefix_mt
-+ lappend pf_prefix "singlethreaded:"
-+
-+ set executable ${testfile}-${type}-st
-+ set srcfile_main ${srcdir}/${subdir}/${testfile}-st.c
-+ if { [gdb_compile "${srcfile_main} ${srcfile_type}" ${objdir}/${subdir}/${executable} executable [list debug additional_flags=-D$symbol]] != "" } {
-+ untested ${testfile}.exp
-+ return
-+ }
-+ clean_restart $executable
-+
-+ gdb_test "show detach-on-fork" "Whether gdb will detach the child of a fork is on\\."
-+ gdb_test_no_output "set follow-fork-mode $type"
-+ gdb_test "show follow-fork-mode" "Debugger response to a program call of fork or vfork is \"$type\"\\."
-+ # Testcase uses it for the `follow-fork-mode child' type.
-+ gdb_test "handle SIGUSR1 nostop noprint pass" "No\[ \t\]+No\[ \t\]+Yes.*"
-+
-+ if ![runto_main] {
-+ return
-+ }
-+
-+ gdb_test "watch var" "atchpoint \[0-9\]+: var" "Set the watchpoint"
++load_lib mi-support.exp
++set MIFLAGS "-i=mi2"
+
-+ # It is never hit but it should not be left over in the fork()ed-off child.
-+ set hbreak "hbreak"
-+ set test "hbreak marker"
-+ gdb_test_multiple $test $test {
-+ -re "Hardware assisted breakpoint \[0-9\]+ at .*\r\n$gdb_prompt $" {
-+ pass $test
-+ }
-+ -re "(No hardware breakpoint support in the target\\.|Hardware breakpoints used exceeds limit\\.)\r\n$gdb_prompt $" {
-+ pass $test
-+ set hbreak "break"
-+ gdb_test "break marker"
-+ }
-+ }
++gdb_exit
++if [mi_gdb_start] {
++ continue
++}
+
-+ gdb_breakpoint "mark_exit"
++set testfile "mi2-var-stale-type"
++set srcfile ${testfile}.c
++set binfile ${objdir}/${subdir}/${testfile}
++if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} {
++ return -1
++}
+
-+ gdb_test "continue" \
-+ "reakpoint \[0-9\]+, marker.*" "hardware breakpoints work"
-+ gdb_test "continue" \
-+ "atchpoint \[0-9\]+: var.*Old value = 0.*New value = 1.*forkoff *\\(1\\).*" "watchpoints work"
-+ gdb_test "continue" \
-+ "reakpoint \[0-9\]+, marker.*" "breakpoint after the first fork"
-+ gdb_test "continue" \
-+ "atchpoint \[0-9\]+: var.*Old value = 1.*New value = 2.*forkoff *\\(2\\).*" "watchpoint after the first fork"
-+ gdb_test "continue" \
-+ "reakpoint \[0-9\]+, marker.*" "breakpoint after the second fork"
-+ gdb_test "continue" \
-+ "atchpoint \[0-9\]+: var.*Old value = 2.*New value = 3.*mark_exit \\(\\);" "watchpoint after the second fork"
-+ gdb_test "continue" "Continuing\\..*\r\nBreakpoint \[0-9\]+, mark_exit .*" "finish"
++mi_delete_breakpoints
++mi_gdb_reinitialize_dir $srcdir/$subdir
++mi_gdb_load ${binfile}
+
++mi_gdb_test {-interpreter-exec console "maintenance set internal-error quit yes"} \
++ {\^done} \
++ "maintenance set internal-error quit yes"
+
-+ # threads
++mi_gdb_test {-interpreter-exec console "maintenance set internal-error corefile yes"} \
++ {\^done} \
++ "maintenance set internal-error corefile yes"
+
-+ set pf_prefix $prefix_mt
-+ lappend pf_prefix "multithreaded:"
++set line [gdb_get_line_number "break-here"]
++set func "main"
+
-+ set executable ${testfile}-${type}-mt
-+ set srcfile_main ${srcdir}/${subdir}/${testfile}-mt.c
-+ if { [gdb_compile_pthreads "${srcfile_main} ${srcfile_type}" ${objdir}/${subdir}/${executable} executable [list debug "additional_flags=-D$symbol -DTHREAD"]] != "" } {
-+ untested ${testfile}.exp
-+ return
-+ }
-+ clean_restart $executable
++mi_gdb_test "-break-insert -t $srcfile:$line" \
++ "\\^done,bkpt=\{number=\"\[0-9\]+\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"$func\(\\\(.*\\\)\)?\",file=\".*\",line=\"$line\",times=\"0\",original-location=\".*\"\}" \
++ "breakpoint at $func"
+
-+ gdb_test_no_output "set follow-fork-mode $type"
-+ # Testcase uses it for the `follow-fork-mode child' type.
-+ gdb_test "handle SIGUSR1 nostop noprint pass" "No\[ \t\]+No\[ \t\]+Yes.*"
++if { [mi_run_cmd] < 0 } {
++ return -1
++}
++mi_expect_stop "breakpoint-hit" $func ".*" ".*" "\[0-9\]+" { "" "disp=\"del\"" } "stop after initializing vla"
+
-+ if ![runto_main] {
-+ return
-+ }
++mi_create_varobj "vla" "vla" "create local variable vla"
+
-+ gdb_test "watch var" "atchpoint \[0-9\]+: var" "Set the watchpoint"
-+
-+ # It should not be left over in the fork()ed-off child.
-+ gdb_test "$hbreak marker" {reakpoint [0-9]+.*}
-+
-+ gdb_breakpoint "mark_exit"
-+
-+ gdb_test "continue" \
-+ "reakpoint \[0-9\]+, marker.*" "hardware breakpoints work"
-+ gdb_test "continue" \
-+ "atchpoint \[0-9\]+: var.*Old value = 0.*New value = 1.*validity-first.*" "singlethread watchpoints work"
-+ gdb_test "continue" \
-+ "atchpoint \[0-9\]+: var.*Old value = 1.*New value = 2.*validity-thread-A.*" "multithreaded watchpoints work at A"
-+ gdb_test "continue" \
-+ "atchpoint \[0-9\]+: var.*Old value = 2.*New value = 3.*validity-thread-B.*" "multithreaded watchpoints work at B"
-+ gdb_test "continue" \
-+ "reakpoint \[0-9\]+, marker.*" "breakpoint (A) after the first fork"
-+ gdb_test "continue" \
-+ "atchpoint \[0-9\]+: var.*Old value = 3.*New value = 4.*after-fork1-A.*" "watchpoint A after the first fork"
-+ gdb_test "continue" \
-+ "atchpoint \[0-9\]+: var.*Old value = 4.*New value = 5.*after-fork1-B.*" "watchpoint B after the first fork"
-+ gdb_test "continue" \
-+ "reakpoint \[0-9\]+, marker.*" "breakpoint (A) after the second fork"
-+ gdb_test "continue" \
-+ "atchpoint \[0-9\]+: var.*Old value = 5.*New value = 6.*after-fork2-A.*" "watchpoint A after the second fork"
-+ gdb_test "continue" \
-+ "atchpoint \[0-9\]+: var.*Old value = 6.*New value = 7.*after-fork2-B.*" "watchpoint B after the second fork"
-+ gdb_test "continue" "Continuing\\..*\r\nBreakpoint \[0-9\]+, mark_exit .*" "finish"
-+
-+
-+ # cleanup
-+ set pf_prefix $prefix_test
-+}
-+
-+test parent FOLLOW_PARENT
-+
-+# Only GNU/Linux is known to support `set follow-fork-mode child'.
-+if {[istarget "*-*-linux*"] && ![is_remote target]} {
-+ test child FOLLOW_CHILD
-+} else {
-+ untested "child"
-+}
-diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork.h b/gdb/testsuite/gdb.threads/watchpoint-fork.h
++mi_gdb_test "-var-update *" "\\^done,changelist=.*" "-var-update *"
+diff --git a/gdb/testsuite/gdb.opt/array-from-register-func.c b/gdb/testsuite/gdb.opt/array-from-register-func.c
new file mode 100644
-index 0000000..cb109fa
+index 0000000..729f457
--- /dev/null
-+++ b/gdb/testsuite/gdb.threads/watchpoint-fork.h
-@@ -0,0 +1,32 @@
-+/* Test case for forgotten hw-watchpoints after fork()-off of a process.
-+
-+ Copyright 2012 Free Software Foundation, Inc.
++++ b/gdb/testsuite/gdb.opt/array-from-register-func.c
+@@ -0,0 +1,22 @@
++/* This file is part of GDB, the GNU debugger.
+
-+ This file is part of GDB.
++ Copyright 2009 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2 of the License, or
++ 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,
+ 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. */
-+
-+#ifdef THREAD
-+#include <pthread.h>
-+
-+extern volatile int step;
-+extern pthread_t thread;
-+#endif /* THREAD */
-+
-+extern volatile int var;
++ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
-+extern void marker (void);
-+extern void forkoff (int nr);
-diff --git a/gdb/testsuite/gdb.trace/stap-trace.c b/gdb/testsuite/gdb.trace/stap-trace.c
++int
++func (int *arr)
++{
++ return arr[0];
++}
+diff --git a/gdb/testsuite/gdb.opt/array-from-register.c b/gdb/testsuite/gdb.opt/array-from-register.c
new file mode 100644
-index 0000000..27f317e
+index 0000000..3090e7e
--- /dev/null
-+++ b/gdb/testsuite/gdb.trace/stap-trace.c
-@@ -0,0 +1,71 @@
-+/* This testcase is part of GDB, the GNU debugger.
++++ b/gdb/testsuite/gdb.opt/array-from-register.c
+@@ -0,0 +1,28 @@
++/* This file is part of GDB, the GNU debugger.
+
-+ Copyright 2011 Free Software Foundation, Inc.
++ Copyright 2009 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 USE_PROBES
-+
-+#define _SDT_HAS_SEMAPHORES
-+__extension__ unsigned short teste_user_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
-+#define TEST teste_user_semaphore
-+
-+__extension__ unsigned short teste_two_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
-+#define TEST2 teste_two_semaphore
-+
-+#else
-+
-+#define TEST 1
-+#define TEST2 1
-+
-+#endif /* USE_PROBES */
++extern int func (int *arr);
+
-+#include <sys/sdt.h>
++int
++main (void)
++{
++ int arr[] = { 42 };
+
-+/* We only support SystemTap and only the v3 form. */
-+#if _SDT_NOTE_TYPE != 3
-+#error "not using SystemTap v3 probes"
-+#endif
++ func (arr);
+
-+void
-+m1 (int x)
-+{
-+ if (TEST2)
-+ STAP_PROBE1 (teste, two, x);
++ return 0;
+}
+diff --git a/gdb/testsuite/gdb.opt/array-from-register.exp b/gdb/testsuite/gdb.opt/array-from-register.exp
+new file mode 100644
+index 0000000..f2de718
+--- /dev/null
++++ b/gdb/testsuite/gdb.opt/array-from-register.exp
+@@ -0,0 +1,33 @@
++# Copyright 2009 Free Software Foundation, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 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 is part of the gdb testsuite.
+
-+int
-+f (int x)
-+{
-+ if (TEST)
-+ STAP_PROBE1(teste, user, x);
-+ return x+5;
++if { [prepare_for_testing array-from-register.exp "array-from-register" \
++ {array-from-register.c array-from-register-func.c} \
++ {debug optimize=-O2}] } {
++ return -1
+}
+
-+void
-+nothing (void)
-+{
-+ int a = 1 + 1;
-+ return;
++if ![runto func] then {
++ return -1
+}
+
-+int
-+main()
-+{
-+ f (f (23));
-+ m1 (46);
-+ nothing (); /* end-here */
++gdb_test "p arr" "\\$\[0-9\]+ = \\(int \\*\\) *0x\[0-9a-f\]+"
+
-+ return 0;
-+}
-diff --git a/gdb/testsuite/gdb.trace/stap-trace.exp b/gdb/testsuite/gdb.trace/stap-trace.exp
++# Seen regression:
++# Address requested for identifier "arr" which is in register $rdi
++gdb_test "p arr\[0\]" "\\$\[0-9\]+ = 42"
+diff --git a/gdb/testsuite/gdb.pascal/arrays.exp b/gdb/testsuite/gdb.pascal/arrays.exp
new file mode 100644
-index 0000000..b0f1d7d
+index 0000000..ccc6e1e
--- /dev/null
-+++ b/gdb/testsuite/gdb.trace/stap-trace.exp
-@@ -0,0 +1,129 @@
-+# Copyright 2011
-+# Free Software Foundation, Inc.
-+
++++ b/gdb/testsuite/gdb.pascal/arrays.exp
+@@ -0,0 +1,104 @@
++# Copyright 2008, 2009 Free Software Foundation, Inc.
++#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
-+load_lib "trace-support.exp"
-+
+if $tracelevel then {
-+ strace $tracelevel
++ strace $tracelevel
++}
++
++load_lib "pascal.exp"
++
++set testfile "arrays"
++set srcfile ${testfile}.pas
++set binfile ${objdir}/${subdir}/${testfile}$EXEEXT
++
++# These tests only work with fpc, using the -gw3 compile-option
++pascal_init
++if { $pascal_compiler_is_fpc != 1 } {
++ return -1
++}
++
++# Detect if the fpc version is below 2.3.0
++set fpc_generates_dwarf_for_dynamic_arrays 1
++if { ($fpcversion_major < 2) || ( ($fpcversion_major == 2) && ($fpcversion_minor < 3))} {
++ set fpc_generates_dwarf_for_dynamic_arrays 0
++}
++
++
++if {[gdb_compile_pascal "-gw3 ${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug ]] != "" } {
++ return -1
++}
++
++gdb_exit
++gdb_start
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_load ${binfile}
++set bp_location1 [gdb_get_line_number "set breakpoint 1 here"]
++set bp_location2 [gdb_get_line_number "set breakpoint 2 here"]
++
++
++if { [gdb_breakpoint ${srcfile}:${bp_location1}] } {
++ pass "setting breakpoint 1"
++}
++if { [gdb_breakpoint ${srcfile}:${bp_location2}] } {
++ pass "setting breakpoint 2"
++}
++
++# Verify that "start" lands inside the right procedure.
++if { [gdb_start_cmd] < 0 } {
++ untested start
++ return -1
++}
++
++gdb_test "" ".* at .*${srcfile}.*" "start"
++
++gdb_test "cont" "Breakpoint .*:${bp_location1}.*" "Going to first breakpoint"
++
++gdb_test "print StatArrInt" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61\\}" "Print static array of integer type"
++gdb_test "print StatArrInt_" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61\\}" "Print static array of integer"
++
++gdb_test "cont" "Breakpoint .*:${bp_location2}.*" "Going to second breakpoint"
++
++gdb_test "print StatArrChar" ".* = 'abcdefghijkl'" "Print static array of char"
++gdb_test "print Stat2dArrInt" ".* = \\{\\{0, 1, 2, 3, 4\\}, \\{1, 2, 3, 4, 5\\}, \\{2, 3, 4, 5, 6\\}, \\{3, 4, 5, 6, 7\\}, \\{4, 5, 6, 7, 8\\}, \\{5, 6, 7, 8, 9\\}, \\{6, 7, 8, 9, 10\\}, \\{7, 8, 9, 10, 11\\}, \\{8, 9, 10, 11, 12\\}, \\{9, 10, 11, 12, 13\\}, \\{10, 11, 12, 13, 14\\}, \\{11, 12, 13, 14, 15\\}\\}" "Print static 2-dimensional array of integer"
++
++if { $fpc_generates_dwarf_for_dynamic_arrays == 0} {
++ setup_xfail "*-*-*"
++}
++gdb_test "print DynArrInt" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62\\}" "Print dynamic array of integer type"
++if { $fpc_generates_dwarf_for_dynamic_arrays == 0} {
++ setup_xfail "*-*-*"
+}
++gdb_test "print DynArrInt_" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62\\}" "Print dynamic array of integer"
+
-+set testfile "stap-trace"
-+set srcfile ${testfile}.c
-+set executable $testfile
-+set binfile $objdir/$subdir/$executable
-+
-+set ws "\[\r\n\t \]+"
-+set cr "\[\r\n\]+"
-+
-+# Only x86 and x86_64 targets are supported for now.
-+
-+if { ![istarget "x86_64-*"] && ![istarget "i?86-*"] } {
-+ continue
++if { $fpc_generates_dwarf_for_dynamic_arrays == 0} {
++ setup_xfail "*-*-*"
+}
++gdb_test "print s" ".* = 'test'#0'string'" "Print string containing null-char"
+
-+proc compile_stap_bin {{ arg "" }} {
-+ global srcfile
-+ global binfile
-+ global srcdir
-+ global subdir
++if { $fpc_generates_dwarf_for_dynamic_arrays == 0} {
++ setup_xfail "*-*-*"
++}
++gdb_test "print DynArrStr" ".* = \\{'dstr0', 'dstr1', 'dstr2', 'dstr3', 'dstr4', 'dstr5', 'dstr6', 'dstr7', 'dstr8', 'dstr9', 'dstr10', 'dstr11', 'dstr12'\\}" "Print dynamic array of string"
+
-+ if { $arg != "" } {
-+ set arg "additional_flags=$arg"
-+ }
++if { $fpc_generates_dwarf_for_dynamic_arrays == 0} {
++ setup_xfail "*-*-*"
++}
++gdb_test "print StatArrStr" ".* = \\{'str0', 'str1', 'str2', 'str3', 'str4', 'str5', 'str6', 'str7', 'str8', 'str9', 'str10', 'str11', 'str12'\\}" "Print static array of string"
+
-+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
-+ executable [concat $arg debug nowarnings]] != "" } {
-+ untested "Could not compile ${srcfile}"
-+ return -1
-+ }
++if { $fpc_generates_dwarf_for_dynamic_arrays == 0} {
++ setup_xfail "*-*-*"
+}
++gdb_test "print DynArrChar" ".* = 'abcdefghijklm'" "Print dynamic array of char"
+
-+proc prepare_for_trace_test {} {
-+ global executable
+diff --git a/gdb/testsuite/gdb.pascal/arrays.pas b/gdb/testsuite/gdb.pascal/arrays.pas
+new file mode 100644
+index 0000000..295602d
+--- /dev/null
++++ b/gdb/testsuite/gdb.pascal/arrays.pas
+@@ -0,0 +1,82 @@
++{
++ Copyright 2008, 2009 Free Software Foundation, Inc.
+
-+ clean_restart $executable
++ 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.
+
-+ if { ![runto_main] } {
-+ perror "Could not run to `main'."
-+ continue
-+ }
++ 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.
+
-+ gdb_breakpoint [gdb_get_line_number "end-here"]
++ You should have received a copy of the GNU General Public License
++ along with this program. If not, see <http://www.gnu.org/licenses/>.
+}
+
-+proc run_trace_experiment { test_probe msg } {
-+ global gdb_prompt
-+
-+ set test "collect $msg: start trace experiment"
-+ gdb_test_multiple "tstart" "$test" {
-+ -re "^tstart\r\n$gdb_prompt $" {
-+ pass "$test"
-+ }
-+ }
++program arrays;
+
-+ gdb_test "continue" \
-+ "Continuing.*Breakpoint \[0-9\]+.*" \
-+ "collect $msg: run trace experiment"
-+ gdb_test "tstop" \
-+ "\[\r\n\]+" \
-+ "collect $msg: stop trace experiment"
-+ gdb_test "tfind start" \
-+ "#0 .*" \
-+ "collect $msg: tfind test frame"
-+}
++{$mode objfpc}{$h+}
+
-+proc gdb_collect_probe_arg { msg probe val_arg0 } {
-+ global gdb_prompt
-+ global cr
++uses sysutils;
+
-+ prepare_for_trace_test
++type TStatArrInt= array[0..11] of integer;
++ TDynArrInt= array of integer;
++ TStatArrStr= array[0..12] of string;
++ TDynArrStr= array of string;
++ TDynArrChar = array of char;
++ TStatArrChar = array [0..11] of char;
+
-+ gdb_test "trace $probe" \
-+ "Tracepoint \[0-9\]+ at .*" \
-+ "collect $msg: set tracepoint"
-+ gdb_trace_setactions "collect $msg: define actions" \
-+ "" \
-+ "collect \$_probe_arg0" "^$"
++ TStat2dArrInt = array[0..11,0..4] of integer;
+
-+ # Begin the test.
-+ run_trace_experiment $msg $probe
++var StatArrInt: TStatArrInt;
++ StatArrInt_: Array[0..11] of integer;
++ DynArrInt: TDynArrInt;
++ DynArrInt_: Array of integer;
++ StatArrStr: TStatArrStr;
++ DynArrStr: TDynArrStr;
++ StatArrChar: TStatArrChar;
++ DynArrChar: TDynArrChar;
+
-+ gdb_test "print \$_probe_arg0" \
-+ "\\$\[0-9\]+ = $val_arg0$cr" \
-+ "collect $msg: collected probe arg0"
-+}
++ Stat2dArrInt: TStat2dArrInt;
+
-+compile_stap_bin ""
++ s: string;
++
++ i,j : integer;
+
-+clean_restart $executable
-+if { ![runto_main] } {
-+ perror "Could not run to `main'."
-+ continue
-+}
++begin
++ for i := 0 to 11 do
++ begin
++ StatArrInt[i]:= i+50;
++ StatArrInt_[i]:= i+50;
++ StatArrChar[i]:= chr(ord('a')+i);
++ for j := 0 to 4 do
++ Stat2dArrInt[i,j]:=i+j;
++ end;
++ writeln(StatArrInt_[0]);
++ writeln(StatArrInt[0]); { set breakpoint 1 here }
++ writeln(StatArrChar[0]);
++ writeln(Stat2dArrInt[0,0]);
+
-+if { ![gdb_target_supports_trace] } {
-+ # Test cannot run on this target.
-+ return 1;
-+}
++ setlength(DynArrInt,13);
++ setlength(DynArrInt_,13);
++ setlength(DynArrStr,13);
++ setlength(DynArrChar,13);
++ for i := 0 to 12 do
++ begin
++ DynArrInt[i]:= i+50;
++ DynArrInt_[i]:= i+50;
++ DynArrChar[i]:= chr(ord('a')+i);
++ StatArrStr[i]:='str'+inttostr(i);
++ DynArrStr[i]:='dstr'+inttostr(i);
++ end;
++ writeln(DynArrInt_[1]);
++ writeln(DynArrInt[1]);
++ writeln(DynArrStr[1]);
++ writeln(StatArrStr[1]);
++ writeln(DynArrChar[1]);
+
-+gdb_collect_probe_arg "probe args without semaphore" "-p user" "23"
-+gdb_exit
++ s := 'test'#0'string';
++ writeln(s); { set breakpoint 2 here }
++end.
+diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp
+index 993e774..52dbd17 100644
+--- a/gdb/testsuite/gdb.python/py-frame.exp
++++ b/gdb/testsuite/gdb.python/py-frame.exp
+@@ -74,8 +74,6 @@ gdb_test "python print bframe == gdb.newest_frame()" True \
+
+ gdb_test "python print 'result =', f0 == f1" " = False" "test equality comparison (false)"
+ gdb_test "python print 'result =', f0 == f0" " = True" "test equality comparison (true)"
+-gdb_test "python print 'result =', f0 != f1" " = True" "test inequality comparison (true)"
+-gdb_test "python print 'result =', f0 != f0" " = False" "test inequality comparison (false)"
+ gdb_test "python print 'result =', f0.is_valid ()" " = True" "test Frame.is_valid"
+ gdb_test "python print 'result =', f0.name ()" " = f2" "test Frame.name"
+ gdb_test "python print 'result =', f0.type () == gdb.NORMAL_FRAME" " = True" "test Frame.type"
+@@ -90,3 +88,5 @@ gdb_test "python print 'result =', f0.read_var ('variable_which_surely_doesnt_ex
+ gdb_test "python print 'result =', f0.read_var ('a')" " = 1" "test Frame.read_var - success"
+
+ gdb_test "python print 'result =', gdb.selected_frame () == f1" " = True" "test gdb.selected_frame"
+
-+compile_stap_bin "-DUSE_PROBES"
-+gdb_collect_probe_arg "probe args with semaphore" "-p two" "46"
++gdb_test "python print 'result =', f0.block ()" "<gdb.Block object at 0x\[\[:xdigit:\]\]+>" "test Frame.block"
+diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp
+index acfd89b..c77d9c2 100644
+--- a/gdb/testsuite/gdb.python/py-value.exp
++++ b/gdb/testsuite/gdb.python/py-value.exp
+@@ -358,6 +358,15 @@ proc test_value_after_death {} {
+ "print value's type"
+ }
+
++# Regression test for a cast failure. The bug was that if we cast a
++# value to its own type, gdb could crash. This happened because we
++# could end up double-freeing a struct value.
++proc test_cast_regression {} {
++ gdb_test "python v = gdb.Value(5)" "" "create value for cast test"
++ gdb_test "python v = v.cast(v.type)" "" "cast value for cast test"
++ gdb_test "python print v" "5" "print value for cast test"
++}
+
-+# Finished!
-+gdb_test "tfind none" ".*" ""
+ # Regression test for invalid subscript operations. The bug was that
+ # the type of the value was not being checked before allowing a
+ # subscript operation to proceed.
+@@ -494,6 +503,7 @@ test_value_in_inferior
+ test_inferior_function_call
+ test_lazy_strings
+ test_value_after_death
++test_cast_regression
+
+ # Test either C or C++ values.
+ test_subscript_regression "${binfile}" "c"
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
-index 00fe71c..5ca9563 100644
+index 4f2b7c9..0daef25 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
-@@ -139,6 +139,11 @@ proc gdb_unload {} {
+@@ -142,6 +142,11 @@ proc gdb_unload {} {
send_gdb "y\n"
exp_continue
}
}
set pascal_init_done 1
}
-diff --git a/gdb/thread.c b/gdb/thread.c
-index 9a29383..1a49b00 100644
---- a/gdb/thread.c
-+++ b/gdb/thread.c
-@@ -1431,7 +1431,8 @@ update_thread_list (void)
- no thread is selected, or no threads exist. */
-
- static struct value *
--thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var)
-+thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var,
-+ void *ignore)
- {
- struct thread_info *tp = find_thread_ptid (inferior_ptid);
-
-@@ -1442,6 +1443,15 @@ thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var)
- /* Commands with a prefix of `thread'. */
- struct cmd_list_element *thread_cmd_list = NULL;
-
-+/* Implementation of `thread' variable. */
-+
-+static struct internalvar_funcs thread_funcs =
-+{
-+ thread_id_make_value,
-+ NULL,
-+ NULL
-+};
-+
- void
- _initialize_thread (void)
- {
-@@ -1487,5 +1497,5 @@ Show printing of thread events (such as thread start and exit)."), NULL,
- show_print_thread_events,
- &setprintlist, &showprintlist);
-
-- create_internalvar_type_lazy ("_thread", thread_id_make_value);
-+ create_internalvar_type_lazy ("_thread", &thread_funcs, NULL);
- }
diff --git a/gdb/top.c b/gdb/top.c
-index c4e913d..5b79983 100644
+index 061ad48..d615cfc 100644
--- a/gdb/top.c
+++ b/gdb/top.c
-@@ -349,6 +349,9 @@ prepare_execute_command (void)
+@@ -352,6 +352,9 @@ prepare_execute_command (void)
mark = value_mark ();
cleanup = make_cleanup_value_free_to_mark (mark);
/* With multiple threads running while the one we're examining is
stopped, the dcache can get stale without us being able to detect
-diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
-index ede3742..b20f733 100644
---- a/gdb/tracepoint.c
-+++ b/gdb/tracepoint.c
-@@ -683,7 +683,7 @@ validate_actionline (char **line, struct breakpoint *b)
- struct cleanup *old_chain = NULL;
- char *p, *tmp_p;
- struct bp_location *loc;
-- struct agent_expr *aexpr;
-+ struct agent_expr *aexpr = NULL;
- struct tracepoint *t = (struct tracepoint *) b;
-
- /* If EOF is typed, *line is NULL. */
-@@ -1352,7 +1352,7 @@ encode_actions_1 (struct command_line *action,
- int i;
- struct value *tempval;
- struct cmd_list_element *cmd;
-- struct agent_expr *aexpr;
-+ struct agent_expr *aexpr = NULL;
-
- for (; action; action = action->next)
- {
-@@ -1716,6 +1716,7 @@ start_tracing (char *notes)
- for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, b); ix++)
- {
- struct tracepoint *t = (struct tracepoint *) b;
-+ struct bp_location *loc;
-
- if (b->enable_state == bp_enabled)
- any_enabled = 1;
-@@ -1778,6 +1779,9 @@ start_tracing (char *notes)
- }
-
- t->number_on_target = b->number;
-+
-+ for (loc = b->loc; loc; loc = loc->next)
-+ modify_semaphore (loc, 1);
- }
- VEC_free (breakpoint_p, tp_vec);
-
-@@ -1850,9 +1854,28 @@ void
- stop_tracing (char *note)
- {
- int ret;
-+ VEC(breakpoint_p) *tp_vec = NULL;
-+ int ix;
-+ struct breakpoint *t;
-
- target_trace_stop ();
-
-+ tp_vec = all_tracepoints ();
-+ for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
-+ {
-+ struct bp_location *loc;
-+
-+ if ((t->type == bp_fast_tracepoint
-+ ? !may_insert_fast_tracepoints
-+ : !may_insert_tracepoints))
-+ continue;
-+
-+ for (loc = t->loc; loc; loc = loc->next)
-+ modify_semaphore (loc, 0);
-+ }
-+
-+ VEC_free (breakpoint_p, tp_vec);
-+
- if (!note)
- note = trace_stop_notes;
- ret = target_set_trace_notes (NULL, NULL, note);
-@@ -4924,7 +4947,8 @@ info_static_tracepoint_markers_command (char *arg, int from_tty)
- available. */
-
- static struct value *
--sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var)
-+sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var,
-+ void *ignore)
- {
- LONGEST size;
- gdb_byte *buf;
-@@ -5103,6 +5127,15 @@ traceframe_available_memory (VEC(mem_range_s) **result,
- return 0;
- }
-
-+/* Implementation of `sdata' variable. */
-+
-+static const struct internalvar_funcs sdata_funcs =
-+{
-+ sdata_make_value,
-+ NULL,
-+ NULL
-+};
-+
- /* module initialization */
- void
- _initialize_tracepoint (void)
-@@ -5113,7 +5146,7 @@ _initialize_tracepoint (void)
- value with a void typed value, and when we get here, gdbarch
- isn't initialized yet. At this point, we're quite sure there
- isn't another convenience variable of the same name. */
-- create_internalvar_type_lazy ("_sdata", sdata_make_value);
-+ create_internalvar_type_lazy ("_sdata", &sdata_funcs, NULL);
-
- traceframe_number = -1;
- tracepoint_number = -1;
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
-index de96fd5..75485ff 100644
+index c25e705..498958a 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -35,6 +35,7 @@
extern void _initialize_typeprint (void);
@@ -76,6 +77,9 @@ void
- type_print (struct type *type, char *varstring, struct ui_file *stream,
+ type_print (struct type *type, const char *varstring, struct ui_file *stream,
int show)
{
+ if (show >= 0 && current_language->la_language != language_ada)
type = value_type (val);
get_user_print_options (&opts);
-@@ -167,8 +173,7 @@ whatis_exp (char *exp, int show)
+@@ -158,8 +164,7 @@ whatis_exp (char *exp, int show)
type_print (type, "", gdb_stdout, show);
printf_filtered ("\n");
static void
diff --git a/gdb/utils.c b/gdb/utils.c
-index 4863e41..c1fec82 100644
+index 5566149..6e1aa34 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
-@@ -1904,6 +1904,36 @@ set_batch_flag_and_make_cleanup_restore_page_info (void)
+@@ -27,6 +27,7 @@
+ #include "exceptions.h"
+ #include "gdbthread.h"
+ #include "fnmatch.h"
++#include "gdb_bfd.h"
+ #ifdef HAVE_SYS_RESOURCE_H
+ #include <sys/resource.h>
+ #endif /* HAVE_SYS_RESOURCE_H */
+@@ -198,11 +199,11 @@ make_cleanup_dyn_string_delete (dyn_string_t arg)
+ static void
+ do_bfd_close_cleanup (void *arg)
+ {
+- bfd_close (arg);
++ gdb_bfd_unref (arg);
+ }
+
+ struct cleanup *
+-make_cleanup_bfd_close (bfd *abfd)
++make_cleanup_bfd_unref (bfd *abfd)
+ {
+ return make_cleanup (do_bfd_close_cleanup, abfd);
+ }
+@@ -1738,6 +1739,36 @@ set_batch_flag_and_make_cleanup_restore_page_info (void)
return back_to;
}
static void
diff --git a/gdb/valarith.c b/gdb/valarith.c
-index b8bcc6b..fb83c70 100644
+index 96d5411..37bd464 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -197,7 +197,10 @@ value_subscripted_rvalue (struct value *array, LONGEST index, int lowerbound)
}
diff --git a/gdb/valops.c b/gdb/valops.c
-index 5453b1a..5a4a8fa 100644
+index 97d889b..6ae77b8 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -45,6 +45,7 @@
extern int overload_debug;
/* Local functions. */
-@@ -915,6 +916,65 @@ value_one (struct type *type)
+@@ -919,6 +920,65 @@ value_one (struct type *type)
return val;
}
/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack. */
static struct value *
-@@ -1011,12 +1071,20 @@ value_fetch_lazy (struct value *val)
+@@ -981,7 +1041,8 @@ int
+ value_fetch_lazy (struct value *val)
+ {
+ gdb_assert (value_lazy (val));
+- allocate_value_contents (val);
++ if (VALUE_LVAL (val) != lval_memory)
++ allocate_value_contents (val);
+ if (value_bitsize (val))
+ {
+ /* To read a lazy bitfield, read the entire enclosing value. This
+@@ -1015,12 +1076,24 @@ value_fetch_lazy (struct value *val)
}
else if (VALUE_LVAL (val) == lval_memory)
{
+
+ if (length)
+ {
++ /* Delay it after object_address_get_data above. */
++ allocate_value_contents (val);
+ addr += value_offset (val);
+ read_value_memory (val, 0, value_stack (val),
+ addr, value_contents_all_raw (val), length);
+ }
+ }
++ /* Just to be sure it has been called. */
++ allocate_value_contents (val);
}
else if (VALUE_LVAL (val) == lval_register)
{
-@@ -1528,7 +1596,18 @@ address_of_variable (struct symbol *var, struct block *b)
+@@ -1530,7 +1603,18 @@ address_of_variable (struct symbol *var, struct block *b)
if ((VALUE_LVAL (val) == lval_memory && value_lazy (val))
|| TYPE_CODE (type) == TYPE_CODE_FUNC)
{
return value_from_pointer (lookup_pointer_type (type), addr);
}
-@@ -1635,6 +1714,7 @@ struct value *
+@@ -1637,6 +1721,7 @@ struct value *
value_coerce_array (struct value *arg1)
{
struct type *type = check_typedef (value_type (arg1));
/* If the user tries to do something requiring a pointer with an
array that has not yet been pushed to the target, then this would
-@@ -1644,8 +1724,12 @@ value_coerce_array (struct value *arg1)
+@@ -1646,8 +1731,12 @@ value_coerce_array (struct value *arg1)
if (VALUE_LVAL (arg1) != lval_memory)
error (_("Attempt to take address of value not located in memory."));
}
/* Given a value which is a function, return a value which is a pointer
-@@ -3694,6 +3778,8 @@ value_slice (struct value *array, int lowbound, int length)
+@@ -3769,6 +3858,8 @@ value_slice (struct value *array, int lowbound, int length)
TYPE_TARGET_TYPE (range_type),
lowbound,
lowbound + length - 1);
{
int i;
diff --git a/gdb/valprint.c b/gdb/valprint.c
-index 325cf40..70a98c2 100644
+index fc5942d..8333eb4 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -37,6 +37,7 @@
#include <errno.h>
-@@ -240,7 +241,6 @@ scalar_type_p (struct type *type)
+@@ -251,7 +252,6 @@ scalar_type_p (struct type *type)
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
case TYPE_CODE_SET:
case TYPE_CODE_BITSTRING:
return 0;
default:
-@@ -1198,6 +1198,7 @@ val_print_array_elements (struct type *type,
+@@ -1570,6 +1570,7 @@ val_print_array_elements (struct type *type,
{
unsigned int things_printed = 0;
unsigned len;
struct type *elttype, *index_type;
unsigned eltlen;
/* Position of the array element we are examining to see
-@@ -1206,9 +1207,33 @@ val_print_array_elements (struct type *type,
+@@ -1578,9 +1579,33 @@ val_print_array_elements (struct type *type,
/* Number of repetitions we have detected so far. */
unsigned int reps;
LONGEST low_bound, high_bound;
index_type = TYPE_INDEX_TYPE (type);
if (get_array_bounds (type, &low_bound, &high_bound))
-@@ -1295,6 +1320,8 @@ val_print_array_elements (struct type *type,
+@@ -1667,6 +1692,8 @@ val_print_array_elements (struct type *type,
{
fprintf_filtered (stream, "...");
}
/* Read LEN bytes of target memory at address MEMADDR, placing the
diff --git a/gdb/value.c b/gdb/value.c
-index 583be33..cb73eda 100644
+index a6bb718..7b08d1f 100644
--- a/gdb/value.c
+++ b/gdb/value.c
-@@ -41,6 +41,7 @@
- #include "python/python.h"
+@@ -42,6 +42,7 @@
#include <ctype.h>
#include "tracepoint.h"
+ #include "cp-abi.h"
+#include "observer.h"
/* Prototypes for exported functions. */
-@@ -1385,12 +1386,15 @@ void
+@@ -1437,12 +1438,15 @@ void
set_value_component_location (struct value *component,
const struct value *whole)
{
if (whole->lval == lval_computed)
{
const struct lval_funcs *funcs = whole->location.computed.funcs;
-@@ -1398,6 +1402,12 @@ set_value_component_location (struct value *component,
+@@ -1450,6 +1454,12 @@ set_value_component_location (struct value *component,
if (funcs->copy_closure)
component->location.computed.closure = funcs->copy_closure (whole);
}
}
\f
-@@ -1531,6 +1541,31 @@ show_values (char *num_exp, int from_tty)
+@@ -1583,6 +1593,31 @@ show_values (char *num_exp, int from_tty)
num_exp[1] = '\0';
}
}
\f
/* Internal variables. These are variables within the debugger
that hold values assigned by debugger commands.
-@@ -1576,7 +1611,14 @@ struct internalvar
- struct value *value;
-
- /* The call-back routine used with INTERNALVAR_MAKE_VALUE. */
-- internalvar_make_value make_value;
-+ struct
-+ {
-+ /* The functions to call. */
-+ const struct internalvar_funcs *functions;
-+
-+ /* The function's user-data. */
-+ void *data;
-+ } make_value;
-
- /* The internal function used with INTERNALVAR_FUNCTION. */
- struct
-@@ -1675,18 +1717,39 @@ create_internalvar (const char *name)
- /* Create an internal variable with name NAME and register FUN as the
- function that value_of_internalvar uses to create a value whenever
- this variable is referenced. NAME should not normally include a
-- dollar sign. */
-+ dollar sign. DATA is passed uninterpreted to FUN when it is
-+ called. CLEANUP, if not NULL, is called when the internal variable
-+ is destroyed. It is passed DATA as its only argument. */
-
- struct internalvar *
--create_internalvar_type_lazy (char *name, internalvar_make_value fun)
-+create_internalvar_type_lazy (const char *name,
-+ const struct internalvar_funcs *funcs,
-+ void *data)
- {
- struct internalvar *var = create_internalvar (name);
-
- var->kind = INTERNALVAR_MAKE_VALUE;
-- var->u.make_value = fun;
-+ var->u.make_value.functions = funcs;
-+ var->u.make_value.data = data;
- return var;
- }
-
-+/* See documentation in value.h. */
-+
-+int
-+compile_internalvar_to_ax (struct internalvar *var,
-+ struct agent_expr *expr,
-+ struct axs_value *value)
-+{
-+ if (var->kind != INTERNALVAR_MAKE_VALUE
-+ || var->u.make_value.functions->compile_to_ax == NULL)
-+ return 0;
-+
-+ var->u.make_value.functions->compile_to_ax (var, expr, value,
-+ var->u.make_value.data);
-+ return 1;
-+}
-+
- /* Look up an internal variable with name NAME. NAME should not
- normally include a dollar sign.
-
-@@ -1759,7 +1822,8 @@ value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var)
- break;
-
- case INTERNALVAR_MAKE_VALUE:
-- val = (*var->u.make_value) (gdbarch, var);
-+ val = (*var->u.make_value.functions->make_value) (gdbarch, var,
-+ var->u.make_value.data);
- break;
-
- default:
-@@ -1955,6 +2019,11 @@ clear_internalvar (struct internalvar *var)
- xfree (var->u.string);
- break;
-
-+ case INTERNALVAR_MAKE_VALUE:
-+ if (var->u.make_value.functions->destroy != NULL)
-+ var->u.make_value.functions->destroy (var->u.make_value.data);
-+ break;
-+
- default:
- break;
- }
-@@ -2009,6 +2078,38 @@ call_internal_function (struct gdbarch *gdbarch,
+@@ -2118,6 +2153,38 @@ call_internal_function (struct gdbarch *gdbarch,
return (*ifn->handler) (gdbarch, language, ifn->cookie, argc, argv);
}
/* The 'function' command. This does nothing -- it is just a
placeholder to let "help function NAME" work. This is also used as
the implementation of the sub-command that is created when
-@@ -2056,11 +2157,10 @@ preserve_one_value (struct value *value, struct objfile *objfile,
+@@ -2165,11 +2232,10 @@ preserve_one_value (struct value *value, struct objfile *objfile,
htab_t copied_types)
{
if (TYPE_OBJFILE (value->type) == objfile)
copied_types);
}
-@@ -2075,7 +2175,7 @@ preserve_one_internalvar (struct internalvar *var, struct objfile *objfile,
+@@ -2184,7 +2250,7 @@ preserve_one_internalvar (struct internalvar *var, struct objfile *objfile,
case INTERNALVAR_INTEGER:
if (var->u.integer.type && TYPE_OBJFILE (var->u.integer.type) == objfile)
var->u.integer.type
break;
case INTERNALVAR_VALUE:
-@@ -3137,9 +3237,26 @@ coerce_ref_if_computed (const struct value *arg)
+@@ -3276,10 +3342,27 @@ readjust_indirect_value_type (struct value *value, struct type *enc_type,
struct value *
coerce_ref (struct value *arg)
{
- struct type *value_type_arg_tmp = check_typedef (value_type (arg));
+ struct type *value_type_arg_tmp;
struct value *retval;
+ struct type *enc_type;
+ if (TYPE_DYNAMIC (value_type (arg)))
+ {
retval = coerce_ref_if_computed (arg);
if (retval)
return retval;
-@@ -3241,4 +3358,10 @@ VARIABLE is already initialized."));
+@@ -3386,4 +3469,10 @@ VARIABLE is already initialized."));
add_prefix_cmd ("function", no_class, function_command, _("\
Placeholder command for showing help on convenience functions."),
&functionlist, "function ", 0, &cmdlist);
+#endif
}
diff --git a/gdb/value.h b/gdb/value.h
-index 4727755..d8d22c8 100644
+index d8b157f..f49e827 100644
--- a/gdb/value.h
+++ b/gdb/value.h
-@@ -488,6 +488,10 @@ extern struct value *value_from_decfloat (struct type *type,
+@@ -533,6 +533,10 @@ extern struct value *value_from_decfloat (struct type *type,
const gdb_byte *decbytes);
extern struct value *value_from_history_ref (char *, char **);
extern struct value *value_at (struct type *type, CORE_ADDR addr);
extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr);
-@@ -717,10 +721,52 @@ extern struct internalvar *lookup_only_internalvar (const char *name);
+diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
+index f16588a..afef615 100644
+--- a/gdb/windows-nat.c
++++ b/gdb/windows-nat.c
+@@ -752,7 +752,7 @@ windows_make_so (const char *name, LPVOID load_addr)
+ asection *text = NULL;
+ CORE_ADDR text_vma;
- extern struct internalvar *create_internalvar (const char *name);
+- abfd = bfd_openr (so->so_name, "pei-i386");
++ abfd = gdb_bfd_openr (so->so_name, "pei-i386");
--typedef struct value * (*internalvar_make_value) (struct gdbarch *,
-- struct internalvar *);
-+/* An internalvar can be dynamically computed by supplying a vector of
-+ function pointers to perform various operations. */
-+
-+struct internalvar_funcs
-+{
-+ /* Compute the value of the variable. The DATA argument passed to
-+ the function is the same argument that was passed to
-+ `create_internalvar_type_lazy'. */
-+
-+ struct value *(*make_value) (struct gdbarch *arch,
-+ struct internalvar *var,
-+ void *data);
-+
-+ /* Update the agent expression EXPR with bytecode to compute the
-+ value. VALUE is the agent value we are updating. The DATA
-+ argument passed to this function is the same argument that was
-+ passed to `create_internalvar_type_lazy'. If this pointer is
-+ NULL, then the internalvar cannot be compiled to an agent
-+ expression. */
-+
-+ void (*compile_to_ax) (struct internalvar *var,
-+ struct agent_expr *expr,
-+ struct axs_value *value,
-+ void *data);
-+
-+ /* If non-NULL, this is called to destroy DATA. The DATA argument
-+ passed to this function is the same argument that was passed to
-+ `create_internalvar_type_lazy'. */
-+
-+ void (*destroy) (void *data);
-+};
-+
- extern struct internalvar *
-- create_internalvar_type_lazy (char *name, internalvar_make_value fun);
-+create_internalvar_type_lazy (const char *name,
-+ const struct internalvar_funcs *funcs,
-+ void *data);
-+
-+/* Compile an internal variable to an agent expression. VAR is the
-+ variable to compile; EXPR and VALUE are the agent expression we are
-+ updating. This will return 0 if there is no known way to compile
-+ VAR, and 1 if VAR was successfully compiled. It may also throw an
-+ exception on error. */
-+
-+extern int compile_internalvar_to_ax (struct internalvar *var,
-+ struct agent_expr *expr,
-+ struct axs_value *value);
+ if (!abfd)
+ return so;
+@@ -762,7 +762,7 @@ windows_make_so (const char *name, LPVOID load_addr)
- extern struct internalvar *lookup_internalvar (const char *name);
+ if (!text)
+ {
+- bfd_close (abfd);
++ gdb_bfd_unref (abfd);
+ return so;
+ }
-diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
-index e111d41..18e3180 100644
---- a/gdb/windows-tdep.c
-+++ b/gdb/windows-tdep.c
-@@ -268,7 +268,7 @@ static const struct lval_funcs tlb_value_funcs =
- if there's no object available. */
+@@ -773,7 +773,7 @@ windows_make_so (const char *name, LPVOID load_addr)
+ load_addr + 0x1000);
+ cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text);
- static struct value *
--tlb_make_value (struct gdbarch *gdbarch, struct internalvar *var)
-+tlb_make_value (struct gdbarch *gdbarch, struct internalvar *var, void *ignore)
- {
- if (target_has_stack && !ptid_equal (inferior_ptid, null_ptid))
- {
-@@ -425,6 +425,15 @@ init_w32_command_list (void)
+- bfd_close (abfd);
++ gdb_bfd_unref (abfd);
}
- }
-
-+/* Implementation of `tlb' variable. */
-+
-+static const struct internalvar_funcs tlb_funcs =
-+{
-+ tlb_make_value,
-+ NULL,
-+ NULL
-+};
-+
- void
- _initialize_windows_tdep (void)
- {
-@@ -451,5 +460,5 @@ even if their meaning is unknown."),
- value with a void typed value, and when we get here, gdbarch
- isn't initialized yet. At this point, we're quite sure there
- isn't another convenience variable of the same name. */
-- create_internalvar_type_lazy ("_tlb", tlb_make_value);
-+ create_internalvar_type_lazy ("_tlb", &tlb_funcs, NULL);
- }
-diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
-index 1a2bb14..d43e946 100644
---- a/gdb/xcoffread.c
-+++ b/gdb/xcoffread.c
-@@ -3123,6 +3123,7 @@ static const struct sym_fns xcoff_sym_fns =
- default_symfile_segments, /* Get segment information from a file. */
- aix_process_linenos,
- default_symfile_relocate, /* Relocate a debug section. */
-+ NULL, /* sym_probe_fns */
- &psym_functions
- };
+ #endif