Blob Blame History Raw
http://sourceware.org/gdb/wiki/ProjectArcher
http://sourceware.org/gdb/wiki/ArcherBranchManagement

GIT snapshot:
commit 16f3f01cc2cbc15283462eaabdfcde92cf42cdc6

branch `archer' - the merge of branches:
archer-tromey-call-frame-cfa
archer-tromey-delayed-symfile
archer-tromey-dw-op-value
archer-jankratochvil-vla
archer-jankratochvil-misc
archer-keiths-expr-cumulative
archer-tromey-python
archer-jankratochvil-fortran-module
archer-jankratochvil-watchpoint
archer-jankratochvil-bp_location-accel
archer-pmuldoon-next-over-throw


diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index f5e1dde..73ee55c 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -169,6 +169,10 @@ TARGET_SYSTEM_ROOT_DEFINE = @TARGET_SYSTEM_ROOT_DEFINE@
 # Did the user give us a --with-gdb-datadir option?
 GDB_DATADIR_PATH = @GDB_DATADIR_PATH@
 
+# The argument to --with-pythondir.  If not given, this is
+# GDB_DATADIR_PATH/python.
+pythondir = @pythondir@
+
 # Helper code from gnulib.
 LIBGNU = gnulib/libgnu.a
 INCGNU = -I$(srcdir)/gnulib -Ignulib
@@ -267,21 +271,37 @@ SUBDIR_TUI_CFLAGS= \
 #
 SUBDIR_PYTHON_OBS = \
 	python.o \
+	py-block.o \
+	py-breakpoint.o \
 	py-cmd.o \
 	py-frame.o \
 	py-function.o \
+	py-hooks.o \
+	py-inferior.o \
+	py-infthread.o \
 	py-objfile.o \
+	py-param.o \
 	py-prettyprint.o \
+	py-symbol.o \
+	py-symtab.o \
 	py-type.o \
 	py-utils.o \
 	py-value.o
 SUBDIR_PYTHON_SRCS = \
 	python/python.c \
+	python/py-block.c \
+	python/py-breakpoint.c \
 	python/py-cmd.c \
 	python/py-frame.c \
 	python/py-function.c \
+	python/py-hooks.c \
+	python/py-inferior.c \
+	python/py-infthread.c \
 	python/py-objfile.c \
+	python/py-param.c \
 	python/py-prettyprint.c \
+	python/py-symbol.c \
+	python/py-symtab.c \
 	python/py-type.c \
 	python/py-utils.c \
 	python/py-value.c
@@ -750,7 +770,7 @@ config/rs6000/nm-rs6000.h top.h bsd-kvm.h gdb-stabs.h reggroups.h \
 annotate.h sim-regno.h dictionary.h dfp.h main.h frame-unwind.h	\
 remote-fileio.h i386-linux-tdep.h vax-tdep.h objc-lang.h \
 sentinel-frame.h bcache.h symfile.h windows-tdep.h linux-tdep.h \
-gdb_usleep.h jit.h xml-syscall.h ada-operator.inc
+gdb_usleep.h jit.h xml-syscall.h ada-operator.inc python/python.h python/python-internal.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -874,7 +894,7 @@ generated_files = config.h observer.h observer.inc ada-lex.c \
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
-all: gdb$(EXEEXT) $(CONFIG_ALL) xml-syscall-copy
+all: gdb$(EXEEXT) $(CONFIG_ALL) xml-syscall-copy .gdbinit
 	@$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do
 .PHONY: all-tui
 all-tui: $(TUI)$(EXEEXT)
@@ -1264,6 +1284,12 @@ stamp-h: $(srcdir)/config.in config.status
 	  CONFIG_LINKS= \
 	  $(SHELL) config.status
 
+.gdbinit: $(srcdir)/gdbinit.in config.status
+	CONFIG_FILES=".gdbinit:gdbinit.in" \
+	  CONFIG_COMMANDS= \
+	  CONFIG_HEADERS= \
+	  $(SHELL) config.status
+
 config.status: $(srcdir)/configure configure.tgt configure.host
 	$(SHELL) config.status --recheck
 
@@ -1963,6 +1989,14 @@ python.o: $(srcdir)/python/python.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
 	$(POSTCOMPILE)
 
+py-block.o: $(srcdir)/python/py-block.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-block.c
+	$(POSTCOMPILE)
+
+py-breakpoint.o: $(srcdir)/python/py-breakpoint.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-breakpoint.c
+	$(POSTCOMPILE)
+
 py-cmd.o: $(srcdir)/python/py-cmd.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-cmd.c
 	$(POSTCOMPILE)
@@ -1975,14 +2009,38 @@ py-function.o: $(srcdir)/python/py-function.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-function.c
 	$(POSTCOMPILE)
 
+py-hooks.o: $(srcdir)/python/py-hooks.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-hooks.c
+	$(POSTCOMPILE)
+
+py-inferior.o: $(srcdir)/python/py-inferior.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-inferior.c
+	$(POSTCOMPILE)
+
+py-infthread.o: $(srcdir)/python/py-infthread.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-infthread.c
+	$(POSTCOMPILE)
+
 py-objfile.o: $(srcdir)/python/py-objfile.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-objfile.c
 	$(POSTCOMPILE)
 
+py-param.o: $(srcdir)/python/py-param.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-param.c
+	$(POSTCOMPILE)
+
 py-prettyprint.o: $(srcdir)/python/py-prettyprint.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-prettyprint.c
 	$(POSTCOMPILE)
 
+py-symbol.o: $(srcdir)/python/py-symbol.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-symbol.c
+	$(POSTCOMPILE)
+
+py-symtab.o: $(srcdir)/python/py-symtab.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-symtab.c
+	$(POSTCOMPILE)
+
 py-type.o: $(srcdir)/python/py-type.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-type.c
 	$(POSTCOMPILE)
@@ -1995,6 +2053,36 @@ py-value.o: $(srcdir)/python/py-value.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-value.c
 	$(POSTCOMPILE)
 
+# All python library files, with the "python/lib" stripped off.
+# Note that we should only install files in the "gdb" module.
+PY_FILES = gdb/FrameIterator.py gdb/FrameWrapper.py gdb/command/alias.py \
+    gdb/command/backtrace.py gdb/command/require.py \
+    gdb/command/pahole.py gdb/command/upto.py gdb/command/__init__.py \
+    gdb/command/ignore_errors.py gdb/command/save_breakpoints.py \
+    gdb/function/caller_is.py gdb/function/in_scope.py \
+    gdb/function/__init__.py gdb/backtrace.py gdb/__init__.py
+
+# Install the Python library.  Python library files go under
+# $(pythondir).
+install-python:
+	files='$(PY_FILES)'; for file in $$files; do \
+	  dir=`echo "$$file" | sed 's,/[^/]*$$,,'`; \
+	  $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(pythondir)/$$dir; \
+	  $(INSTALL_DATA) $(srcdir)/python/lib/$$file $(DESTDIR)$(pythondir)/$$file; \
+	done
+
+# Other packages may have their files installed in $(pythondir).
+uninstall-python:
+	files='$(PY_FILES)'; for file in $$files; do \
+	  slashdir=`echo "/$$file" | sed 's,/[^/]*$$,,'`; \
+	  rm -f $(DESTDIR)$(pythondir)/$$file; \
+	  while test "x$$file" != "x$$slashdir"; do \
+	    rmdir 2>/dev/null "$(DESTDIR)$(pythondir)$$slashdir"; \
+	    file="$$slashdir"; \
+	    slashdir=`echo "$$file" | sed 's,/[^/]*$$,,'`; \
+	  done \
+	done
+
 #
 # Dependency tracking.  Most of this is conditional on GNU Make being
 # found by configure; if GNU Make is not found, we fall back to a
diff --git a/gdb/NEWS b/gdb/NEWS
index 4fc6dcd..6744b23 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -462,6 +462,13 @@ x86/x86_64 Darwin		i[34567]86-*-darwin*
 
 x86_64 MinGW			x86_64-*-mingw*
 
+* New native configurations
+
+x86/x86_64 Darwin		i[34567]86-*-darwin*
+
+info os processes
+  Show operating system information about processes.
+
 * New targets
 
 Lattice Mico32                  lm32-*
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 9b5d2c6..61676a9 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -1621,7 +1621,7 @@ ada_type_of_array (struct value *arr, int bounds)
         return NULL;
       while (arity > 0)
         {
-          struct type *range_type = alloc_type_copy (value_type (arr));
+	  struct type *range_type = alloc_type_copy (value_type (arr));
           struct type *array_type = alloc_type_copy (value_type (arr));
           struct value *low = desc_one_bound (descriptor, arity, 0);
           struct value *high = desc_one_bound (descriptor, arity, 1);
@@ -4727,14 +4727,10 @@ ada_lookup_symbol (const char *name, const struct block *block0,
 
 static struct symbol *
 ada_lookup_symbol_nonlocal (const char *name,
-                            const char *linkage_name,
                             const struct block *block,
                             const domain_enum domain)
 {
-  if (linkage_name == NULL)
-    linkage_name = name;
-  return ada_lookup_symbol (linkage_name, block_static_block (block), domain,
-                            NULL);
+  return ada_lookup_symbol (name, block_static_block (block), domain, NULL);
 }
 
 
@@ -10839,6 +10835,40 @@ ada_operator_length (struct expression *exp, int pc, int *oplenp, int *argsp)
     }
 }
 
+/* Implementation of the exp_descriptor method operator_check.  */
+
+static int
+ada_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)
+{
+  const union exp_element *const elts = exp->elts;
+  struct type *type = NULL;
+
+  switch (elts[pos].opcode)
+    {
+      case UNOP_IN_RANGE:
+      case UNOP_QUAL:
+	type = elts[pos + 1].type;
+	break;
+
+      default:
+	return operator_check_standard (exp, pos, type_func, objfile_func,
+					data);
+    }
+
+  /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL.  */
+
+  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;
+
+  return 0;
+}
+
 static char *
 ada_op_name (enum exp_opcode opcode)
 {
@@ -11227,6 +11257,7 @@ parse (void)
 static const struct exp_descriptor ada_exp_descriptor = {
   ada_print_subexp,
   ada_operator_length,
+  ada_operator_check,
   ada_op_name,
   ada_dump_subexp_body,
   ada_evaluate_subexp
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 7d8461c..a6d35d7 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -270,6 +270,8 @@ amd64_linux_dr_get (ptid_t ptid, int regnum)
   return value;
 }
 
+/* Set debug register REGNUM to VALUE in only the one LWP of PTID.  */
+
 static void
 amd64_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
 {
@@ -286,6 +288,8 @@ amd64_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
     perror_with_name (_("Couldn't write debug register"));
 }
 
+/* Set DR_CONTROL to ADDR in all LWPs of LWP_LIST.  */
+
 static void
 amd64_linux_dr_set_control (unsigned long control)
 {
@@ -297,6 +301,8 @@ amd64_linux_dr_set_control (unsigned long control)
     amd64_linux_dr_set (ptid, DR_CONTROL, control);
 }
 
+/* Set address REGNUM (zero based) to ADDR in all LWPs of LWP_LIST.  */
+
 static void
 amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
 {
@@ -310,18 +316,55 @@ amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
     amd64_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
 }
 
+/* Set address REGNUM (zero based) to zero in all LWPs of LWP_LIST.  */
+
 static void
 amd64_linux_dr_reset_addr (int regnum)
 {
   amd64_linux_dr_set_addr (regnum, 0);
 }
 
+/* Get DR_STATUS from only the one LWP of INFERIOR_PTID.  */
+
 static unsigned long
 amd64_linux_dr_get_status (void)
 {
   return amd64_linux_dr_get (inferior_ptid, DR_STATUS);
 }
 
+/* Unset VALUE bits in DR_STATUS in all LWPs of LWP_LIST.  */
+
+static void
+amd64_linux_dr_unset_status (unsigned long mask)
+{
+  struct lwp_info *lp;
+  ptid_t ptid;
+
+  ALL_LWPS (lp, ptid)
+    {
+      unsigned long value;
+      
+      value = amd64_linux_dr_get (ptid, DR_STATUS);
+      value &= ~mask;
+      amd64_linux_dr_set (ptid, DR_STATUS, value);
+    }
+}
+
+/* See i386_dr_low_type.detach.  Do not use wrappers amd64_linux_dr_set_control
+   or amd64_linux_dr_reset_addr as they would modify the register cache
+   (amd64_linux_dr).  */
+
+static void
+amd64_linux_dr_detach (void)
+{
+  int regnum;
+
+  amd64_linux_dr_set (inferior_ptid, DR_CONTROL, 0);
+  amd64_linux_dr_unset_status (~0UL);
+  for (regnum = DR_FIRSTADDR; regnum <= DR_LASTADDR; regnum++)
+    amd64_linux_dr_set (inferior_ptid, regnum, 0);
+}
+
 static void
 amd64_linux_new_thread (ptid_t ptid)
 {
@@ -672,6 +715,8 @@ _initialize_amd64_linux_nat (void)
   i386_dr_low.set_addr = amd64_linux_dr_set_addr;
   i386_dr_low.reset_addr = amd64_linux_dr_reset_addr;
   i386_dr_low.get_status = amd64_linux_dr_get_status;
+  i386_dr_low.unset_status = amd64_linux_dr_unset_status;
+  i386_dr_low.detach = amd64_linux_dr_detach;
   i386_set_debug_register_length (8);
 
   /* Override the GNU/Linux inferior startup hook.  */
diff --git a/gdb/block.c b/gdb/block.c
index 97ea67a..b20beeb 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -227,8 +227,9 @@ block_set_scope (struct block *block, const char *scope,
   BLOCK_NAMESPACE (block)->scope = scope;
 }
 
-/* This returns the using directives list associated with BLOCK, if
-   any.  */
+/* This returns the first using directives associated with BLOCK, if
+   any.  Each BLOCK_NAMESPACE()->USING already contains all the namespaces
+   imported at that code point - even those from its parent blocks.  */
 
 struct using_direct *
 block_using (const struct block *block)
@@ -318,6 +319,25 @@ allocate_block (struct obstack *obstack)
   BLOCK_SUPERBLOCK (bl) = NULL;
   BLOCK_DICT (bl) = NULL;
   BLOCK_NAMESPACE (bl) = NULL;
+  BLOCK_FORTRAN_USE (bl) = NULL;
 
   return bl;
 }
+
+/* Return OBJFILE in which BLOCK is located or NULL if we cannot find it for
+   whatever reason.  */
+
+struct objfile *
+block_objfile (const struct block *block)
+{
+  struct symbol *func;
+
+  if (block == NULL)
+    return NULL;
+
+  func = block_linkage_function (block);
+  if (func == NULL)
+    return NULL;
+
+  return SYMBOL_SYMTAB (func)->objfile;
+}
diff --git a/gdb/block.h b/gdb/block.h
index 53e7371..d373f8a 100644
--- a/gdb/block.h
+++ b/gdb/block.h
@@ -96,6 +96,15 @@ struct block
     cplus_specific;
   }
   language_specific;
+
+  /* FIXME: It should be in the LANGUAGE_SPECIFIC region but the
+     BLOCK_NAMESPACE accessor is not protected by the C language check.  */
+
+  struct
+    {
+      struct fortran_using *use;
+    }
+  fortran_specific;
 };
 
 #define BLOCK_START(bl)		(bl)->startaddr
@@ -104,6 +113,7 @@ struct block
 #define BLOCK_SUPERBLOCK(bl)	(bl)->superblock
 #define BLOCK_DICT(bl)		(bl)->dict
 #define BLOCK_NAMESPACE(bl)   (bl)->language_specific.cplus_specific.namespace
+#define BLOCK_FORTRAN_USE(bl)	(bl)->fortran_specific.use
 
 /* Macro to loop through all symbols in a block BL, in no particular
    order.  ITER helps keep track of the iteration, and should be a
@@ -166,4 +176,6 @@ extern const struct block *block_global_block (const struct block *block);
 
 extern struct block *allocate_block (struct obstack *obstack);
 
+extern struct objfile *block_objfile (const struct block *block);
+
 #endif /* BLOCK_H */
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 811cdfb..b0bf314 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -61,6 +61,7 @@
 #include "valprint.h"
 #include "jit.h"
 #include "xml-syscall.h"
+#include "parser-defs.h"
 
 /* readline include files */
 #include "readline/readline.h"
@@ -112,8 +113,6 @@ struct breakpoint *set_raw_breakpoint (struct gdbarch *gdbarch,
 					      struct symtab_and_line,
 					      enum bptype);
 
-static void check_duplicates (struct breakpoint *);
-
 static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int);
 
 static CORE_ADDR adjust_breakpoint_address (struct gdbarch *gdbarch,
@@ -337,14 +336,14 @@ static int executing_startup;
 	     B ? (TMP=B->next, 1): 0;	\
 	     B = TMP)
 
-/* Similar iterators for the low-level breakpoints.  */
-
-#define ALL_BP_LOCATIONS(B)  for (B = bp_location_chain; B; B = B->global_next)
+/* Similar iterator for the low-level breakpoints.  SAFE variant is not
+   provided so update_global_location_list must not be called while executing
+   the block of ALL_BP_LOCATIONS.  */
 
-#define ALL_BP_LOCATIONS_SAFE(B,TMP)	\
-	for (B = bp_location_chain;	\
-	     B ? (TMP=B->global_next, 1): 0;	\
-	     B = TMP)
+#define ALL_BP_LOCATIONS(B,BP_TMP)					\
+	for (BP_TMP = bp_location;					\
+	     BP_TMP < bp_location + bp_location_count && (B = *BP_TMP);	\
+	     BP_TMP++)
 
 /* Iterator for tracepoints only.  */
 
@@ -356,10 +355,31 @@ static int executing_startup;
 
 struct breakpoint *breakpoint_chain;
 
-struct bp_location *bp_location_chain;
+/* Array is sorted by bp_location_compare - primarily by the ADDRESS.  */
+
+static struct bp_location **bp_location;
+
+/* Number of elements of BP_LOCATION.  */
+
+static unsigned bp_location_count;
+
+/* Maximum alignment offset between bp_target_info.PLACED_ADDRESS and ADDRESS
+   for the current elements of BP_LOCATION which get a valid result from
+   bp_location_has_shadow.  You can use it for roughly limiting the subrange of
+   BP_LOCATION to scan for shadow bytes for an address you need to read.  */
+
+static CORE_ADDR bp_location_placed_address_before_address_max;
+
+/* Maximum offset plus alignment between
+   bp_target_info.PLACED_ADDRESS + bp_target_info.SHADOW_LEN and ADDRESS for
+   the current elements of BP_LOCATION which get a valid result from
+   bp_location_has_shadow.  You can use it for roughly limiting the subrange of
+   BP_LOCATION to scan for shadow bytes for an address you need to read.  */
+
+static CORE_ADDR bp_location_shadow_len_after_address_max;
 
 /* The locations that no longer correspond to any breakpoint,
-   unlinked from bp_location_chain, but for which a hit
+   unlinked from bp_location array, but for which a hit
    may still be reported by a target.  */
 VEC(bp_location_p) *moribund_locations = NULL;
 
@@ -582,6 +602,53 @@ get_breakpoint (int num)
 }
 
 
+/* Set break condition of breakpoint B to EXP.  */
+
+void
+set_breakpoint_condition (struct breakpoint *b, char *exp, int from_tty)
+{
+  struct bp_location *loc = b->loc;
+
+  for (; loc; loc = loc->next)
+    {
+      if (loc->cond)
+	{
+	  xfree (loc->cond);
+	  loc->cond = 0;
+	}
+    }
+
+  if (b->cond_string != NULL)
+    xfree (b->cond_string);
+
+  if (*exp == 0)
+    {
+      b->cond_string = NULL;
+      if (from_tty)
+	printf_filtered (_("Breakpoint %d now unconditional.\n"), b->number);
+    }
+  else
+    {
+      char *arg = exp;
+
+      /* I don't know if it matters whether this is the string the user
+	 typed in or the decompiled expression.  */
+      b->cond_string = xstrdup (arg);
+      b->condition_not_parsed = 0;
+      for (loc = b->loc; loc; loc = loc->next)
+	{
+	  arg = exp;
+	  loc->cond =
+	    parse_exp_1 (&arg, block_for_pc (loc->address), 0);
+	  if (*arg)
+	    error (_("Junk at end of expression"));
+	}
+    }
+
+  breakpoints_changed ();
+  observer_notify_breakpoint_modified (b->number);
+}
+
 /* condition N EXP -- set break condition of breakpoint N to EXP.  */
 
 static void
@@ -602,42 +669,7 @@ condition_command (char *arg, int from_tty)
   ALL_BREAKPOINTS (b)
     if (b->number == bnum)
       {
-	struct bp_location *loc = b->loc;
-	for (; loc; loc = loc->next)
-	  {
-	    if (loc->cond)
-	      {
-		xfree (loc->cond);
-		loc->cond = 0;
-	      }
-	  }
-	if (b->cond_string != NULL)
-	  xfree (b->cond_string);
-
-	if (*p == 0)
-	  {
-	    b->cond_string = NULL;
-	    if (from_tty)
-	      printf_filtered (_("Breakpoint %d now unconditional.\n"), bnum);
-	  }
-	else
-	  {
-	    arg = p;
-	    /* I don't know if it matters whether this is the string the user
-	       typed in or the decompiled expression.  */
-	    b->cond_string = xstrdup (arg);
-	    b->condition_not_parsed = 0;
-	    for (loc = b->loc; loc; loc = loc->next)
-	      {
-		arg = p;
-		loc->cond =
-		  parse_exp_1 (&arg, block_for_pc (loc->address), 0);
-		if (*arg)
-		  error (_("Junk at end of expression"));
-	      }
-	  }
-	breakpoints_changed ();
-	observer_notify_breakpoint_modified (b->number);
+	set_breakpoint_condition (b, p, from_tty);
 	return;
       }
 
@@ -735,35 +767,88 @@ commands_from_control_command (char *arg, struct command_line *cmd)
       }
   error (_("No breakpoint number %d."), bnum);
 }
-
+
+/* Return non-zero if BL->TARGET_INFO contains valid information.  */
+
+static int
+bp_location_has_shadow (struct bp_location *bl)
+{
+  if (bl->loc_type != bp_loc_software_breakpoint)
+    return 0;
+  if (!bl->inserted)
+    return 0;
+  if (bl->target_info.shadow_len == 0)
+    /* bp isn't valid, or doesn't shadow memory.  */
+    return 0;
+  return 1;
+}
+
 /* Update BUF, which is LEN bytes read from the target address MEMADDR,
-   by replacing any memory breakpoints with their shadowed contents.  */
+   by replacing any memory breakpoints with their shadowed contents.
+
+   The range of shadowed area by each bp_location is:
+     b->address - bp_location_placed_address_before_address_max
+     up to b->address + bp_location_shadow_len_after_address_max
+   The range we were requested to resolve shadows for is:
+     memaddr ... memaddr + le
+   Thus the safe cutoff boundaries for performance optimization are
+     memaddr + len <= b->address - bp_location_placed_address_before_address_max
+   and:
+     b->address + bp_location_shadow_len_after_address_max <= memaddr  */
 
 void
 breakpoint_restore_shadows (gdb_byte *buf, ULONGEST memaddr, LONGEST len)
 {
-  struct bp_location *b;
-  CORE_ADDR bp_addr = 0;
-  int bp_size = 0;
-  int bptoffset = 0;
+  /* Left boundary, right boundary and media element of our binary search.  */
+  unsigned bc_l, bc_r, bc;
+
+  /* Find BC_L which is a leftmost element which may affect BUF content.  It is
+     safe to report lower value but a failure to report higher one.  */
+
+  bc_l = 0;
+  bc_r = bp_location_count;
+  while (bc_l + 1 < bc_r)
+    {
+      struct bp_location *b;
 
-  ALL_BP_LOCATIONS (b)
+      bc = (bc_l + bc_r) / 2;
+      b = bp_location[bc];
+
+      if (b->address + bp_location_shadow_len_after_address_max >= b->address
+	  && b->address + bp_location_shadow_len_after_address_max <= memaddr)
+	bc_l = bc;
+      else
+	bc_r = bc;
+    }
+
+  /* Now do full processing of the found relevant range of elements.  */
+
+  for (bc = bc_l; bc < bp_location_count; bc++)
   {
+    struct bp_location *b = bp_location[bc];
+    CORE_ADDR bp_addr = 0;
+    int bp_size = 0;
+    int bptoffset = 0;
+
     if (b->owner->type == bp_none)
       warning (_("reading through apparently deleted breakpoint #%d?"),
               b->owner->number);
 
-    if (b->loc_type != bp_loc_software_breakpoint)
-      continue;
-    if (!b->inserted)
+    /* Performance optimization: any futher element can no longer affect BUF
+       content.  */
+
+    if (b->address >= bp_location_placed_address_before_address_max
+        && memaddr + len <= b->address
+			    - bp_location_placed_address_before_address_max)
+      break;
+
+    if (!bp_location_has_shadow (b))
       continue;
+
     /* Addresses and length of the part of the breakpoint that
        we need to copy.  */
     bp_addr = b->target_info.placed_address;
     bp_size = b->target_info.shadow_len;
-    if (bp_size == 0)
-      /* bp isn't valid, or doesn't shadow memory.  */
-      continue;
 
     if (bp_addr + bp_size <= memaddr)
       /* The breakpoint is entirely before the chunk of memory we
@@ -912,7 +997,7 @@ update_watchpoint (struct breakpoint *b, int reparse)
   struct bp_location *loc;
   bpstat bs;
 
-  /* We don't free locations.  They are stored in bp_location_chain and
+  /* We don't free locations.  They are stored in bp_location array and
      update_global_locations will eventually delete them and remove
      breakpoints if needed.  */
   b->loc = NULL;
@@ -1347,7 +1432,7 @@ static void
 insert_breakpoint_locations (void)
 {
   struct breakpoint *bpt;
-  struct bp_location *b, *temp;
+  struct bp_location *b, **bp_tmp;
   int error = 0;
   int val = 0;
   int disabled_breaks = 0;
@@ -1360,7 +1445,7 @@ insert_breakpoint_locations (void)
      there was an error.  */
   fprintf_unfiltered (tmp_error_stream, "Warning:\n");
 	
-  ALL_BP_LOCATIONS_SAFE (b, temp)
+  ALL_BP_LOCATIONS (b, bp_tmp)
     {
       if (!should_be_inserted (b) || b->inserted)
 	continue;
@@ -1434,10 +1519,10 @@ You may have requested too many hardware breakpoints/watchpoints.\n");
 int
 remove_breakpoints (void)
 {
-  struct bp_location *b;
+  struct bp_location *b, **bp_tmp;
   int val = 0;
 
-  ALL_BP_LOCATIONS (b)
+  ALL_BP_LOCATIONS (b, bp_tmp)
   {
     if (b->inserted)
       val |= remove_breakpoint (b, mark_uninserted);
@@ -1448,10 +1533,10 @@ remove_breakpoints (void)
 int
 remove_hw_watchpoints (void)
 {
-  struct bp_location *b;
+  struct bp_location *b, **bp_tmp;
   int val = 0;
 
-  ALL_BP_LOCATIONS (b)
+  ALL_BP_LOCATIONS (b, bp_tmp)
   {
     if (b->inserted && b->loc_type == bp_loc_hardware_watchpoint)
       val |= remove_breakpoint (b, mark_uninserted);
@@ -1462,7 +1547,7 @@ remove_hw_watchpoints (void)
 int
 reattach_breakpoints (int pid)
 {
-  struct bp_location *b;
+  struct bp_location *b, **bp_tmp;
   int val;
   struct cleanup *old_chain = save_inferior_ptid ();
   struct ui_file *tmp_error_stream = mem_fileopen ();
@@ -1471,7 +1556,7 @@ reattach_breakpoints (int pid)
   make_cleanup_ui_file_delete (tmp_error_stream);
 
   inferior_ptid = pid_to_ptid (pid);
-  ALL_BP_LOCATIONS (b)
+  ALL_BP_LOCATIONS (b, bp_tmp)
   {
     if (b->inserted)
       {
@@ -1569,12 +1654,42 @@ create_longjmp_master_breakpoint (char *func_name)
   update_global_location_list (1);
 }
 
+/* Install a master breakpoint on the unwinder's debug hook.  */
+
+void
+create_exception_master_breakpoint (void)
+{
+  struct objfile *objfile;
+
+  ALL_OBJFILES (objfile)
+    {
+      struct minimal_symbol *debug_hook;
+
+      debug_hook = lookup_minimal_symbol_text ("_Unwind_DebugHook", objfile);
+      if (debug_hook != NULL)
+	{
+	  CORE_ADDR pc;
+	  struct breakpoint *b;
+
+	  pc = find_function_start_pc (get_objfile_arch (objfile),
+				       SYMBOL_VALUE_ADDRESS (debug_hook),
+				       SYMBOL_OBJ_SECTION (debug_hook));
+	  b = create_internal_breakpoint (get_objfile_arch (objfile),
+					  pc, bp_exception_master);
+	  b->addr_string = xstrdup ("_Unwind_DebugHook");
+	  b->enable_state = bp_disabled;
+	}
+    }
+
+  update_global_location_list (1);
+}
+
 void
 update_breakpoints_after_exec (void)
 {
   struct breakpoint *b;
   struct breakpoint *temp;
-  struct bp_location *bploc;
+  struct bp_location *bploc, **bplocp_tmp;
 
   /* We're about to delete breakpoints from GDB's lists.  If the
      INSERTED flag is true, GDB will try to lift the breakpoints by
@@ -1584,7 +1699,7 @@ update_breakpoints_after_exec (void)
      breakpoints out as soon as it detects an exec.  We don't do that
      here instead, because there may be other attempts to delete
      breakpoints after detecting an exec and before reaching here.  */
-  ALL_BP_LOCATIONS (bploc)
+  ALL_BP_LOCATIONS (bploc, bplocp_tmp)
     gdb_assert (!bploc->inserted);
 
   ALL_BREAKPOINTS_SAFE (b, temp)
@@ -1606,7 +1721,7 @@ update_breakpoints_after_exec (void)
     /* Thread event breakpoints must be set anew after an exec(),
        as must overlay event and longjmp master breakpoints.  */
     if (b->type == bp_thread_event || b->type == bp_overlay_event
-	|| b->type == bp_longjmp_master)
+	|| b->type == bp_longjmp_master || b->type == bp_exception_master)
       {
 	delete_breakpoint (b);
 	continue;
@@ -1621,7 +1736,8 @@ update_breakpoints_after_exec (void)
 
     /* Longjmp and longjmp-resume breakpoints are also meaningless
        after an exec.  */
-    if (b->type == bp_longjmp || b->type == bp_longjmp_resume)
+    if (b->type == bp_longjmp || b->type == bp_longjmp_resume
+	|| b->type == bp_exception || b->type == bp_exception_resume)
       {
 	delete_breakpoint (b);
 	continue;
@@ -1682,12 +1798,13 @@ update_breakpoints_after_exec (void)
   create_longjmp_master_breakpoint ("_longjmp");
   create_longjmp_master_breakpoint ("siglongjmp");
   create_longjmp_master_breakpoint ("_siglongjmp");
+  create_exception_master_breakpoint ();
 }
 
 int
 detach_breakpoints (int pid)
 {
-  struct bp_location *b;
+  struct bp_location *b, **bp_tmp;
   int val = 0;
   struct cleanup *old_chain = save_inferior_ptid ();
 
@@ -1696,11 +1813,12 @@ detach_breakpoints (int pid)
 
   /* Set inferior_ptid; remove_breakpoint uses this global.  */
   inferior_ptid = pid_to_ptid (pid);
-  ALL_BP_LOCATIONS (b)
+  ALL_BP_LOCATIONS (b, bp_tmp)
   {
     if (b->inserted)
       val |= remove_breakpoint (b, mark_inserted);
   }
+  val |= target_detach_watchpoints ();
   do_cleanups (old_chain);
   return val;
 }
@@ -1793,12 +1911,14 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is)
 	return val;
       b->inserted = (is == mark_inserted);
     }
-  else if (b->loc_type == bp_loc_hardware_watchpoint)
+  /* bp_loc_hardware_watchpoint with mark_inserted is being handled by
+     target_detach_watchpoints.  */
+  else if (b->loc_type == bp_loc_hardware_watchpoint && is == mark_uninserted)
     {
       struct value *v;
       struct value *n;
 
-      b->inserted = (is == mark_inserted);
+      b->inserted = 0;
       val = target_remove_watchpoint (b->address, b->length, 
 				      b->watchpoint_type);
 
@@ -1827,9 +1947,9 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is)
 void
 mark_breakpoints_out (void)
 {
-  struct bp_location *bpt;
+  struct bp_location *bpt, **bptp_tmp;
 
-  ALL_BP_LOCATIONS (bpt)
+  ALL_BP_LOCATIONS (bpt, bptp_tmp)
     bpt->inserted = 0;
 }
 
@@ -1849,7 +1969,7 @@ void
 breakpoint_init_inferior (enum inf_context context)
 {
   struct breakpoint *b, *temp;
-  struct bp_location *bpt;
+  struct bp_location *bpt, **bptp_tmp;
   int ix;
 
   /* If breakpoint locations are shared across processes, then there's
@@ -1857,7 +1977,7 @@ breakpoint_init_inferior (enum inf_context context)
   if (gdbarch_has_global_breakpoints (target_gdbarch))
     return;
 
-  ALL_BP_LOCATIONS (bpt)
+  ALL_BP_LOCATIONS (bpt, bptp_tmp)
     if (bpt->owner->enable_state != bp_permanent)
       bpt->inserted = 0;
 
@@ -1918,10 +2038,10 @@ breakpoint_init_inferior (enum inf_context context)
 enum breakpoint_here
 breakpoint_here_p (CORE_ADDR pc)
 {
-  const struct bp_location *bpt;
+  struct bp_location *bpt, **bptp_tmp;
   int any_breakpoint_here = 0;
 
-  ALL_BP_LOCATIONS (bpt)
+  ALL_BP_LOCATIONS (bpt, bptp_tmp)
     {
       if (bpt->loc_type != bp_loc_software_breakpoint
 	  && bpt->loc_type != bp_loc_hardware_breakpoint)
@@ -1961,16 +2081,16 @@ moribund_breakpoint_here_p (CORE_ADDR pc)
 }
 
 /* Returns non-zero if there's a breakpoint inserted at PC, which is
-   inserted using regular breakpoint_chain/bp_location_chain mechanism.
+   inserted using regular breakpoint_chain / bp_location array mechanism.
    This does not check for single-step breakpoints, which are
    inserted and removed using direct target manipulation.  */
 
 int
 regular_breakpoint_inserted_here_p (CORE_ADDR pc)
 {
-  const struct bp_location *bpt;
+  struct bp_location *bpt, **bptp_tmp;
 
-  ALL_BP_LOCATIONS (bpt)
+  ALL_BP_LOCATIONS (bpt, bptp_tmp)
     {
       if (bpt->loc_type != bp_loc_software_breakpoint
 	  && bpt->loc_type != bp_loc_hardware_breakpoint)
@@ -2011,10 +2131,10 @@ breakpoint_inserted_here_p (CORE_ADDR pc)
 int
 software_breakpoint_inserted_here_p (CORE_ADDR pc)
 {
-  const struct bp_location *bpt;
+  struct bp_location *bpt, **bptp_tmp;
   int any_breakpoint_here = 0;
 
-  ALL_BP_LOCATIONS (bpt)
+  ALL_BP_LOCATIONS (bpt, bptp_tmp)
     {
       if (bpt->loc_type != bp_loc_software_breakpoint)
 	continue;
@@ -2044,12 +2164,12 @@ software_breakpoint_inserted_here_p (CORE_ADDR pc)
 int
 breakpoint_thread_match (CORE_ADDR pc, ptid_t ptid)
 {
-  const struct bp_location *bpt;
+  struct bp_location *bpt, **bptp_tmp;
   /* The thread and task IDs associated to PTID, computed lazily.  */
   int thread = -1;
   int task = 0;
   
-  ALL_BP_LOCATIONS (bpt)
+  ALL_BP_LOCATIONS (bpt, bptp_tmp)
     {
       if (bpt->loc_type != bp_loc_software_breakpoint
 	  && bpt->loc_type != bp_loc_hardware_breakpoint)
@@ -2503,6 +2623,12 @@ print_it_typical (bpstat bs)
       result = PRINT_NOTHING;
       break;
 
+    case bp_exception_master:
+      /* These should never be enabled.  */
+      printf_filtered (_("Exception Master Breakpoint: gdb should not stop!\n"));
+      result = PRINT_NOTHING;
+      break;
+
     case bp_watchpoint:
     case bp_hardware_watchpoint:
       annotate_watchpoint (b->number);
@@ -2590,6 +2716,8 @@ print_it_typical (bpstat bs)
     case bp_none:
     case bp_longjmp:
     case bp_longjmp_resume:
+    case bp_exception:
+    case bp_exception_resume:
     case bp_step_resume:
     case bp_watchpoint_scope:
     case bp_call_dummy:
@@ -2973,8 +3101,12 @@ bpstat_check_location (const struct bp_location *bl, CORE_ADDR bp_addr)
 
 /* If BS refers to a watchpoint, determine if the watched values
    has actually changed, and we should stop.  If not, set BS->stop
-   to 0.  */
-static void
+   to 0.
+   Return 0 for watchpoints which could not be the cause of this trap.
+   In such case PRINT_IT will be print_it_noop and STOP will be 0.
+   Otherwise return 1 but in such case it is not guaranteed whether this
+   breakpoint did or did not trigger this trap.  */
+static int
 bpstat_check_watchpoint (bpstat bs)
 {
   const struct bp_location *bl = bs->breakpoint_at;
@@ -3063,8 +3195,10 @@ bpstat_check_watchpoint (bpstat bs)
 	     anything for this watchpoint.  */
 	  bs->print_it = print_it_noop;
 	  bs->stop = 0;
+	  return 0;
 	}
     }
+  return 1;
 }
 
 
@@ -3157,17 +3291,19 @@ bpstat
 bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
 {
   struct breakpoint *b = NULL;
-  const struct bp_location *bl;
+  struct bp_location *bl, **blp_tmp;
   struct bp_location *loc;
   /* Root of the chain of bpstat's */
   struct bpstats root_bs[1];
   /* Pointer to the last thing in the chain currently.  */
   bpstat bs = root_bs;
   int ix;
-  int need_remove_insert;
+  int need_remove_insert, update_locations = 0;
 
-  ALL_BP_LOCATIONS (bl)
+  ALL_BP_LOCATIONS (bl, blp_tmp)
   {
+    bpstat bs_prev = bs;
+
     b = bl->owner;
     gdb_assert (b);
     if (!breakpoint_enabled (b) && b->enable_state != bp_permanent)
@@ -3188,6 +3324,7 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
     /* Come here if it's a watchpoint, or if the break address matches */
 
     bs = bpstat_alloc (bl, bs);	/* Alloc a bpstat to explain stop */
+    gdb_assert (bs_prev->next == bs);
 
     /* Assume we stop.  Should we find watchpoint that is not actually
        triggered, or if condition of breakpoint is false, we'll reset
@@ -3195,12 +3332,21 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
     bs->stop = 1;
     bs->print = 1;
 
-    bpstat_check_watchpoint (bs);
-    if (!bs->stop)
-      continue;
+    if (!bpstat_check_watchpoint (bs))
+      {
+	/* Ensure bpstat_explains_signal stays false if this BL could not be
+	   the cause of this trap.  */
+
+	gdb_assert (bs->print_it == print_it_noop);
+	gdb_assert (!bs->stop);
+	xfree (bs);
+	bs = bs_prev;
+	bs->next = NULL;
+	continue;
+      }
 
     if (b->type == bp_thread_event || b->type == bp_overlay_event
-	|| b->type == bp_longjmp_master)
+	|| b->type == bp_longjmp_master || b->type == bp_exception_master)
       /* We do not stop for these.  */
       bs->stop = 0;
     else
@@ -3208,14 +3354,15 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
   
     if (bs->stop)
       {
-	++(b->hit_count);
+	if (b->enable_state != bp_disabled)
+	  ++(b->hit_count);
 
 	/* We will stop here */
 	if (b->disposition == disp_disable)
 	  {
 	    if (b->enable_state != bp_permanent)
 	      b->enable_state = bp_disabled;
-	    update_global_location_list (0);
+	    update_locations = 1;
 	  }
 	if (b->silent)
 	  bs->print = 0;
@@ -3235,6 +3382,10 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
       bs->print_it = print_it_noop;
   }
 
+  /* Delay this call which would break the ALL_BP_LOCATIONS iteration above.  */
+  if (update_locations)
+    update_global_location_list (0);
+
   for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
     {
       if (loc->address == bp_addr)
@@ -3412,6 +3563,7 @@ bpstat_what (bpstat bs)
   struct bpstat_what retval;
 
   retval.call_dummy = 0;
+  retval.is_longjmp = 0;
   for (; bs != NULL; bs = bs->next)
     {
       enum class bs_class = no_effect;
@@ -3458,10 +3610,15 @@ bpstat_what (bpstat bs)
 	    bs_class = no_effect;
 	  break;
 	case bp_longjmp:
+	case bp_exception:
 	  bs_class = long_jump;
+	  retval.is_longjmp = bs->breakpoint_at->owner->type == bp_longjmp;
 	  break;
 	case bp_longjmp_resume:
+	case bp_exception_resume:
 	  bs_class = long_resume;
+	  retval.is_longjmp
+	    = bs->breakpoint_at->owner->type == bp_longjmp_resume;
 	  break;
 	case bp_step_resume:
 	  if (bs->stop)
@@ -3484,6 +3641,7 @@ bpstat_what (bpstat bs)
 	case bp_thread_event:
 	case bp_overlay_event:
 	case bp_longjmp_master:
+	case bp_exception_master:
 	  bs_class = bp_nostop;
 	  break;
 	case bp_catchpoint:
@@ -3605,6 +3763,8 @@ print_one_breakpoint_location (struct breakpoint *b,
     {bp_access_watchpoint, "acc watchpoint"},
     {bp_longjmp, "longjmp"},
     {bp_longjmp_resume, "longjmp resume"},
+    {bp_exception, "exception"},
+    {bp_exception_resume, "exception resume"},
     {bp_step_resume, "step resume"},
     {bp_watchpoint_scope, "watchpoint scope"},
     {bp_call_dummy, "call dummy"},
@@ -3612,6 +3772,7 @@ print_one_breakpoint_location (struct breakpoint *b,
     {bp_thread_event, "thread events"},
     {bp_overlay_event, "overlay events"},
     {bp_longjmp_master, "longjmp master"},
+    {bp_exception_master, "exception master"},
     {bp_catchpoint, "catchpoint"},
     {bp_tracepoint, "tracepoint"},
     {bp_jit_event, "jit events"},
@@ -3735,6 +3896,8 @@ print_one_breakpoint_location (struct breakpoint *b,
       case bp_finish:
       case bp_longjmp:
       case bp_longjmp_resume:
+      case bp_exception:
+      case bp_exception_resume:
       case bp_step_resume:
       case bp_watchpoint_scope:
       case bp_call_dummy:
@@ -3742,6 +3905,7 @@ print_one_breakpoint_location (struct breakpoint *b,
       case bp_thread_event:
       case bp_overlay_event:
       case bp_longjmp_master:
+      case bp_exception_master:
       case bp_tracepoint:
       case bp_jit_event:
 	if (opts.addressprint)
@@ -4197,9 +4361,8 @@ set_default_breakpoint (int valid, CORE_ADDR addr, struct symtab *symtab,
    (or use it for any other purpose either).
 
    More specifically, each of the following breakpoint types will always
-   have a zero valued address and we don't want check_duplicates() to mark
-   breakpoints of any of these types to be a duplicate of an actual
-   breakpoint at address zero:
+   have a zero valued address and we don't want to mark breakpoints of any of
+   these types to be a duplicate of an actual breakpoint at address zero:
 
       bp_watchpoint
       bp_hardware_watchpoint
@@ -4219,88 +4382,6 @@ breakpoint_address_is_meaningful (struct breakpoint *bpt)
 	  && type != bp_catchpoint);
 }
 
-/* Rescan breakpoints at the same address and section as BPT,
-   marking the first one as "first" and any others as "duplicates".
-   This is so that the bpt instruction is only inserted once.
-   If we have a permanent breakpoint at the same place as BPT, make
-   that one the official one, and the rest as duplicates.  */
-
-static void
-check_duplicates_for (CORE_ADDR address, struct obj_section *section)
-{
-  struct bp_location *b;
-  int count = 0;
-  struct bp_location *perm_bp = 0;
-
-  ALL_BP_LOCATIONS (b)
-    if (b->owner->enable_state != bp_disabled
-	&& b->owner->enable_state != bp_call_disabled
-	&& b->owner->enable_state != bp_startup_disabled
-	&& b->enabled
-	&& !b->shlib_disabled
-	&& b->address == address	/* address / overlay match */
-	&& (!overlay_debugging || b->section == section)
-	&& breakpoint_address_is_meaningful (b->owner))
-    {
-      /* Have we found a permanent breakpoint?  */
-      if (b->owner->enable_state == bp_permanent)
-	{
-	  perm_bp = b;
-	  break;
-	}
-	
-      count++;
-      b->duplicate = count > 1;
-    }
-
-  /* If we found a permanent breakpoint at this address, go over the
-     list again and declare all the other breakpoints there (except
-     other permanent breakpoints) to be the duplicates.  */
-  if (perm_bp)
-    {
-      perm_bp->duplicate = 0;
-
-      /* Permanent breakpoint should always be inserted.  */
-      if (! perm_bp->inserted)
-	internal_error (__FILE__, __LINE__,
-			_("allegedly permanent breakpoint is not "
-			"actually inserted"));
-
-      ALL_BP_LOCATIONS (b)
-	if (b != perm_bp)
-	  {
-	    if (b->owner->enable_state != bp_permanent
-		&& b->owner->enable_state != bp_disabled
-		&& b->owner->enable_state != bp_call_disabled
-		&& b->owner->enable_state != bp_startup_disabled
-		&& b->enabled && !b->shlib_disabled		
-		&& b->address == address	/* address / overlay match */
-		&& (!overlay_debugging || b->section == section)
-		&& breakpoint_address_is_meaningful (b->owner))
-	      {
-		if (b->inserted)
-		  internal_error (__FILE__, __LINE__,
-				  _("another breakpoint was inserted on top of "
-				  "a permanent breakpoint"));
-
-		b->duplicate = 1;
-	      }
-	  }
-    }
-}
-
-static void
-check_duplicates (struct breakpoint *bpt)
-{
-  struct bp_location *bl = bpt->loc;
-
-  if (! breakpoint_address_is_meaningful (bpt))
-    return;
-
-  for (; bl; bl = bl->next)
-    check_duplicates_for (bl->address, bl->section);    
-}
-
 static void
 breakpoint_adjustment_warning (CORE_ADDR from_addr, CORE_ADDR to_addr,
                                int bnum, int have_bnum)
@@ -4382,6 +4463,8 @@ allocate_bp_location (struct breakpoint *bpt)
     case bp_finish:
     case bp_longjmp:
     case bp_longjmp_resume:
+    case bp_exception:
+    case bp_exception_resume:
     case bp_step_resume:
     case bp_watchpoint_scope:
     case bp_call_dummy:
@@ -4390,6 +4473,7 @@ allocate_bp_location (struct breakpoint *bpt)
     case bp_overlay_event:
     case bp_jit_event:
     case bp_longjmp_master:
+    case bp_exception_master:
       loc->loc_type = bp_loc_software_breakpoint;
       break;
     case bp_hardware_breakpoint:
@@ -4568,8 +4652,7 @@ make_breakpoint_permanent (struct breakpoint *b)
 }
 
 /* Call this routine when stepping and nexting to enable a breakpoint
-   if we do a longjmp() in THREAD.  When we hit that breakpoint, call
-   set_longjmp_resume_breakpoint() to figure out where we are going. */
+   if we do a longjmp() or 'throw' in THREAD.  */
 
 void
 set_longjmp_breakpoint (int thread)
@@ -4581,10 +4664,10 @@ set_longjmp_breakpoint (int thread)
      longjmp "master" breakpoints.  Here, we simply create momentary
      clones of those and enable them for the requested thread.  */
   ALL_BREAKPOINTS_SAFE (b, temp)
-    if (b->type == bp_longjmp_master)
+    if (b->type == bp_longjmp_master || b->type == bp_exception_master)
       {
 	struct breakpoint *clone = clone_momentary_breakpoint (b);
-	clone->type = bp_longjmp;
+	clone->type = b->type == bp_longjmp_master ? bp_longjmp : bp_exception;
 	clone->thread = thread;
       }
 }
@@ -4596,7 +4679,7 @@ delete_longjmp_breakpoint (int thread)
   struct breakpoint *b, *temp;
 
   ALL_BREAKPOINTS_SAFE (b, temp)
-    if (b->type == bp_longjmp)
+    if (b->type == bp_longjmp || b->type == bp_exception)
       {
 	if (b->thread == thread)
 	  delete_breakpoint (b);
@@ -4710,9 +4793,9 @@ create_solib_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
 void
 disable_breakpoints_in_shlibs (void)
 {
-  struct bp_location *loc;
+  struct bp_location *loc, **locp_tmp;
 
-  ALL_BP_LOCATIONS (loc)
+  ALL_BP_LOCATIONS (loc, locp_tmp)
   {
     struct breakpoint *b = loc->owner;
     /* We apply the check to all breakpoints, including disabled
@@ -4742,7 +4825,7 @@ disable_breakpoints_in_shlibs (void)
 static void
 disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
 {
-  struct bp_location *loc;
+  struct bp_location *loc, **locp_tmp;
   int disabled_shlib_breaks = 0;
 
   /* SunOS a.out shared libraries are always mapped, so do not
@@ -4753,7 +4836,7 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
       && bfd_get_flavour (exec_bfd) == bfd_target_aout_flavour)
     return;
 
-  ALL_BP_LOCATIONS (loc)
+  ALL_BP_LOCATIONS (loc, locp_tmp)
   {
     struct breakpoint *b = loc->owner;
     if ((loc->loc_type == bp_loc_hardware_breakpoint
@@ -5648,6 +5731,8 @@ mention (struct breakpoint *b)
       case bp_finish:
       case bp_longjmp:
       case bp_longjmp_resume:
+      case bp_exception:
+      case bp_exception_resume:
       case bp_step_resume:
       case bp_call_dummy:
       case bp_watchpoint_scope:
@@ -5656,6 +5741,7 @@ mention (struct breakpoint *b)
       case bp_overlay_event:
       case bp_jit_event:
       case bp_longjmp_master:
+      case bp_exception_master:
 	break;
       }
 
@@ -6958,6 +7044,7 @@ struct until_break_command_continuation_args
 {
   struct breakpoint *breakpoint;
   struct breakpoint *breakpoint2;
+  int thread_num;
 };
 
 /* This function is called by fetch_inferior_event via the
@@ -6972,6 +7059,7 @@ until_break_command_continuation (void *arg)
   delete_breakpoint (a->breakpoint);
   if (a->breakpoint2)
     delete_breakpoint (a->breakpoint2);
+  delete_longjmp_breakpoint (a->thread_num);
 }
 
 void
@@ -6983,6 +7071,8 @@ until_break_command (char *arg, int from_tty, int anywhere)
   struct breakpoint *breakpoint;
   struct breakpoint *breakpoint2 = NULL;
   struct cleanup *old_chain;
+  int thread;
+  struct thread_info *tp;
 
   clear_proceed_status ();
 
@@ -7021,6 +7111,9 @@ until_break_command (char *arg, int from_tty, int anywhere)
 
   old_chain = make_cleanup_delete_breakpoint (breakpoint);
 
+  tp = inferior_thread ();
+  thread = tp->num;
+
   /* Keep within the current frame, or in frames called by the current
      one.  */
 
@@ -7033,6 +7126,10 @@ until_break_command (char *arg, int from_tty, int anywhere)
 					      frame_unwind_caller_id (frame),
 					      bp_until);
       make_cleanup_delete_breakpoint (breakpoint2);
+
+      set_longjmp_breakpoint (thread);
+      tp->initiating_frame = frame_unwind_caller_id (frame);
+      make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
     }
 
   proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
@@ -7049,6 +7146,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
 
       args->breakpoint = breakpoint;
       args->breakpoint2 = breakpoint2;
+      args->thread_num = thread;
 
       discard_cleanups (old_chain);
       add_continuation (inferior_thread (),
@@ -7758,6 +7856,82 @@ do_vec_free (void *p)
     VEC_free (bp_location_p, *vec);
 }
 
+/* A comparison function for bp_location A and B being interfaced to qsort.
+   Sort elements primarily by their ADDRESS (no matter what does
+   breakpoint_address_is_meaningful say for its OWNER), secondarily by ordering
+   first bp_permanent OWNERed elements and terciarily just ensuring the array
+   is sorted stable way despite qsort being an instable algorithm.  */
+
+static int
+bp_location_compare (struct bp_location *a, struct bp_location *b)
+{
+  int a_perm = a->owner->enable_state == bp_permanent;
+  int b_perm = b->owner->enable_state == bp_permanent;
+
+  if (a->address != b->address)
+    return (a->address > b->address) - (a->address < b->address);
+
+  /* Sort permanent breakpoints first.  */
+  if (a_perm != b_perm)
+    return (a_perm < b_perm) - (a_perm > b_perm);
+
+  /* Make the user-visible order stable across GDB runs.  Locations of the same
+     breakpoint can be sorted in arbitrary order.  */
+
+  if (a->owner->number != b->owner->number)
+    return (a->owner->number > b->owner->number)
+           - (a->owner->number < b->owner->number);
+
+  return (a > b) - (a < b);
+}
+
+/* Interface bp_location_compare as the COMPAR parameter of qsort function.  */
+
+static int
+bp_location_compare_for_qsort (const void *ap, const void *bp)
+{
+  struct bp_location *a = *(void **) ap;
+  struct bp_location *b = *(void **) bp;
+
+  return bp_location_compare (a, b);
+}
+
+/* Set bp_location_placed_address_before_address_max and
+   bp_location_shadow_len_after_address_max according to the current content of
+   the bp_location array.  */
+
+static void
+bp_location_target_extensions_update (void)
+{
+  struct bp_location *bl, **blp_tmp;
+
+  bp_location_placed_address_before_address_max = 0;
+  bp_location_shadow_len_after_address_max = 0;
+
+  ALL_BP_LOCATIONS (bl, blp_tmp)
+    {
+      CORE_ADDR start, end, addr;
+
+      if (!bp_location_has_shadow (bl))
+	continue;
+
+      start = bl->target_info.placed_address;
+      end = start + bl->target_info.shadow_len;
+
+      gdb_assert (bl->address >= start);
+      addr = bl->address - start;
+      if (addr > bp_location_placed_address_before_address_max)
+	bp_location_placed_address_before_address_max = addr;
+
+      /* Zero SHADOW_LEN would not pass bp_location_has_shadow.  */
+
+      gdb_assert (bl->address < end);
+      addr = end - bl->address;
+      if (addr > bp_location_shadow_len_after_address_max)
+	bp_location_shadow_len_after_address_max = addr;
+    }
+}
+
 /* If SHOULD_INSERT is false, do not insert any breakpoint locations
    into the inferior, only remove already-inserted locations that no
    longer should be inserted.  Functions that delete a breakpoint or
@@ -7777,49 +7951,66 @@ static void
 update_global_location_list (int should_insert)
 {
   struct breakpoint *b;
-  struct bp_location **next = &bp_location_chain;
-  struct bp_location *loc;
-  struct bp_location *loc2;
-  VEC(bp_location_p) *old_locations = NULL;
-  int ret;
-  int ix;
+  struct bp_location **locp, *loc;
   struct cleanup *cleanups;
 
-  cleanups = make_cleanup (do_vec_free, &old_locations);
-  /* Store old locations for future reference.  */
-  for (loc = bp_location_chain; loc; loc = loc->global_next)
-    VEC_safe_push (bp_location_p, old_locations, loc);
+  /* The first bp_location being the only one non-DUPLICATE for the current run
+     of the same ADDRESS.  */
+  struct bp_location *loc_first;
+
+  /* Saved former bp_location array which we compare against the newly built
+     bp_location from the current state of ALL_BREAKPOINTS.  */
+  struct bp_location **old_location, **old_locp;
+  unsigned old_location_count;
+
+  old_location = bp_location;
+  old_location_count = bp_location_count;
+  bp_location = NULL;
+  bp_location_count = 0;
+  cleanups = make_cleanup (xfree, old_location);
 
-  bp_location_chain = NULL;
   ALL_BREAKPOINTS (b)
-    {
-      for (loc = b->loc; loc; loc = loc->next)
-	{
-	  *next = loc;
-	  next = &(loc->global_next);
-	  *next = NULL;
-	}
-    }
+    for (loc = b->loc; loc; loc = loc->next)
+      bp_location_count++;
+
+  bp_location = xmalloc (sizeof (*bp_location) * bp_location_count);
+  locp = bp_location;
+  ALL_BREAKPOINTS (b)
+    for (loc = b->loc; loc; loc = loc->next)
+      *locp++ = loc;
+  qsort (bp_location, bp_location_count, sizeof (*bp_location),
+	 bp_location_compare_for_qsort);
+
+  bp_location_target_extensions_update ();
 
   /* Identify bp_location instances that are no longer present in the new
      list, and therefore should be freed.  Note that it's not necessary that
      those locations should be removed from inferior -- if there's another
      location at the same address (previously marked as duplicate),
-     we don't need to remove/insert the location.  */
-  for (ix = 0; VEC_iterate(bp_location_p, old_locations, ix, loc); ++ix)
+     we don't need to remove/insert the location.
+     
+     LOCP is kept in sync with OLD_LOCP, each pointing to the current and
+     former bp_location array state respectively.  */
+
+  locp = bp_location;
+  for (old_locp = old_location; old_locp < old_location + old_location_count;
+       old_locp++)
     {
-      /* Tells if 'loc' is found amoung the new locations.  If not, we
+      struct bp_location *old_loc = *old_locp;
+
+      /* Tells if 'old_loc' is found amoung the new locations.  If not, we
 	 have to free it.  */
-      int found_object = 0;
+      int found_object;
       /* Tells if the location should remain inserted in the target.  */
       int keep_in_target = 0;
       int removed = 0;
-      for (loc2 = bp_location_chain; loc2; loc2 = loc2->global_next)
-	if (loc2 == loc)
-	  {
-	    found_object = 1;
-	    break;
-	  }
+
+      /* Skip LOCP entries which will definitely never be needed.  Stop either
+	 at or being the one matching OLD_LOC.  */
+      while (locp < bp_location + bp_location_count
+	     && bp_location_compare (*locp, old_loc) < 0)
+	locp++;
+      found_object = locp < bp_location + bp_location_count && *locp == old_loc;
 
       /* If this location is no longer present, and inserted, look if there's
 	 maybe a new location at the same address.  If so, mark that one 
@@ -7827,11 +8018,11 @@ update_global_location_list (int should_insert)
 	 don't have a time window where a breakpoint at certain location is not
 	 inserted.  */
 
-      if (loc->inserted)
+      if (old_loc->inserted)
 	{
 	  /* If the location is inserted now, we might have to remove it.  */
 
-	  if (found_object && should_be_inserted (loc))
+	  if (found_object && should_be_inserted (old_loc))
 	    {
 	      /* The location is still present in the location list, and still
 		 should be inserted.  Don't do anything.  */
@@ -7842,37 +8033,46 @@ update_global_location_list (int should_insert)
 	      /* The location is either no longer present, or got disabled.
 		 See if there's another location at the same address, in which 
 		 case we don't need to remove this one from the target.  */
-	      if (breakpoint_address_is_meaningful (loc->owner))
-		for (loc2 = bp_location_chain; loc2; loc2 = loc2->global_next)
-		  {
-		    /* For the sake of should_insert_location.  The
-		       call to check_duplicates will fix up this later.  */
-		    loc2->duplicate = 0;
-		    if (should_be_inserted (loc2)
-			&& loc2 != loc && loc2->address == loc->address)
-		      {		  
-			loc2->inserted = 1;
-			loc2->target_info = loc->target_info;
-			keep_in_target = 1;
-			break;
-		      }
-		  }
+
+	      if (breakpoint_address_is_meaningful (old_loc->owner))
+		{
+		  struct bp_location **loc2p;
+
+		  for (loc2p = locp;
+		       loc2p < bp_location + bp_location_count
+		       && (*loc2p)->address == old_loc->address;
+		       loc2p++)
+		    {
+		      struct bp_location *loc2 = *loc2p;
+
+		      /* For the sake of should_be_inserted.
+			 Duplicates check below will fix up this later.  */
+		      loc2->duplicate = 0;
+		      if (loc2 != old_loc && should_be_inserted (loc2))
+			{		  
+			  loc2->inserted = 1;
+			  loc2->target_info = old_loc->target_info;
+			  keep_in_target = 1;
+			  break;
+			}
+		    }
+		}
 	    }
 
 	  if (!keep_in_target)
 	    {
-	      if (remove_breakpoint (loc, mark_uninserted))
+	      if (remove_breakpoint (old_loc, mark_uninserted))
 		{
 		  /* This is just about all we can do.  We could keep this
 		     location on the global list, and try to remove it next
 		     time, but there's no particular reason why we will
 		     succeed next time.  
 		     
-		     Note that at this point, loc->owner is still valid,
+		     Note that at this point, old_loc->owner is still valid,
 		     as delete_breakpoint frees the breakpoint only
 		     after calling us.  */
 		  printf_filtered (_("warning: Error removing breakpoint %d\n"), 
-				   loc->owner->number);
+				   old_loc->owner->number);
 		}
 	      removed = 1;
 	    }
@@ -7894,19 +8094,59 @@ update_global_location_list (int should_insert)
 		 longer need to keep this breakpoint.  This is just a
 		 heuristic, but if it's wrong, we'll report unexpected SIGTRAP,
 		 which is usability issue, but not a correctness problem.  */
-	      loc->events_till_retirement = 3 * (thread_count () + 1);
-	      loc->owner = NULL;
+	      old_loc->events_till_retirement = 3 * (thread_count () + 1);
+	      old_loc->owner = NULL;
 
-	      VEC_safe_push (bp_location_p, moribund_locations, loc);
+	      VEC_safe_push (bp_location_p, moribund_locations, old_loc);
 	    }
 	  else
-	    free_bp_location (loc);
+	    free_bp_location (old_loc);
 	}
     }
 
-  ALL_BREAKPOINTS (b)
+  /* Rescan breakpoints at the same address and section,
+     marking the first one as "first" and any others as "duplicates".
+     This is so that the bpt instruction is only inserted once.
+     If we have a permanent breakpoint at the same place as BPT, make
+     that one the official one, and the rest as duplicates.  Permanent
+     breakpoints are sorted first for the same address.  */
+
+  loc_first = NULL;
+  ALL_BP_LOCATIONS (loc, locp)
     {
-      check_duplicates (b);
+      struct breakpoint *b = loc->owner;
+
+      if (b->enable_state == bp_disabled
+	  || b->enable_state == bp_call_disabled
+	  || b->enable_state == bp_startup_disabled
+	  || !loc->enabled
+	  || loc->shlib_disabled
+	  || !breakpoint_address_is_meaningful (b))
+	continue;
+
+      /* Permanent breakpoint should always be inserted.  */
+      if (b->enable_state == bp_permanent && ! loc->inserted)
+	internal_error (__FILE__, __LINE__,
+			_("allegedly permanent breakpoint is not "
+			"actually inserted"));
+
+      if (loc_first == NULL
+	  /* address / overlay match */
+	  || loc->address != loc_first->address
+	  || (overlay_debugging && loc->section != loc_first->section))
+	{
+	  loc_first = loc;
+	  loc->duplicate = 0;
+	  continue;
+	}
+
+      loc->duplicate = 1;
+
+      if (loc_first->owner->enable_state == bp_permanent && loc->inserted
+          && b->enable_state != bp_permanent)
+	internal_error (__FILE__, __LINE__,
+			_("another breakpoint was inserted on top of "
+			"a permanent breakpoint"));
     }
 
   if (breakpoints_always_inserted_mode () && should_insert
@@ -8083,6 +8323,7 @@ delete_command (char *arg, int from_tty)
 	    && b->type != bp_thread_event
 	    && b->type != bp_overlay_event
 	    && b->type != bp_longjmp_master
+	    && b->type != bp_exception_master
 	    && b->number >= 0)
 	  {
 	    breaks_to_delete = 1;
@@ -8102,6 +8343,7 @@ delete_command (char *arg, int from_tty)
 		&& b->type != bp_jit_event
 		&& b->type != bp_overlay_event
 		&& b->type != bp_longjmp_master
+		&& b->type != bp_exception_master
 		&& b->number >= 0)
 	      delete_breakpoint (b);
 	  }
@@ -8404,6 +8646,7 @@ breakpoint_re_set_one (void *bint)
 	 reset later by breakpoint_re_set.  */
     case bp_overlay_event:
     case bp_longjmp_master:
+    case bp_exception_master:
       delete_breakpoint (b);
       break;
 
@@ -8427,6 +8670,8 @@ breakpoint_re_set_one (void *bint)
     case bp_longjmp:
     case bp_longjmp_resume:
     case bp_jit_event:
+    case bp_exception:
+    case bp_exception_resume:
       break;
     }
 
@@ -8462,6 +8707,7 @@ breakpoint_re_set (void)
   create_longjmp_master_breakpoint ("_longjmp");
   create_longjmp_master_breakpoint ("siglongjmp");
   create_longjmp_master_breakpoint ("_siglongjmp");
+  create_exception_master_breakpoint ();
 }
 
 /* Reset the thread number of this breakpoint:
@@ -9327,6 +9573,22 @@ all_tracepoints ()
   return tp_vec;
 }
 
+/* Call type_mark_used for any TYPEs referenced from this GDB source file.  */
+
+static void
+breakpoint_types_mark_used (void)
+{
+  struct breakpoint *b;
+
+  ALL_BREAKPOINTS (b)
+    {
+      if (b->exp)
+	exp_types_mark_used (b->exp);
+      if (b->val)
+	type_mark_used (value_type (b->val));
+    }
+}
+
 
 /* This help string is used for the break, hbreak, tbreak and thbreak commands.
    It is defined as a macro to prevent duplication.
@@ -9850,4 +10112,5 @@ inferior in all-stop mode, gdb behaves as if always-inserted mode is off."),
   automatic_hardware_breakpoints = 1;
 
   observer_attach_about_to_proceed (breakpoint_about_to_proceed);
+  observer_attach_mark_used (breakpoint_types_mark_used);
 }
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index ba499c6..80f702f 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -56,6 +56,13 @@ enum bptype
     bp_longjmp,			/* secret breakpoint to find longjmp() */
     bp_longjmp_resume,		/* secret breakpoint to escape longjmp() */
 
+    /* An internal breakpoint that is installed on the unwinder's
+       debug hook.  */
+    bp_exception,
+    /* An internal breakpoint that is set at the point where an
+       exception will land.  */
+    bp_exception_resume,
+
     /* Used by wait_for_inferior for stepping over subroutine calls, for
        stepping over signal handlers, and for skipping prologues.  */
     bp_step_resume,
@@ -118,6 +125,9 @@ enum bptype
 
     bp_longjmp_master,
 
+    /* Like bp_longjmp_master, but for exceptions.  */
+    bp_exception_master,
+
     bp_catchpoint,
 
     bp_tracepoint,
@@ -228,10 +238,6 @@ struct bp_location
      the same parent breakpoint.  */
   struct bp_location *next;
 
-  /* Pointer to the next breakpoint location, in a global
-     list of all breakpoint locations.  */
-  struct bp_location *global_next;
- 
   /* Type of this breakpoint location.  */
   enum bp_loc_type loc_type;
 
@@ -583,6 +589,10 @@ struct bpstat_what
        continuing from a call dummy without popping the frame is not a
        useful one).  */
     int call_dummy;
+
+    /* Used for BPSTAT_WHAT_SET_LONGJMP_RESUME.  True if we are
+       handling a longjmp, false if we are handling an exception.  */
+    int is_longjmp;
   };
 
 /* The possible return values for print_bpstat, print_it_normal,
@@ -946,6 +956,9 @@ extern int catching_syscall_number (int syscall_number);
 /* Tell a breakpoint to be quiet.  */
 extern void make_breakpoint_silent (struct breakpoint *);
 
+/* Set break condition of breakpoint B to EXP.  */
+extern void set_breakpoint_condition (struct breakpoint *b, char *exp, int from_tty);
+
 /* Return a tracepoint with the given number if found.  */
 extern struct breakpoint *get_tracepoint (int num);
 
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index f8e4f12..5b47e2e 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -117,6 +117,8 @@ static int yylex (void);
 
 void yyerror (char *);
 
+/* Cleanup for 'nonempty_typelist' */
+static struct cleanup *typelist_cleanup;
 %}
 
 /* Although the yacc "value" of an expression is not used,
@@ -157,6 +159,7 @@ void yyerror (char *);
 %{
 /* YYSTYPE gets defined by %union */
 static int parse_number (char *, int, int, YYSTYPE *);
+static struct stoken operator_stoken (const char *);
 %}
 
 %type <voidval> exp exp1 type_exp start variable qualified_name lcurly
@@ -199,9 +202,12 @@ static int parse_number (char *, int, int, YYSTYPE *);
 
 %token <ssym> NAME_OR_INT 
 
+%token OPERATOR
 %token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON
 %token TEMPLATE
 %token ERROR
+%token NEW DELETE
+%type <sval> operator
 
 /* Special type cases, put in to allow the parser to distinguish different
    legal basetypes.  */
@@ -401,6 +407,36 @@ arglist	:	arglist ',' exp   %prec ABOVE_COMMA
 			{ arglist_len++; }
 	;
 
+exp     :       exp '(' nonempty_typelist ')' const_or_volatile
+			{ int i;
+			  write_exp_elt_opcode (TYPE_INSTANCE);
+			  write_exp_elt_longcst ((LONGEST) $<ivec>3[0]);
+			  for (i = 0; i < $<ivec>3[0]; ++i)
+			    write_exp_elt_type ($<tvec>3[i + 1]);
+			  write_exp_elt_longcst((LONGEST) $<ivec>3[0]);
+			  write_exp_elt_opcode (TYPE_INSTANCE);
+			  do_cleanups (typelist_cleanup);
+			}
+	;
+
+/*
+exp     :       BLOCKNAME '(' nonempty_typelist ')'
+			{ int i;
+			  write_exp_elt_opcode (TYPE_INSTANCE_LOOKUP);
+			  write_exp_elt_sym ($1.sym);
+			  write_exp_elt_opcode (TYPE_INSTANCE_LOOKUP);
+
+			  write_exp_elt_opcode (TYPE_INSTANCE);
+			  write_exp_elt_longcst ((LONGEST) $<ivec>3[0]);
+			  for (i = 0; i < $<ivec>3[0]; ++i)
+			    write_exp_elt_type ($<tvec>3[i + 1]);
+			  write_exp_elt_longcst((LONGEST) $<ivec>3[0]);
+			  write_exp_elt_opcode (TYPE_INSTANCE);
+			  do_cleanups (typelist_cleanup);
+			}
+	;
+*/
+
 rcurly	:	'}'
 			{ $$ = end_arglist () - 1; }
 	;
@@ -703,6 +739,7 @@ variable:	block COLONCOLON name
 qualified_name:	typebase COLONCOLON name
 			{
 			  struct type *type = $1;
+			  CHECK_TYPEDEF (type);
 			  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
 			      && TYPE_CODE (type) != TYPE_CODE_UNION
 			      && TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
@@ -718,6 +755,7 @@ qualified_name:	typebase COLONCOLON name
 			{
 			  struct type *type = $1;
 			  struct stoken tmp_token;
+			  CHECK_TYPEDEF (type);
 			  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
 			      && TYPE_CODE (type) != TYPE_CODE_UNION
 			      && TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
@@ -740,12 +778,13 @@ qualified_name:	typebase COLONCOLON name
 	;
 
 variable:	qualified_name
+	|	COLONCOLON qualified_name
 	|	COLONCOLON name
 			{
 			  char *name = copy_name ($2);
 			  struct symbol *sym;
 			  struct minimal_symbol *msymbol;
-
+			  
 			  sym =
 			    lookup_symbol (name, (const struct block *) NULL,
 					   VAR_DOMAIN, (int *) NULL);
@@ -883,7 +922,7 @@ array_mod:	'[' ']'
 func_mod:	'(' ')'
 			{ $$ = 0; }
 	|	'(' nonempty_typelist ')'
-			{ free ($2); $$ = 0; }
+			{ do_cleanups (typelist_cleanup); $$ = 0; }
 	;
 
 /* We used to try to recognize pointer to member types here, but
@@ -1088,12 +1127,15 @@ typename:	TYPENAME
 nonempty_typelist
 	:	type
 		{ $$ = (struct type **) malloc (sizeof (struct type *) * 2);
+		  typelist_cleanup = make_cleanup (free, $$);
 		  $<ivec>$[0] = 1;	/* Number of types in vector */
 		  $$[1] = $1;
 		}
 	|	nonempty_typelist ',' type
 		{ int len = sizeof (struct type *) * (++($<ivec>1[0]) + 1);
 		  $$ = (struct type **) realloc ((char *) $1, len);
+		  discard_cleanups (typelist_cleanup);
+		  typelist_cleanup = make_cleanup (free, $$);
 		  $$[$<ivec>$[0]] = $3;
 		}
 	;
@@ -1117,10 +1159,135 @@ const_or_volatile_noopt:  	const_and_volatile
 			{ push_type (tp_volatile); }
 	;
 
+operator:	OPERATOR NEW
+			{ $$ = operator_stoken (" new"); }
+	|	OPERATOR DELETE
+			{ $$ = operator_stoken (" delete"); }
+	|	OPERATOR NEW '[' ']'
+			{ $$ = operator_stoken (" new[]"); }
+	|	OPERATOR DELETE '[' ']'
+			{ $$ = operator_stoken (" delete[]"); }
+	|	OPERATOR '+'
+			{ $$ = operator_stoken ("+"); }
+	|	OPERATOR '-'
+			{ $$ = operator_stoken ("-"); }
+	|	OPERATOR '*'
+			{ $$ = operator_stoken ("*"); }
+	|	OPERATOR '/'
+			{ $$ = operator_stoken ("/"); }
+	|	OPERATOR '%'
+			{ $$ = operator_stoken ("%"); }
+	|	OPERATOR '^'
+			{ $$ = operator_stoken ("^"); }
+	|	OPERATOR '&'
+			{ $$ = operator_stoken ("&"); }
+	|	OPERATOR '|'
+			{ $$ = operator_stoken ("|"); }
+	|	OPERATOR '~'
+			{ $$ = operator_stoken ("~"); }
+	|	OPERATOR '!'
+			{ $$ = operator_stoken ("!"); }
+	|	OPERATOR '='
+			{ $$ = operator_stoken ("="); }
+	|	OPERATOR '<'
+			{ $$ = operator_stoken ("<"); }
+	|	OPERATOR '>'
+			{ $$ = operator_stoken (">"); }
+	|	OPERATOR ASSIGN_MODIFY
+			{ const char *op = "unknown";
+			  switch ($2)
+			    {
+			    case BINOP_RSH:
+			      op = ">>=";
+			      break;
+			    case BINOP_LSH:
+			      op = "<<=";
+			      break;
+			    case BINOP_ADD:
+			      op = "+=";
+			      break;
+			    case BINOP_SUB:
+			      op = "-=";
+			      break;
+			    case BINOP_MUL:
+			      op = "*=";
+			      break;
+			    case BINOP_DIV:
+			      op = "/=";
+			      break;
+			    case BINOP_REM:
+			      op = "%=";
+			      break;
+			    case BINOP_BITWISE_IOR:
+			      op = "|=";
+			      break;
+			    case BINOP_BITWISE_AND:
+			      op = "&=";
+			      break;
+			    case BINOP_BITWISE_XOR:
+			      op = "^=";
+			      break;
+			    default:
+			      break;
+			    }
+
+			  $$ = operator_stoken (op);
+			}
+	|	OPERATOR LSH
+			{ $$ = operator_stoken ("<<"); }
+	|	OPERATOR RSH
+			{ $$ = operator_stoken (">>"); }
+	|	OPERATOR EQUAL
+			{ $$ = operator_stoken ("=="); }
+	|	OPERATOR NOTEQUAL
+			{ $$ = operator_stoken ("!="); }
+	|	OPERATOR LEQ
+			{ $$ = operator_stoken ("<="); }
+	|	OPERATOR GEQ
+			{ $$ = operator_stoken (">="); }
+	|	OPERATOR ANDAND
+			{ $$ = operator_stoken ("&&"); }
+	|	OPERATOR OROR
+			{ $$ = operator_stoken ("||"); }
+	|	OPERATOR INCREMENT
+			{ $$ = operator_stoken ("++"); }
+	|	OPERATOR DECREMENT
+			{ $$ = operator_stoken ("--"); }
+	|	OPERATOR ','
+			{ $$ = operator_stoken (","); }
+	|	OPERATOR ARROW_STAR
+			{ $$ = operator_stoken ("->*"); }
+	|	OPERATOR ARROW
+			{ $$ = operator_stoken ("->"); }
+	|	OPERATOR '(' ')'
+			{ $$ = operator_stoken ("()"); }
+	|	OPERATOR '[' ']'
+			{ $$ = operator_stoken ("[]"); }
+	|	OPERATOR ptype
+			{ char *name, *canon;
+			  long length;
+			  struct ui_file *buf = mem_fileopen ();
+
+			  c_print_type ($2, NULL, buf, -1, 0);
+			  name = ui_file_xstrdup (buf, &length);
+			  canon = cp_canonicalize_string (name);
+			  if (canon != NULL)
+			    {
+			      xfree (name);
+			      name = canon;
+			    }
+			  ui_file_delete (buf);
+			  $$ = operator_stoken (name);
+			}
+	;
+
+
+
 name	:	NAME { $$ = $1.stoken; }
 	|	BLOCKNAME { $$ = $1.stoken; }
 	|	TYPENAME { $$ = $1.stoken; }
 	|	NAME_OR_INT  { $$ = $1.stoken; }
+	|	operator { $$ = $1; }
 	;
 
 name_not_typename :	NAME
@@ -1136,6 +1303,20 @@ name_not_typename :	NAME
 
 %%
 
+/* Returns a stoken of the operator name given by OP (which does not
+   include the string "operator").  The result is xmalloc'd.  */
+static struct stoken
+operator_stoken (const char *op)
+{
+  static const char *operator_string = "operator";
+  struct stoken st = { NULL, 0 };
+  st.length = strlen (operator_string) + strlen (op);
+  st.ptr = xmalloc (st.length + 1);
+  strcpy (st.ptr, operator_string);
+  strcat (st.ptr, op);
+  return st;
+};
+
 /* Take care of parsing a number (anything that starts with a digit).
    Set yylval and return the token type; update lexptr.
    LEN is the number of characters in it.  */
@@ -1714,6 +1895,9 @@ static const struct token ident_tokens[] =
     {"long", LONG, OP_NULL, 0},
     {"true", TRUEKEYWORD, OP_NULL, 1},
     {"int", INT_KEYWORD, OP_NULL, 0},
+    {"new", NEW, OP_NULL, 1},
+    {"delete", DELETE, OP_NULL, 1},
+    {"operator", OPERATOR, OP_NULL, 1},
 
     {"and", ANDAND, BINOP_END, 1},
     {"and_eq", ASSIGN_MODIFY, BINOP_BITWISE_AND, 1},
@@ -1822,6 +2006,13 @@ static int last_was_structop;
 static int
 yylex (void)
 {
+  /* name_prefix stores the full qualification of a variable that is
+     specified in the expression. It is used to eleminate confusion 
+     during lookup.*/
+  static char *name_prefix = NULL;
+  static int name_prefix_len = 0;
+  static int terminate_prefix = 0;
+  
   int c;
   int namelen;
   unsigned int i;
@@ -1830,9 +2021,19 @@ yylex (void)
   char *copy;
 
   last_was_structop = 0;
-
+  
  retry:
-
+  
+  if (terminate_prefix
+      || lexptr != name_prefix + name_prefix_len)
+    {
+      /* Some token was skipped, so clear name_prefix. */
+      name_prefix = NULL;
+      name_prefix_len = 0;
+    }
+    
+  terminate_prefix = 1;
+  	  	  
   /* Check if this is a macro invocation that we need to expand.  */
   if (! scanning_macro_expansion ())
     {
@@ -1868,10 +2069,19 @@ yylex (void)
 	    && parse_language->la_language != language_cplus)
 	  break;
 
+	if (tokentab2[i].token == COLONCOLON)
+	  {
+	    name_prefix_len += 2;
+	    terminate_prefix = 0;
+	    if (name_prefix == NULL)
+	      name_prefix = lexptr;
+	  }
+
 	lexptr += 2;
 	yylval.opcode = tokentab2[i].opcode;
 	if (in_parse_field && tokentab2[i].token == ARROW)
 	  last_was_structop = 1;
+	
 	return tokentab2[i].token;
       }
 
@@ -1900,6 +2110,8 @@ yylex (void)
         return 0;
 
     case ' ':
+      name_prefix_len++;
+      terminate_prefix = 0;
     case '\t':
     case '\n':
       lexptr++;
@@ -2057,11 +2269,13 @@ yylex (void)
     error ("Invalid character '%c' in expression.", c);
 
   /* It's a name.  See how long it is.  */
+  
   namelen = 0;
   for (c = tokstart[namelen];
        (c == '_' || c == '$' || (c >= '0' && c <= '9')
 	|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');)
     {
+    
       /* Template parameter lists are part of the name.
 	 FIXME: This mishandles `print $a<4&&$a>3'.  */
 
@@ -2125,14 +2339,29 @@ yylex (void)
      currently as names of types; NAME for other symbols.
      The caller is not constrained to care about the distinction.  */
   {
+    char *tmp = copy;
     struct symbol *sym;
     int is_a_field_of_this = 0;
     int hextype;
 
-    sym = lookup_symbol (copy, expression_context_block,
+    if (name_prefix != NULL)
+      tmp = savestring (name_prefix, name_prefix_len+namelen);
+
+    sym = lookup_symbol (tmp, expression_context_block,
 			 VAR_DOMAIN,
 			 parse_language->la_language == language_cplus
 			 ? &is_a_field_of_this : (int *) NULL);
+			 
+    /* Keep this name as the prefix for the next name. */
+    if (sym)
+      {
+	if (name_prefix == NULL)
+	  name_prefix = tokstart;
+
+	name_prefix_len += namelen;
+	terminate_prefix = 0;
+      }
+
     /* Call lookup_symtab, not lookup_partial_symtab, in case there are
        no psymtabs (coff, xcoff, or some future change to blow away the
        psymtabs once once symbols are read).  */
@@ -2191,6 +2420,7 @@ yylex (void)
     yylval.ssym.is_a_field_of_this = is_a_field_of_this;
     if (in_parse_field && *lexptr == '\0')
       saw_name_at_eof = 1;
+        
     return NAME;
   }
 }
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 4ba81ba..bc35a3e 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -459,7 +459,7 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
 	 single character in isolation.  This makes the code simpler
 	 and probably does the sensible thing in the majority of
 	 cases.  */
-      while (num_chars == 1)
+      while (num_chars == 1 && things_printed < options->print_max)
 	{
 	  /* Count the number of repetitions.  */
 	  unsigned int reps = 0;
@@ -715,7 +715,7 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
      If length returned from read_string was > 0, return the number of
      characters read by dividing the number of bytes by width.  */
   if (*length != 0)
-     *length = *length / width;
+    *length = *length / width;
 
   *charset = target_charset ();
 
@@ -1038,6 +1038,9 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
   return evaluate_subexp_standard (expect_type, exp, pos, noside);
 }
 
+
+/* Preprocessing and parsing C and C++ expressions.  */
+
 
 
 /* Table mapping opcodes into strings for printing operators
@@ -1138,6 +1141,7 @@ static const struct exp_descriptor exp_descriptor_c =
 {
   print_subexp_standard,
   operator_length_standard,
+  operator_check_standard,
   op_name_standard,
   dump_subexp_body_standard,
   evaluate_subexp_c
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index b193080..04cf3bc 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -32,6 +32,7 @@
 #include "c-lang.h"
 #include "typeprint.h"
 #include "cp-abi.h"
+#include "jv-lang.h"
 
 #include "gdb_string.h"
 #include <errno.h>
@@ -40,8 +41,6 @@ static void cp_type_print_method_args (struct type *mtype, char *prefix,
 				       char *varstring, int staticp,
 				       struct ui_file *stream);
 
-static void c_type_print_args (struct type *, struct ui_file *);
-
 static void cp_type_print_derivation_info (struct ui_file *, struct type *);
 
 static void c_type_print_varspec_prefix (struct type *, struct ui_file *, int,
@@ -199,6 +198,23 @@ cp_type_print_method_args (struct type *mtype, char *prefix, char *varstring,
     fprintf_filtered (stream, "void");
 
   fprintf_filtered (stream, ")");
+
+  /* For non-static methods, read qualifiers from the type of
+     THIS.  */
+  if (!staticp)
+    {
+      struct type *domain;
+
+      gdb_assert (nargs > 0);
+      gdb_assert (TYPE_CODE (args[0].type) == TYPE_CODE_PTR);
+      domain = TYPE_TARGET_TYPE (args[0].type);
+
+      if (TYPE_CONST (domain))
+	fprintf_filtered (stream, " const");
+
+      if (TYPE_VOLATILE (domain))
+	fprintf_filtered (stream, " volatile");
+    }
 }
 
 
@@ -355,10 +371,14 @@ c_type_print_modifier (struct type *type, struct ui_file *stream,
 
 /* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD
    or TYPE_CODE_FUNC, to STREAM.  Artificial arguments, such as "this"
-   in non-static methods, are displayed.  */
+   in non-static methods, are displayed if SHOW_ARTIFICIAL is
+   non-zero. LANGUAGE is the language in which TYPE was defined.  This is
+   a necessary evil since this code is used by the C, C++, and Java
+   backends. */
 
-static void
-c_type_print_args (struct type *type, struct ui_file *stream)
+void
+c_type_print_args (struct type *type, struct ui_file *stream,
+		   int show_artificial, enum language language)
 {
   int i, len;
   struct field *args;
@@ -370,13 +390,19 @@ c_type_print_args (struct type *type, struct ui_file *stream)
 
   for (i = 0; i < TYPE_NFIELDS (type); i++)
     {
+      if (TYPE_FIELD_ARTIFICIAL (type, i) && !show_artificial)
+	continue;
+
       if (printed_any)
 	{
 	  fprintf_filtered (stream, ", ");
 	  wrap_here ("    ");
 	}
 
-      c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+      if (language == language_java)
+	java_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+      else
+	c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
       printed_any = 1;
     }
 
@@ -560,7 +586,12 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
 	fprintf_filtered (stream, ")");
 
       fprintf_filtered (stream, "[");
-      if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
+      if (TYPE_ARRAY_BOUND_IS_DWARF_BLOCK (type, 1))
+	{
+	  /* No _() - printed sources should not be locale dependent.  */
+	  fprintf_filtered (stream, "variable");
+	}
+      else if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
 	&& !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
 	fprintf_filtered (stream, "%d",
 			  (TYPE_LENGTH (type)
@@ -593,7 +624,7 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
       if (passed_a_ptr)
 	fprintf_filtered (stream, ")");
       if (!demangled_args)
-	c_type_print_args (type, stream);
+	c_type_print_args (type, stream, 1, language_c);
       c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
 				   passed_a_ptr, 0);
       break;
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index ce7c2a6..6380fec 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -46,6 +46,8 @@
 #include "cli/cli-setshow.h"
 #include "cli/cli-cmds.h"
 
+#include "python/python.h"
+
 #ifdef TUI
 #include "tui/tui.h"		/* For tui_active et.al.   */
 #endif
@@ -183,6 +185,7 @@ struct cmd_list_element *showchecklist;
 
 /* Command tracing state.  */
 
+static int source_python = 0;
 int source_verbose = 0;
 int trace_commands = 0;
 
@@ -444,6 +447,7 @@ source_script (char *file, int from_tty)
   struct cleanup *old_cleanups;
   char *full_pathname = NULL;
   int fd;
+  int is_python;
 
   if (file == NULL || *file == 0)
     {
@@ -476,8 +480,16 @@ source_script (char *file, int from_tty)
 	}
     }
 
+  is_python = source_python;
+  if (strlen (file) > 3 && !strcmp (&file[strlen (file) - 3], ".py"))
+    is_python = 1;
+
   stream = fdopen (fd, FOPEN_RT);
-  script_from_file (stream, file);
+
+  if (is_python)
+    source_python_script (stream, file);
+  else
+    script_from_file (stream, file);
 
   do_cleanups (old_cleanups);
 }
@@ -491,15 +503,30 @@ source_verbose_cleanup (void *old_value)
   xfree (old_value);
 }
 
+/* A helper for source_command.  Look for an argument in *ARGS.
+   Update *ARGS by stripping leading whitespace.  If an argument is
+   found, return it (a character).  Otherwise, return 0.  */
+static int
+find_argument (char **args)
+{
+  int result = 0;
+  while (isspace ((*args)[0]))
+    ++*args;
+  if ((*args)[0] == '-' && isalpha ((*args)[1]))
+    {
+      result = (*args)[1];
+      *args += 3;
+    }
+  return result;
+}
+
 static void
 source_command (char *args, int from_tty)
 {
   struct cleanup *old_cleanups;
-  char *file = args;
-  int *old_source_verbose = xmalloc (sizeof(int));
 
-  *old_source_verbose = source_verbose;
-  old_cleanups = make_cleanup (source_verbose_cleanup, old_source_verbose);
+  old_cleanups = make_cleanup_restore_integer (&source_verbose);
+  make_cleanup_restore_integer (&source_python);
 
   /* -v causes the source command to run in verbose mode.
      We still have to be able to handle filenames with spaces in a
@@ -507,23 +534,28 @@ source_command (char *args, int from_tty)
 
   if (args)
     {
-      /* Make sure leading white space does not break the comparisons.  */
-      while (isspace(args[0]))
-	args++;
-
-      /* Is -v the first thing in the string?  */
-      if (args[0] == '-' && args[1] == 'v' && isspace (args[2]))
+      while (1)
 	{
-	  source_verbose = 1;
-
-	  /* Trim -v and whitespace from the filename.  */
-	  file = &args[3];
-	  while (isspace (file[0]))
-	    file++;
+	  int arg = find_argument (&args);
+	  if (!arg)
+	    break;
+	  switch (arg)
+	    {
+	    case 'v':
+	      source_verbose = 1;
+	      break;
+	    case 'p':
+	      source_python = 1;
+	      break;
+	    default:
+	      error (_("unrecognized option -%c"), arg);
+	    }
 	}
     }
 
-  source_script (file, from_tty);
+  source_script (args, from_tty);
+
+  do_cleanups (old_cleanups);
 }
 
 
@@ -1307,7 +1339,9 @@ Read commands from a file named FILE.\n\
 Optional -v switch (before the filename) causes each command in\n\
 FILE to be echoed as it is executed.\n\
 Note that the file \"%s\" is read automatically in this way\n\
-when GDB is started."), gdbinit);
+when GDB is started.\n\
+Optional -p switch (before the filename) causes FILE to be evaluated\n\
+as Python code."), gdbinit);
   c = add_cmd ("source", class_support, source_command,
 	       source_help_text, &cmdlist);
   set_cmd_completer (c, filename_completer);
diff --git a/gdb/coffread.c b/gdb/coffread.c
index 888f8b4..65494b8 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -346,7 +346,7 @@ coff_alloc_type (int index)
      We will fill it in later if we find out how.  */
   if (type == NULL)
     {
-      type = alloc_type (current_objfile);
+      type = alloc_type (current_objfile, NULL);
       *type_addr = type;
     }
   return type;
@@ -2121,6 +2121,7 @@ static struct sym_fns coff_sym_fns =
   coff_new_init,		/* sym_new_init: init anything gbl to entire symtab */
   coff_symfile_init,		/* sym_init: read initial info, setup for sym_read() */
   coff_symfile_read,		/* sym_read: read a symbol file into symtab */
+  NULL,				/* sym_read_psymbols */
   coff_symfile_finish,		/* sym_finish: finished with file, cleanup */
   default_symfile_offsets,	/* sym_offsets:  xlate external to internal form */
   default_symfile_segments,	/* sym_segments: Get segment information from
diff --git a/gdb/config.in b/gdb/config.in
index 4716524..0745c65 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -46,11 +46,10 @@
    language is requested. */
 #undef ENABLE_NLS
 
-/* look for global separate data files in this path [DATADIR/gdb] */
+/* Global directory for GDB data files. */
 #undef GDB_DATADIR
 
-/* Define if the gdb-datadir directory should be relocated when GDB is moved.
-   */
+/* Define if GDB datadir should be relocated when GDB is moved. */
 #undef GDB_DATADIR_RELOCATABLE
 
 /* Define to be a string naming the default host character set. */
@@ -647,6 +646,9 @@
    'ptrdiff_t'. */
 #undef PTRDIFF_T_SUFFIX
 
+/* Define to install path for Python sources */
+#undef PYTHONDIR
+
 /* Relocated directory for source files. */
 #undef RELOC_SRCDIR
 
diff --git a/gdb/config/i386/nm-i386.h b/gdb/config/i386/nm-i386.h
new file mode 100644
index 0000000..5f237cc
--- /dev/null
+++ b/gdb/config/i386/nm-i386.h
@@ -0,0 +1,125 @@
+/* Native macro definitions for GDB on an Intel i[3456]86.
+   Copyright 2001, 2004, 2007, 2008, 2009 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/>.  */
+
+#ifndef NM_I386_H
+#define NM_I386_H 1
+
+/* Hardware-assisted breakpoints and watchpoints.  */
+
+/* Targets should define this to use the generic x86 watchpoint support.  */
+#ifdef I386_USE_GENERIC_WATCHPOINTS
+
+/* Add watchpoint methods to the provided target_ops.  Targets which call
+   this should also define I386_WATCHPOINTS_IN_TARGET_VECTOR.  */
+struct target_ops;
+void i386_use_watchpoints (struct target_ops *);
+
+/* Clear the reference counts and forget everything we knew about DRi.  */
+extern void i386_cleanup_dregs (void);
+
+/* Insert a watchpoint to watch a memory region which starts at
+   address ADDR and whose length is LEN bytes.  Watch memory accesses
+   of the type TYPE.  Return 0 on success, -1 on failure.  */
+extern int i386_insert_watchpoint (CORE_ADDR addr, int len, int type);
+
+/* Remove a watchpoint that watched the memory region which starts at
+   address ADDR, whose length is LEN bytes, and for accesses of the
+   type TYPE.  Return 0 on success, -1 on failure.  */
+extern int i386_remove_watchpoint (CORE_ADDR addr, int len, int type);
+
+/* Return non-zero if we can watch a memory region that starts at
+   address ADDR and whose length is LEN bytes.  */
+extern int i386_region_ok_for_watchpoint (CORE_ADDR addr, int len);
+
+/* Return non-zero if the inferior has some break/watchpoint that
+   triggered.  */
+extern int i386_stopped_by_hwbp (void);
+
+/* If the inferior has some break/watchpoint that triggered, set
+   the address associated with that break/watchpoint and return
+   true.  Otherwise, return false.  */
+extern int i386_stopped_data_address (struct target_ops *, CORE_ADDR *);
+
+/* Insert a hardware-assisted breakpoint at BP_TGT->placed_address.
+   Return 0 on success, EBUSY on failure.  */
+struct bp_target_info;
+extern int i386_insert_hw_breakpoint (struct bp_target_info *bp_tgt);
+
+/* Remove a hardware-assisted breakpoint at BP_TGT->placed_address.
+   Return 0 on success, -1 on failure.  */
+extern int  i386_remove_hw_breakpoint (struct bp_target_info *bp_tgt);
+
+extern int i386_stopped_by_watchpoint (void);
+
+#ifndef I386_WATCHPOINTS_IN_TARGET_VECTOR
+
+/* Returns the number of hardware watchpoints of type TYPE that we can
+   set.  Value is positive if we can set CNT watchpoints, zero if
+   setting watchpoints of type TYPE is not supported, and negative if
+   CNT is more than the maximum number of watchpoints of type TYPE
+   that we can support.  TYPE is one of bp_hardware_watchpoint,
+   bp_read_watchpoint, bp_write_watchpoint, or bp_hardware_breakpoint.
+   CNT is the number of such watchpoints used so far (including this
+   one).  OTHERTYPE is non-zero if other types of watchpoints are
+   currently enabled.
+
+   We always return 1 here because we don't have enough information
+   about possible overlap of addresses that they want to watch.  As an
+   extreme example, consider the case where all the watchpoints watch
+   the same address and the same region length: then we can handle a
+   virtually unlimited number of watchpoints, due to debug register
+   sharing implemented via reference counts in i386-nat.c.  */
+
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1
+
+/* Returns non-zero if we can use hardware watchpoints to watch a
+   region whose address is ADDR and whose length is LEN.  */
+
+#define TARGET_REGION_OK_FOR_HW_WATCHPOINT(addr, len) \
+  i386_region_ok_for_watchpoint (addr, len)
+
+/* After a watchpoint trap, the PC points to the instruction after the
+   one that caused the trap.  Therefore we don't need to step over it.
+   But we do need to reset the status register to avoid another trap.  */
+
+#define HAVE_CONTINUABLE_WATCHPOINT 1
+
+#define STOPPED_BY_WATCHPOINT(W)       (i386_stopped_by_watchpoint () != 0)
+
+#define target_stopped_data_address(target, x) \
+  i386_stopped_data_address(target, x)
+
+/* Use these macros for watchpoint insertion/removal.  */
+
+#define target_insert_watchpoint(addr, len, type) \
+  i386_insert_watchpoint (addr, len, type)
+
+#define target_remove_watchpoint(addr, len, type) \
+  i386_remove_watchpoint (addr, len, type)
+
+#define target_insert_hw_breakpoint(bp_tgt) \
+  i386_insert_hw_breakpoint (bp_tgt)
+
+#define target_remove_hw_breakpoint(bp_tgt) \
+  i386_remove_hw_breakpoint (bp_tgt)
+
+#endif /* I386_WATCHPOINTS_IN_TARGET_VECTOR */
+
+#endif /* I386_USE_GENERIC_WATCHPOINTS */
+
+#endif /* NM_I386_H */
diff --git a/gdb/config/i386/nm-linux64.h b/gdb/config/i386/nm-linux64.h
new file mode 100644
index 0000000..19d710a
--- /dev/null
+++ b/gdb/config/i386/nm-linux64.h
@@ -0,0 +1,54 @@
+/* Native support for GNU/Linux x86-64.
+
+   Copyright 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+   Free Software Foundation, Inc.
+
+   Contributed by Jiri Smid, SuSE Labs.
+
+   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/>.  */
+
+#ifndef NM_LINUX64_H
+#define NM_LINUX64_H
+
+/* GNU/Linux supports the i386 hardware debugging registers.  */
+#define I386_USE_GENERIC_WATCHPOINTS
+#define I386_WATCHPOINTS_IN_TARGET_VECTOR
+
+#include "i386/nm-i386.h"
+#include "config/nm-linux.h"
+
+/* Support for 8-byte wide hardware watchpoints.  */
+#define TARGET_HAS_DR_LEN_8 1
+
+/* Provide access to the i386 hardware debugging registers.  */
+
+extern void amd64_linux_dr_set_control (unsigned long control);
+#define I386_DR_LOW_SET_CONTROL(control) \
+  amd64_linux_dr_set_control (control)
+
+extern void amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr);
+#define I386_DR_LOW_SET_ADDR(regnum, addr) \
+  amd64_linux_dr_set_addr (regnum, addr)
+
+extern void amd64_linux_dr_reset_addr (int regnum);
+#define I386_DR_LOW_RESET_ADDR(regnum) \
+  amd64_linux_dr_reset_addr (regnum)
+
+extern unsigned long amd64_linux_dr_get_status (void);
+#define I386_DR_LOW_GET_STATUS() \
+  amd64_linux_dr_get_status ()
+
+#endif /* nm-linux64.h */
diff --git a/gdb/config/mips/nm-irix5.h b/gdb/config/mips/nm-irix5.h
new file mode 100644
index 0000000..49ac420
--- /dev/null
+++ b/gdb/config/mips/nm-irix5.h
@@ -0,0 +1,44 @@
+/* Definitions for native support of irix5.
+
+   Copyright 1993, 1996, 1998, 1999, 2000, 2007, 2008, 2009
+   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/>.  */
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+
+/* TARGET_CAN_USE_HARDWARE_WATCHPOINT is now defined to go through
+   the target vector.  For Irix5, procfs_can_use_hw_watchpoint()
+   should be invoked.  */
+
+/* When a hardware watchpoint fires off the PC will be left at the
+   instruction which caused the watchpoint.  It will be necessary for
+   GDB to step over the watchpoint. */
+
+#define STOPPED_BY_WATCHPOINT(W) \
+     procfs_stopped_by_watchpoint(inferior_ptid)
+extern int procfs_stopped_by_watchpoint (ptid_t);
+
+/* Use these macros for watchpoint insertion/deletion.  */
+/* type can be 0: write watch, 1: read watch, 2: access watch (read/write) */
+#define target_insert_watchpoint(ADDR, LEN, TYPE) \
+     procfs_set_watchpoint (inferior_ptid, ADDR, LEN, TYPE, 0)
+#define target_remove_watchpoint(ADDR, LEN, TYPE) \
+     procfs_set_watchpoint (inferior_ptid, ADDR, 0, 0, 0)
+extern int procfs_set_watchpoint (ptid_t, CORE_ADDR, int, int, int);
+
+#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(SIZE) 1
+
diff --git a/gdb/configure b/gdb/configure
index 99acc2f..a2ea1ae 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -676,6 +676,8 @@ REPORT_BUGS_TO
 PKGVERSION
 TARGET_OBS
 subdirs
+pythondir
+GDB_DATADIR_PATH
 GDB_DATADIR
 DEBUGDIR
 am__fastdepCC_FALSE
@@ -883,6 +885,7 @@ enable_dependency_tracking
 with_separate_debug_dir
 with_gdb_datadir
 with_relocated_sources
+with_pythondir
 enable_targets
 enable_64_bit_bfd
 enable_gdbcli
@@ -1581,6 +1584,10 @@ Optional Packages:
                           [DATADIR/gdb]
   --with-relocated-sources=PATH
                           automatically relocate this path for source files
+  --with-gdb-datadir      look for global separate data files in this path
+                          [DATADIR/gdb]
+  --with-pythondir        install Python data files in this path
+                          [DATADIR/gdb/python]
   --with-libunwind        use libunwind frame unwinding support
   --with-curses           use the curses library instead of the termcap
                           library
@@ -6602,6 +6609,73 @@ _ACEOF
 fi
 
 
+# GDB's datadir relocation
+
+gdbdatadir=${datadir}/gdb
+
+
+# Check whether --with-gdb-datadir was given.
+if test "${with_gdb_datadir+set}" = set; then :
+  withval=$with_gdb_datadir; gdbdatadir="${withval}"
+fi
+
+
+
+  test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+  test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+  ac_define_dir=`eval echo $gdbdatadir`
+  ac_define_dir=`eval echo $ac_define_dir`
+
+cat >>confdefs.h <<_ACEOF
+#define GDB_DATADIR "$ac_define_dir"
+_ACEOF
+
+
+
+if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then
+  if test "x$prefix" = xNONE; then
+    test_prefix=/usr/local
+  else
+    test_prefix=$prefix
+  fi
+else
+  test_prefix=$exec_prefix
+fi
+
+case ${gdbdatadir} in
+  "${test_prefix}"|"${test_prefix}/"*|\
+  '${exec_prefix}'|'${exec_prefix}/'*)
+
+$as_echo "#define GDB_DATADIR_RELOCATABLE 1" >>confdefs.h
+
+  ;;
+esac
+GDB_DATADIR_PATH=${gdbdatadir}
+
+
+
+# Check whether --with-pythondir was given.
+if test "${with_pythondir+set}" = set; then :
+  withval=$with_pythondir; pythondir="${withval}"
+else
+  pythondir=no
+fi
+
+
+# If the user passed in a path, define it.  Otherwise, compute it at
+# runtime based on the possibly-relocatable datadir.
+if test "$pythondir" = "no"; then
+  pythondir='$(GDB_DATADIR_PATH)/python'
+else
+
+cat >>confdefs.h <<_ACEOF
+#define PYTHONDIR "$pythondir"
+_ACEOF
+
+fi
+
+
+
 
 
 subdirs="$subdirs doc testsuite"
@@ -9282,6 +9356,8 @@ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h
   CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_PYTHON_OBS)"
   CONFIG_DEPS="$CONFIG_DEPS \$(SUBDIR_PYTHON_DEPS)"
   CONFIG_SRCS="$CONFIG_SRCS \$(SUBDIR_PYTHON_SRCS)"
+  CONFIG_INSTALL="$CONFIG_INSTALL install-python"
+  CONFIG_UNINSTALL="$CONFIG_UNINSTALL uninstall-python"
   ENABLE_CFLAGS="$ENABLE_CFLAGS \$(SUBDIR_PYTHON_CFLAGS)"
 
   # Flags needed to compile Python code (taken from python-config --cflags).
diff --git a/gdb/configure.ac b/gdb/configure.ac
index b31d9b7..a1969bc 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -107,6 +107,51 @@ AS_HELP_STRING([--with-relocated-sources=PATH], [automatically relocate this pat
               [Relocated directory for source files. ])
 ])
 
+# GDB's datadir relocation
+
+gdbdatadir=${datadir}/gdb
+
+AC_ARG_WITH([gdb-datadir],
+  [AS_HELP_STRING([--with-gdb-datadir],
+                  [look for global separate data files in this path [DATADIR/gdb]])], [gdbdatadir="${withval}"])
+
+AC_DEFINE_DIR(GDB_DATADIR, gdbdatadir,
+              [Global directory for GDB data files. ])
+
+if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then
+  if test "x$prefix" = xNONE; then
+    test_prefix=/usr/local
+  else
+    test_prefix=$prefix
+  fi
+else
+  test_prefix=$exec_prefix
+fi
+
+case ${gdbdatadir} in
+  "${test_prefix}"|"${test_prefix}/"*|\
+  '${exec_prefix}'|'${exec_prefix}/'*)
+    AC_DEFINE(GDB_DATADIR_RELOCATABLE, 1, [Define if GDB datadir should be relocated when GDB is moved.])
+  ;;
+esac
+GDB_DATADIR_PATH=${gdbdatadir}
+AC_SUBST(GDB_DATADIR_PATH)
+
+AC_ARG_WITH([pythondir],
+  [AS_HELP_STRING([--with-pythondir],
+                  [install Python data files in this path [DATADIR/gdb/python]])], [pythondir="${withval}"], [pythondir=no])
+
+# If the user passed in a path, define it.  Otherwise, compute it at
+# runtime based on the possibly-relocatable datadir.
+if test "$pythondir" = "no"; then
+  pythondir='$(GDB_DATADIR_PATH)/python'
+else
+  AC_DEFINE_UNQUOTED(PYTHONDIR, "$pythondir",
+      [Define to install path for Python sources])
+fi
+AC_SUBST(pythondir)
+
+
 AC_CONFIG_SUBDIRS(doc testsuite)
 
 # Check whether to support alternative target configurations
@@ -658,6 +703,8 @@ if test "${have_libpython}" = yes; then
   CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_PYTHON_OBS)"
   CONFIG_DEPS="$CONFIG_DEPS \$(SUBDIR_PYTHON_DEPS)"
   CONFIG_SRCS="$CONFIG_SRCS \$(SUBDIR_PYTHON_SRCS)"
+  CONFIG_INSTALL="$CONFIG_INSTALL install-python"
+  CONFIG_UNINSTALL="$CONFIG_UNINSTALL uninstall-python"
   ENABLE_CFLAGS="$ENABLE_CFLAGS \$(SUBDIR_PYTHON_CFLAGS)"
 
   # Flags needed to compile Python code (taken from python-config --cflags).
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index 62800b8..97d587b 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -1,7 +1,6 @@
 /* YACC parser for C++ names, for GDB.
 
-   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    Parts of the lexer are based on c-exp.y from GDB.
 
@@ -389,7 +388,7 @@ function
 		|	colon_ext_only function_arglist start_opt
 			{ $$ = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
 			  if ($3) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $3); }
-
+		|	colon_ext_only
 		|	conversion_op_name start_opt
 			{ $$ = $1.comp;
 			  if ($2) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $2); }
diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index d2d8f2e..b950147 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -36,14 +36,17 @@ static struct using_direct *cp_copy_usings (struct using_direct *using,
 					    struct obstack *obstack);
 
 static struct symbol *lookup_namespace_scope (const char *name,
-					      const char *linkage_name,
 					      const struct block *block,
 					      const domain_enum domain,
 					      const char *scope,
 					      int scope_len);
 
+static struct symbol *cp_lookup_symbol_in_namespace (const char *namespace,
+                                                     const char *name,
+                                                     const struct block *block,
+                                                     const domain_enum domain);
+
 static struct symbol *lookup_symbol_file (const char *name,
-					  const char *linkage_name,
 					  const struct block *block,
 					  const domain_enum domain,
 					  int anonymous_namespace);
@@ -119,7 +122,7 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
 		 anonymous namespace.  So add symbols in it to the
 		 namespace given by the previous component if there is
 		 one, or to the global namespace if there isn't.  */
-	      cp_add_using_directive (dest, src);
+	      cp_add_using_directive (dest, src, "", "", 0);
 	    }
 	  /* The "+ 2" is for the "::".  */
 	  previous_component = next_component + 2;
@@ -134,7 +137,8 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
    has already been added, don't add it twice.  */
 
 void
-cp_add_using_directive (const char *dest, const char *src)
+cp_add_using_directive (const char *dest, const char *src, const char* alias,
+			const char *declaration, const int line_number)
 {
   struct using_direct *current;
   struct using_direct *new;
@@ -148,7 +152,8 @@ cp_add_using_directive (const char *dest, const char *src)
 	return;
     }
 
-  using_directives = cp_add_using (dest, src, using_directives);
+  using_directives = cp_add_using (dest, src, alias, declaration,
+				   line_number, using_directives);
 
 }
 
@@ -201,7 +206,10 @@ cp_is_anonymous (const char *namespace)
 }
 
 /* Create a new struct using direct which imports the namespace SRC
-   into the scope DEST.
+   into the scope DEST.  ALIAS is the name of the imported namespace
+   in the current scope.  If ALIAS is an empty string  then the
+   namespace is known by its original name.
+
    Set its next member in the linked list to NEXT; allocate all memory
    using xmalloc.  It copies the strings, so NAME can be a temporary
    string.  */
@@ -209,14 +217,21 @@ cp_is_anonymous (const char *namespace)
 struct using_direct *
 cp_add_using (const char *dest,
               const char *src,
+              const char *alias,
+              const char *declaration,
+              const int line_number,
 	      struct using_direct *next)
 {
   struct using_direct *retval;
 
   retval = xmalloc (sizeof (struct using_direct));
-  retval->import_src = savestring (src, strlen(src));
-  retval->import_dest = savestring (dest, strlen(dest));
+  retval->import_src = savestring (src, strlen (src));
+  retval->import_dest = savestring (dest, strlen (dest));
+  retval->alias = savestring (alias, strlen (alias));
+  retval->declaration = savestring (declaration, strlen (declaration));
+  retval->line_number = line_number;
   retval->next = next;
+  retval->searched = 0;
 
   return retval;
 }
@@ -241,10 +256,18 @@ cp_copy_usings (struct using_direct *using,
 				    obstack);
       retval->import_dest = obsavestring (using->import_dest, strlen (using->import_dest),
 				    obstack);
+      retval->alias = obsavestring (using->alias, strlen (using->alias),
+                                    obstack);
+      retval->declaration = obsavestring (using->declaration, strlen (using->declaration),
+                                    obstack);
       retval->next = cp_copy_usings (using->next, obstack);
 
+      retval->searched = using->searched;
+
       xfree (using->import_src);
       xfree (using->import_dest);
+      xfree (using->alias);
+      xfree (using->declaration);
       xfree (using);
 
       return retval;
@@ -261,12 +284,48 @@ cp_copy_usings (struct using_direct *using,
 
 struct symbol *
 cp_lookup_symbol_nonlocal (const char *name,
-			   const char *linkage_name,
 			   const struct block *block,
 			   const domain_enum domain)
 {
-  return lookup_namespace_scope (name, linkage_name, block, domain,
-				 block_scope (block), 0);
+  struct symbol *sym; 
+  const char *scope = block_scope (block);
+
+  sym = lookup_namespace_scope (name, block, domain, scope, 0);
+  if (sym != NULL)
+    return sym;
+
+  return cp_lookup_symbol_namespace(scope, name, block, domain);
+}
+
+/* Searches for NAME in the current namespace, and by applying relevant import
+   statements belonging to BLOCK and its parents.  SCOPE is the namespace
+   scope of the context in which the search is being evaluated.  */
+
+struct symbol*
+cp_lookup_symbol_namespace (const char *scope,
+                            const char *name,
+                            const struct block *block,
+                            const domain_enum domain)
+{
+  struct symbol *sym;
+
+  /* First, try to find the symbol in the given namespace.  */
+  sym = cp_lookup_symbol_in_namespace (scope, name, block, domain);
+  if ( sym != NULL)
+    return sym;
+    
+  /* Search for name in namespaces imported to this and parent blocks.  */
+  while (block != NULL)
+    {
+      sym = cp_lookup_symbol_imports(scope,name, block, domain,0,1);
+
+      if (sym)
+        return sym;
+
+      block = BLOCK_SUPERBLOCK(block);
+    }
+
+  return NULL;
 }
 
 /* Lookup NAME at namespace scope (or, in C terms, in static and
@@ -284,9 +343,8 @@ cp_lookup_symbol_nonlocal (const char *name,
    "A::x", and if that call fails, then the first call looks for
    "x".  */
 
-static struct symbol *
+struct symbol *
 lookup_namespace_scope (const char *name,
-			const char *linkage_name,
 			const struct block *block,
 			const domain_enum domain,
 			const char *scope,
@@ -308,8 +366,7 @@ lookup_namespace_scope (const char *name,
 	  new_scope_len += 2;
 	}
       new_scope_len += cp_find_first_component (scope + new_scope_len);
-      sym = lookup_namespace_scope (name, linkage_name, block,
-				    domain, scope, new_scope_len);
+      sym = lookup_namespace_scope (name, block, domain, scope, new_scope_len);
       if (sym != NULL)
 	return sym;
     }
@@ -320,25 +377,81 @@ lookup_namespace_scope (const char *name,
   namespace = alloca (scope_len + 1);
   strncpy (namespace, scope, scope_len);
   namespace[scope_len] = '\0';
-  return cp_lookup_symbol_namespace (namespace, name, linkage_name,
-				     block, domain);
+  return cp_lookup_symbol_in_namespace (namespace, name,block, domain);
 }
 
-/* Look up NAME in the C++ namespace NAMESPACE, applying the using
-   directives that are active in BLOCK.  Other arguments are as in
+/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in
    cp_lookup_symbol_nonlocal.  */
 
+static struct symbol *
+cp_lookup_symbol_in_namespace (const char *namespace,
+			       const char *name,
+			       const struct block *block,
+			       const domain_enum domain)
+{
+
+  if (namespace[0] == '\0')
+    {
+      return lookup_symbol_file (name, block,domain, 0);
+    }
+  else
+    {
+      char *concatenated_name
+	= alloca (strlen (namespace) + 2 + strlen (name) + 1);
+      strcpy (concatenated_name, namespace);
+      strcat (concatenated_name, "::");
+      strcat (concatenated_name, name);
+      return lookup_symbol_file (concatenated_name, block, domain,
+				cp_is_anonymous (namespace));
+    }
+}
+
+/* Search for NAME by applying all import statements belonging
+   to BLOCK which are applicable in SCOPE. If DECLARATION_ONLY the search
+   is restricted to using declarations.
+   Example:
+
+     namespace A{
+       int x;
+     }
+     using A::x;
+
+   If SEARCH_PARENTS the search will include imports which are applicable in
+   parents of scopes.
+   Example:
+
+     namespace A{
+       using namespace X;
+       namespace B{
+         using namespace Y;
+       }
+     }
+
+   If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X
+   and Y will be considered. If SEARCH_PARENTS is false only the import of Y
+   is considered.  */
+
 struct symbol *
-cp_lookup_symbol_namespace (const char *namespace,
-			    const char *name,
-			    const char *linkage_name,
-			    const struct block *block,
-			    const domain_enum domain)
+cp_lookup_symbol_imports (const char *scope,
+                            const char *name,
+                            const struct block *block,
+                            const domain_enum domain,
+                            int declaration_only,
+                            int search_parents)
 {
-  const struct using_direct *current;
-  struct symbol *sym;
+  struct using_direct *current;
+  struct symbol *sym = NULL;
+  int directive_match;
+  int current_line = find_pc_line (get_frame_pc (get_selected_frame (NULL)), 0).line;
 
-  /* First, go through the using directives.  If any of them add new
+  if(!declaration_only)
+    /* First, try to find the symbol in the given namespace.  */
+    sym = cp_lookup_symbol_in_namespace (scope, name, block, domain);
+
+  if ( sym != NULL)
+    return sym;
+
+  /* Go through the using directives.  If any of them add new
      names to the namespace we're searching in, see if we can find a
      match by applying them.  */
 
@@ -346,39 +459,74 @@ cp_lookup_symbol_namespace (const char *namespace,
        current != NULL;
        current = current->next)
     {
-      if (strcmp (namespace, current->import_dest) == 0)
+  
+      /* If the import destination is the current scope or one of its ancestors then
+         it is applicable.  */
+      directive_match = search_parents ?
+                        strncmp (scope, current->import_dest,
+                                 strlen(current->import_dest)) == 0 :
+                        strcmp (scope, current->import_dest) == 0;
+
+      if (directive_match &&
+          current->line_number < current_line &&
+          !current->searched)
 	{
-	  sym = cp_lookup_symbol_namespace (current->import_src,
-					    name,
-					    linkage_name,
-					    block,
-					    domain);
+	  current->searched = 1;
+	  /* If there is an import of a single declaration, compare the imported
+	     declaration with the sought out name. If there is a match pass
+	     current->import_src as NAMESPACE to direct the search towards the
+	     imported namespace.  */
+	  if (strcmp ("", current->declaration) != 0)
+	    {
+	    if (strcmp (name, current->declaration) == 0)
+	      {
+	        sym = cp_lookup_symbol_in_namespace (current->import_src,
+	                                          name,
+	                                          block,
+	                                          domain);
+	      }
+	    }
+	   
+	  if (declaration_only)
+            {
+              current->searched = 0;
+              if (sym)
+                {
+                  return sym;
+                } else {
+                  continue;
+                }
+            }
+
+	  if (strcmp (name, current->alias) == 0)
+	    /* If the import is creating an alias and the alias matches the
+	       sought name. Pass current->inner as the NAME to direct the
+	       search towards the aliased namespace */
+	    {
+	    sym = cp_lookup_symbol_in_namespace (scope,
+	                                      current->import_src,
+	                                      block,
+	                                      domain);
+	    } else if (strcmp ("", current->alias) == 0){
+	    /* If this import statement creates no alias, pass current->inner as
+	       NAMESPACE to direct the search towards the imported namespace. */
+	      sym = cp_lookup_symbol_imports (current->import_src,
+		                                name,
+		                                block,
+		                                domain,
+		                                0,
+		                                0);
+	    }
+
+	  current->searched = 0;
 	  if (sym != NULL)
-	    return sym;
+	    {
+	      return sym;
+	    }
 	}
     }
 
-  /* We didn't find anything by applying any of the using directives
-     that are still applicable; so let's see if we've got a match
-     using the current namespace.  */
-  
-  if (namespace[0] == '\0')
-    {
-      return lookup_symbol_file (name, linkage_name, block,
-				 domain, 0);
-    }
-  else
-    {
-      char *concatenated_name
-	= alloca (strlen (namespace) + 2 + strlen (name) + 1);
-      strcpy (concatenated_name, namespace);
-      strcat (concatenated_name, "::");
-      strcat (concatenated_name, name);
-      sym = lookup_symbol_file (concatenated_name, linkage_name,
-				block, domain, 
-				cp_is_anonymous (namespace));
-      return sym;
-    }
+  return NULL;
 }
 
 /* Look up NAME in BLOCK's static block and in global blocks.  If
@@ -388,17 +536,15 @@ cp_lookup_symbol_namespace (const char *namespace,
 
 static struct symbol *
 lookup_symbol_file (const char *name,
-		    const char *linkage_name,
 		    const struct block *block,
 		    const domain_enum domain,
 		    int anonymous_namespace)
 {
   struct symbol *sym = NULL;
 
-  sym = lookup_symbol_static (name, linkage_name, block, domain);
+  sym = lookup_symbol_static (name, block, domain);
   if (sym != NULL)
     return sym;
-
   if (anonymous_namespace)
     {
       /* Symbols defined in anonymous namespaces have external linkage
@@ -408,12 +554,11 @@ lookup_symbol_file (const char *name,
       const struct block *global_block = block_global_block (block);
       
       if (global_block != NULL)
-	sym = lookup_symbol_aux_block (name, linkage_name, global_block,
-				       domain);
+	sym = lookup_symbol_aux_block (name, global_block, domain);
     }
   else
     {
-      sym = lookup_symbol_global (name, linkage_name, block, domain);
+      sym = lookup_symbol_global (name, block, domain);
     }
 
   if (sym != NULL)
@@ -434,6 +579,7 @@ lookup_symbol_file (const char *name,
       sym = lookup_possible_namespace_symbol (name);
       if (sym != NULL)
 	return sym;
+
     }
 
   return NULL;
@@ -461,9 +607,8 @@ cp_lookup_nested_type (struct type *parent_type,
 	   lookup_symbol_namespace works when looking them up.  */
 
 	const char *parent_name = TYPE_TAG_NAME (parent_type);
-	struct symbol *sym = cp_lookup_symbol_namespace (parent_name,
+	struct symbol *sym = cp_lookup_symbol_in_namespace (parent_name,
 							 nested_name,
-							 NULL,
 							 block,
 							 VAR_DOMAIN);
 	if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
@@ -709,7 +854,7 @@ check_one_possible_namespace_symbol (const char *name, int len,
 
   memcpy (name_copy, name, len);
   name_copy[len] = '\0';
-  sym = lookup_block_symbol (block, name_copy, NULL, VAR_DOMAIN);
+  sym = lookup_block_symbol (block, name_copy, VAR_DOMAIN);
 
   if (sym == NULL)
     {
@@ -749,7 +894,7 @@ lookup_possible_namespace_symbol (const char *name)
       struct symbol *sym;
 
       sym = lookup_block_symbol (get_possible_namespace_block (objfile),
-				 name, NULL, VAR_DOMAIN);
+				 name, VAR_DOMAIN);
 
       if (sym != NULL)
 	return sym;
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index f12d785..ca10007 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -70,6 +70,21 @@ struct cmd_list_element *maint_cplus_cmd_list = NULL;
 static void maint_cplus_command (char *arg, int from_tty);
 static void first_component_command (char *arg, int from_tty);
 
+/* Operator validation. This is used by cp_validate_opeartor,
+   which is in turn used by both the expression parser (clex)
+   and decode_line (decode_compound, actually).
+
+   NOTE: Multi-byte operators (usually the assignment variety operator)
+   must appear before the single byte version, i.e., "+=" before "+". */
+static const char *operator_tokens[] =
+  {
+    "++", "+=", "+", "->*", "->", "--", "-=", "-", "*=", "*", "/=", "/",
+    "%=", "%", "!=", "==", "!", "&&", "<<=", "<<", ">>=", ">>",
+    "<=", "<", ">=", ">", "~", "&=", "&", "|=", "||", "|", "^=", "^",
+    "=", "()", "[]", ",", "new", "delete"
+    /* new[] and delete[] require special whitespace handling */
+  };
+
 /* Return 1 if STRING is clearly already in canonical form.  This
    function is conservative; things which it does not recognize are
    assumed to be non-canonical, and the parser will sort them out
@@ -175,7 +190,8 @@ mangled_name_to_comp (const char *mangled_name, int options,
   return ret;
 }
 
-/* Return the name of the class containing method PHYSNAME.  */
+/* Return the name of the class or namespace containing
+   function, method, or variable PHYSNAME.  */
 
 char *
 cp_class_name_from_physname (const char *physname)
@@ -825,9 +841,9 @@ read_in_psymtabs (const char *func_name)
     if (ps->readin)
       continue;
 
-    if ((lookup_partial_symbol (ps, func_name, NULL, 1, VAR_DOMAIN)
+    if ((lookup_partial_symbol (ps, func_name, 1, VAR_DOMAIN)
 	 != NULL)
-	|| (lookup_partial_symbol (ps, func_name, NULL, 0, VAR_DOMAIN)
+	|| (lookup_partial_symbol (ps, func_name, 0, VAR_DOMAIN)
 	    != NULL))
       psymtab_to_symtab (ps);
   }
@@ -909,6 +925,72 @@ first_component_command (char *arg, int from_tty)
 
 extern initialize_file_ftype _initialize_cp_support; /* -Wmissing-prototypes */
 
+#define SKIP_SPACE(P)				\
+  do						\
+  {						\
+    while (*(P) == ' ' || *(P) == '\t')		\
+      ++(P);					\
+  }						\
+  while (0)
+
+/* Returns the length of the operator name or 0 if INPUT does not
+   point to a valid C++ operator. INPUT should start with "operator". */
+int
+cp_validate_operator (const char *input)
+{
+  int i;
+  const char *p = input;
+  int valid = 0;
+
+  /* Most callers appear to do this already, but since this is not
+     really time-critical code, it is double-checked here. */
+  if (strncmp (p, "operator", 8) == 0)
+    {
+      p += 8;
+
+      SKIP_SPACE (p);
+      for (i = 0; i < sizeof (operator_tokens) / sizeof (operator_tokens[0]);
+	   ++i)
+	{
+	  int length = strlen (operator_tokens[i]);
+	  /* By using strncmp here, we MUST have operator_tokens ordered!
+	     See additional notes where operator_tokens is defined above. */
+	  if (strncmp (p, operator_tokens[i], length) == 0)
+	    {
+	      const char *op = p;
+	      valid = 1;
+	      p += length;
+
+	      if (strncmp (op, "new", 3) == 0
+		  || strncmp (op, "delete", 6) == 0)
+		{
+
+		  /* Special case: new[] and delete[]. We must be careful
+		     to swallow whitespace before/in "[]".*/
+		  SKIP_SPACE (p);
+
+		  if (*p == '[')
+		    {
+		      ++p;
+		      SKIP_SPACE (p);
+		      if (*p == ']')
+			++p;
+		      else
+			valid = 0;
+		    }
+		}
+
+	      break;
+	    }
+	}
+
+      if (!valid)
+	p = input;
+    }
+
+  return (p - input);
+}
+
 void
 _initialize_cp_support (void)
 {
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index b5a5c5f..3f48f98 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -38,15 +38,33 @@ struct demangle_component;
 
 /* This struct is designed to store data from using directives.  It
    says that names from namespace IMPORT_SRC should be visible within
-   namespace IMPORT_DEST. IMPORT_DEST should always be a strict initial
-   substring of IMPORT_SRC. These form a linked list; NEXT is the next element
-   of the list.  */
+   namespace IMPORT_DEST.  IMPORT_DEST should always be a strict initial
+   substring of IMPORT_SRC.  These form a linked list; NEXT is the next
+   element of the list.  ALIAS is set to a non empty string if the imported
+   namespace has been aliased.Eg:
+       namespace C=A::B;
+   ALIAS = "C"
+   DECLARATION is the name of the imported declaration, if this import 
+   statement represents one. Eg:
+       using A::x;
+   Where x is variable in namespace A. declaration is set to x.  
+*/
 
 struct using_direct
 {
   char *import_src;
   char *import_dest;
+
+  char *alias;
+
+  char *declaration;
+
+  int line_number;
+
   struct using_direct *next;
+
+  /* Used during import search to temporarly mark this node as searced.  */
+  int searched;
 };
 
 
@@ -54,6 +72,7 @@ struct using_direct
 
 extern char *cp_canonicalize_string (const char *string);
 
+
 extern char *cp_class_name_from_physname (const char *physname);
 
 extern char *method_name_from_physname (const char *physname);
@@ -72,15 +91,23 @@ extern struct symbol **make_symbol_overload_list (const char *,
 extern struct type *cp_lookup_rtti_type (const char *name,
 					 struct block *block);
 
+extern int cp_validate_operator (const char *input);
+
 /* Functions/variables from cp-namespace.c.  */
 
 extern int cp_is_anonymous (const char *namespace);
 
 extern void cp_add_using_directive (const char *dest,
-                                    const char *src);
+                                    const char *src,
+                                    const char *alias,
+                                    const char *declaration,
+                                    const int line_number);
 
 extern struct using_direct *cp_add_using (const char *dest,
                                           const char *src,
+                                          const char *alias,
+                                          const char *declaration,
+                                          const int line_number,
 					  struct using_direct *next);
 
 extern void cp_initialize_namespace (void);
@@ -97,15 +124,20 @@ extern void cp_set_block_scope (const struct symbol *symbol,
 extern void cp_scan_for_anonymous_namespaces (const struct symbol *symbol);
 
 extern struct symbol *cp_lookup_symbol_nonlocal (const char *name,
-						 const char *linkage_name,
 						 const struct block *block,
 						 const domain_enum domain);
 
+struct symbol *cp_lookup_symbol_imports (const char *scope,
+                                         const char *name,
+                                         const struct block *block,
+                                         const domain_enum domain,
+                                         int declaration_only,
+                                         int search_parents);
+
 extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
-						  const char *name,
-						  const char *linkage_name,
-						  const struct block *block,
-						  const domain_enum domain);
+                                                  const char *name,
+                                                  const struct block *block,
+                                                  const domain_enum domain);
 
 extern struct type *cp_lookup_nested_type (struct type *parent_type,
 					   const char *nested_name,
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index 7cb016d..bb9e35a 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -3581,6 +3581,7 @@ static struct sym_fns aout_sym_fns =
   dbx_new_init,		/* sym_new_init: init anything gbl to entire symtab */
   dbx_symfile_init,	/* sym_init: read initial info, setup for sym_read() */
   dbx_symfile_read,		/* sym_read: read a symbol file into symtab */
+  NULL,				/* sym_read_psymbols */
   dbx_symfile_finish,		/* sym_finish: finished with file, cleanup */
   default_symfile_offsets, /* sym_offsets: parse user's offsets to
 			      internal form */
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 5a5f542..2c6bcef 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -959,8 +959,10 @@ Connect to process ID @var{number}, as with the @code{attach} command.
 @itemx -x @var{file}
 @cindex @code{--command}
 @cindex @code{-x}
-Execute @value{GDBN} commands from file @var{file}.  @xref{Command
-Files,, Command files}.
+Execute commands from file @var{file}.  If @var{file} ends in
+@samp{.py}, then the file is evaluated as Python code.  If Python
+support is not enabled in this @value{GDBN}, then an error occurs.
+@xref{Command Files,, Command files}.
 
 @item -eval-command @var{command}
 @itemx -ex @var{command}
@@ -1152,6 +1154,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.
 
+@item -P
+@cindex @code{-P}
+@itemx --python
+@cindex @code{--python}
+Change interpretation of command line so that the argument immediately
+following this switch is taken to be the name of a Python script file.
+This option stops option processing; subsequent options are passed to
+Python as @code{sys.argv}.  This option is only available if Python
+scripting support was enabled when @value{GDBN} was configured.
+
 @c resolve the situation of these eventually
 @item -tui
 @cindex @code{--tui}
@@ -18650,7 +18662,7 @@ command:
 @table @code
 @kindex source
 @cindex execute commands from a file
-@item source [@code{-v}] @var{filename}
+@item source [@code{-v}] [@code{-p}] @var{filename}
 Execute the command file @var{filename}.
 @end table
 
@@ -18667,6 +18679,11 @@ If @code{-v}, for verbose mode, is given then @value{GDBN} displays
 each command as it is executed.  The option must be given before
 @var{filename}, and is interpreted as part of the filename anywhere else.
 
+If @var{filename} ends in @samp{.py}, or if @code{-p}, for Python, is
+given then @value{GDBN} evaluates the contents of the file as Python
+code.  If Python support is not compiled in to @value{GDBN}, then an
+error occurs.
+
 Commands that would ask for confirmation if used interactively proceed
 without asking when used in a command file.  Many @value{GDBN} commands that
 normally print messages to say what they are doing omit the messages
@@ -18928,8 +18945,6 @@ containing @code{end}.  For example:
 
 @smallexample
 (@value{GDBP}) python
-Type python script
-End with a line saying just "end".
 >print 23
 >end
 23
@@ -18942,6 +18957,14 @@ in a Python script.  This can be controlled using @code{maint set
 python print-stack}: if @code{on}, the default, then Python stack
 printing is enabled; if @code{off}, then Python stack printing is
 disabled.
+
+@kindex maint set python auto-load
+@item maint set python auto-load
+By default, @value{GDBN} will attempt to automatically load Python
+code when an object file is opened.  This can be controlled using
+@code{maint set python auto-load}: if @code{on}, the default, then
+Python auto-loading is enabled; if @code{off}, then Python
+auto-loading is disabled.
 @end table
 
 @node Python API
@@ -18949,6 +18972,14 @@ disabled.
 @cindex python api
 @cindex programming in python
 
+You can get quick online help for @value{GDBN}'s Python API by issuing
+the command @w{@kbd{python help (gdb)}}.
+
+Functions and methods which have two or more optional arguments allow
+them to be specified using keyword syntax.  This allows passing some
+optional arguments while skipping others.  Example:
+@w{@code{gdb.some_function ('foo', bar = 1, baz = 2)}}.
+
 @cindex python stdout
 @cindex python pagination
 At startup, @value{GDBN} overrides Python's @code{sys.stdout} and
@@ -18961,13 +18992,17 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown.
 * Basic Python::                Basic Python Functions.
 * Exception Handling::
 * Auto-loading::                Automatically loading Python code.
-* Values From Inferior::
+* Values From Inferior::	Python representation of values.
 * Types In Python::		Python representation of types.
 * Pretty Printing::		Pretty-printing values.
 * Selecting Pretty-Printers::   How GDB chooses a pretty-printer.
+* Inferiors In Python::		Python representation of inferiors (processes)
+* Threads In Python::           Accessing inferior threads from Python.
 * Commands In Python::          Implementing new commands in Python.
+* Parameters In Python::        Adding new @value{GDBN} parameters.
 * Functions In Python::         Writing new convenience functions.
 * Objfiles In Python::          Object files.
+* Breakpoints In Python::       Manipulating breakpoints using Python.
 * Frames In Python::            Acessing inferior stack frames from Python.
 @end menu
 
@@ -18994,6 +19029,12 @@ command as having originated from the user invoking it interactively.
 It must be a boolean value.  If omitted, it defaults to @code{False}.
 @end defun
 
+@findex gdb.breakpoints
+@defun breakpoints
+Return a sequence holding all of @value{GDBN}'s breakpoints.
+@xref{Breakpoints In Python}, for more information.
+@end defun
+
 @findex gdb.parameter
 @defun parameter parameter
 Return the value of a @value{GDBN} parameter.  @var{parameter} is a
@@ -19010,6 +19051,7 @@ a Python value of the appropriate type, and returned.
 @defun history number
 Return a value from @value{GDBN}'s value history (@pxref{Value
 History}).  @var{number} indicates which history element to return.
+
 If @var{number} is negative, then @value{GDBN} will take its absolute value
 and count backward from the last element (i.e., the most recent element) to
 find the value to return.  If @var{number} is zero, then @value{GDBN} will
@@ -19021,6 +19063,28 @@ If no exception is raised, the return value is always an instance of
 @code{gdb.Value} (@pxref{Values From Inferior}).
 @end defun
 
+@findex gdb.parse_and_eval
+@defun parse_and_eval expression
+Parse @var{expression} as an expression in the current language,
+evaluate it, and return the result as a @code{gdb.Value}.
+@var{expression} must be a string.
+@end defun
+
+@findex gdb.post_event
+@defun post_event event
+Put @var{event}, a callable object taking no arguments, into
+@value{GDBN}'s internal event queue.  This callable will be invoked at
+some later point, during @value{GDBN}'s event processing.  Events
+posted using @code{post_event} will be run in the order in which they
+were posted; however, there is no way to know when they will be
+processed relative to other events inside @value{GDBN}.
+
+@value{GDBN} is not thread-safe.  If your Python program uses multiple
+threads, you must be careful to only call @value{GDBN}-specific
+functions in the main @value{GDBN} thread.  @code{post_event} ensures
+this.
+@end defun
+
 @findex gdb.write
 @defun write string
 Print a string to @value{GDBN}'s paginated standard output stream.
@@ -19035,6 +19099,11 @@ Flush @value{GDBN}'s paginated standard output stream.  Flushing
 function.
 @end defun
 
+@findex gdb.solib_address
+@defun solib_address @var{address}
+Return the name of the shared library holding the given address, or None.
+@end defun
+
 @node Exception Handling
 @subsubsection Exception Handling
 @cindex python exceptions
@@ -19171,6 +19240,13 @@ The type of this @code{gdb.Value}.  The value of this attribute is a
 The following methods are provided:
 
 @table @code
+@defmethod Value cast type
+Cast the @code{gdb.Value} to the type represented by @var{type}, and
+return a new @code{gdb.Value}.  @var{type} must be a @code{gdb.Type}
+object.  If the cast cannot be performed for some reason, an exception
+is thrown.
+@end defmethod
+
 @defmethod Value dereference
 For pointer data types, this method returns a new @code{gdb.Value} object
 whose contents is the object pointed to by the pointer.  For example, if
@@ -19242,6 +19318,9 @@ module:
 This function looks up a type by name.  @var{name} is the name of the
 type to look up.  It must be a string.
 
+If @var{block} is given, then @var{name} is looked up in that scope.
+Otherwise, it is searched for globally.
+
 Ordinarily, this function will return an instance of @code{gdb.Type}.
 If the named type cannot be found, it will throw an exception.
 @end defun
@@ -19294,6 +19373,12 @@ This is @code{True} if the field is artificial, usually meaning that
 it was provided by the compiler and not the user.  This attribute is
 always provided, and is @code{False} if the field is not artificial.
 
+@item is_base_class
+This is @code{True} if the field represents a base class of a C@t{++}
+structure.  This attribute is always provided, and is @code{False}
+if the field is not a base class of the type on which @code{fields} was
+called, or if that type was not a C@t{++} class.
+
 @item bitsize
 If the field is packed, or is a bitfield, then this will have a
 non-zero value, which is the size of the field in bits.  Otherwise,
@@ -19346,7 +19431,7 @@ If the type does not have a target, this method will throw an
 exception.
 @end defmethod
 
-@defmethod Type template_argument n
+@defmethod Type template_argument n [block]
 If this @code{gdb.Type} is an instantiation of a template, this will
 return a new @code{gdb.Type} which represents the type of the
 @var{n}th template argument.
@@ -19354,7 +19439,8 @@ return a new @code{gdb.Type} which represents the type of the
 If this @code{gdb.Type} is not a template type, this will throw an
 exception.  Ordinarily, only C@t{++} code will have template types.
 
-@var{name} is searched for globally.
+If @var{block} is given, then @var{name} is looked up in that scope.
+Otherwise, it is searched for globally.
 @end defmethod
 @end table
 
@@ -19708,6 +19794,121 @@ import gdb.libstdcxx.v6
 gdb.libstdcxx.v6.register_printers (gdb.current_objfile ())
 @end smallexample
 
+@node Inferiors In Python
+@subsubsection Inferiors In Python
+
+Programs which are being run under @value{GDBN} are called inferiors
+(@pxref{Inferiors}).  Python scripts can access information about and
+manipulate inferiors controlled by @value{GDBN} via objects of the
+@code{gdb.Inferior} class.
+
+The following inferior-related functions are available in the @code{gdb}
+module:
+
+@defun inferiors
+Return a tuple containing all inferior objects.
+@end defun
+
+A @code{gdb.Inferior} object has the following attributes:
+
+@table @code
+@defivar Inferior num 
+ID of inferior, as assigned by GDB.
+@end defivar
+
+@defivar Inferior pid 
+Process ID of the inferior, assigned by the underlying OS.
+@end defivar
+
+@defivar Inferior was_attached
+Boolean signaling whether the inferior was created using `attach', or
+started by @value{GDBN} itself.
+@end defivar
+@end table
+
+A @code{gdb.Inferior} object has the following methods:
+
+@table @code
+@defmethod Inferior threads 
+This method returns a tuple holding all the threads which are valid
+when it is called.  If there are no valid threads, the method will
+return an empty list.
+@end defmethod
+
+@findex gdb.read_memory
+@defmethod Inferior read_memory @var{address} @var{length}
+Read @var{length} bytes of memory from the inferior, starting at
+@var{address}.  Returns a buffer object, which behaves much like an array
+or a string. It can be modified and given to the @code{gdb.write_memory}
+function.
+@end defmethod
+
+@findex gdb.write_memory
+@defmethod Inferior write_memory @var{address} @var{buffer} @r{[}@var{length}@r{]}
+Write the contents of @var{buffer} (a Python object which supports the
+buffer protocol, i.e., a string, an array or the object returned from
+@code{gdb.read_memory}) to the inferior, starting at @var{address}.
+If given, @var{length} determines the number of bytes from @var{buffer} to
+be written.
+@end defmethod
+
+@findex gdb.search_memory
+@defmethod Inferior search_memory @var{address} @var{length} @var{pattern} @r{[}@var{size}@r{]} @r{[}@var{max_count}@r{]}
+Search a region of the inferior memory starting at @var{address} with the
+given @var{length}.  @var{pattern} can be a string, a byte array, a buffer
+object, a number, a @code{gdb.Value} object (@pxref{Values From Inferior})
+or a list or tuple with elements in any combination of those types.  If
+@var{size} is given and is non-zero, it specifies the size in bytes of a
+Python scalar or @code{gdb.Value} in the search pattern.  If @var{size} is
+zero or not specified, it is taken from the value's type in the current
+language.  This is useful when one wants to specify the search pattern as
+a mixture of types.  Note that this means, for example, that in the case of
+C-like languages a search for an untyped 0x42 will search for
+@samp{(int) 0x42} which is typically four bytes.  @var{max_count} is the
+highest number of matches to search for.
+@end defmethod
+@end table
+
+@node Threads In Python
+@subsubsection Threads In Python
+
+Python scripts can access information about and manipulate inferior threads
+controlled by @value{GDBN} via objects of the @code{gdb.InferiorThread} class.
+
+The following inferior-related functions are available in the @code{gdb}
+module:
+
+@findex gdb.selected_thread
+@defun selected_thread
+This function returns the thread object for the selected thread.  If there
+is no selected thread, this will return @code{None}.
+@end defun
+
+A @code{gdb.InferiorThread} object has the following attributes:
+
+@table @code
+@defivar InferiorThread num 
+ID of the thread, as assigned by GDB.
+@end defivar
+@end table
+
+A @code{gdb.InferiorThread} object has the following methods:
+
+@table @code
+@defmethod InferiorThread frames
+Return a tuple containing all frames in the thread.
+@end defmethod
+
+@defmethod InferiorThread newest_frame
+Return the newest frame thread's stack.
+@end defmethod
+
+@defmethod InferiorThread switch_to_thread 
+This changes @value{GDBN}'s currently selected thread to the one represented
+by this object.
+@end defmethod
+@end table
+
 @node Commands In Python
 @subsubsection Commands In Python
 
@@ -19960,6 +20161,135 @@ registration of the command with @value{GDBN}.  Depending on how the
 Python code is read into @value{GDBN}, you may need to import the
 @code{gdb} module explicitly.
 
+@node Parameters In Python
+@subsubsection Parameters In Python
+
+@cindex parameters in python
+@cindex python parameters
+@tindex gdb.Parameter
+@tindex Parameter
+You can implement new @value{GDBN} parameters using Python.  A new
+parameter is implemented as an instance of the @code{gdb.Parameter}
+class.  Parameters are exposed to the user via the @code{set} and
+@code{show} commands.
+
+@defmethod Parameter __init__ name @var{command-class} @var{parameter-class} @r{[}@var{enum-sequence}@r{]}
+The object initializer for @code{Parameter} registers the new
+parameter with @value{GDBN}.  This initializer is normally invoked
+from the subclass' own @code{__init__} method.
+
+@var{name} is the name of the new parameter.  If @var{name} consists
+of multiple words, then the initial words are looked for as prefix
+commands.  In this case, if one of the prefix commands does not exist,
+an exception is raised.
+
+@var{command-class} should be one of the @samp{COMMAND_} constants
+(@pxref{Commands In Python}).  This argument tells @value{GDBN} how to
+categorize the new parameter in the help system.
+
+@var{parameter-class} should be one of the @samp{PARAM_} constants
+defined below.  This argument tells @value{GDBN} the type of the new
+parameter; this information is used for input validation and
+completion.
+
+If @var{parameter-class} is @code{PARAM_ENUM}, then
+@var{enum-sequence} must be a sequence of strings.  These strings
+represent the possible values for the parameter.
+
+If @var{parameter-class} is not @code{PARAM_ENUM}, then the presence
+of a fourth argument will cause an exception to be thrown.
+
+The help text for the new parameter is taken from the Python
+documentation string for the parameter's class, if there is one.  If
+there is no documentation string, a default value is used.
+@end defmethod
+
+@defivar Parameter set_doc
+If this attribute exists, and is a string, then its value is used as
+the help text for this parameter's @code{set} command.  The value is
+examined when @code{Parameter.__init__} is invoked; subsequent changes
+have no effect.
+@end defivar
+
+@defivar Parameter show_doc
+If this attribute exists, and is a string, then its value is used as
+the help text for this parameter's @code{show} command.  The value is
+examined when @code{Parameter.__init__} is invoked; subsequent changes
+have no effect.
+@end defivar
+
+@defivar Parameter value
+The @code{value} attribute holds the underlying value of the
+parameter.  It can be read and assigned to just as any other
+attribute.  @value{GDBN} does validation when assignments are made.
+@end defivar
+
+
+When a new parameter is defined, its type must be specified.  The
+available types are represented by constants defined in the @code{gdb}
+module:
+
+@table @code
+@findex PARAM_BOOLEAN
+@findex gdb.PARAM_BOOLEAN
+@item PARAM_BOOLEAN
+The value is a plain boolean.  The Python boolean values, @code{True}
+and @code{False} are the only valid values.
+
+@findex PARAM_AUTO_BOOLEAN
+@findex gdb.PARAM_AUTO_BOOLEAN
+@item PARAM_AUTO_BOOLEAN
+The value has three possible states: true, false, and @samp{auto}.  In
+Python, true and false are represented using boolean constants, and
+@samp{auto} is represented using @code{None}.
+
+@findex PARAM_UINTEGER
+@findex gdb.PARAM_UINTEGER
+@item PARAM_UINTEGER
+The value is an unsigned integer.  The value of 0 should be
+interpreted to mean ``unlimited''.
+
+@findex PARAM_INTEGER
+@findex gdb.PARAM_INTEGER
+@item PARAM_INTEGER
+The value is a signed integer.  The value of 0 should be interpreted
+to mean ``unlimited''.
+
+@findex PARAM_STRING
+@findex gdb.PARAM_STRING
+@item PARAM_STRING
+The value is a string.  When the user modifies the string, escapes are
+translated.
+
+@findex PARAM_STRING_NOESCAPE
+@findex gdb.PARAM_STRING_NOESCAPE
+@item PARAM_STRING_NOESCAPE
+The value is a string.  When the user modifies the string, escapes are
+passed through untranslated.
+
+@findex PARAM_OPTIONAL_FILENAME
+@findex gdb.PARAM_OPTIONAL_FILENAME
+@item PARAM_OPTIONAL_FILENAME
+The value is a either a filename (a string), or @code{None}.
+
+@findex PARAM_FILENAME
+@findex gdb.PARAM_FILENAME
+@item PARAM_FILENAME
+The value is a filename (a string).
+
+@findex PARAM_ZINTEGER
+@findex gdb.PARAM_ZINTEGER
+@item PARAM_ZINTEGER
+The value is an integer.  This is like @code{PARAM_INTEGER}, except 0
+is interpreted as itself.
+
+@findex PARAM_ENUM
+@findex gdb.PARAM_ENUM
+@item PARAM_ENUM
+The value is a string, which must be one of a collection string
+constants provided when the parameter is created.
+@end table
+
 @node Functions In Python
 @subsubsection Writing new convenience functions
 
@@ -20064,6 +20394,82 @@ which is used to format the value.  @xref{Pretty Printing}, for more
 information.
 @end defivar
 
+@node Breakpoints In Python
+@subsubsection Manipulating breakpoints using Python
+
+@cindex breakpoints in python
+@cindex python breakpoints
+@tindex gdb.Breakpoint
+@tindex Breakpoint
+Python code can manipulate breakpoints via the @code{gdb.Breakpoint}
+class.
+
+@defmethod Breakpoint __init__ location
+Create a new breakpoint.  @var{location} is a string naming the
+location of the breakpoint.  The contents can be any location
+recognized by the @code{break} command.
+@end defmethod
+
+@defmethod Breakpoint is_valid
+Return @code{True} if this @code{Breakpoint} object is valid,
+@code{False} otherwise.  A @code{Breakpoint} object can become invalid
+if the user deletes the breakpoint.  In this case, the object still
+exists, but the underlying breakpoint does not.
+@end defmethod
+
+@defivar Breakpoint enabled
+This attribute is @code{True} if the breakpoint is enabled, and
+@code{False} otherwise.  This attribute is writable.
+@end defivar
+
+@defivar Breakpoint silent
+This attribute is @code{True} if the breakpoint is silent, and
+@code{False} otherwise.  This attribute is writable.
+
+Note that a breakpoint can also be silent if it has commands and the
+first command is @code{silent}.  This is not reported by the
+@code{silent} attribute.
+@end defivar
+
+@defivar Breakpoint thread
+If the breakpoint is thread-specific, this attribute holds the thread
+id.  If the breakpoint is not thread-specific, this attribute is
+@code{None}.  This attribute is writable.
+@end defivar
+
+@defivar Breakpoint ignore_count
+This attribute holds the ignore count for the breakpoint, an integer.
+This attribute is writable.
+@end defivar
+
+@defivar Breakpoint number
+This attribute holds the breakpoint's number -- the identifier used by
+the user to manipulate the breakpoint.  This attribute is not writable.
+@end defivar
+
+@defivar Breakpoint hit_count
+This attribute holds the hit count for the breakpoint, an integer.
+This attribute is writable, but currently it can only be set to zero.
+@end defivar
+
+@defivar Breakpoint location
+This attribute holds the location of the breakpoint, as specified by
+the user.  It is a string.  This attribute is not writable.
+@end defivar
+
+@defivar Breakpoint condition
+This attribute holds the condition of the breakpoint, as specified by
+the user.  It is a string.  If there is no condition, this attribute's
+value is @code{None}.  This attribute is writable.
+@end defivar
+
+@defivar Breakpoint commands
+This attribute holds the commands attached to the breakpoint.  If
+there are commands, this returns a string holding all the commands,
+separated by newlines.  If there are no commands, this attribute is
+@code{None}.  This attribute is not writable.
+@end defivar
+
 @node Frames In Python
 @subsubsection Acessing inferior stack frames from Python.
 
@@ -20128,6 +20534,14 @@ function to a string.
 Returns the frame's resume address.
 @end defmethod
 
+@defmethod Frame block
+Returns the frame's code block. @c (@pxref{Block,,Code Blocks and Scopes}).
+@end defmethod
+
+@defmethod Frame function
+Returns the symbol for the function corresponding to this frame. @c (@pxref{Symbols In Python}).
+@end defmethod
+
 @defmethod Frame older
 Return the frame that called this frame.
 @end defmethod
@@ -20136,10 +20550,18 @@ Return the frame that called this frame.
 Return the frame called by this frame.
 @end defmethod
 
+@defmethod Frame find_sal
+Return the frame's symtab and line object. @c (@pxref{Symtab_and_line,, Symtab and line}).
+@end defmethod
+
 @defmethod Frame read_var variable
 Return the value of the given variable in this frame.  @var{variable} must
 be a string.
 @end defmethod
+
+@defmethod Frame select
+Set this frame to be the user's selected frame.
+@end defmethod
 @end table
 
 @node Interpreters
diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo
index c2be3f7..a7811ab 100644
--- a/gdb/doc/gdbint.texinfo
+++ b/gdb/doc/gdbint.texinfo
@@ -2114,6 +2114,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.
 
+@menu
+* Symbol Reading::
+* Partial Symbol Tables::
+* Types::
+* Object File Formats::
+* Debugging File Formats::
+* Adding a New Symbol Reader to GDB::
+* Memory Management for Symbol Files::
+* Memory Management for Types::
+@end menu
+
+@node Symbol Reading
 @section Symbol Reading
 
 @cindex symbol reading
@@ -2206,6 +2218,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
 
+@node Partial Symbol Tables
 @section Partial Symbol Tables
 
 @value{GDBN} has three types of symbol tables:
@@ -2301,6 +2314,7 @@ and all the psymbols themselves are allocated in a pair of large arrays
 on an obstack, so there is little to be gained by trying to free them
 unless you want to do a lot more work.
 
+@node Types
 @section Types
 
 @unnumberedsubsec Fundamental Types (e.g., @code{FT_VOID}, @code{FT_BOOLEAN}).
@@ -2323,6 +2337,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.
 
+@anchor{Builtin Types}
 @unnumberedsubsec Builtin Types (e.g., @code{builtin_type_void}, @code{builtin_type_char}).
 
 These are instances of type structs that roughly correspond to
@@ -2337,6 +2352,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.
 
+@node Object File Formats
 @section Object File Formats
 @cindex object file formats
 
@@ -2422,6 +2438,7 @@ SOM, which is a cross-language ABI).
 
 The SOM reader is in @file{somread.c}.
 
+@node Debugging File Formats
 @section Debugging File Formats
 
 This section describes characteristics of debugging information that
@@ -2493,6 +2510,7 @@ DWARF 3 is an improved version of DWARF 2.
 @cindex SOM debugging info
 Like COFF, the SOM definition includes debugging information.
 
+@node Adding a New Symbol Reader to GDB
 @section Adding a New Symbol Reader to @value{GDBN}
 
 @cindex adding debugging info reader
@@ -2515,6 +2533,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}.
 
+@node Memory Management for Symbol Files
 @section Memory Management for Symbol Files
 
 Most memory associated with a loaded symbol file is stored on
@@ -2526,10 +2545,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.
 
-User convenience variables, et cetera, have associated types.  Normally
-these types live in the associated objfile.  However, when the objfile
-is unloaded, those types are deep copied to global memory, so that
-the values of the user variables and history items are not lost.
+@node Memory Management for Types
+@section Memory Management for Types
+@cindex memory management for types
+
+@findex TYPE_OBJFILE
+@code{TYPE_OBJFILE} macro indicates the current memory owner of the type.
+Non-@code{NULL} value indicates it is owned by an objfile (specifically by its
+obstack) and in such case the type remains valid till the objfile is unloaded
+or reloaded.  For such types with an associated objfile no reference counting
+is being made.
+
+User convenience variables, et cetera, have associated types.  Normally these
+types live in the associated objfile.  However, when the objfile is unloaded,
+those types are deep copied to global memory, so that the values of the user
+variables and history items are not lost.  During the copy they will get their
+@code{TYPE_OBJFILE} set to @code{NULL} and become so-called @dfn{reclaimable}
+types.
+
+Types with null @code{TYPE_OBJFILE} can be either permanent types
+(@pxref{Builtin Types}) or reclaimable types which will be deallocated at the
+first idle @value{GDBN} moment if the last object referencing them is removed.
+Permanent types are allocated by the function @code{alloc_type} (and its
+derivations like @code{init_type}) specifying objfile as @code{NULL}.  The
+reclaimable types are created the same way but moreover they need to have
+@code{type_init_group} called to start their tracking as being possibly
+deallocatable.
+
+@findex free_all_types
+When @value{GDBN} gets idle it always calls the @code{free_all_types} function
+which deallocates any unused types.  All types currently not owned by an
+objfile must be marked as used on each @code{free_all_types} call as they would
+get deallocated as unused otherwise.
+
+@code{free_all_types} automatically checks for any cross-type references such
+as through @code{TYPE_TARGET_TYPE}, @code{TYPE_POINTER_TYPE} etc.@: and
+prevents early deallocation for any such existing references.  Reclaimable
+types may reference any other reclaimable types or even permanent types.  But
+permanent types must not reference reclaimable types (nor an objfile associated
+type).
 
 
 @node Language Support
diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi
index 4984f31..fcf1b5d 100644
--- a/gdb/doc/observer.texi
+++ b/gdb/doc/observer.texi
@@ -206,6 +206,11 @@ Either @value{GDBN} detached from the inferior, or the inferior
 exited.  The argument @var{pid} identifies the inferior.
 @end deftypefun
 
+@deftypefun void mark_used (void)
+Mark any possibly reclaimable objects as used during a mark-and-sweep garbage
+collector pass.  Currently only @code{type_mark_used} marker is supported.
+@end deftypefun
+
  @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/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 668c434..c29c3a5 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -38,6 +38,7 @@
 
 #include "complaints.h"
 #include "dwarf2-frame.h"
+#include "addrmap.h"
 
 struct comp_unit;
 
@@ -1574,6 +1575,14 @@ dwarf2_frame_find_fde (CORE_ADDR *pc)
       CORE_ADDR offset;
       CORE_ADDR seek_pc;
 
+      if (objfile->quick_addrmap)
+	{
+	  if (!addrmap_find (objfile->quick_addrmap, *pc))
+	    continue;
+	}
+      /* FIXME: Read-in only .debug_frame/.eh_frame without .debug_info?  */
+      require_partial_symbols (objfile);
+
       fde_table = objfile_data (objfile, dwarf2_frame_objfile_data);
       if (fde_table == NULL)
 	continue;
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 46bc9d7..e675575 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -848,6 +848,13 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  ctx->initialized = 0;
 	  goto no_push;
 
+	case DW_OP_push_object_address:
+	  if (ctx->get_object_address == NULL)
+	    error (_("DWARF-2 expression error: DW_OP_push_object_address must "
+	           "have a value to push."));
+	  result = (ctx->get_object_address) (ctx->baton);
+	  break;
+
 	default:
 	  error (_("Unhandled dwarf expression opcode 0x%x"), op);
 	}
diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h
index a9a8a05..d449012 100644
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -102,10 +102,10 @@ struct dwarf_expr_context
      The result must be live until the current expression evaluation
      is complete.  */
   unsigned char *(*get_subr) (void *baton, off_t offset, size_t *length);
+#endif
 
   /* Return the `object address' for DW_OP_push_object_address.  */
   CORE_ADDR (*get_object_address) (void *baton);
-#endif
 
   /* The current depth of dwarf expression recursion, via DW_OP_call*,
      DW_OP_fbreg, DW_OP_push_object_address, etc., and the maximum
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 3a81202..85f4487 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -116,6 +116,9 @@ struct dwarf_expr_baton
 {
   struct frame_info *frame;
   struct objfile *objfile;
+  /* From DW_TAG_variable's DW_AT_location (not DW_TAG_type's
+     DW_AT_data_location) for DW_OP_push_object_address.  */
+  CORE_ADDR object_address;
 };
 
 /* Helper functions for dwarf2_evaluate_loc_desc.  */
@@ -177,22 +180,33 @@ dwarf_expr_frame_base (void *baton, gdb_byte **start, size_t * length)
       *start = find_location_expression (symbaton, length,
 					 get_frame_address_in_block (frame));
     }
-  else
+  else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_locexpr_funcs)
     {
       struct dwarf2_locexpr_baton *symbaton;
+
       symbaton = SYMBOL_LOCATION_BATON (framefunc);
-      if (symbaton != NULL)
-	{
-	  *length = symbaton->size;
-	  *start = symbaton->data;
-	}
-      else
-	*start = NULL;
+      gdb_assert (symbaton != NULL);
+      *start = symbaton->data;
+      *length = symbaton->size;
     }
+  else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_missing_funcs)
+    {
+      struct dwarf2_locexpr_baton *symbaton;
+
+      symbaton = SYMBOL_LOCATION_BATON (framefunc);
+      gdb_assert (symbaton == NULL);
+      *start = NULL;
+      *length = 0;	/* unused */
+    }
+  else
+    internal_error (__FILE__, __LINE__,
+		    _("Unsupported SYMBOL_COMPUTED_OPS %p for \"%s\""),
+		    SYMBOL_COMPUTED_OPS (framefunc),
+		    SYMBOL_PRINT_NAME (framefunc));
 
   if (*start == NULL)
     error (_("Could not find the frame base for \"%s\"."),
-	   SYMBOL_NATURAL_NAME (framefunc));
+	   SYMBOL_PRINT_NAME (framefunc));
 }
 
 /* Helper function for dwarf2_evaluate_loc_desc.  Computes the CFA for
@@ -215,6 +229,129 @@ dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
   return target_translate_tls_address (debaton->objfile, offset);
 }
 
+static CORE_ADDR
+dwarf_expr_object_address (void *baton)
+{
+  struct dwarf_expr_baton *debaton = baton;
+
+  /* The message is suppressed in DWARF_BLOCK_EXEC.  */
+  if (debaton->object_address == 0)
+    error (_("Cannot resolve DW_OP_push_object_address for a missing object"));
+
+  return debaton->object_address;
+}
+
+/* Address of the variable we are currently referring to.  It is set from
+   DW_TAG_variable's DW_AT_location (not DW_TAG_type's DW_AT_data_location) for
+   DW_OP_push_object_address.  */
+
+static CORE_ADDR object_address;
+
+/* Callers use object_address_set while their callers use the result set so we
+   cannot run the cleanup at the local block of our direct caller.  Still we
+   should reset OBJECT_ADDRESS at least for the next GDB command.  */
+
+static void
+object_address_cleanup (void *prev_save_voidp)
+{
+  CORE_ADDR *prev_save = prev_save_voidp;
+
+  object_address = *prev_save;
+  xfree (prev_save);
+}
+
+/* Set the base address - DW_AT_location - of a variable.  It is being later
+   used to derive other object addresses by DW_OP_push_object_address.
+
+   It would be useful to sanity check ADDRESS - such as for some objects with
+   unset value_raw_address - but some valid addresses may be zero (such as first
+   objects in relocatable .o files).  */
+
+void
+object_address_set (CORE_ADDR address)
+{
+  CORE_ADDR *prev_save;
+
+  prev_save = xmalloc (sizeof *prev_save);
+  *prev_save = object_address;
+  make_cleanup (object_address_cleanup, prev_save);
+
+  object_address = address;
+}
+
+/* Evaluate DWARF expression at DATA ... DATA + SIZE with its result readable
+   by dwarf_expr_fetch (RETVAL, 0).  FRAME parameter can be NULL to call
+   get_selected_frame to find it.  Returned dwarf_expr_context freeing is
+   pushed on the cleanup chain.  */
+
+static struct dwarf_expr_context *
+dwarf_expr_prep_ctx (struct frame_info *frame, gdb_byte *data,
+		     unsigned short size, struct dwarf2_per_cu_data *per_cu)
+{
+  struct dwarf_expr_context *ctx;
+  struct dwarf_expr_baton baton;
+
+  if (!frame)
+    frame = get_selected_frame (NULL);
+
+  baton.frame = frame;
+  baton.objfile = dwarf2_per_cu_objfile (per_cu);
+  baton.object_address = object_address;
+
+  ctx = new_dwarf_expr_context ();
+  make_cleanup_free_dwarf_expr_context (ctx);
+
+  ctx->gdbarch = get_objfile_arch (baton.objfile);
+  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
+  ctx->baton = &baton;
+  ctx->read_reg = dwarf_expr_read_reg;
+  ctx->read_mem = dwarf_expr_read_mem;
+  ctx->get_frame_base = dwarf_expr_frame_base;
+  ctx->get_frame_cfa = dwarf_expr_frame_cfa;
+  ctx->get_tls_address = dwarf_expr_tls_address;
+  ctx->get_object_address = dwarf_expr_object_address;
+
+  dwarf_expr_eval (ctx, data, size);
+
+  /* It was used only during dwarf_expr_eval.  */
+  ctx->baton = NULL;
+
+  return ctx;
+}
+
+/* Evaluate DWARF expression at DLBATON expecting it produces exactly one
+   CORE_ADDR result on the DWARF stack stack.  */
+
+CORE_ADDR
+dwarf_locexpr_baton_eval (struct dwarf2_locexpr_baton *dlbaton)
+{
+  struct dwarf_expr_context *ctx;
+  CORE_ADDR retval;
+  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
+
+  ctx = dwarf_expr_prep_ctx (NULL, dlbaton->data, dlbaton->size,
+			     dlbaton->per_cu);
+  if (ctx->num_pieces > 0)
+    error (_("DW_OP_*piece is unsupported for DW_FORM_block"));
+
+  retval = dwarf_expr_fetch (ctx, 0);
+
+  if (ctx->location == DWARF_VALUE_REGISTER)
+    {
+      /* Inlined dwarf_expr_read_reg as we no longer have the baton. */
+
+      int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (ctx->gdbarch, retval);
+      struct type *type = builtin_type (ctx->gdbarch)->builtin_data_ptr;
+      struct frame_info *frame = get_selected_frame (NULL);
+
+      retval = address_from_register (type, gdb_regnum, frame);
+    }
+
+  do_cleanups (back_to);
+
+  return retval;
+}
+
 struct piece_closure
 {
   /* The number of pieces used to describe this variable.  */
@@ -382,9 +519,8 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
 			  struct dwarf2_per_cu_data *per_cu)
 {
   struct value *retval;
-  struct dwarf_expr_baton baton;
   struct dwarf_expr_context *ctx;
-  struct cleanup *old_chain;
+  struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
 
   if (size == 0)
     {
@@ -394,22 +530,8 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
       return retval;
     }
 
-  baton.frame = frame;
-  baton.objfile = dwarf2_per_cu_objfile (per_cu);
+  ctx = dwarf_expr_prep_ctx (frame, data, size, per_cu);
 
-  ctx = new_dwarf_expr_context ();
-  old_chain = make_cleanup_free_dwarf_expr_context (ctx);
-
-  ctx->gdbarch = get_objfile_arch (baton.objfile);
-  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
-  ctx->baton = &baton;
-  ctx->read_reg = dwarf_expr_read_reg;
-  ctx->read_mem = dwarf_expr_read_mem;
-  ctx->get_frame_base = dwarf_expr_frame_base;
-  ctx->get_frame_cfa = dwarf_expr_frame_cfa;
-  ctx->get_tls_address = dwarf_expr_tls_address;
-
-  dwarf_expr_eval (ctx, data, size);
   if (ctx->num_pieces > 0)
     {
       struct piece_closure *c;
@@ -439,6 +561,11 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
 	    CORE_ADDR address = dwarf_expr_fetch (ctx, 0);
 	    int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
 
+	    /* object_address_set called here is required in ALLOCATE_VALUE's
+	       CHECK_TYPEDEF for the object's possible
+	       DW_OP_push_object_address.  */
+	    object_address_set (address);
+
 	    retval = allocate_value (SYMBOL_TYPE (var));
 	    VALUE_LVAL (retval) = lval_memory;
 	    set_value_lazy (retval, 1);
@@ -815,7 +942,7 @@ static int
 loclist_describe_location (struct symbol *symbol, struct ui_file *stream)
 {
   /* FIXME: Could print the entire list of locations.  */
-  fprintf_filtered (stream, "a variable with multiple locations");
+  fprintf_filtered (stream, _("a variable with multiple locations"));
   return 1;
 }
 
@@ -831,16 +958,56 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
 
   data = find_location_expression (dlbaton, &size, ax->scope);
   if (data == NULL)
-    error (_("Variable \"%s\" is not available."), SYMBOL_NATURAL_NAME (symbol));
+    error (_("Variable \"%s\" is not available."), SYMBOL_PRINT_NAME (symbol));
 
   dwarf2_tracepoint_var_ref (symbol, gdbarch, ax, value, data, size);
 }
 
-/* The set of location functions used with the DWARF-2 expression
-   evaluator and location lists.  */
+/* The set of location functions used with the DWARF-2 location lists.  */
 const struct symbol_computed_ops dwarf2_loclist_funcs = {
   loclist_read_variable,
   loclist_read_needs_frame,
   loclist_describe_location,
   loclist_tracepoint_var_ref
 };
+
+static struct value *
+missing_read_variable (struct symbol *symbol, struct frame_info *frame)
+{
+  struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
+
+  gdb_assert (dlbaton == NULL);
+  error (_("Unable to resolve variable \"%s\""), SYMBOL_PRINT_NAME (symbol));
+}
+
+static int
+missing_read_needs_frame (struct symbol *symbol)
+{
+  return 0;
+}
+
+static int
+missing_describe_location (struct symbol *symbol, struct ui_file *stream)
+{
+  fprintf_filtered (stream, _("a variable we are unable to resolve"));
+  return 1;
+}
+
+static void
+missing_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
+			    struct agent_expr *ax, struct axs_value *value)
+{
+  struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
+
+  gdb_assert (dlbaton == NULL);
+  error (_("Unable to resolve variable \"%s\""), SYMBOL_PRINT_NAME (symbol));
+}
+
+/* The set of location functions used with the DWARF-2 evaluator when we are
+   unable to resolve the symbols.  */
+const struct symbol_computed_ops dwarf2_missing_funcs = {
+  missing_read_variable,
+  missing_read_needs_frame,
+  missing_describe_location,
+  missing_tracepoint_var_ref
+};
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
index 0bfcfca..01018d6 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -71,5 +71,11 @@ struct dwarf2_loclist_baton
 
 extern const struct symbol_computed_ops dwarf2_locexpr_funcs;
 extern const struct symbol_computed_ops dwarf2_loclist_funcs;
+extern const struct symbol_computed_ops dwarf2_missing_funcs;
+
+extern void object_address_set (CORE_ADDR address);
+
+extern CORE_ADDR dwarf_locexpr_baton_eval
+  (struct dwarf2_locexpr_baton *dlbaton);
 
 #endif /* dwarf2loc.h */
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 4cce36b..d394887 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -48,6 +48,12 @@
 #include "gdbcmd.h"
 #include "block.h"
 #include "addrmap.h"
+#include "f-lang.h"
+#include "c-lang.h"
+#include "jv-lang.h"
+#include "typeprint.h"
+#include "vec.h"
+#include "block.h"
 
 #include <fcntl.h>
 #include "gdb_string.h"
@@ -93,7 +99,7 @@ typedef struct pubnames_header
 _PUBNAMES_HEADER;
 #define _ACTUAL_PUBNAMES_HEADER_SIZE 13
 
-/* .debug_pubnames header
+/* .debug_aranges header
    Because of alignment constraints, this structure has padding and cannot
    be mapped directly onto the beginning of the .debug_info section.  */
 typedef struct aranges_header
@@ -150,7 +156,10 @@ struct dwarf2_section_info
   asection *asection;
   gdb_byte *buffer;
   bfd_size_type size;
-  int was_mmapped;
+  /* A function to call to deallocate BUFFER.  If NULL, no
+     deallocation is needed.  A pointer to this structure is passed as
+     the only argument.  */
+  void (*destructor) (struct dwarf2_section_info *);
 };
 
 struct dwarf2_per_objfile
@@ -336,6 +345,19 @@ struct dwarf2_cu
 
   /* Field `ranges_offset' is filled in; flag as the value may be zero.  */
   unsigned int has_ranges_offset : 1;
+
+  /* Fields are valid according to the LANGUAGE field.  */
+  union
+    {
+      /* language_fortran */
+      struct
+        {
+	  /* Module names imported to the block being currently read in.  */
+	  struct fortran_using *use;
+	}
+      fortran;
+    }
+  language_specific;
 };
 
 /* Persistent data held for a compilation unit, even when not
@@ -495,8 +517,7 @@ struct partial_die_info
     unsigned int has_byte_size : 1;
 
     /* The name of this DIE.  Normally the value of DW_AT_name, but
-       sometimes DW_TAG_MIPS_linkage_name or a string computed in some
-       other fashion.  */
+       sometimes a default name for unnamed DIEs.  */
     char *name;
     char *dirname;
 
@@ -689,6 +710,11 @@ struct field_info
     int nfnfields;
   };
 
+/* A vector used during linkage name generation.  */
+typedef struct die_info *die_info_p;
+DEF_VEC_P (die_info_p);
+static VEC(die_info_p) *die_list;
+
 /* One item on the queue of compilation units to read in full symbols
    for.  */
 struct dwarf2_queue_item
@@ -800,7 +826,10 @@ static void scan_partial_symbols (struct partial_die_info *,
 static void add_partial_symbol (struct partial_die_info *,
 				struct dwarf2_cu *);
 
-static int pdi_needs_namespace (enum dwarf_tag tag);
+static gdb_byte *read_comp_unit_head (struct comp_unit_head *, gdb_byte *,
+				      bfd *);
+
+static int die_needs_namespace (struct die_info *, struct dwarf2_cu *);
 
 static void add_partial_namespace (struct partial_die_info *pdi,
 				   CORE_ADDR *lowpc, CORE_ADDR *highpc,
@@ -825,6 +854,10 @@ static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
 
 static void psymtab_to_symtab_1 (struct partial_symtab *);
 
+static void dwarf2_read_section_1 (struct objfile *objfile,
+				   struct obstack *obstack,
+				   struct dwarf2_section_info *info);
+
 static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu);
 
 static void dwarf2_free_abbrev_table (void *);
@@ -945,8 +978,13 @@ static struct type *tag_type_to_type (struct die_info *, struct dwarf2_cu *);
 
 static struct type *read_type_die (struct die_info *, struct dwarf2_cu *);
 
+static void physname_prefix_1 (struct ui_file *, struct die_info *,
+			       struct dwarf2_cu *);
+
 static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
 
+static char *physname_prefix (struct die_info *die, struct dwarf2_cu *);
+
 static char *typename_concat (struct obstack *,
                               const char *prefix, 
                               const char *suffix,
@@ -964,7 +1002,8 @@ static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
 			       struct dwarf2_cu *, struct partial_symtab *);
 
 static int dwarf2_get_pc_bounds (struct die_info *,
-				 CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *);
+				 CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *,
+				 struct partial_symtab *pst);
 
 static void get_scope_pc_bounds (struct die_info *,
 				 CORE_ADDR *, CORE_ADDR *,
@@ -988,17 +1027,25 @@ static void dwarf2_attach_fn_fields_to_type (struct field_info *,
 
 static void process_structure_scope (struct die_info *, struct dwarf2_cu *);
 
-static const char *determine_class_name (struct die_info *die,
-					 struct dwarf2_cu *cu);
-
 static void read_common_block (struct die_info *, struct dwarf2_cu *);
 
 static void read_namespace (struct die_info *die, struct dwarf2_cu *);
 
+static void read_import_statement (struct die_info *die, struct dwarf2_cu *);
+
 static void read_module (struct die_info *die, struct dwarf2_cu *cu);
 
 static void read_import_statement (struct die_info *die, struct dwarf2_cu *);
 
+static struct type *read_module_type (struct die_info *die,
+				      struct dwarf2_cu *cu);
+
+static void read_fortran_imported_module (struct die_info *die,
+					  struct dwarf2_cu *cu);
+
+static void read_fortran_imported_declaration (struct die_info *die,
+					       struct dwarf2_cu *cu);
+
 static const char *namespace_name (struct die_info *die,
 				   int *is_anonymous, struct dwarf2_cu *);
 
@@ -1034,6 +1081,9 @@ static void process_die (struct die_info *, struct dwarf2_cu *);
 
 static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
 
+static char *fortran_module_linkage_name (struct die_info *die,
+					  struct dwarf2_cu *cu);
+
 static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *,
 				       struct obstack *);
 
@@ -1076,7 +1126,7 @@ static int is_ref_attr (struct attribute *);
 
 static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
 
-static int dwarf2_get_attr_constant_value (struct attribute *, int);
+static CORE_ADDR dwarf2_get_attr_constant_value (struct attribute *, CORE_ADDR);
 
 static struct die_info *follow_die_ref_or_sig (struct die_info *,
 					       struct attribute *,
@@ -1148,6 +1198,9 @@ static void age_cached_comp_units (void);
 
 static void free_one_cached_comp_unit (void *);
 
+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 *);
 
@@ -1167,22 +1220,31 @@ static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
 
 static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
 
+static void destroy_section (struct dwarf2_section_info *info);
+
+static struct dwarf2_locexpr_baton *dwarf2_attr_to_locexpr_baton
+  (struct attribute *attr, struct dwarf2_cu *cu);
+
 /* Try to locate the sections we need for DWARF 2 debugging
    information and return true if we have enough to do something.  */
 
 int
 dwarf2_has_info (struct objfile *objfile)
 {
-  struct dwarf2_per_objfile *data;
-
-  /* Initialize per-objfile state.  */
-  data = obstack_alloc (&objfile->objfile_obstack, sizeof (*data));
-  memset (data, 0, sizeof (*data));
-  set_objfile_data (objfile, dwarf2_objfile_data_key, data);
-  dwarf2_per_objfile = data;
+  dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+  if (!dwarf2_per_objfile)
+    {
+      /* Initialize per-objfile state.  */
+      struct dwarf2_per_objfile *data
+	= obstack_alloc (&objfile->objfile_obstack, sizeof (*data));
+      memset (data, 0, sizeof (*data));
+      set_objfile_data (objfile, dwarf2_objfile_data_key, data);
+      dwarf2_per_objfile = data;
 
-  bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL);
-  return (data->info.asection != NULL && data->abbrev.asection != NULL);
+      bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL);
+    }
+  return (dwarf2_per_objfile->info.asection != NULL
+	  && dwarf2_per_objfile->abbrev.asection != NULL);
 }
 
 /* When loading sections, we can either look for ".<name>", or for
@@ -1275,10 +1337,13 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr)
 }
 
 /* Decompress a section that was compressed using zlib.  Store the
-   decompressed buffer, and its size, in OUTBUF and OUTSIZE.  */
+   decompressed buffer, and its size, in OUTBUF and OUTSIZE.  The
+   result is allocated on OBSTACK; if OBSTACK is NULL, xmalloc is
+   used.  */
 
 static void
-zlib_decompress_section (struct objfile *objfile, asection *sectp,
+zlib_decompress_section (struct objfile *objfile, struct obstack *obstack,
+			 asection *sectp,
                          gdb_byte **outbuf, bfd_size_type *outsize)
 {
   bfd *abfd = objfile->obfd;
@@ -1295,6 +1360,7 @@ zlib_decompress_section (struct objfile *objfile, asection *sectp,
   z_stream strm;
   int rc;
   int header_size = 12;
+  struct cleanup *old = NULL;
 
   if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
       || bfd_bread (compressed_buffer, compressed_size, abfd) != compressed_size)
@@ -1324,8 +1390,13 @@ zlib_decompress_section (struct objfile *objfile, asection *sectp,
   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);
+  if (obstack)
+    uncompressed_buffer = obstack_alloc (obstack, uncompressed_size);
+  else
+    {
+      uncompressed_buffer = xmalloc (uncompressed_size);
+      old = make_cleanup (xfree, uncompressed_buffer);
+    }
   rc = inflateInit (&strm);
   while (strm.avail_in > 0)
     {
@@ -1346,26 +1417,176 @@ zlib_decompress_section (struct objfile *objfile, asection *sectp,
     error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"),
            bfd_get_filename (abfd), rc);
 
+  if (old)
+    discard_cleanups (old);
   do_cleanups (cleanup);
   *outbuf = uncompressed_buffer;
   *outsize = uncompressed_size;
 #endif
 }
 
-/* Read the contents of the section SECTP from object file specified by
-   OBJFILE, store info about the section into INFO.
-   If the section is compressed, uncompress it before returning.  */
+/* A cleanup that calls destroy_section.  */
 
 static void
-dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
+destroy_section_cleanup (void *arg)
+{
+  destroy_section (arg);
+}
+
+/* Read the .debug_aranges section and construct an address map.  */
+
+void
+dwarf2_create_quick_addrmap (struct objfile *objfile)
+{
+  char *aranges_buffer, *aranges_ptr;
+  bfd *abfd = objfile->obfd;
+  CORE_ADDR baseaddr;
+  struct cleanup *old;
+  struct obstack temp_obstack;
+  struct addrmap *mutable_map;
+
+  if (!dwarf2_per_objfile->aranges.asection)
+    return;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+  dwarf2_read_section_1 (objfile, NULL, &dwarf2_per_objfile->aranges);
+  aranges_buffer = dwarf2_per_objfile->aranges.buffer;
+  aranges_ptr = aranges_buffer;
+  old = make_cleanup (destroy_section_cleanup, &dwarf2_per_objfile->aranges);
+
+  obstack_init (&temp_obstack);
+  make_cleanup_obstack_free (&temp_obstack);
+  mutable_map = addrmap_create_mutable (&temp_obstack);
+
+  while ((aranges_ptr - aranges_buffer) < dwarf2_per_objfile->aranges.size)
+    {
+      struct comp_unit_head cu_header;
+      unsigned int bytes_read, segment_size, delta;
+      LONGEST info_offset;
+      struct dwarf2_cu cu;
+      char *end_ptr;
+
+      cu_header.initial_length_size = 0;
+      end_ptr = aranges_ptr;
+      aranges_ptr = read_comp_unit_head (&cu_header, aranges_ptr, abfd);
+      end_ptr += cu_header.initial_length_size + cu_header.length;
+
+      /* Sanity check.  */
+      if (end_ptr - aranges_ptr >= dwarf2_per_objfile->aranges.size)
+	{
+	  do_cleanups (old);
+	  complaint (&symfile_complaints,
+		     _("aranges entry runs off end of `.debug_aranges' section, ignored"));
+	  return;
+	}
+      if (cu_header.addr_size == 0)
+	{
+	  do_cleanups (old);
+	  complaint (&symfile_complaints,
+		     _("aranges entry has zero addr_size, ignored"));
+	  return;
+	}
+
+      segment_size = read_1_byte (abfd, aranges_ptr);
+      aranges_ptr += 1;
+
+      /* Align the pointer to twice the pointer size.  I didn't see
+	 this in the spec but it appears to be required.  */
+      delta = (aranges_ptr - aranges_buffer) % (2 * cu_header.addr_size);
+      delta = (2 * cu_header.addr_size - delta) % (2 * cu_header.addr_size);
+      aranges_ptr += delta;
+
+      memset (&cu, 0, sizeof (cu));
+      cu.header.addr_size = cu_header.addr_size;
+
+      while (1)
+	{
+	  CORE_ADDR address, length;
+
+	  address = read_address (abfd, aranges_ptr, &cu, &bytes_read);
+	  aranges_ptr += bytes_read;
+
+	  length = read_address (abfd, aranges_ptr, &cu, &bytes_read);
+	  aranges_ptr += bytes_read;
+
+	  if (address == 0 && length == 0)
+	    break;
+
+	  if (length == 0)
+	    {
+	      do_cleanups (old);
+	      complaint (&symfile_complaints,
+			 _("aranges entry has zero length, ignored"));
+	      return;
+	    }
+
+	  address += baseaddr;
+
+	  addrmap_set_empty (mutable_map, address, address + length - 1,
+			     objfile);
+	}
+
+      /* Some older versions of GCC incorrectly started the arange
+	 with a (0,0) pair.  If we encounter any oddity while reading
+	 the section, just abandon the attempt; falling back to the
+	 slower code is always safe.  */
+      if (aranges_ptr != end_ptr)
+	{
+	  do_cleanups (old);
+	  complaint (&symfile_complaints,
+		     _("aranges entry ends early, ignored"));
+	  return;
+	}
+    }
+
+  objfile->quick_addrmap = addrmap_create_fixed (mutable_map,
+						 &objfile->objfile_obstack);
+  do_cleanups (old);
+}
+
+/* Free a section buffer allocated with xmalloc.  */
+
+static void
+xfree_section_buffer (struct dwarf2_section_info *info)
+{
+  xfree (info->buffer);
+}
+
+/* If section described by INFO was mmapped, munmap it now.  */
+
+static void
+munmap_section_buffer (struct dwarf2_section_info *info)
+{
+#ifdef HAVE_MMAP
+  intptr_t begin = (intptr_t) info->buffer;
+  intptr_t map_begin = begin & ~(pagesize - 1);
+  size_t map_length = info->size + begin - map_begin;
+  gdb_assert (munmap ((void *) map_begin, map_length) == 0);
+#else
+  /* Without HAVE_MMAP, we should never be here to begin with.  */
+  gdb_assert (0);
+#endif
+}
+
+/* Read the contents of the section at OFFSET and of size SIZE from
+   the object file specified by OBJFILE into OBSTACK and store it into
+   INFO.  If OBSTACK is NULL, xmalloc is used instead.  If the section
+   is compressed, uncompress it before returning.  */
+
+static void
+dwarf2_read_section_1 (struct objfile *objfile,
+		       struct obstack *obstack,
+		       struct dwarf2_section_info *info)
 {
   bfd *abfd = objfile->obfd;
   asection *sectp = info->asection;
   gdb_byte *buf, *retbuf;
   unsigned char header[4];
+  struct cleanup *old = NULL;
 
   info->buffer = NULL;
-  info->was_mmapped = 0;
+  info->destructor = 0;
 
   if (info->asection == NULL || info->size == 0)
     return;
@@ -1378,7 +1599,7 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
       /* Upon decompression, update the buffer and its size.  */
       if (strncmp (header, "ZLIB", sizeof (header)) == 0)
         {
-          zlib_decompress_section (objfile, sectp, &info->buffer,
+          zlib_decompress_section (objfile, obstack, sectp, &info->buffer,
 				   &info->size);
           return;
         }
@@ -1401,7 +1622,7 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
 
       if (retbuf != MAP_FAILED)
 	{
-	  info->was_mmapped = 1;
+	  info->destructor = munmap_section_buffer;
 	  info->buffer = retbuf + (sectp->filepos & (pagesize - 1)) ;
 	  return;
 	}
@@ -1409,8 +1630,15 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
 #endif
 
   /* If we get here, we are a normal, not-compressed section.  */
-  info->buffer = buf
-    = obstack_alloc (&objfile->objfile_obstack, info->size);
+  if (obstack)
+    buf = obstack_alloc (obstack, info->size);
+  else
+    {
+      buf = xmalloc (info->size);
+      old = make_cleanup (xfree, buf);
+      info->destructor = xfree_section_buffer;
+    }
+  info->buffer = buf;
 
   /* When debugging .o files, we may need to apply relocations; see
      http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
@@ -1419,6 +1647,8 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
   retbuf = symfile_relocate_debug_section (abfd, sectp, buf);
   if (retbuf != NULL)
     {
+      if (old)
+	discard_cleanups (old);
       info->buffer = retbuf;
       return;
     }
@@ -1427,6 +1657,19 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
       || bfd_bread (buf, info->size, abfd) != info->size)
     error (_("Dwarf Error: Can't read DWARF data from '%s'"),
 	   bfd_get_filename (abfd));
+
+  if (old)
+    discard_cleanups (old);
+}
+
+/* Read the contents of the section SECTP from object file specified by
+   OBJFILE, store info about the section into INFO.
+   If the section is compressed, uncompress it before returning.  */
+
+static void
+dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
+{
+  dwarf2_read_section_1 (objfile, &objfile->objfile_obstack, info);
 }
 
 /* Fill in SECTP, BUFP and SIZEP with section info, given OBJFILE and
@@ -1810,6 +2053,37 @@ lookup_signatured_type (struct objfile *objfile, ULONGEST sig)
   return entry;
 }
 
+/* Find the base address of the compilation unit for range lists and
+   location lists.  It will normally be specified by DW_AT_low_pc.
+   In DWARF-3 draft 4, the base address could be overridden by
+   DW_AT_entry_pc.  It's been removed, but GCC still uses this for
+   compilation units with discontinuous ranges.  */
+
+static void
+dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct attribute *attr;
+
+  cu->base_known = 0;
+  cu->base_address = 0;
+
+  attr = dwarf2_attr (die, DW_AT_entry_pc, cu);
+  if (attr)
+    {
+      cu->base_address = DW_ADDR (attr);
+      cu->base_known = 1;
+    }
+  else
+    {
+      attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+      if (attr)
+	{
+	  cu->base_address = DW_ADDR (attr);
+	  cu->base_known = 1;
+	}
+    }
+}
+
 /* Subroutine of process_type_comp_unit and dwarf2_build_psymtabs_hard
    to combine the common parts.
    Process a compilation unit for a psymtab.
@@ -2359,7 +2633,7 @@ partial_die_parent_scope (struct partial_die_info *pdi,
 	 ignoring them.  */
       complaint (&symfile_complaints,
 		 _("unhandled containing DIE tag %d for DIE at %d"),
-		 parent->tag, pdi->offset);
+		 parent->tag, real_pdi->offset);
       parent->scope = grandparent_scope;
     }
 
@@ -2374,12 +2648,22 @@ partial_die_full_name (struct partial_die_info *pdi,
 		       struct dwarf2_cu *cu)
 {
   char *parent_scope;
+  struct partial_die_info *real_pdi;
 
-  parent_scope = partial_die_parent_scope (pdi, cu);
-  if (parent_scope == NULL)
-    return NULL;
-  else
+  /* We need to look at our parent DIE; if we have a DW_AT_specification,
+     then this means the parent of the specification DIE.
+     partial_die_parent_scope does this loop also, but we do it here
+     since we need to examine real_pdi->parent ourselves.  */
+
+  real_pdi = pdi;
+  while (real_pdi->has_specification)
+    real_pdi = find_partial_die (real_pdi->spec_offset, cu);
+
+  parent_scope = partial_die_parent_scope (real_pdi, cu);
+  if (parent_scope != NULL)
     return typename_concat (NULL, parent_scope, pdi->name, cu);
+
+  return NULL;
 }
 
 static void
@@ -2395,12 +2679,9 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  if (pdi_needs_namespace (pdi->tag))
-    {
-      actual_name = partial_die_full_name (pdi, cu);
-      if (actual_name)
-	built_actual_name = 1;
-    }
+  actual_name = partial_die_full_name (pdi, cu);
+  if (actual_name)
+    built_actual_name = 1;
 
   if (actual_name == NULL)
     actual_name = pdi->name;
@@ -2491,6 +2772,12 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 			   &objfile->global_psymbols,
 			   0, (CORE_ADDR) 0, cu->language, objfile);
       break;
+    case DW_TAG_module:
+      add_psymbol_to_list (actual_name, strlen (actual_name),
+			   MODULE_DOMAIN, LOC_STATIC,
+			   &objfile->global_psymbols,
+			   0, (CORE_ADDR) 0, cu->language, objfile);
+      break;
     case DW_TAG_class_type:
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
@@ -2532,22 +2819,6 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
       break;
     }
 
-  /* Check to see if we should scan the name for possible namespace
-     info.  Only do this if this is C++, if we don't have namespace
-     debugging info in the file, if the psym is of an appropriate type
-     (otherwise we'll have psym == NULL), and if we actually had a
-     mangled name to begin with.  */
-
-  /* FIXME drow/2004-02-22: Why don't we do this for classes, i.e. the
-     cases which do not set PSYM above?  */
-
-  if (cu->language == language_cplus
-      && cu->has_namespace_info == 0
-      && psym != NULL
-      && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
-    cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym),
-					 objfile);
-
   if (built_actual_name)
     xfree (actual_name);
 }
@@ -2557,9 +2828,9 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
    name listed in the die.  */
 
 static int
-pdi_needs_namespace (enum dwarf_tag tag)
+die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
 {
-  switch (tag)
+  switch (die->tag)
     {
     case DW_TAG_namespace:
     case DW_TAG_typedef:
@@ -2569,7 +2840,23 @@ pdi_needs_namespace (enum dwarf_tag tag)
     case DW_TAG_union_type:
     case DW_TAG_enumeration_type:
     case DW_TAG_enumerator:
+    case DW_TAG_subprogram:
+    case DW_TAG_member:
       return 1;
+
+    case DW_TAG_variable:
+      {
+	struct attribute *attr;
+	attr = dwarf2_attr (die, DW_AT_specification, cu);
+	if (attr)
+	  return 1;
+	attr = dwarf2_attr (die, DW_AT_external, cu);
+	if (attr == NULL && die->parent->tag != DW_TAG_namespace)
+	  return 0;
+	return 1;
+      }
+      break;
+
     default:
       return 0;
     }
@@ -2602,12 +2889,12 @@ static void
 add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc,
 		    CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu)
 {
-  /* Now scan partial symbols in that module.
+  /* Add a symbol for the module.  */
 
-     FIXME: Support the separate Fortran module namespaces.  */
+  add_partial_symbol (pdi, cu);
 
-  if (pdi->has_children)
-    scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu);
+  /* Partial symbols in that module are not scanned as they are never globally
+     visible.  They get imported to the specific scopes on the full read.  */
 }
 
 /* Read a partial die corresponding to a subprogram and create a partial
@@ -2698,27 +2985,6 @@ guess_structure_name (struct partial_die_info *struct_pdi,
 
       if (real_pdi->die_parent != NULL)
 	return;
-
-      while (child_pdi != NULL)
-	{
-	  if (child_pdi->tag == DW_TAG_subprogram)
-	    {
-	      char *actual_class_name
-		= language_class_name_from_physname (cu->language_defn,
-						     child_pdi->name);
-	      if (actual_class_name != NULL)
-		{
-		  struct_pdi->name
-		    = obsavestring (actual_class_name,
-				    strlen (actual_class_name),
-				    &cu->comp_unit_obstack);
-		  xfree (actual_class_name);
-		}
-	      break;
-	    }
-
-	  child_pdi = child_pdi->die_sibling;
-	}
     }
 }
 
@@ -3295,6 +3561,14 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_imported_declaration:
     case DW_TAG_imported_module:
       processing_has_namespace_info = 1;
+      if (cu->language == language_fortran)
+	{
+	  if (die->tag == DW_TAG_imported_declaration)
+	    read_fortran_imported_declaration (die, cu);
+	  else
+	    read_fortran_imported_module (die, cu);
+	  break;
+	}
       if (die->child != NULL && (die->tag == DW_TAG_imported_declaration
 				 || cu->language != language_fortran))
 	complaint (&symfile_complaints, _("Tag '%s' has unexpected children"),
@@ -3310,41 +3584,68 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
 /* Return the fully qualified name of DIE, based on its DW_AT_name.
    If scope qualifiers are appropriate they will be added.  The result
    will be allocated on the objfile_obstack, or NULL if the DIE does
-   not have a name.  */
+   not have a name.
+
+   The output string will be canonicalized (if C++/Java). */
 
 static const char *
 dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct attribute *attr;
-  char *prefix, *name;
-  struct ui_file *buf = NULL;
+  char *name;
 
   name = dwarf2_name (die, cu);
-  if (!name)
-    return NULL;
 
   /* These are the only languages we know how to qualify names in.  */
-  if (cu->language != language_cplus
-      && cu->language != language_java)
-    return name;
+  if (name != NULL
+      && (cu->language == language_cplus || cu->language == language_java))
+    {
+      if (die_needs_namespace (die, cu))
+	{
+	  long length;
+	  char *prefix;
+	  struct ui_file *buf;
 
-  /* If no prefix is necessary for this type of DIE, return the
-     unqualified name.  The other three tags listed could be handled
-     in pdi_needs_namespace, but that requires broader changes.  */
-  if (!pdi_needs_namespace (die->tag)
-      && die->tag != DW_TAG_subprogram
-      && die->tag != DW_TAG_variable
-      && die->tag != DW_TAG_member)
-    return name;
+	  buf = mem_fileopen ();
+	  prefix = determine_prefix (die, cu);
+	  if (*prefix != '\0')
+	    {
+	      char *prefixed_name = typename_concat (NULL, prefix, name, cu);
+	      fputs_unfiltered (prefixed_name, buf);
+	      xfree (prefixed_name);
+	    }
+	  else
+	    fputs_unfiltered (name, buf);
 
-  prefix = determine_prefix (die, cu);
-  if (*prefix != '\0')
-    name = typename_concat (&cu->objfile->objfile_obstack, prefix,
-			    name, cu);
+	  name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack,
+				       &length);
+	  ui_file_delete (buf);
+
+	  if (cu->language == language_cplus)
+	    {
+	      char *cname
+		= dwarf2_canonicalize_name (name, cu,
+					    &cu->objfile->objfile_obstack);
+	      if (cname != NULL)
+		name = cname;
+	    }
+	}
+    }
 
   return name;
 }
 
+/* read the given die's decl_line number. Return -1 if in case of an error */
+static const int dwarf2_read_decl_line (struct die_info *die, struct dwarf2_cu *cu){
+  struct attribute *line_attr;
+
+  line_attr = dwarf2_attr (die, DW_AT_decl_line, cu);
+  if (line_attr){
+    return  DW_UNSND (line_attr);
+  }
+
+  return -1;
+}
+
 /* Read the import statement specified by the given die and record it.  */
 
 static void
@@ -3354,9 +3655,15 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *imported_die;
   const char *imported_name;
   const char *imported_name_prefix;
-  const char *import_prefix;
   char *canonical_name;
-
+  const char *import_alias;
+  const char *imported_declaration = "";
+  const char *import_prefix;
+  
+  int line_number = -1;
+  
+  int is_anonymous = 0;
+  
   import_attr = dwarf2_attr (die, DW_AT_import, cu);
   if (import_attr == NULL)
     {
@@ -3404,17 +3711,27 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
       return;
     }
 
-  /* FIXME: dwarf2_name (die); for the local name after import.  */
-
-  /* Figure out where the statement is being imported to.  */
+  /* Figure out the local name after import.  */
+  import_alias = dwarf2_name(die, cu);
+  if(import_alias == NULL){
+    import_alias = "";
+  }
+  
+  /* Determine the line number at which the import was made */
+  line_number = dwarf2_read_decl_line(die, cu);
+  
+  /* Figure out where the statement is being imported to */
   import_prefix = determine_prefix (die, cu);
 
   /* Figure out what the scope of the imported die is and prepend it
      to the name of the imported die.  */
   imported_name_prefix = determine_prefix (imported_die, cu);
-
-  if (strlen (imported_name_prefix) > 0)
-    {
+  
+  if(imported_die->tag != DW_TAG_namespace){
+    imported_declaration = imported_name;
+    canonical_name = (char*)imported_name_prefix;
+  }else{
+    if(strlen (imported_name_prefix) > 0){
       canonical_name = alloca (strlen (imported_name_prefix) + 2 + strlen (imported_name) + 1);
       strcpy (canonical_name, imported_name_prefix);
       strcat (canonical_name, "::");
@@ -3425,8 +3742,14 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
       canonical_name = alloca (strlen (imported_name) + 1);
       strcpy (canonical_name, imported_name);
     }
-
-  using_directives = cp_add_using (import_prefix,canonical_name, using_directives);
+  }
+  
+  using_directives = cp_add_using (import_prefix,
+                                   canonical_name,
+                                   import_alias,
+                                   imported_declaration,
+                                   line_number,
+                                   using_directives);
 }
 
 static void
@@ -3695,6 +4018,14 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
   struct attribute *attr;
 
   attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);
+  
+  /* GCC 4.3 incorrectly uses DW_AT_specification to indicate die inheritence
+     in the case of import statements. The following is to accommodate 
+     that.  */
+  if(!attr){
+    attr = dwarf2_attr (die, DW_AT_specification, cu);
+  }
+  
   if (!attr)
     return;
 
@@ -3793,6 +4124,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   char *name;
   CORE_ADDR baseaddr;
   struct block *block;
+  unsigned die_children = 0;
   int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
 
   if (inlined_func)
@@ -3811,13 +4143,23 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  name = dwarf2_linkage_name (die, cu);
+  name = dwarf2_name (die, cu);
 
   /* Ignore functions with missing or empty names and functions with
      missing or invalid low and high pc attributes.  */
-  if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
+  if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)){
+    /* explore abstract origins if present. They might contain useful information
+     such as import statements. */
+    child_die = die->child;
+    while (child_die && child_die->tag)
+      {
+	child_die = sibling_die (child_die);
+	die_children++;
+      }
+    inherit_abstract_dies(die, cu);
     return;
-
+  }
+  
   lowpc += baseaddr;
   highpc += baseaddr;
 
@@ -3844,14 +4186,19 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   cu->list_in_scope = &local_symbols;
 
-  if (die->child != NULL)
+  switch (cu->language)
     {
-      child_die = die->child;
-      while (child_die && child_die->tag)
-	{
-	  process_die (child_die, cu);
-	  child_die = sibling_die (child_die);
-	}
+    case language_fortran:
+      cu->language_specific.fortran.use = NULL;
+      break;
+    }
+
+  child_die = die->child;
+  while (child_die && child_die->tag)
+    {
+      process_die (child_die, cu);
+      child_die = sibling_die (child_die);
+      die_children++;
     }
 
   inherit_abstract_dies (die, cu);
@@ -3867,6 +4214,13 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 			determine_prefix (die, cu),
 			processing_has_namespace_info);
 
+  switch (cu->language)
+    {
+    case language_fortran:
+      BLOCK_FORTRAN_USE (block) = cu->language_specific.fortran.use;
+      break;
+    }
+
   /* If we have address ranges, record them.  */
   dwarf2_record_block_ranges (die, block, baseaddr, cu);
   
@@ -3903,7 +4257,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
      as multiple lexical blocks?  Handling children in a sane way would
      be nasty.  Might be easier to properly extend generic blocks to 
      describe ranges.  */
-  if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
+  if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL))
     return;
   lowpc += baseaddr;
   highpc += baseaddr;
@@ -3920,7 +4274,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
   new = pop_context ();
 
-  if (local_symbols != NULL)
+  if (local_symbols != NULL || using_directives != NULL)
     {
       struct block *block
         = finish_block (0, &local_symbols, new->old_blocks, new->start_addr,
@@ -4075,7 +4429,8 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
    discontinuous, i.e. derived from DW_AT_ranges information.  */
 static int
 dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
-		      CORE_ADDR *highpc, struct dwarf2_cu *cu)
+		      CORE_ADDR *highpc, struct dwarf2_cu *cu,
+		      struct partial_symtab *pst)
 {
   struct attribute *attr;
   CORE_ADDR low = 0;
@@ -4103,7 +4458,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
 	{
 	  /* Value of the DW_AT_ranges attribute is the offset in the
 	     .debug_ranges section.  */
-	  if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, NULL))
+	  if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, pst))
 	    return 0;
 	  /* Found discontinuous range of addresses.  */
 	  ret = -1;
@@ -4142,7 +4497,7 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die,
   CORE_ADDR low, high;
   struct die_info *child = die->child;
 
-  if (dwarf2_get_pc_bounds (die, &low, &high, cu))
+  if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL))
     {
       *lowpc = min (*lowpc, low);
       *highpc = max (*highpc, high);
@@ -4179,7 +4534,7 @@ get_scope_pc_bounds (struct die_info *die,
   CORE_ADDR best_high = (CORE_ADDR) 0;
   CORE_ADDR current_low, current_high;
 
-  if (dwarf2_get_pc_bounds (die, &current_low, &current_high, cu))
+  if (dwarf2_get_pc_bounds (die, &current_low, &current_high, cu, NULL))
     {
       best_low = current_low;
       best_high = current_high;
@@ -4661,7 +5016,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   /* The name is already allocated along with this objfile, so we don't
      need to duplicate it for the type.  */
   fnp->physname = physname ? physname : "";
-  fnp->type = alloc_type (objfile);
+  fnp->type = alloc_type (objfile, NULL);
   this_type = read_type_die (die, cu);
   if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
     {
@@ -4721,18 +5076,18 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
     {
       /* Support the .debug_loc offsets */
       if (attr_form_is_block (attr))
-        {
-          fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2;
-        }
+	{
+	  fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2;
+	}
       else if (attr_form_is_section_offset (attr))
-        {
+	{
 	  dwarf2_complex_location_expr_complaint ();
-        }
+	}
       else
-        {
+	{
 	  dwarf2_invalid_attrib_class_complaint ("DW_AT_vtable_elem_location",
 						 fieldname);
-        }
+	}
    }
 }
 
@@ -4845,7 +5200,7 @@ quirk_gcc_member_function_pointer (struct die_info *die, struct dwarf2_cu *cu)
     return NULL;
 
   domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
-  type = alloc_type (objfile);
+  type = alloc_type (objfile, NULL);
   smash_to_method_type (type, domain_type, TYPE_TARGET_TYPE (pfn_type),
 			TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
 			TYPE_VARARGS (pfn_type));
@@ -4898,7 +5253,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
       return set_die_type (die, type, cu);
     }
 
-  type = alloc_type (objfile);
+  type = alloc_type (objfile, NULL);
   INIT_CPLUS_SPECIFIC (type);
 
   name = dwarf2_name (die, cu);
@@ -4907,14 +5262,18 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
       if (cu->language == language_cplus
 	  || cu->language == language_java)
 	{
-	  const char *new_prefix = determine_class_name (die, cu);
-	  TYPE_TAG_NAME (type) = (char *) new_prefix;
+	  TYPE_TAG_NAME (type) = (char *) dwarf2_full_name (die, cu);
+	  if (die->tag == DW_TAG_structure_type
+	      || die->tag == DW_TAG_class_type)
+	    TYPE_NAME (type) = TYPE_TAG_NAME (type);
 	}
       else
 	{
 	  /* The name is already allocated along with this objfile, so
 	     we don't need to duplicate it for the type.  */
-	  TYPE_TAG_NAME (type) = name;
+	  TYPE_TAG_NAME (type) = (char *) name;
+	  if (die->tag == DW_TAG_class_type)
+	    TYPE_NAME (type) = TYPE_TAG_NAME (type);
 	}
     }
 
@@ -5124,7 +5483,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
       return set_die_type (die, type, cu);
     }
 
-  type = alloc_type (objfile);
+  type = alloc_type (objfile, NULL);
 
   TYPE_CODE (type) = TYPE_CODE_ENUM;
   name = dwarf2_full_name (die, cu);
@@ -5152,51 +5511,6 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, type, cu);
 }
 
-/* Determine the name of the type represented by DIE, which should be
-   a named C++ or Java compound type.  Return the name in question,
-   allocated on the objfile obstack.  */
-
-static const char *
-determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
-{
-  const char *new_prefix = NULL;
-
-  /* If we don't have namespace debug info, guess the name by trying
-     to demangle the names of members, just like we did in
-     guess_structure_name.  */
-  if (!processing_has_namespace_info)
-    {
-      struct die_info *child;
-
-      for (child = die->child;
-	   child != NULL && child->tag != 0;
-	   child = sibling_die (child))
-	{
-	  if (child->tag == DW_TAG_subprogram)
-	    {
-	      char *phys_prefix
-		= language_class_name_from_physname (cu->language_defn,
-						     dwarf2_linkage_name
-						     (child, cu));
-
-	      if (phys_prefix != NULL)
-		{
-		  new_prefix
-		    = obsavestring (phys_prefix, strlen (phys_prefix),
-				    &cu->objfile->objfile_obstack);
-		  xfree (phys_prefix);
-		  break;
-		}
-	    }
-	}
-    }
-
-  if (new_prefix == NULL)
-    new_prefix = dwarf2_full_name (die, cu);
-
-  return new_prefix;
-}
-
 /* Given a pointer to a die which begins an enumeration, process all
    the dies that define the members of the enumeration, and create the
    symbol for the enumeration type.
@@ -5274,6 +5588,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.  */
@@ -5287,7 +5624,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;
 
@@ -5334,16 +5671,11 @@ 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);
 
   /* Understand Dwarf2 support for vector types (like they occur on
      the PowerPC w/ AltiVec).  Gcc just adds another attribute to the
@@ -5410,12 +5742,14 @@ read_set_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, set_type, cu);
 }
 
-/* First cut: install each common block member as a global variable.  */
+/* Create appropriate locally-scoped variables for all the DW_TAG_common_block
+   entries.  Create also TYPE_CODE_STRUCT listing all such variables to be
+   available for `info common'.  COMMON_BLOCK_DOMAIN is used to sepate the
+   common blocks name namespace from regular variable names.  */
 
 static void
 read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct die_info *child_die;
   struct attribute *attr;
   struct symbol *sym;
   CORE_ADDR base = (CORE_ADDR) 0;
@@ -5425,25 +5759,55 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
     {
       /* Support the .debug_loc offsets */
       if (attr_form_is_block (attr))
-        {
-          base = decode_locdesc (DW_BLOCK (attr), cu);
-        }
+	{
+	  base = decode_locdesc (DW_BLOCK (attr), cu);
+	}
       else if (attr_form_is_section_offset (attr))
-        {
+	{
 	  dwarf2_complex_location_expr_complaint ();
-        }
+	}
       else
-        {
+	{
 	  dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
 						 "common block member");
-        }
+	}
     }
   if (die->child != NULL)
     {
+      struct objfile *objfile = cu->objfile;
+      struct die_info *child_die;
+      struct type *type;
+      struct field *field;
+      char *name;
+      struct symbol *sym;
+
+      type = alloc_type (objfile, NULL);
+      TYPE_CODE (type) = TYPE_CODE_STRUCT;
+      /* Artificial type to be used only by `info common'.  */
+      TYPE_NAME (type) = "<common>";
+
       child_die = die->child;
       while (child_die && child_die->tag)
 	{
+	  TYPE_NFIELDS (type)++;
+	  child_die = sibling_die (child_die);
+	}
+
+      TYPE_FIELDS (type) = obstack_alloc (&objfile->objfile_obstack,
+					  sizeof (*TYPE_FIELDS (type))
+					  * TYPE_NFIELDS (type));
+      memset (TYPE_FIELDS (type), 0, sizeof (*TYPE_FIELDS (type))
+				     * TYPE_NFIELDS (type));
+      
+      field = TYPE_FIELDS (type);
+      child_die = die->child;
+      while (child_die && child_die->tag)
+	{
+	  /* Create the symbol in the DW_TAG_common_block block in the current
+	     symbol scope.  */
 	  sym = new_symbol (child_die, NULL, cu);
+
+	  /* Undocumented in DWARF3, when it can be present?  */
 	  attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu);
 	  if (attr)
 	    {
@@ -5461,8 +5825,25 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
 	      SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset;
 	      add_symbol_to_list (sym, &global_symbols);
 	    }
+
+	  if (SYMBOL_CLASS (sym) == LOC_STATIC)
+	    SET_FIELD_PHYSADDR (*field, SYMBOL_VALUE_ADDRESS (sym));
+	  else
+	    SET_FIELD_PHYSNAME (*field, SYMBOL_LINKAGE_NAME (sym));
+	  FIELD_TYPE (*field) = SYMBOL_TYPE (sym);
+	  FIELD_NAME (*field) = SYMBOL_NATURAL_NAME (sym);
+	  field++;
 	  child_die = sibling_die (child_die);
 	}
+
+      /* TYPE_LENGTH (type) is left 0 - it is only a virtual structure even
+	 with no consecutive address space.  */
+
+      sym = new_symbol (die, type, cu);
+      /* SYMBOL_VALUE_ADDRESS never gets used as all its fields are static.  */
+      SYMBOL_VALUE_ADDRESS (sym) = base;
+
+      set_die_type (die, type, cu);
     }
 }
 
@@ -5530,7 +5911,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
       if (is_anonymous)
 	{
 	  const char *previous_prefix = determine_prefix (die, cu);
-	  cp_add_using_directive (previous_prefix, TYPE_NAME (type));
+	  cp_add_using_directive (previous_prefix, TYPE_NAME (type), "", "", dwarf2_read_decl_line(die, cu));
 	}
     }
 
@@ -5546,20 +5927,155 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
     }
 }
 
-/* Read a Fortran module.  */
+/* Read a Fortran module as global symbol which can be later looked up by
+   f_lookup_symbol_nonlocal.  */
 
 static void
 read_module (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct die_info *child_die = die->child;
+  struct type *type;
+
+  type = read_module_type (die, cu);
+
+  if (type)
+    new_symbol (die, type, cu);
+}
+
+/* Read a Fortran module as type.
+
+   Modules present only as declarations - being used only for DW_AT_import of
+   DW_TAG_imported_module - are ignored here.  They are read in only in form of
+   the module name by read_fortran_imported_module.  */
+
+static struct type *
+read_module_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct objfile *objfile = cu->objfile;
+  struct die_info *child_die;
+  struct type *type;
+  char *module_name;
+  struct context_stack *new;
+  struct pending *save_file_symbols;
+  struct pending *save_global_symbols;
+  struct pending **save_list_in_scope;
+
+  if (die_is_declaration (die, cu))
+    return NULL;
+
+  module_name = dwarf2_name (die, cu);
+  if (!module_name)
+    complaint (&symfile_complaints, _("DW_TAG_module has no name, offset 0x%x"),
+               die->offset);
+  type = init_type (TYPE_CODE_MODULE, 0, 0, module_name, objfile);
+
+  /* Create a context for reading the module variables.  */
 
-  /* FIXME: Support the separate Fortran module namespaces.  */
+  new = push_context (0, 0);
 
+  save_file_symbols = file_symbols;
+  file_symbols = NULL;
+  save_global_symbols = global_symbols;
+  global_symbols = NULL;
+  save_list_in_scope = cu->list_in_scope;
+
+  /* Process the child DIEs.  */
+
+  child_die = die->child;
   while (child_die && child_die->tag)
     {
+      /* Any DW_TAG_subprogram will reset LIST_IN_SCOPE to LOCAL_SYMBOLS.  */
+      cu->list_in_scope = &global_symbols;
+
       process_die (child_die, cu);
       child_die = sibling_die (child_die);
     }
+
+  /* Finish this module and restore the context.  */
+
+  TYPE_MODULE_BLOCK (type) = finish_block (NULL, &global_symbols,
+                                           new->old_blocks, 0, 0, objfile);
+
+  if (file_symbols)
+    complaint (&symfile_complaints, _("DW_TAG_module contains static symbols"));
+  if (local_symbols)
+    complaint (&symfile_complaints, _("DW_TAG_module contains local symbols"));
+  if (param_symbols)
+    complaint (&symfile_complaints, _("DW_TAG_module contains function "
+				      "parameters"));
+
+  file_symbols = save_file_symbols;
+  global_symbols = save_global_symbols;
+  cu->list_in_scope = save_list_in_scope;
+
+  pop_context ();
+
+  set_die_type (die, type, cu);
+
+  return type;
+}
+
+/* Import a Fortran module.  Only store the module name for its later lookup by
+   f_lookup_symbol_nonlocal.  */
+
+static void
+read_fortran_imported_module (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct objfile *objfile = cu->objfile;
+  struct attribute *attr;
+  struct die_info *module_die;
+  char *module_name;
+  struct fortran_using *use;
+
+  attr = dwarf2_attr (die, DW_AT_import, cu);
+  if (attr == NULL)
+    return;
+
+  module_die = follow_die_ref (die, attr, &cu);
+  module_name = dwarf2_name (module_die, cu);
+  if (module_name == NULL)
+    {
+      complaint (&symfile_complaints,
+		 _("Imported DIE at offset 0x%x has no name"), die->offset);
+      return;
+    }
+
+  /* Fortran does not allow any duplicity between local and any of the imported
+     symbols.  Therefore the order of the USE statements is not portant.
+     gfortran prints:
+     Error: Name 'X' at (1) is an ambiguous reference to 'X' from module 'Y'  */
+
+  use = obstack_alloc (&objfile->objfile_obstack, sizeof (*use)
+						  + strlen (module_name));
+  strcpy (use->module_name, module_name);
+  gdb_assert (cu->language == language_fortran);
+  use->next = cu->language_specific.fortran.use;
+  cu->language_specific.fortran.use = use;
+}
+
+/* Import a single Fortran declaration and possibly rename it.  */
+
+static void
+read_fortran_imported_declaration (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct attribute *attr;
+  struct die_info *imported_die;
+  struct symbol *sym;
+  char *rename = dwarf2_name (die, cu);
+
+  attr = dwarf2_attr (die, DW_AT_import, cu);
+  if (attr == NULL)
+    {
+      complaint (&symfile_complaints,
+		 _("Fortran DW_TAG_imported_declaration is missing "
+		   "DW_AT_import at offset 0x%x"), die->offset);
+      return;
+    }
+  imported_die = follow_die_ref (die, attr, &cu);
+
+  sym = new_symbol (imported_die, NULL, cu);
+
+  if (sym && rename)
+    (sym)->ginfo.language_specific.cplus_specific.demangled_name = rename;
 }
 
 /* Return the name of the namespace represented by DIE.  Set
@@ -5724,29 +6240,113 @@ 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;
-  unsigned int length;
+  int length;
+
+  index_type = objfile_type (objfile)->builtin_int;
+  /* RANGE_TYPE is allocated from OBJFILE, not as a permanent type.  */
+  range_type = alloc_type (objfile, NULL);
+  /* LOW_BOUND and HIGH_BOUND are set for real below.  */
+  range_type = create_range_type (range_type, index_type, 0, -1);
+
+  /* C/C++ should probably have the low bound 0 but C/C++ does not use
+     DW_TAG_string_type.  */
+  TYPE_LOW_BOUND (range_type) = 1;
 
   attr = dwarf2_attr (die, DW_AT_string_length, cu);
-  if (attr)
-    {
-      length = DW_UNSND (attr);
+  if (attr && attr_form_is_block (attr))
+    {
+      /* Security check for a size overflow.  */
+      if (DW_BLOCK (attr)->size + 2 < DW_BLOCK (attr)->size)
+	TYPE_HIGH_BOUND (range_type) = 1;
+      /* Extend the DWARF block by a new DW_OP_deref/DW_OP_deref_size
+	 instruction as DW_AT_string_length specifies the length location, not
+	 its value.  */
+      else
+	{
+	  struct dwarf2_locexpr_baton *length_baton = NULL;
+	  struct dwarf_block *blk = DW_BLOCK (attr);
+
+	  /* Turn any single DW_OP_reg* into DW_OP_breg*(0) but clearing
+	     DW_OP_deref* in such case.  */
+
+	  if (blk->size == 1 && blk->data[0] >= DW_OP_reg0
+	      && blk->data[0] <= DW_OP_reg31)
+	    length_baton = dwarf2_attr_to_locexpr_baton (attr, cu);
+	  else if (blk->size > 1 && blk->data[0] == DW_OP_regx)
+	    {
+	      ULONGEST ulongest;
+	      gdb_byte *end;
+
+	      end = 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);
+	    }
+
+	  if (length_baton == NULL)
+	    {
+	      struct attribute *size_attr;
+
+	      length_baton = obstack_alloc (&cu->comp_unit_obstack,
+					    sizeof (*length_baton));
+	      length_baton->per_cu = cu->per_cu;
+	      length_baton->size = DW_BLOCK (attr)->size + 2;
+	      length_baton->data = obstack_alloc (&cu->comp_unit_obstack,
+						  length_baton->size);
+	      memcpy (length_baton->data, DW_BLOCK (attr)->data,
+		      DW_BLOCK (attr)->size);
+
+	      /* DW_AT_BYTE_SIZE existing together with DW_AT_STRING_LENGTH
+		 specifies the size of an integer to fetch.  */
+	      size_attr = dwarf2_attr (die, DW_AT_byte_size, cu);
+	      if (size_attr)
+		{
+		  length_baton->data[DW_BLOCK (attr)->size] = DW_OP_deref_size;
+		  length_baton->data[DW_BLOCK (attr)->size + 1] =
+							   DW_UNSND (size_attr);
+		  if (length_baton->data[DW_BLOCK (attr)->size + 1]
+		      != DW_UNSND (size_attr))
+		    complaint (&symfile_complaints,
+			       _("DW_AT_string_length's DW_AT_byte_size "
+				 "integer exceeds the byte size storage"));
+		}
+	      else
+		{
+		  length_baton->data[DW_BLOCK (attr)->size] = DW_OP_deref;
+		  length_baton->data[DW_BLOCK (attr)->size + 1] = DW_OP_nop;
+		}
+	    }
+
+	  TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 1);
+	  TYPE_FIELD_DWARF_BLOCK (range_type, 1) = length_baton;
+	  TYPE_DYNAMIC (range_type) = 1;
+	}
     }
   else
     {
-      /* check for the DW_AT_byte_size attribute */
+      if (attr && attr_form_is_constant (attr))
+	{
+	  /* We currently do not support a constant address where the location
+	     should be read from - attr_form_is_block is expected instead.  See
+	     DWARF for the DW_AT_STRING_LENGTH vs. DW_AT_BYTE_SIZE difference.
+	     */
+	  /* PASSTHRU */
+	}
+
       attr = dwarf2_attr (die, DW_AT_byte_size, cu);
-      if (attr)
-        {
-          length = DW_UNSND (attr);
-        }
+      if (attr && attr_form_is_block (attr))
+	{
+	  TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 1);
+	  TYPE_FIELD_DWARF_BLOCK (range_type, 1) =
+					dwarf2_attr_to_locexpr_baton (attr, cu);
+	  TYPE_DYNAMIC (range_type) = 1;
+	}
+      else if (attr && attr_form_is_constant (attr))
+	TYPE_HIGH_BOUND (range_type) = dwarf2_get_attr_constant_value (attr, 0);
       else
-        {
-          length = 1;
-        }
+	TYPE_HIGH_BOUND (range_type) = 1;
     }
 
-  index_type = objfile_type (objfile)->builtin_int;
-  range_type = create_range_type (NULL, index_type, 1, length);
   char_type = language_string_char_type (cu->language_defn, gdbarch);
   type = create_string_type (NULL, char_type, range_type);
 
@@ -5841,7 +6441,6 @@ static struct type *
 read_typedef (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
-  struct attribute *attr;
   const char *name = NULL;
   struct type *this_type;
 
@@ -5949,8 +6548,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   struct type *base_type;
   struct type *range_type;
   struct attribute *attr;
-  int low = 0;
-  int high = -1;
+  int low;
   char *name;
   
   base_type = die_type (die, cu);
@@ -5963,42 +6561,89 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 		     0, NULL, cu->objfile);
     }
 
-  if (cu->language == language_fortran)
-    { 
-      /* FORTRAN implies a lower bound of 1, if not given.  */
-      low = 1;
-    }
+  /* LOW_BOUND and HIGH_BOUND are set for real below.  */
+  range_type = create_range_type (NULL, base_type, 0, -1);
 
-  /* 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);
+  if (attr && attr_form_is_block (attr))
+    {
+      TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 0);
+      TYPE_FIELD_DWARF_BLOCK (range_type, 0) = dwarf2_attr_to_locexpr_baton
+								     (attr, cu);
+      TYPE_DYNAMIC (range_type) = 1;
+      /* For setting a default if DW_AT_UPPER_BOUND would be missing.  */
+      low = 0;
+    }
+  else
+    {
+      if (attr && attr_form_is_constant (attr))
+	low = dwarf2_get_attr_constant_value (attr, 0);
+      else
+	{
+	  if (cu->language == language_fortran)
+	    {
+	      /* FORTRAN implies a lower bound of 1, if not given.  */
+	      low = 1;
+	    }
+	  else
+	    {
+	      /* According to DWARF we should assume the value 0 only for
+		 LANGUAGE_C and LANGUAGE_CPLUS.  */
+	      low = 0;
+	    }
+	}
+      TYPE_LOW_BOUND (range_type) = low;
+      if (low >= 0)
+	TYPE_UNSIGNED (range_type) = 1;
+    }
 
   attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
-  if (attr)
-    {       
-      if (attr->form == DW_FORM_block1)
-        {
-          /* GCC encodes arrays with unspecified or dynamic length
-             with a DW_FORM_block1 attribute.
-             FIXME: GDB does not yet know how to handle dynamic
-             arrays properly, treat them as arrays with unspecified
-             length for now.
-
-             FIXME: jimb/2003-09-22: GDB does not really know
-             how to handle arrays of unspecified length
-             either; we just represent them as zero-length
-             arrays.  Choose an appropriate upper bound given
-             the lower bound we've computed above.  */
-          high = low - 1;
-        }
+  if (!attr || (!attr_form_is_block (attr) && !attr_form_is_constant (attr)))
+    {
+      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_block (attr))
+    {
+      TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 1);
+      TYPE_FIELD_DWARF_BLOCK (range_type, 1) = dwarf2_attr_to_locexpr_baton
+								     (attr, cu);
+      TYPE_DYNAMIC (range_type) = 1;
+    }
+  else
+    {
+      if (attr && attr_form_is_constant (attr))
+	TYPE_HIGH_BOUND (range_type) = dwarf2_get_attr_constant_value (attr, 0);
       else
-        high = dwarf2_get_attr_constant_value (attr, 1);
+	{
+	  TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED (range_type) = 1;
+	  TYPE_HIGH_BOUND (range_type) = low - 1;
+	}
     }
 
-  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))
+    {
+      TYPE_RANGE_BOUND_SET_DWARF_BLOCK (range_type, 2);
+      TYPE_FIELD_DWARF_BLOCK (range_type, 2) = dwarf2_attr_to_locexpr_baton
+								     (attr, cu);
+      TYPE_DYNAMIC (range_type) = 1;
+    }
+  else if (attr && attr_form_is_constant (attr))
+    {
+      TYPE_BYTE_STRIDE (range_type) = dwarf2_get_attr_constant_value (attr, 0);
+      if (TYPE_BYTE_STRIDE (range_type) == 0)
+	complaint (&symfile_complaints,
+		   _("Found DW_AT_byte_stride with unsupported value 0"));
+    }
 
   name = dwarf2_name (die, cu);
   if (name)
@@ -6469,6 +7114,7 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
 	  && abbrev->tag != DW_TAG_lexical_block
 	  && abbrev->tag != DW_TAG_variable
 	  && abbrev->tag != DW_TAG_namespace
+	  && abbrev->tag != DW_TAG_module
 	  && abbrev->tag != DW_TAG_member)
 	{
 	  /* Otherwise we skip to the next sibling, if any.  */
@@ -6689,9 +7335,6 @@ read_partial_die (struct partial_die_info *part_die,
 	  if (part_die->dirname == NULL)
 	    part_die->dirname = DW_STRING (&attr);
 	  break;
-	case DW_AT_MIPS_linkage_name:
-	  part_die->name = DW_STRING (&attr);
-	  break;
 	case DW_AT_low_pc:
 	  has_low_pc_attr = 1;
 	  part_die->lowpc = DW_ADDR (&attr);
@@ -6923,7 +7566,8 @@ fixup_partial_die (struct partial_die_info *part_die,
   /* If we found a reference attribute and the DIE has no name, try
      to find a name in the referred to DIE.  */
 
-  if (part_die->name == NULL && part_die->has_specification)
+  if (part_die->has_specification
+      && (part_die->name == NULL || !part_die->is_external))
     {
       struct partial_die_info *spec_die;
 
@@ -8265,10 +8909,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
-     or memory numbers show me otherwise.  */
+     or memory numbers show me otherwise.
+     
+     SYMBOL_CLASS may get overriden by dwarf2_symbol_mark_computed.  */
 
-  dwarf2_symbol_mark_computed (attr, sym, cu);
   SYMBOL_CLASS (sym) = LOC_COMPUTED;
+  dwarf2_symbol_mark_computed (attr, sym, cu);
 }
 
 /* Given a pointer to a DWARF information entry, figure out if we need
@@ -8290,21 +8936,30 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  if (die->tag != DW_TAG_namespace)
-    name = dwarf2_linkage_name (die, cu);
-  else
-    name = TYPE_NAME (type);
-
+  name = dwarf2_name (die, cu);
   if (name)
     {
+      const char *linkagename;
+
       sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
 					     sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
+      /* Some methods are called w/o checking SYMBOL_COMPUTED_OPS validity.  */
+      SYMBOL_COMPUTED_OPS (sym) = &dwarf2_missing_funcs;
 
-      /* Cache this symbol's name and the name's demangled form (if any).  */
       SYMBOL_LANGUAGE (sym) = cu->language;
-      SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
+
+      /* Cache this symbol's name and the name's demangled form (if any).  */
+
+      linkagename = dwarf2_linkage_name (die, cu);
+      SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), objfile);
+      if (cu->language == language_fortran)
+	{
+	  (sym)->ginfo.language_specific.cplus_specific.demangled_name =
+	    SYMBOL_LINKAGE_NAME (sym);
+	  SYMBOL_LINKAGE_NAME (sym) = fortran_module_linkage_name (die, cu);
+	}
 
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
@@ -8402,9 +9057,28 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 	  if (attr)
 	    {
 	      var_decode_location (attr, sym, cu);
+
 	      attr2 = dwarf2_attr (die, DW_AT_external, cu);
+
+	      /* Fortran explicitely imports any global symbols to the local
+		 scope by DW_TAG_common_block.  */
+	      if (cu->language == language_fortran && die->parent
+		  && die->parent->tag == DW_TAG_common_block)
+		attr2 = NULL;
+
 	      if (attr2 && (DW_UNSND (attr2) != 0))
-		add_symbol_to_list (sym, &global_symbols);
+		{
+		  /* Workaround gfortran PR debug/40040 - it uses
+		     DW_AT_location for variables in -fPIC libraries which may
+		     get overriden by other libraries/executable and get
+		     a different address.  Resolve it by .dynsym instead.  */
+
+		  if (cu->language == language_fortran && die->parent
+		      && die->parent->tag == DW_TAG_module)
+		    SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
+
+		  add_symbol_to_list (sym, &global_symbols);
+		}
 	      else
 		add_symbol_to_list (sym, cu->list_in_scope);
 	    }
@@ -8534,7 +9208,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 	  add_symbol_to_list (sym, cu->list_in_scope);
 	  break;
 	case DW_TAG_enumerator:
-	  SYMBOL_LINKAGE_NAME (sym) = (char *) dwarf2_full_name (die, cu);
+	  SYMBOL_LINKAGE_NAME (sym) = (char *) dwarf2_name (die, cu);
 	  attr = dwarf2_attr (die, DW_AT_const_value, cu);
 	  if (attr)
 	    {
@@ -8558,6 +9232,16 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
 	  add_symbol_to_list (sym, &global_symbols);
 	  break;
+	case DW_TAG_common_block:
+	  SYMBOL_CLASS (sym) = LOC_STATIC;
+	  SYMBOL_DOMAIN (sym) = COMMON_BLOCK_DOMAIN;
+	  add_symbol_to_list (sym, cu->list_in_scope);
+	  break;
+	case DW_TAG_module:
+	  SYMBOL_CLASS (sym) = LOC_STATIC;
+	  SYMBOL_DOMAIN (sym) = MODULE_DOMAIN;
+	  add_symbol_to_list (sym, &global_symbols);
+	  break;
 	default:
 	  /* Not a tag we recognize.  Hopefully we aren't processing
 	     trash data, but since we must specifically ignore things
@@ -8571,8 +9255,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
       /* For the benefit of old versions of GCC, check for anonymous
 	 namespaces based on the demangled name.  */
       if (!processing_has_namespace_info
-	  && cu->language == language_cplus
-	  && dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu) != NULL)
+	  && cu->language == language_cplus)
 	cp_scan_for_anonymous_namespaces (sym);
     }
   return (sym);
@@ -8823,12 +9506,18 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_namespace:
       this_type = read_namespace_type (die, cu);
       break;
+    case DW_TAG_module:
+      this_type = read_module_type (die, cu);
+      break;
     default:
       complaint (&symfile_complaints, _("unexpected tag in read_type_die: '%s'"),
 		 dwarf_tag_name (die->tag));
       break;
     }
 
+  if (this_type)
+    finalize_type (this_type);
+
   return this_type;
 }
 
@@ -8910,10 +9599,97 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
 	     So it does not need a prefix.  */
 	  return "";
       default:
-	return determine_prefix (parent, cu);
+        return determine_prefix (parent, cu);
       }
 }
 
+/* Determines the prefix for a symbol's physname. Unlike determine_prefix,
+   this method does not simply look at the DIE's immediate parent.
+   It will compute the symbol's physname by scanning through all parent
+   DIEs until it gets to the compilation unit's DIE. */
+
+static char *
+physname_prefix (struct die_info *die, struct dwarf2_cu *cu)
+{
+  long length;
+  struct ui_file *buf;
+  struct die_info *d, *spec_die;
+  struct dwarf2_cu *spec_cu;
+
+  /* Construct a stack containing all of the DIE's parents.  Caution
+     must be observed for dealing with DW_AT_specification. */
+  spec_cu = cu;
+  spec_die = die_specification (die, &spec_cu);
+  if (spec_die != NULL)
+    d = spec_die->parent;
+  else
+    d = die->parent;
+  while (d != NULL && d->tag != DW_TAG_compile_unit)
+    {
+      struct attribute *attr;
+
+      spec_die = die_specification (d, &spec_cu);
+      if (spec_die != NULL)
+	d = spec_die;
+
+      VEC_quick_push (die_info_p, die_list, d);
+      d = d->parent;
+    }
+
+  /* Now pop all the elements, printing their names as we go */
+  buf = mem_fileopen ();
+  while (!VEC_empty (die_info_p, die_list))
+    {
+      d = VEC_pop (die_info_p, die_list);
+      physname_prefix_1 (buf, d, cu);
+
+      if (!VEC_empty (die_info_p, die_list))
+	{
+	  if (cu->language == language_cplus)
+	    fputs_unfiltered ("::", buf);
+	  else
+	    fputs_unfiltered (".", buf);
+	}
+    }
+
+  return ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, &length);
+}
+
+static void
+physname_prefix_1 (struct ui_file *buf, struct die_info *die,
+		   struct dwarf2_cu *cu)
+{
+  const char *name = NULL;
+  gdb_assert (buf != NULL);
+
+  if (die != NULL)
+    {
+      switch (die->tag)
+	{
+	case DW_TAG_namespace:
+	  name = dwarf2_name (die, cu);
+	  if (name == NULL)
+	    name = "(anonymous namespace)";
+	  break;
+
+	case DW_TAG_class_type:
+	case DW_TAG_structure_type:
+	case DW_TAG_union_type:
+	case DW_TAG_enumeration_type:
+	case DW_TAG_interface_type:
+	case DW_TAG_subprogram:
+	  name = dwarf2_name (die, cu);
+	  break;
+
+	default:
+	  break;
+	}
+    }
+
+  if (name != NULL)
+    fputs_unfiltered (name, buf);
+}
+
 /* Return a newly-allocated string formed by concatenating PREFIX and
    SUFFIX with appropriate separator.  If PREFIX or SUFFIX is NULL or empty, then
    simply copy the SUFFIX or PREFIX, respectively.  If OBS is non-null,
@@ -8969,11 +9745,105 @@ static char *
 dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
+  char *name;
+
+  name = dwarf2_name (die, cu);
+
+  /* These are the only languages we know how to qualify names in.  */
+  if (cu->language != language_cplus
+      && cu->language != language_java)
+    return name;
+
+  if (die_needs_namespace (die, cu))
+    {
+      long length;
+      char *prefix;
+      struct ui_file *buf;
+
+      prefix = physname_prefix (die, cu);
+      buf = mem_fileopen ();
+      if (*prefix != '\0')
+	{
+	  char *prefixed_name = typename_concat (NULL, prefix, name, cu);
+	  fputs_unfiltered (prefixed_name, buf);
+	  xfree (prefixed_name);
+	}
+      else
+	fputs_unfiltered (name ? name : "", buf);
+
+      /* For Java and C++ methods, append formal parameter type
+	 information. */
+      if ((cu->language == language_cplus || cu->language == language_java)
+	  && die->tag == DW_TAG_subprogram)
+	{
+	  struct type *type = read_type_die (die, cu);
+
+	  c_type_print_args (type, buf, 0, cu->language);
+
+	  if (cu->language == language_java)
+	    {
+	      /* For java, we must append the return type to method names. */
+	      if (die->tag == DW_TAG_subprogram)
+		java_print_type (TYPE_TARGET_TYPE (type), "", buf, 0, 0);
+	    }
+	  else if (cu->language == language_cplus)
+	    {
+	      /* c_type_print_args adds argument types, but it does
+		 not add any necessary "const". */
+	      if (TYPE_NFIELDS (type) > 0 && TYPE_FIELD_ARTIFICIAL (type, 0)
+		  && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0))))
+		fputs_unfiltered (" const", buf);
+	    }
+	}
 
-  attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
-  if (attr && DW_STRING (attr))
-    return DW_STRING (attr);
-  return dwarf2_name (die, cu);
+      name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack,
+				   &length);
+      ui_file_delete (buf);
+
+      if (cu->language == language_cplus)
+	{
+	  char *cname
+	    = dwarf2_canonicalize_name (name, cu,
+					&cu->objfile->objfile_obstack);
+	  if (cname != NULL)
+	    name = cname;
+	}
+    }
+
+  return name;
+}
+
+/* Return the fully qualified .symtab name for symbols contained in Fortran
+   modules.  Return DWARF2_NAME otherwise.  */
+
+static char *
+fortran_module_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
+{
+  char *name;
+
+  gdb_assert (cu->language == language_fortran);
+
+  name = dwarf2_name (die, cu);
+
+  if (name && die->parent && die->parent->tag == DW_TAG_module)
+    {
+      char *module_name = dwarf2_name (die->parent, cu);
+
+      if (module_name)
+	{
+	  char *retval;
+
+	  /* `__modulename_MOD_variablename0'.  */
+	  retval = obstack_alloc (&cu->objfile->objfile_obstack,
+				  2 + strlen (module_name) + 5 + strlen (name)
+				  + 1);
+	  sprintf (retval, "__%s_MOD_%s", module_name, name);
+
+	  return retval;
+	}
+    }
+
+  return name;
 }
 
 /* Get name of a die, return NULL if not found.  */
@@ -10200,11 +11070,11 @@ dwarf2_get_ref_die_offset (struct attribute *attr)
   return 0;
 }
 
-/* Return the constant value held by the given attribute.  Return -1
+/* Return the constant value held by the given attribute.  Return DEFAULT_VALUE
    if the value held by the attribute is not constant.  */
 
-static int
-dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
+static CORE_ADDR
+dwarf2_get_attr_constant_value (struct attribute *attr, CORE_ADDR default_value)
 {
   if (attr->form == DW_FORM_sdata)
     return DW_SND (attr);
@@ -11009,8 +11879,6 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 {
   gdb_byte *mac_ptr, *mac_end;
   struct macro_source_file *current_file = 0;
-  enum dwarf_macinfo_record_type macinfo_type;
-  int at_commandline;
 
   if (dwarf2_per_objfile->macinfo.buffer == NULL)
     {
@@ -11018,29 +11886,19 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
       return;
     }
 
-  /* First pass: Find the name of the base filename.
-     This filename is needed in order to process all macros whose definition
-     (or undefinition) comes from the command line.  These macros are defined
-     before the first DW_MACINFO_start_file entry, and yet still need to be
-     associated to the base file.
-
-     To determine the base file name, we scan the macro definitions until we
-     reach the first DW_MACINFO_start_file entry.  We then initialize
-     CURRENT_FILE accordingly so that any macro definition found before the
-     first DW_MACINFO_start_file can still be associated to the base file.  */
-
   mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
   mac_end = dwarf2_per_objfile->macinfo.buffer
     + dwarf2_per_objfile->macinfo.size;
 
-  do
+  for (;;)
     {
+      enum dwarf_macinfo_record_type macinfo_type;
+
       /* Do we at least have room for a macinfo type byte?  */
       if (mac_ptr >= mac_end)
         {
-	  /* Complaint is printed during the second pass as GDB will probably
-	     stop the first pass earlier upon finding DW_MACINFO_start_file.  */
-	  break;
+	  dwarf2_macros_too_long_complaint ();
+          return;
         }
 
       macinfo_type = read_1_byte (abfd, mac_ptr);
@@ -11051,92 +11909,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
           /* A zero macinfo type indicates the end of the macro
              information.  */
         case 0:
-	  break;
-
-	case DW_MACINFO_define:
-	case DW_MACINFO_undef:
-	  /* Only skip the data by MAC_PTR.  */
-	  {
-	    unsigned int bytes_read;
-
-	    read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-	    mac_ptr += bytes_read;
-	    read_string (abfd, mac_ptr, &bytes_read);
-	    mac_ptr += bytes_read;
-	  }
-	  break;
-
-	case DW_MACINFO_start_file:
-	  {
-	    unsigned int bytes_read;
-	    int line, file;
-
-	    line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-	    mac_ptr += bytes_read;
-	    file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-	    mac_ptr += bytes_read;
-
-	    current_file = macro_start_file (file, line, current_file, comp_dir,
-					     lh, cu->objfile);
-	  }
-	  break;
-
-	case DW_MACINFO_end_file:
-	  /* No data to skip by MAC_PTR.  */
-	  break;
-
-	case DW_MACINFO_vendor_ext:
-	  /* Only skip the data by MAC_PTR.  */
-	  {
-	    unsigned int bytes_read;
-
-	    read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-	    mac_ptr += bytes_read;
-	    read_string (abfd, mac_ptr, &bytes_read);
-	    mac_ptr += bytes_read;
-	  }
-	  break;
-
-	default:
-	  break;
-	}
-    } while (macinfo_type != 0 && current_file == NULL);
-
-  /* Second pass: Process all entries.
-
-     Use the AT_COMMAND_LINE flag to determine whether we are still processing
-     command-line macro definitions/undefinitions.  This flag is unset when we
-     reach the first DW_MACINFO_start_file entry.  */
-
-  mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
-
-  /* Determines if GDB is still before first DW_MACINFO_start_file.  If true
-     GDB is still reading the definitions from command line.  First
-     DW_MACINFO_start_file will need to be ignored as it was already executed
-     to create CURRENT_FILE for the main source holding also the command line
-     definitions.  On first met DW_MACINFO_start_file this flag is reset to
-     normally execute all the remaining DW_MACINFO_start_file macinfos.  */
-
-  at_commandline = 1;
-
-  do
-    {
-      /* Do we at least have room for a macinfo type byte?  */
-      if (mac_ptr >= mac_end)
-	{
-	  dwarf2_macros_too_long_complaint ();
-	  break;
-	}
-
-      macinfo_type = read_1_byte (abfd, mac_ptr);
-      mac_ptr++;
-
-      switch (macinfo_type)
-	{
-	  /* A zero macinfo type indicates the end of the macro
-	     information.  */
-	case 0:
-	  break;
+          return;
 
         case DW_MACINFO_define:
         case DW_MACINFO_undef:
@@ -11151,31 +11924,19 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
             mac_ptr += bytes_read;
 
             if (! current_file)
-	      {
-		/* DWARF violation as no main source is present.  */
-		complaint (&symfile_complaints,
-			   _("debug info with no main source gives macro %s "
-			     "on line %d: %s"),
-			   macinfo_type ==
-			   DW_MACINFO_define ? _("definition") : macinfo_type ==
-			   DW_MACINFO_undef ? _("undefinition") :
-			   "something-or-other", line, body);
-		break;
-	      }
-	    if ((line == 0 && !at_commandline) || (line != 0 && at_commandline))
 	      complaint (&symfile_complaints,
-			 _("debug info gives %s macro %s with %s line %d: %s"),
-			 at_commandline ? _("command-line") : _("in-file"),
+			 _("debug info gives macro %s outside of any file: %s"),
 			 macinfo_type ==
-			 DW_MACINFO_define ? _("definition") : macinfo_type ==
-			 DW_MACINFO_undef ? _("undefinition") :
-			 "something-or-other",
-			 line == 0 ? _("zero") : _("non-zero"), line, body);
-
-	    if (macinfo_type == DW_MACINFO_define)
-	      parse_macro_definition (current_file, line, body);
-	    else if (macinfo_type == DW_MACINFO_undef)
-	      macro_undef (current_file, line, body);
+			 DW_MACINFO_define ? "definition" : macinfo_type ==
+			 DW_MACINFO_undef ? "undefinition" :
+			 "something-or-other", body);
+            else
+              {
+                if (macinfo_type == DW_MACINFO_define)
+                  parse_macro_definition (current_file, line, body);
+                else if (macinfo_type == DW_MACINFO_undef)
+                  macro_undef (current_file, line, body);
+              }
           }
           break;
 
@@ -11189,22 +11950,9 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
             file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
             mac_ptr += bytes_read;
 
-	    if ((line == 0 && !at_commandline) || (line != 0 && at_commandline))
-	      complaint (&symfile_complaints,
-			 _("debug info gives source %d included "
-			   "from %s at %s line %d"),
-			 file, at_commandline ? _("command-line") : _("file"),
-			 line == 0 ? _("zero") : _("non-zero"), line);
-
-	    if (at_commandline)
-	      {
-		/* This DW_MACINFO_start_file was executed in the pass one.  */
-		at_commandline = 0;
-	      }
-	    else
-	      current_file = macro_start_file (file, line,
-					       current_file, comp_dir,
-					       lh, cu->objfile);
+            current_file = macro_start_file (file, line,
+                                             current_file, comp_dir,
+                                             lh, cu->objfile);
           }
           break;
 
@@ -11258,7 +12006,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
           }
           break;
         }
-    } while (macinfo_type != 0);
+    }
 }
 
 /* Check if the attribute's form is a DW_FORM_block*
@@ -11318,6 +12066,34 @@ attr_form_is_constant (struct attribute *attr)
     }
 }
 
+/* Convert DW_BLOCK into struct dwarf2_locexpr_baton.  ATTR must be a DW_BLOCK
+   attribute type.  */
+
+static struct dwarf2_locexpr_baton *
+dwarf2_attr_to_locexpr_baton (struct attribute *attr, struct dwarf2_cu *cu)
+{
+  struct dwarf2_locexpr_baton *baton;
+
+  gdb_assert (attr_form_is_block (attr));
+
+  baton = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (*baton));
+  baton->per_cu = cu->per_cu;
+  gdb_assert (baton->per_cu);
+
+  /* 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
+     that buffer, but when we do clean up properly this may
+     need to change.  */
+  baton->size = DW_BLOCK (attr)->size;
+  baton->data = DW_BLOCK (attr)->data;
+  gdb_assert (baton->size == 0 || baton->data != NULL);
+
+  return baton;
+}
+
+/* SYM may get its SYMBOL_CLASS overriden on invalid ATTR content.  */
+
 static void
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
 			     struct dwarf2_cu *cu)
@@ -11347,35 +12123,25 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
       SYMBOL_COMPUTED_OPS (sym) = &dwarf2_loclist_funcs;
       SYMBOL_LOCATION_BATON (sym) = baton;
     }
+  else if (attr_form_is_block (attr))
+    {
+      SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
+      SYMBOL_LOCATION_BATON (sym) = dwarf2_attr_to_locexpr_baton (attr, cu);
+    }
   else
     {
-      struct dwarf2_locexpr_baton *baton;
+      dwarf2_invalid_attrib_class_complaint ("location description",
+					     SYMBOL_NATURAL_NAME (sym));
 
-      baton = obstack_alloc (&cu->objfile->objfile_obstack,
-			     sizeof (struct dwarf2_locexpr_baton));
-      baton->per_cu = cu->per_cu;
-      gdb_assert (baton->per_cu);
+      /* Some methods are called w/o checking SYMBOL_COMPUTED_OPS validity.  */
 
-      if (attr_form_is_block (attr))
-	{
-	  /* 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
-	     that buffer, but when we do clean up properly this may
-	     need to change.  */
-	  baton->size = DW_BLOCK (attr)->size;
-	  baton->data = DW_BLOCK (attr)->data;
-	}
-      else
-	{
-	  dwarf2_invalid_attrib_class_complaint ("location description",
-						 SYMBOL_NATURAL_NAME (sym));
-	  baton->size = 0;
-	  baton->data = NULL;
-	}
-      
-      SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
-      SYMBOL_LOCATION_BATON (sym) = baton;
+      SYMBOL_COMPUTED_OPS (sym) = &dwarf2_missing_funcs;
+      SYMBOL_LOCATION_BATON (sym) = NULL;
+
+      /* For functions a missing DW_AT_frame_base does not optimize out the
+	 whole function definition, only its frame base resolving.  */
+      if (attr->name == DW_AT_location)
+	SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
     }
 }
 
@@ -11663,6 +12429,31 @@ offset_and_type_eq (const void *item_lhs, const void *item_rhs)
   return ofs_lhs->offset == ofs_rhs->offset;
 }
 
+/* Fill in generic attributes applicable for type DIEs.  */
+
+static void
+fetch_die_type_attrs (struct die_info *die, struct type *type,
+		      struct dwarf2_cu *cu)
+{
+  struct attribute *attr;
+
+  attr = dwarf2_attr (die, DW_AT_data_location, cu);
+  if (attr_form_is_block (attr))
+    TYPE_DATA_LOCATION_DWARF_BLOCK (type) = dwarf2_attr_to_locexpr_baton (attr,
+									  cu);
+  gdb_assert (!TYPE_DATA_LOCATION_IS_ADDR (type));
+
+  attr = dwarf2_attr (die, DW_AT_allocated, cu);
+  if (attr_form_is_block (attr))
+    TYPE_ALLOCATED (type) = dwarf2_attr_to_locexpr_baton (attr, cu);
+  gdb_assert (!TYPE_NOT_ALLOCATED (type));
+
+  attr = dwarf2_attr (die, DW_AT_associated, cu);
+  if (attr_form_is_block (attr))
+    TYPE_ASSOCIATED (type) = dwarf2_attr_to_locexpr_baton (attr, cu);
+  gdb_assert (!TYPE_NOT_ASSOCIATED (type));
+}
+
 /* Set the type associated with DIE to TYPE.  Save it in CU's hash
    table if necessary.  For convenience, return TYPE.  */
 
@@ -11671,6 +12462,8 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 {
   struct dwarf2_offset_and_type **slot, ofs;
 
+  fetch_die_type_attrs (die, type, cu);
+
   if (cu->type_hash == NULL)
     {
       gdb_assert (cu->per_cu != NULL);
@@ -11813,23 +12606,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.  */
+/* A helper function to destroy a debug section.  */
 
 static void
-munmap_section_buffer (struct dwarf2_section_info *info)
+destroy_section (struct dwarf2_section_info *info)
 {
-  if (info->was_mmapped)
-    {
-#ifdef HAVE_MMAP
-      intptr_t begin = (intptr_t) info->buffer;
-      intptr_t map_begin = begin & ~(pagesize - 1);
-      size_t map_length = info->size + begin - map_begin;
-      gdb_assert (munmap ((void *) map_begin, map_length) == 0);
-#else
-      /* Without HAVE_MMAP, we should never be here to begin with.  */
-      gdb_assert (0);
-#endif
-    }
+  if (info->destructor)
+    (*info->destructor) (info);
 }
 
 /* munmap debug sections for OBJFILE, if necessary.  */
@@ -11838,15 +12621,15 @@ static void
 dwarf2_per_objfile_free (struct objfile *objfile, void *d)
 {
   struct dwarf2_per_objfile *data = d;
-  munmap_section_buffer (&data->info);
-  munmap_section_buffer (&data->abbrev);
-  munmap_section_buffer (&data->line);
-  munmap_section_buffer (&data->str);
-  munmap_section_buffer (&data->macinfo);
-  munmap_section_buffer (&data->ranges);
-  munmap_section_buffer (&data->loc);
-  munmap_section_buffer (&data->frame);
-  munmap_section_buffer (&data->eh_frame);
+  destroy_section (&data->info);
+  destroy_section (&data->abbrev);
+  destroy_section (&data->line);
+  destroy_section (&data->str);
+  destroy_section (&data->macinfo);
+  destroy_section (&data->ranges);
+  destroy_section (&data->loc);
+  destroy_section (&data->frame);
+  destroy_section (&data->eh_frame);
 }
 
 void _initialize_dwarf2_read (void);
@@ -11854,6 +12637,7 @@ void _initialize_dwarf2_read (void);
 void
 _initialize_dwarf2_read (void)
 {
+  die_list = VEC_alloc (die_info_p, 32);
   dwarf2_objfile_data_key
     = register_objfile_data_with_cleanup (NULL, dwarf2_per_objfile_free);
 
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 6e79d4a..198bae3 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -728,10 +728,18 @@ elf_symfile_read (struct objfile *objfile, int mainline)
 				str_sect->filepos,
 				bfd_section_size (abfd, str_sect));
     }
+
+  if (dwarf2_has_info (objfile))
+    dwarf2_create_quick_addrmap (objfile);
+}
+
+static void
+read_psyms (struct objfile *objfile)
+{
   if (dwarf2_has_info (objfile))
     {
       /* DWARF 2 sections */
-      dwarf2_build_psymtabs (objfile, mainline);
+      dwarf2_build_psymtabs (objfile, 0);
     }
 
   /* FIXME: kettenis/20030504: This still needs to be integrated with
@@ -881,6 +889,7 @@ static struct sym_fns elf_sym_fns =
   elf_new_init,			/* sym_new_init: init anything gbl to entire symtab */
   elf_symfile_init,		/* sym_init: read initial info, setup for sym_read() */
   elf_symfile_read,		/* sym_read: read a symbol file into symtab */
+  read_psyms,			/* sym_read_psymbols */
   elf_symfile_finish,		/* sym_finish: finished with file, cleanup */
   default_symfile_offsets,	/* sym_offsets:  Translate ext. to int. relocation */
   elf_symfile_segments,		/* sym_segments: Get segment information from
diff --git a/gdb/eval.c b/gdb/eval.c
index 7e41d39..37ffe23 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -39,8 +39,12 @@
 #include "exceptions.h"
 #include "regcache.h"
 #include "user-regs.h"
+#include "python/python.h"
 #include "valprint.h"
+#include "gdb_obstack.h"
+#include "objfiles.h"
 #include "python/python.h"
+#include "dwarf2loc.h"
 
 #include "gdb_assert.h"
 
@@ -651,6 +655,36 @@ ptrmath_type_p (struct type *type)
     }
 }
 
+/* Constructs a fake method with the given parameter types. */
+static void
+free_param_types (void *arg)
+{
+  struct type *type = (struct type *) arg;
+  xfree (TYPE_FIELDS (type));
+  xfree (TYPE_MAIN_TYPE (type));
+  xfree (type);
+}
+
+static struct type *
+make_params (int num_types, struct type **param_types)
+{
+  struct type *type = XZALLOC (struct type);
+  TYPE_MAIN_TYPE (type) = XZALLOC (struct main_type);
+  TYPE_LENGTH (type) = 1;
+  TYPE_CODE (type) = TYPE_CODE_METHOD;
+  TYPE_VPTR_FIELDNO (type) = -1;
+  TYPE_CHAIN (type) = type;
+  TYPE_NFIELDS (type) = num_types;
+  TYPE_FIELDS (type) = (struct field *)
+    TYPE_ZALLOC (type, sizeof (struct field) * num_types);
+
+  while (num_types-- > 0)
+    TYPE_FIELD_TYPE (type, num_types) = param_types[num_types];
+
+  make_cleanup (free_param_types, type);
+  return type;
+}
+
 struct value *
 evaluate_subexp_standard (struct type *expect_type,
 			  struct expression *exp, int *pos,
@@ -671,6 +705,7 @@ evaluate_subexp_standard (struct type *expect_type,
   long mem_offset;
   struct type **arg_types;
   int save_pos1;
+  struct cleanup *old_chain;
 
   pc = (*pos)++;
   op = exp->elts[pc].opcode;
@@ -684,7 +719,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	goto nosideret;
       arg1 = value_aggregate_elt (exp->elts[pc + 1].type,
 				  &exp->elts[pc + 3].string,
-				  0, noside);
+				  expect_type, 0, noside);
       if (arg1 == NULL)
 	error (_("There is no field named %s"), &exp->elts[pc + 3].string);
       return arg1;
@@ -1293,7 +1328,6 @@ evaluate_subexp_standard (struct type *expect_type,
       argvec = (struct value **) alloca (sizeof (struct value *) * (nargs + 3));
       if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
 	{
-	  nargs++;
 	  /* First, evaluate the structure into arg2 */
 	  pc2 = (*pos)++;
 
@@ -1317,21 +1351,40 @@ evaluate_subexp_standard (struct type *expect_type,
 
 	  arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
 
-	  if (TYPE_CODE (check_typedef (value_type (arg1)))
-	      != TYPE_CODE_METHODPTR)
-	    error (_("Non-pointer-to-member value used in pointer-to-member "
-		     "construct"));
-
-	  if (noside == EVAL_AVOID_SIDE_EFFECTS)
+	  type = check_typedef (value_type (arg1));
+	  switch (TYPE_CODE (type))
 	    {
-	      struct type *method_type = check_typedef (value_type (arg1));
-	      arg1 = value_zero (method_type, not_lval);
+	    case TYPE_CODE_METHODPTR:
+	      if (noside == EVAL_AVOID_SIDE_EFFECTS)
+		arg1 = value_zero (TYPE_TARGET_TYPE (type), not_lval);
+	      else
+		arg1 = cplus_method_ptr_to_value (&arg2, arg1);
+
+	      /* Now, say which argument to start evaluating from */
+	      nargs++;
+	      tem = 2;
+	      argvec[1] = arg2;
+	      break;
+
+	    case TYPE_CODE_MEMBERPTR:
+	      /* Now, convert these values to an address.  */
+	      arg2 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)),
+				 arg2);
+
+	      mem_offset = value_as_long (arg1);
+
+	      arg1 = value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
+					 value_as_long (arg2) + mem_offset);
+	      arg1 = value_ind (arg1);
+	      tem = 1;
+	      break;
+
+	    default:
+	      error (_("Non-pointer-to-member value used in pointer-to-member "
+		       "construct"));
 	    }
-	  else
-	    arg1 = cplus_method_ptr_to_value (&arg2, arg1);
 
-	  /* Now, say which argument to start evaluating from */
-	  tem = 2;
+	  argvec[0] = arg1;
 	}
       else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
 	{
@@ -1457,8 +1510,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	}
       else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
 	{
-	  argvec[1] = arg2;
-	  argvec[0] = arg1;
+	  /* Pointer to member.  argvec is already set up.  */
 	}
       else if (op == OP_VAR_VALUE)
 	{
@@ -1542,7 +1594,10 @@ evaluate_subexp_standard (struct type *expect_type,
 
       /* First determine the type code we are dealing with.  */
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      old_chain = make_cleanup (null_cleanup, 0);
+      object_address_set (value_raw_address (arg1));
       type = check_typedef (value_type (arg1));
+      do_cleanups (old_chain);
       code = TYPE_CODE (type);
 
       if (code == TYPE_CODE_PTR)
@@ -1709,6 +1764,37 @@ evaluate_subexp_standard (struct type *expect_type,
 	  error (_("non-pointer-to-member value used in pointer-to-member construct"));
 	}
 
+    case TYPE_INSTANCE:
+      nargs = longest_to_int (exp->elts[pc + 1].longconst);
+      arg_types = (struct type **) alloca (nargs * sizeof (struct type *));
+      for (ix = 0; ix < nargs; ++ix)
+	arg_types[ix] = exp->elts[pc + 1 + ix + 1].type;
+
+      expect_type = make_params (nargs, arg_types);
+      *(pos) += 3 + nargs;
+      return evaluate_subexp_standard (expect_type, exp, pos, noside);
+
+    case TYPE_INSTANCE_LOOKUP:
+      {
+	int i;
+	struct symbol *sym;
+	struct type **arg_types;
+	(*pos) += 3;
+	printf ("TYPE_INSTANCE_LOOKUP\n");
+	arg_types = (struct type **) alloca (TYPE_NFIELDS (expect_type)
+					     * sizeof (struct type *));
+	for (i = 0; i < TYPE_NFIELDS (expect_type); ++i)
+	  arg_types[i] = TYPE_FIELD_TYPE (expect_type, i);
+	(void) find_overload_match (arg_types, TYPE_NFIELDS (expect_type),
+				    NULL /* no need for name */,
+				    0 /* not method */,
+				    0 /* strict match */,
+				    NULL, exp->elts[pc + 1].symbol, NULL,
+				    &sym, NULL);
+	i = 0;
+      }
+      break;
+
     case BINOP_CONCAT:
       arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
       arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
@@ -1980,13 +2066,19 @@ evaluate_subexp_standard (struct type *expect_type,
       {
 	int subscript_array[MAX_FORTRAN_DIMS];
 	int array_size_array[MAX_FORTRAN_DIMS];
+	int byte_stride_array[MAX_FORTRAN_DIMS];
 	int ndimensions = 1, i;
 	struct type *tmp_type;
 	int offset_item;	/* The array offset where the item lives */
+	CORE_ADDR offset_byte;	/* byte_stride based offset  */
+	unsigned element_size;
 
 	if (nargs > MAX_FORTRAN_DIMS)
 	  error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS);
 
+	old_chain = make_cleanup (null_cleanup, 0);
+	object_address_set (value_raw_address (arg1));
+
 	tmp_type = check_typedef (value_type (arg1));
 	ndimensions = calc_f77_array_dims (type);
 
@@ -2016,6 +2108,9 @@ evaluate_subexp_standard (struct type *expect_type,
 	    upper = f77_get_upperbound (tmp_type);
 	    lower = f77_get_lowerbound (tmp_type);
 
+	    byte_stride_array[nargs - i - 1] =
+					TYPE_ARRAY_BYTE_STRIDE_VALUE (tmp_type);
+
 	    array_size_array[nargs - i - 1] = upper - lower + 1;
 
 	    /* Zero-normalize subscripts so that offsetting will work. */
@@ -2034,13 +2129,25 @@ evaluate_subexp_standard (struct type *expect_type,
 	      tmp_type = check_typedef (TYPE_TARGET_TYPE (tmp_type));
 	  }
 
+	/* Kept for the f77_get_upperbound / f77_get_lowerbound calls above.  */
+	do_cleanups (old_chain);
+
 	/* Now let us calculate the offset for this item */
 
-	offset_item = subscript_array[ndimensions - 1];
+	offset_item = 0;
+	offset_byte = 0;
+
+	for (i = ndimensions - 1; i >= 0; --i)
+	  {
+	    offset_item *= array_size_array[i];
+	    if (byte_stride_array[i] == 0)
+	      offset_item += subscript_array[i];
+	    else
+	      offset_byte += subscript_array[i] * byte_stride_array[i];
+	  }
 
-	for (i = ndimensions - 1; i > 0; --i)
-	  offset_item =
-	    array_size_array[i - 1] * offset_item + subscript_array[i - 1];
+	element_size = TYPE_LENGTH (TYPE_TARGET_TYPE (tmp_type));
+	offset_byte += offset_item * element_size;
 
 	/* Let us now play a dirty trick: we will take arg1 
 	   which is a value node pointing to the topmost level
@@ -2050,7 +2157,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	   returns the correct type value */
 
 	deprecated_set_value_type (arg1, tmp_type);
-	return value_subscripted_rvalue (arg1, offset_item, 0);
+	return value_subscripted_rvalue (arg1, offset_byte);
       }
 
     case BINOP_LOGICAL_AND:
@@ -2591,7 +2698,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
       (*pos) += 5 + BYTES_TO_EXP_ELEM (tem + 1);
       x = value_aggregate_elt (exp->elts[pc + 1].type,
 			       &exp->elts[pc + 3].string,
-			       1, noside);
+			       NULL, 1, noside);
       if (x == NULL)
 	error (_("There is no field named %s"), &exp->elts[pc + 3].string);
       return x;
@@ -2636,7 +2743,7 @@ evaluate_subexp_with_coercion (struct expression *exp,
 {
   enum exp_opcode op;
   int pc;
-  struct value *val;
+  struct value *val = NULL;
   struct symbol *var;
   struct type *type;
 
@@ -2647,12 +2754,17 @@ evaluate_subexp_with_coercion (struct expression *exp,
     {
     case OP_VAR_VALUE:
       var = exp->elts[pc + 2].symbol;
+      /* address_of_variable will call object_address_set for check_typedef.
+	 Call it only if required as it can error-out on VAR in register.  */
+      if (TYPE_DYNAMIC (SYMBOL_TYPE (var)))
+	val = address_of_variable (var, exp->elts[pc + 1].block);
       type = check_typedef (SYMBOL_TYPE (var));
       if (TYPE_CODE (type) == TYPE_CODE_ARRAY
 	  && CAST_IS_CONVERSION)
 	{
 	  (*pos) += 4;
-	  val = address_of_variable (var, exp->elts[pc + 1].block);
+	  if (!val)
+	    val = address_of_variable (var, exp->elts[pc + 1].block);
 	  return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
 			     val);
 	}
@@ -2704,9 +2816,13 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
 
     case OP_VAR_VALUE:
       (*pos) += 4;
-      type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol));
-      return
-	value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
+      /* We do not need to call read_var_value but the object evaluation may
+	 need to have executed object_address_set which needs valid
+	 SYMBOL_VALUE_ADDRESS of the symbol.  Still VALUE returned by
+	 read_var_value we left as lazy.  */
+      type = value_type (read_var_value (exp->elts[pc + 2].symbol,
+					deprecated_safe_get_selected_frame ()));
+      return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 
     default:
       val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
diff --git a/gdb/expression.h b/gdb/expression.h
index effe1f0..3e083ca 100644
--- a/gdb/expression.h
+++ b/gdb/expression.h
@@ -88,6 +88,16 @@ enum exp_opcode
        when X is a pointer instead of an aggregate.  */
     STRUCTOP_MPTR,
 
+    /* TYPE_INSTANCE is used when the user specifies a specific
+       type instantiation for overloaded methods/functions. The format
+       is: TYPE_INSTANCE num_types type0 ... typeN num_types TYPE_INSTANCE*/
+    TYPE_INSTANCE,
+
+    /* TYPE_INSTANCE_LOOKUP is used when the user specifies a specific
+       type instantiation of a function (not a method). In this case,
+       we must toss the results of the parser and manually do the lookup. */
+    TYPE_INSTANCE_LOOKUP,
+
     /* end of C++.  */
 
     /* For Modula-2 integer division DIV */
@@ -438,4 +448,5 @@ extern char *op_string (enum exp_opcode);
 extern void dump_raw_expression (struct expression *, struct ui_file *, char *);
 extern void dump_prefix_expression (struct expression *, struct ui_file *);
 
+
 #endif /* !defined (EXPRESSION_H) */
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index c04c8f4..ddcd460 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -196,6 +196,7 @@ static int parse_number (char *, int, int, YYSTYPE *);
 /* Special type cases, put in to allow the parser to distinguish different
    legal basetypes.  */
 %token INT_KEYWORD INT_S2_KEYWORD LOGICAL_S1_KEYWORD LOGICAL_S2_KEYWORD 
+%token LOGICAL_S8_KEYWORD 
 %token LOGICAL_KEYWORD REAL_KEYWORD REAL_S8_KEYWORD REAL_S16_KEYWORD 
 %token COMPLEX_S8_KEYWORD COMPLEX_S16_KEYWORD COMPLEX_S32_KEYWORD 
 %token BOOL_AND BOOL_OR BOOL_NOT   
@@ -606,6 +607,8 @@ typebase  /* Implements (approximately): (type-qualifier)* type-specifier */
 			{ $$ = parse_f_type->builtin_integer_s2; }
 	|	CHARACTER 
 			{ $$ = parse_f_type->builtin_character; }
+	|	LOGICAL_S8_KEYWORD
+			{ $$ = parse_f_type->builtin_logical_s8;}
 	|	LOGICAL_KEYWORD 
 			{ $$ = parse_f_type->builtin_logical; }
 	|	LOGICAL_S2_KEYWORD
@@ -858,6 +861,7 @@ static const struct token f77_keywords[] =
   { "integer_2", INT_S2_KEYWORD, BINOP_END },
   { "logical_1", LOGICAL_S1_KEYWORD, BINOP_END },
   { "logical_2", LOGICAL_S2_KEYWORD, BINOP_END },
+  { "logical_8", LOGICAL_S8_KEYWORD, BINOP_END },
   { "complex_8", COMPLEX_S8_KEYWORD, BINOP_END },
   { "integer", INT_KEYWORD, BINOP_END },
   { "logical", LOGICAL_KEYWORD, BINOP_END },
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 19c1316..4cc2a40 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -31,6 +31,8 @@
 #include "f-lang.h"
 #include "valprint.h"
 #include "value.h"
+#include "block.h"
+#include "gdb_assert.h"
 
 
 /* Following is dubious stuff that had been in the xcoff reader. */
@@ -55,20 +57,6 @@ typedef struct saved_bf_symnum SAVED_BF, *SAVED_BF_PTR;
 /* Local functions */
 
 extern void _initialize_f_language (void);
-#if 0
-static void clear_function_list (void);
-static long get_bf_for_fcn (long);
-static void clear_bf_list (void);
-static void patch_all_commons_by_name (char *, CORE_ADDR, int);
-static SAVED_F77_COMMON_PTR find_first_common_named (char *);
-static void add_common_entry (struct symbol *);
-static void add_common_block (char *, CORE_ADDR, int, char *);
-static SAVED_FUNCTION *allocate_saved_function_node (void);
-static SAVED_BF_PTR allocate_saved_bf_node (void);
-static COMMON_ENTRY_PTR allocate_common_entry_node (void);
-static SAVED_F77_COMMON_PTR allocate_saved_f77_common_node (void);
-static void patch_common_entries (SAVED_F77_COMMON_PTR, CORE_ADDR, int);
-#endif
 
 static void f_printchar (int c, struct type *type, struct ui_file * stream);
 static void f_emit_char (int c, struct type *type,
@@ -259,6 +247,7 @@ enum f_primitive_types {
   f_primitive_type_logical,
   f_primitive_type_logical_s1,
   f_primitive_type_logical_s2,
+  f_primitive_type_logical_s8,
   f_primitive_type_integer,
   f_primitive_type_integer_s2,
   f_primitive_type_real,
@@ -289,6 +278,8 @@ f_language_arch_info (struct gdbarch *gdbarch,
     = builtin->builtin_logical_s1;
   lai->primitive_type_vector [f_primitive_type_logical_s2]
     = builtin->builtin_logical_s2;
+  lai->primitive_type_vector [f_primitive_type_logical_s8]
+    = builtin->builtin_logical_s8;
   lai->primitive_type_vector [f_primitive_type_real]
     = builtin->builtin_real;
   lai->primitive_type_vector [f_primitive_type_real_s8]
@@ -306,6 +297,46 @@ f_language_arch_info (struct gdbarch *gdbarch,
   lai->bool_type_default = builtin->builtin_logical_s2;
 }
 
+/* Find if NAME is not contained in any of the Fortran modules imported by the
+   Fortran USE statement.
+
+   As Fortran has no nested blocks such lookup can be processed from
+   lookup_symbol_nonlocal - when no local blocks could satisfy the lookup.  */
+
+static struct symbol *
+f_lookup_symbol_nonlocal (const char *name,
+			  const struct block *block,
+			  const domain_enum domain)
+{
+  struct fortran_using *use;
+
+  if (!block)
+    return NULL;
+
+  for (use = BLOCK_FORTRAN_USE (block); use; use = use->next)
+    {
+      struct symbol *sym;
+      struct type *type;
+      struct symbol *retval;
+
+      sym = lookup_symbol_global (use->module_name, block, MODULE_DOMAIN);
+
+      /* Module name lookup should not fail with correct debug info.  */
+      if (sym == NULL)
+	continue;
+
+      type = SYMBOL_TYPE (sym);
+      gdb_assert (TYPE_CODE (type) == TYPE_CODE_MODULE);
+      gdb_assert (TYPE_MODULE_BLOCK (type) != NULL);
+
+      retval = lookup_block_symbol (TYPE_MODULE_BLOCK (type), name, domain);
+      if (retval)
+	return retval;
+    }
+
+  return NULL;
+}
+
 /* This is declared in c-lang.h but it is silly to import that file for what
    is already just a hack. */
 extern int c_value_print (struct value *, struct ui_file *,
@@ -333,7 +364,7 @@ const struct language_defn f_language_defn =
   c_value_print,		/* FIXME */
   NULL,				/* Language specific skip_trampoline */
   NULL,                    	/* name_of_this */
-  basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
+  f_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,				/* Language specific symbol demangler */
   NULL,				/* Language specific class_name_from_physname */
@@ -372,6 +403,10 @@ build_fortran_types (struct gdbarch *gdbarch)
     = arch_boolean_type (gdbarch, gdbarch_short_bit (gdbarch), 1,
 			 "logical*2");
 
+  builtin_f_type->builtin_logical_s8
+    = arch_boolean_type (gdbarch, gdbarch_long_long_bit (gdbarch), 1,
+			 "logical*8");
+
   builtin_f_type->builtin_integer
     = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0,
 			 "integer");
@@ -418,395 +453,3 @@ _initialize_f_language (void)
 
   add_language (&f_language_defn);
 }
-
-#if 0
-static SAVED_BF_PTR
-allocate_saved_bf_node (void)
-{
-  SAVED_BF_PTR new;
-
-  new = (SAVED_BF_PTR) xmalloc (sizeof (SAVED_BF));
-  return (new);
-}
-
-static SAVED_FUNCTION *
-allocate_saved_function_node (void)
-{
-  SAVED_FUNCTION *new;
-
-  new = (SAVED_FUNCTION *) xmalloc (sizeof (SAVED_FUNCTION));
-  return (new);
-}
-
-static SAVED_F77_COMMON_PTR
-allocate_saved_f77_common_node (void)
-{
-  SAVED_F77_COMMON_PTR new;
-
-  new = (SAVED_F77_COMMON_PTR) xmalloc (sizeof (SAVED_F77_COMMON));
-  return (new);
-}
-
-static COMMON_ENTRY_PTR
-allocate_common_entry_node (void)
-{
-  COMMON_ENTRY_PTR new;
-
-  new = (COMMON_ENTRY_PTR) xmalloc (sizeof (COMMON_ENTRY));
-  return (new);
-}
-#endif
-
-SAVED_F77_COMMON_PTR head_common_list = NULL;	/* Ptr to 1st saved COMMON  */
-SAVED_F77_COMMON_PTR tail_common_list = NULL;	/* Ptr to last saved COMMON  */
-SAVED_F77_COMMON_PTR current_common = NULL;	/* Ptr to current COMMON */
-
-#if 0
-static SAVED_BF_PTR saved_bf_list = NULL;	/* Ptr to (.bf,function) 
-						   list */
-static SAVED_BF_PTR saved_bf_list_end = NULL;	/* Ptr to above list's end */
-static SAVED_BF_PTR current_head_bf_list = NULL;	/* Current head of above list
-							 */
-
-static SAVED_BF_PTR tmp_bf_ptr;	/* Generic temporary for use 
-				   in macros */
-
-/* The following function simply enters a given common block onto 
-   the global common block chain */
-
-static void
-add_common_block (char *name, CORE_ADDR offset, int secnum, char *func_stab)
-{
-  SAVED_F77_COMMON_PTR tmp;
-  char *c, *local_copy_func_stab;
-
-  /* If the COMMON block we are trying to add has a blank 
-     name (i.e. "#BLNK_COM") then we set it to __BLANK
-     because the darn "#" character makes GDB's input 
-     parser have fits. */
-
-
-  if (strcmp (name, BLANK_COMMON_NAME_ORIGINAL) == 0
-      || strcmp (name, BLANK_COMMON_NAME_MF77) == 0)
-    {
-
-      xfree (name);
-      name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1);
-      strcpy (name, BLANK_COMMON_NAME_LOCAL);
-    }
-
-  tmp = allocate_saved_f77_common_node ();
-
-  local_copy_func_stab = xmalloc (strlen (func_stab) + 1);
-  strcpy (local_copy_func_stab, func_stab);
-
-  tmp->name = xmalloc (strlen (name) + 1);
-
-  /* local_copy_func_stab is a stabstring, let us first extract the 
-     function name from the stab by NULLing out the ':' character. */
-
-
-  c = NULL;
-  c = strchr (local_copy_func_stab, ':');
-
-  if (c)
-    *c = '\0';
-  else
-    error (_("Malformed function STAB found in add_common_block()"));
-
-
-  tmp->owning_function = xmalloc (strlen (local_copy_func_stab) + 1);
-
-  strcpy (tmp->owning_function, local_copy_func_stab);
-
-  strcpy (tmp->name, name);
-  tmp->offset = offset;
-  tmp->next = NULL;
-  tmp->entries = NULL;
-  tmp->secnum = secnum;
-
-  current_common = tmp;
-
-  if (head_common_list == NULL)
-    {
-      head_common_list = tail_common_list = tmp;
-    }
-  else
-    {
-      tail_common_list->next = tmp;
-      tail_common_list = tmp;
-    }
-}
-#endif
-
-/* The following function simply enters a given common entry onto 
-   the "current_common" block that has been saved away. */
-
-#if 0
-static void
-add_common_entry (struct symbol *entry_sym_ptr)
-{
-  COMMON_ENTRY_PTR tmp;
-
-
-
-  /* The order of this list is important, since 
-     we expect the entries to appear in decl.
-     order when we later issue "info common" calls */
-
-  tmp = allocate_common_entry_node ();
-
-  tmp->next = NULL;
-  tmp->symbol = entry_sym_ptr;
-
-  if (current_common == NULL)
-    error (_("Attempt to add COMMON entry with no block open!"));
-  else
-    {
-      if (current_common->entries == NULL)
-	{
-	  current_common->entries = tmp;
-	  current_common->end_of_entries = tmp;
-	}
-      else
-	{
-	  current_common->end_of_entries->next = tmp;
-	  current_common->end_of_entries = tmp;
-	}
-    }
-}
-#endif
-
-/* This routine finds the first encountred COMMON block named "name" */
-
-#if 0
-static SAVED_F77_COMMON_PTR
-find_first_common_named (char *name)
-{
-
-  SAVED_F77_COMMON_PTR tmp;
-
-  tmp = head_common_list;
-
-  while (tmp != NULL)
-    {
-      if (strcmp (tmp->name, name) == 0)
-	return (tmp);
-      else
-	tmp = tmp->next;
-    }
-  return (NULL);
-}
-#endif
-
-/* This routine finds the first encountred COMMON block named "name" 
-   that belongs to function funcname */
-
-SAVED_F77_COMMON_PTR
-find_common_for_function (char *name, char *funcname)
-{
-
-  SAVED_F77_COMMON_PTR tmp;
-
-  tmp = head_common_list;
-
-  while (tmp != NULL)
-    {
-      if (strcmp (tmp->name, name) == 0
-	  && strcmp (tmp->owning_function, funcname) == 0)
-	return (tmp);
-      else
-	tmp = tmp->next;
-    }
-  return (NULL);
-}
-
-
-#if 0
-
-/* The following function is called to patch up the offsets 
-   for the statics contained in the COMMON block named
-   "name."  */
-
-static void
-patch_common_entries (SAVED_F77_COMMON_PTR blk, CORE_ADDR offset, int secnum)
-{
-  COMMON_ENTRY_PTR entry;
-
-  blk->offset = offset;		/* Keep this around for future use. */
-
-  entry = blk->entries;
-
-  while (entry != NULL)
-    {
-      SYMBOL_VALUE (entry->symbol) += offset;
-      SYMBOL_SECTION (entry->symbol) = secnum;
-
-      entry = entry->next;
-    }
-  blk->secnum = secnum;
-}
-
-/* Patch all commons named "name" that need patching.Since COMMON
-   blocks occur with relative infrequency, we simply do a linear scan on
-   the name.  Eventually, the best way to do this will be a
-   hashed-lookup.  Secnum is the section number for the .bss section
-   (which is where common data lives). */
-
-static void
-patch_all_commons_by_name (char *name, CORE_ADDR offset, int secnum)
-{
-
-  SAVED_F77_COMMON_PTR tmp;
-
-  /* For blank common blocks, change the canonical reprsentation 
-     of a blank name */
-
-  if (strcmp (name, BLANK_COMMON_NAME_ORIGINAL) == 0
-      || strcmp (name, BLANK_COMMON_NAME_MF77) == 0)
-    {
-      xfree (name);
-      name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1);
-      strcpy (name, BLANK_COMMON_NAME_LOCAL);
-    }
-
-  tmp = head_common_list;
-
-  while (tmp != NULL)
-    {
-      if (COMMON_NEEDS_PATCHING (tmp))
-	if (strcmp (tmp->name, name) == 0)
-	  patch_common_entries (tmp, offset, secnum);
-
-      tmp = tmp->next;
-    }
-}
-#endif
-
-/* This macro adds the symbol-number for the start of the function 
-   (the symbol number of the .bf) referenced by symnum_fcn to a 
-   list.  This list, in reality should be a FIFO queue but since 
-   #line pragmas sometimes cause line ranges to get messed up 
-   we simply create a linear list.  This list can then be searched 
-   first by a queueing algorithm and upon failure fall back to 
-   a linear scan. */
-
-#if 0
-#define ADD_BF_SYMNUM(bf_sym,fcn_sym) \
-  \
-  if (saved_bf_list == NULL) \
-{ \
-    tmp_bf_ptr = allocate_saved_bf_node(); \
-      \
-	tmp_bf_ptr->symnum_bf = (bf_sym); \
-	  tmp_bf_ptr->symnum_fcn = (fcn_sym);  \
-	    tmp_bf_ptr->next = NULL; \
-	      \
-		current_head_bf_list = saved_bf_list = tmp_bf_ptr; \
-		  saved_bf_list_end = tmp_bf_ptr; \
-		  } \
-else \
-{  \
-     tmp_bf_ptr = allocate_saved_bf_node(); \
-       \
-         tmp_bf_ptr->symnum_bf = (bf_sym);  \
-	   tmp_bf_ptr->symnum_fcn = (fcn_sym);  \
-	     tmp_bf_ptr->next = NULL;  \
-	       \
-		 saved_bf_list_end->next = tmp_bf_ptr;  \
-		   saved_bf_list_end = tmp_bf_ptr; \
-		   }
-#endif
-
-/* This function frees the entire (.bf,function) list */
-
-#if 0
-static void
-clear_bf_list (void)
-{
-
-  SAVED_BF_PTR tmp = saved_bf_list;
-  SAVED_BF_PTR next = NULL;
-
-  while (tmp != NULL)
-    {
-      next = tmp->next;
-      xfree (tmp);
-      tmp = next;
-    }
-  saved_bf_list = NULL;
-}
-#endif
-
-int global_remote_debug;
-
-#if 0
-
-static long
-get_bf_for_fcn (long the_function)
-{
-  SAVED_BF_PTR tmp;
-  int nprobes = 0;
-
-  /* First use a simple queuing algorithm (i.e. look and see if the 
-     item at the head of the queue is the one you want)  */
-
-  if (saved_bf_list == NULL)
-    internal_error (__FILE__, __LINE__,
-		    _("cannot get .bf node off empty list"));
-
-  if (current_head_bf_list != NULL)
-    if (current_head_bf_list->symnum_fcn == the_function)
-      {
-	if (global_remote_debug)
-	  fprintf_unfiltered (gdb_stderr, "*");
-
-	tmp = current_head_bf_list;
-	current_head_bf_list = current_head_bf_list->next;
-	return (tmp->symnum_bf);
-      }
-
-  /* If the above did not work (probably because #line directives were 
-     used in the sourcefile and they messed up our internal tables) we now do
-     the ugly linear scan */
-
-  if (global_remote_debug)
-    fprintf_unfiltered (gdb_stderr, "\ndefaulting to linear scan\n");
-
-  nprobes = 0;
-  tmp = saved_bf_list;
-  while (tmp != NULL)
-    {
-      nprobes++;
-      if (tmp->symnum_fcn == the_function)
-	{
-	  if (global_remote_debug)
-	    fprintf_unfiltered (gdb_stderr, "Found in %d probes\n", nprobes);
-	  current_head_bf_list = tmp->next;
-	  return (tmp->symnum_bf);
-	}
-      tmp = tmp->next;
-    }
-
-  return (-1);
-}
-
-static SAVED_FUNCTION_PTR saved_function_list = NULL;
-static SAVED_FUNCTION_PTR saved_function_list_end = NULL;
-
-static void
-clear_function_list (void)
-{
-  SAVED_FUNCTION_PTR tmp = saved_function_list;
-  SAVED_FUNCTION_PTR next = NULL;
-
-  while (tmp != NULL)
-    {
-      next = tmp->next;
-      xfree (tmp);
-      tmp = next;
-    }
-
-  saved_function_list = NULL;
-}
-#endif
diff --git a/gdb/f-lang.h b/gdb/f-lang.h
index 711bdba..9d7d92b 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 */
 extern void f_print_type (struct type *, char *, struct ui_file *, int,
 			  int);
 
+extern const char *f_object_address_data_valid_print_to_stream
+  (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_print_options *);
@@ -47,41 +51,8 @@ enum f90_range_type
     NONE_BOUND_DEFAULT		/* "(low:high)"  */
   };
 
-struct common_entry
-  {
-    struct symbol *symbol;	/* The symbol node corresponding
-				   to this component */
-    struct common_entry *next;	/* The next component */
-  };
-
-struct saved_f77_common
-  {
-    char *name;			/* Name of COMMON */
-    char *owning_function;	/* Name of parent function */
-    int secnum;			/* Section # of .bss */
-    CORE_ADDR offset;		/* Offset from .bss for 
-				   this block */
-    struct common_entry *entries;	/* List of block's components */
-    struct common_entry *end_of_entries;	/* ptr. to end of components */
-    struct saved_f77_common *next;	/* Next saved COMMON block */
-  };
-
-typedef struct saved_f77_common SAVED_F77_COMMON, *SAVED_F77_COMMON_PTR;
-
-typedef struct common_entry COMMON_ENTRY, *COMMON_ENTRY_PTR;
-
-extern SAVED_F77_COMMON_PTR head_common_list;	/* Ptr to 1st saved COMMON  */
-extern SAVED_F77_COMMON_PTR tail_common_list;	/* Ptr to last saved COMMON  */
-extern SAVED_F77_COMMON_PTR current_common;	/* Ptr to current COMMON */
-
-extern SAVED_F77_COMMON_PTR find_common_for_function (char *, char *);
-
-#define UNINITIALIZED_SECNUM -1
-#define COMMON_NEEDS_PATCHING(blk) ((blk)->secnum == UNINITIALIZED_SECNUM)
-
 #define BLANK_COMMON_NAME_ORIGINAL "#BLNK_COM"	/* XLF assigned  */
 #define BLANK_COMMON_NAME_MF77     "__BLNK__"	/* MF77 assigned  */
-#define BLANK_COMMON_NAME_LOCAL    "__BLANK"	/* Local GDB */
 
 /* When reasonable array bounds cannot be fetched, such as when 
    you ask to 'mt print symbols' and there is no stack frame and 
@@ -113,6 +84,7 @@ struct builtin_f_type
   struct type *builtin_logical;
   struct type *builtin_logical_s1;
   struct type *builtin_logical_s2;
+  struct type *builtin_logical_s8;
   struct type *builtin_real;
   struct type *builtin_real_s8;
   struct type *builtin_real_s16;
@@ -125,3 +97,10 @@ struct builtin_f_type
 /* Return the Fortran type table for the specified architecture.  */
 extern const struct builtin_f_type *builtin_f_type (struct gdbarch *gdbarch);
 
+/* List of module names being imported by a block though BLOCK_FORTRAN_USE.  */
+
+struct fortran_using
+  {
+    struct fortran_using *next;
+    char module_name[1];
+  };
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 6c9668f..852b9a8 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -31,7 +31,7 @@
 #include "gdbcore.h"
 #include "target.h"
 #include "f-lang.h"
-
+#include "dwarf2loc.h"
 #include "gdb_string.h"
 #include <errno.h>
 
@@ -48,6 +48,34 @@ void f_type_print_varspec_prefix (struct type *, struct ui_file *,
 void f_type_print_base (struct type *, struct ui_file *, int, int);
 
 
+const char *
+f_object_address_data_valid_print_to_stream (struct type *type,
+					     struct ui_file *stream)
+{
+  const char *msg;
+
+  msg = object_address_data_not_valid (type);
+  if (msg != NULL)
+    {
+      /* Assuming the content printed to STREAM should not be localized.  */
+      fprintf_filtered (stream, "<%s>", msg);
+    }
+
+  return msg;
+}
+
+void
+f_object_address_data_valid_or_error (struct type *type)
+{
+  const char *msg;
+
+  msg = object_address_data_not_valid (type);
+  if (msg != NULL)
+    {
+      error (_("Cannot access it because the %s."), _(msg));
+    }
+}
+
 /* LEVEL is the depth to indent lines by.  */
 
 void
@@ -57,6 +85,9 @@ f_print_type (struct type *type, char *varstring, struct ui_file *stream,
   enum type_code code;
   int demangled_args;
 
+  if (f_object_address_data_valid_print_to_stream (type, stream) != NULL)
+    return;
+
   f_type_print_base (type, stream, show, level);
   code = TYPE_CODE (type);
   if ((varstring != NULL && *varstring != '\0')
@@ -166,6 +197,9 @@ f_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
 
   QUIT;
 
+  if (TYPE_CODE (type) != TYPE_CODE_TYPEDEF)
+    CHECK_TYPEDEF (type);
+
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_ARRAY:
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 0a57404..a9ccc77 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -34,10 +34,8 @@
 #include "gdbcore.h"
 #include "command.h"
 #include "block.h"
-
-#if 0
-static int there_is_a_visible_common_named (char *);
-#endif
+#include "dictionary.h"
+#include "gdb_assert.h"
 
 extern void _initialize_f_valprint (void);
 static void info_common_command (char *, int);
@@ -54,15 +52,17 @@ int f77_array_offset_tbl[MAX_FORTRAN_DIMS + 1][2];
 /* The following macro gives us the size of the nth dimension, Where 
    n is 1 based. */
 
-#define F77_DIM_SIZE(n) (f77_array_offset_tbl[n][1])
+#define F77_DIM_COUNT(n) (f77_array_offset_tbl[n][1])
 
-/* The following gives us the offset for row n where n is 1-based. */
+/* The following gives us the element size for row n where n is 1-based. */
 
-#define F77_DIM_OFFSET(n) (f77_array_offset_tbl[n][0])
+#define F77_DIM_BYTE_STRIDE(n) (f77_array_offset_tbl[n][0])
 
 int
 f77_get_lowerbound (struct type *type)
 {
+  f_object_address_data_valid_or_error (type);
+
   if (TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED (type))
     error (_("Lower bound may not be '*' in F77"));
 
@@ -72,14 +72,17 @@ f77_get_lowerbound (struct type *type)
 int
 f77_get_upperbound (struct type *type)
 {
+  f_object_address_data_valid_or_error (type);
+
   if (TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
     {
-      /* We have an assumed size array on our hands.  Assume that
-	 upper_bound == lower_bound so that we show at least 1 element.
-	 If the user wants to see more elements, let him manually ask for 'em
-	 and we'll subscript the array and show him.  */
+      /* We have an assumed size array on our hands.  As type_length_get
+	 already assumes a length zero of arrays with underfined bounds VALADDR
+	 passed to the Fortran functions does not contained the real inferior
+	 memory content.  User should request printing of specific array
+	 elements instead.  */
 
-      return f77_get_lowerbound (type);
+      return f77_get_lowerbound (type) - 1;
     }
 
   return TYPE_ARRAY_UPPER_BOUND_VALUE (type);
@@ -135,24 +138,29 @@ f77_create_arrayprint_offset_tbl (struct type *type, struct ui_file *stream)
       upper = f77_get_upperbound (tmp_type);
       lower = f77_get_lowerbound (tmp_type);
 
-      F77_DIM_SIZE (ndimen) = upper - lower + 1;
+      F77_DIM_COUNT (ndimen) = upper - lower + 1;
+
+      F77_DIM_BYTE_STRIDE (ndimen) =
+        TYPE_ARRAY_BYTE_STRIDE_VALUE (tmp_type);
 
       tmp_type = TYPE_TARGET_TYPE (tmp_type);
       ndimen++;
     }
 
-  /* Now we multiply eltlen by all the offsets, so that later we 
+  /* Now we multiply eltlen by all the BYTE_STRIDEs, so that later we
      can print out array elements correctly.  Up till now we 
-     know an offset to apply to get the item but we also 
+     know an eltlen to apply to get the item but we also
      have to know how much to add to get to the next item */
 
   ndimen--;
   eltlen = TYPE_LENGTH (tmp_type);
-  F77_DIM_OFFSET (ndimen) = eltlen;
+  if (F77_DIM_BYTE_STRIDE (ndimen) == 0)
+    F77_DIM_BYTE_STRIDE (ndimen) = eltlen;
   while (--ndimen > 0)
     {
-      eltlen *= F77_DIM_SIZE (ndimen + 1);
-      F77_DIM_OFFSET (ndimen) = eltlen;
+      eltlen *= F77_DIM_COUNT (ndimen + 1);
+      if (F77_DIM_BYTE_STRIDE (ndimen) == 0)
+	F77_DIM_BYTE_STRIDE (ndimen) = eltlen;
     }
 }
 
@@ -172,34 +180,34 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type,
 
   if (nss != ndimensions)
     {
-      for (i = 0; (i < F77_DIM_SIZE (nss) && (*elts) < options->print_max); i++)
+      for (i = 0; (i < F77_DIM_COUNT (nss) && (*elts) < options->print_max); i++)
 	{
 	  fprintf_filtered (stream, "( ");
 	  f77_print_array_1 (nss + 1, ndimensions, TYPE_TARGET_TYPE (type),
-			     valaddr + i * F77_DIM_OFFSET (nss),
-			     address + i * F77_DIM_OFFSET (nss),
+			     valaddr + i * F77_DIM_BYTE_STRIDE (nss),
+			     address + i * F77_DIM_BYTE_STRIDE (nss),
 			     stream, recurse, options, elts);
 	  fprintf_filtered (stream, ") ");
 	}
-      if (*elts >= options->print_max && i < F77_DIM_SIZE (nss)) 
+      if (*elts >= options->print_max && i < F77_DIM_COUNT (nss))
 	fprintf_filtered (stream, "...");
     }
   else
     {
-      for (i = 0; i < F77_DIM_SIZE (nss) && (*elts) < options->print_max;
+      for (i = 0; i < F77_DIM_COUNT (nss) && (*elts) < options->print_max;
 	   i++, (*elts)++)
 	{
 	  val_print (TYPE_TARGET_TYPE (type),
-		     valaddr + i * F77_DIM_OFFSET (ndimensions),
+		     valaddr + i * F77_DIM_BYTE_STRIDE (ndimensions),
 		     0,
-		     address + i * F77_DIM_OFFSET (ndimensions),
+		     address + i * F77_DIM_BYTE_STRIDE (ndimensions),
 		     stream, recurse, options, current_language);
 
-	  if (i != (F77_DIM_SIZE (nss) - 1))
+	  if (i != (F77_DIM_COUNT (nss) - 1))
 	    fprintf_filtered (stream, ", ");
 
 	  if ((*elts == options->print_max - 1)
-	      && (i != (F77_DIM_SIZE (nss) - 1)))
+	      && (i != (F77_DIM_COUNT (nss) - 1)))
 	    fprintf_filtered (stream, "...");
 	}
     }
@@ -253,6 +261,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;
+
   CHECK_TYPEDEF (type);
   switch (TYPE_CODE (type))
     {
@@ -467,22 +478,54 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
   return 0;
 }
 
-static void
-list_all_visible_commons (char *funname)
+static int
+info_common_command_for_block (struct block *block, struct frame_info *frame,
+			       const char *comname)
 {
-  SAVED_F77_COMMON_PTR tmp;
-
-  tmp = head_common_list;
-
-  printf_filtered (_("All COMMON blocks visible at this level:\n\n"));
-
-  while (tmp != NULL)
-    {
-      if (strcmp (tmp->owning_function, funname) == 0)
-	printf_filtered ("%s\n", tmp->name);
-
-      tmp = tmp->next;
-    }
+  struct dict_iterator iter;
+  struct symbol *sym;
+  int values_printed = 0;
+  const char *name;
+  struct value_print_options opts;
+
+  get_user_print_options (&opts);
+
+  ALL_BLOCK_SYMBOLS (block, iter, sym)
+    if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN)
+      {
+      	struct type *type = SYMBOL_TYPE (sym);
+	int index;
+
+	gdb_assert (SYMBOL_CLASS (sym) == LOC_STATIC);
+	gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT);
+
+	if (comname && (!SYMBOL_LINKAGE_NAME (sym)
+	                || strcmp (comname, SYMBOL_LINKAGE_NAME (sym)) != 0))
+	  continue;
+
+	values_printed = 1;
+	if (SYMBOL_PRINT_NAME (sym))
+	  printf_filtered (_("Contents of F77 COMMON block '%s':\n"),
+			   SYMBOL_PRINT_NAME (sym));
+	else
+	  printf_filtered (_("Contents of blank COMMON block:\n"));
+	
+	for (index = 0; index < TYPE_NFIELDS (type); index++)
+	  {
+	    struct value *val;
+
+	    gdb_assert (field_is_static (&TYPE_FIELD (type, index)));
+	    val = value_static_field (type, index);
+
+	    printf_filtered ("%s = ", TYPE_FIELD_NAME (type, index));
+	    value_print (val, gdb_stdout, &opts);
+	    putchar_filtered ('\n');
+	  }
+
+	putchar_filtered ('\n');
+      }
+
+  return values_printed;
 }
 
 /* This function is used to print out the values in a given COMMON 
@@ -492,11 +535,9 @@ list_all_visible_commons (char *funname)
 static void
 info_common_command (char *comname, int from_tty)
 {
-  SAVED_F77_COMMON_PTR the_common;
-  COMMON_ENTRY_PTR entry;
   struct frame_info *fi;
-  char *funname = 0;
-  struct symbol *func;
+  struct block *block;
+  int values_printed = 0;
 
   /* We have been told to display the contents of F77 COMMON 
      block supposedly visible in this function.  Let us 
@@ -508,136 +549,32 @@ info_common_command (char *comname, int from_tty)
   /* The following is generally ripped off from stack.c's routine 
      print_frame_info() */
 
-  func = find_pc_function (get_frame_pc (fi));
-  if (func)
-    {
-      /* In certain pathological cases, the symtabs give the wrong
-         function (when we are in the first function in a file which
-         is compiled without debugging symbols, the previous function
-         is compiled with debugging symbols, and the "foo.o" symbol
-         that is supposed to tell us where the file with debugging symbols
-         ends has been truncated by ar because it is longer than 15
-         characters).
-
-         So look in the minimal symbol tables as well, and if it comes
-         up with a larger address for the function use that instead.
-         I don't think this can ever cause any problems; there shouldn't
-         be any minimal symbols in the middle of a function.
-         FIXME:  (Not necessarily true.  What about text labels) */
-
-      struct minimal_symbol *msymbol = 
-	lookup_minimal_symbol_by_pc (get_frame_pc (fi));
-
-      if (msymbol != NULL
-	  && (SYMBOL_VALUE_ADDRESS (msymbol)
-	      > BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
-	funname = SYMBOL_LINKAGE_NAME (msymbol);
-      else
-	funname = SYMBOL_LINKAGE_NAME (func);
-    }
-  else
-    {
-      struct minimal_symbol *msymbol =
-      lookup_minimal_symbol_by_pc (get_frame_pc (fi));
-
-      if (msymbol != NULL)
-	funname = SYMBOL_LINKAGE_NAME (msymbol);
-      else /* Got no 'funname', code below will fail.  */
-	error (_("No function found for frame."));
-    }
-
-  /* If comname is NULL, we assume the user wishes to see the 
-     which COMMON blocks are visible here and then return */
-
-  if (comname == 0)
+  block = get_frame_block (fi, 0);
+  if (block == NULL)
     {
-      list_all_visible_commons (funname);
+      printf_filtered (_("No symbol table info available.\n"));
       return;
     }
 
-  the_common = find_common_for_function (comname, funname);
-
-  if (the_common)
+  while (block)
     {
-      if (strcmp (comname, BLANK_COMMON_NAME_LOCAL) == 0)
-	printf_filtered (_("Contents of blank COMMON block:\n"));
-      else
-	printf_filtered (_("Contents of F77 COMMON block '%s':\n"), comname);
-
-      printf_filtered ("\n");
-      entry = the_common->entries;
-
-      while (entry != NULL)
-	{
-	  print_variable_and_value (NULL, entry->symbol, fi, gdb_stdout, 0);
-	  entry = entry->next;
-	}
+      if (info_common_command_for_block (block, fi, comname))
+	values_printed = 1;
+      /* After handling the function's top-level block, stop.  Don't
+         continue to its superblock, the block of per-file symbols.  */
+      if (BLOCK_FUNCTION (block))
+	break;
+      block = BLOCK_SUPERBLOCK (block);
     }
-  else
-    printf_filtered (_("Cannot locate the common block %s in function '%s'\n"),
-		     comname, funname);
-}
-
-/* This function is used to determine whether there is a
-   F77 common block visible at the current scope called 'comname'. */
-
-#if 0
-static int
-there_is_a_visible_common_named (char *comname)
-{
-  SAVED_F77_COMMON_PTR the_common;
-  struct frame_info *fi;
-  char *funname = 0;
-  struct symbol *func;
-
-  if (comname == NULL)
-    error (_("Cannot deal with NULL common name!"));
 
-  fi = get_selected_frame (_("No frame selected"));
-
-  /* The following is generally ripped off from stack.c's routine 
-     print_frame_info() */
-
-  func = find_pc_function (fi->pc);
-  if (func)
+  if (!values_printed)
     {
-      /* In certain pathological cases, the symtabs give the wrong
-         function (when we are in the first function in a file which
-         is compiled without debugging symbols, the previous function
-         is compiled with debugging symbols, and the "foo.o" symbol
-         that is supposed to tell us where the file with debugging symbols
-         ends has been truncated by ar because it is longer than 15
-         characters).
-
-         So look in the minimal symbol tables as well, and if it comes
-         up with a larger address for the function use that instead.
-         I don't think this can ever cause any problems; there shouldn't
-         be any minimal symbols in the middle of a function.
-         FIXME:  (Not necessarily true.  What about text labels) */
-
-      struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (fi->pc);
-
-      if (msymbol != NULL
-	  && (SYMBOL_VALUE_ADDRESS (msymbol)
-	      > BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
-	funname = SYMBOL_LINKAGE_NAME (msymbol);
+      if (comname)
+	printf_filtered (_("No common block '%s'.\n"), comname);
       else
-	funname = SYMBOL_LINKAGE_NAME (func);
+	printf_filtered (_("No common blocks.\n"));
     }
-  else
-    {
-      struct minimal_symbol *msymbol =
-      lookup_minimal_symbol_by_pc (fi->pc);
-
-      if (msymbol != NULL)
-	funname = SYMBOL_LINKAGE_NAME (msymbol);
-    }
-
-  the_common = find_common_for_function (comname, funname);
-
-  return (the_common ? 1 : 0);
 }
-#endif
 
 void
 _initialize_f_valprint (void)
diff --git a/gdb/findcmd.c b/gdb/findcmd.c
index 1d28914..d176341 100644
--- a/gdb/findcmd.c
+++ b/gdb/findcmd.c
@@ -27,7 +27,7 @@
 
 /* Copied from bfd_put_bits.  */
 
-static void
+void
 put_bits (bfd_uint64_t data, char *buf, int bits, bfd_boolean big_p)
 {
   int i;
@@ -45,6 +45,41 @@ put_bits (bfd_uint64_t data, char *buf, int bits, bfd_boolean big_p)
     }
 }
 
+/* Allocates a buffer in *PATTERN_BUF, with a hard-coded initial size which
+   will be returned in *PATTERN_BUF_SIZE. *PATTERN_BUF_END points to the same
+   place as *PATTERN_BUF, indicating that the buffer is initially empty.  */
+
+void
+allocate_pattern_buffer (char **pattern_buf, char **pattern_buf_end,
+			 ULONGEST *pattern_buf_size)
+{
+#define INITIAL_PATTERN_BUF_SIZE 100
+  *pattern_buf_size = INITIAL_PATTERN_BUF_SIZE;
+  *pattern_buf = xmalloc (*pattern_buf_size);
+  *pattern_buf_end = *pattern_buf;
+}
+
+/* Grows *PATTERN_BUF by a factor of two if it's not large enough to hold
+   VAL_BYTES more bytes  or a 64-bit value, whichever is larger.
+   *PATTERN_BUF_END is updated as necessary.  */
+
+void
+increase_pattern_buffer (char **pattern_buf, char **pattern_buf_end,
+			 ULONGEST *pattern_buf_size, int val_bytes)
+{
+    /* Keep it simple and assume size == 'g' when watching for when we
+       need to grow the pattern buf.  */
+    if ((*pattern_buf_end - *pattern_buf + max (val_bytes, sizeof (int64_t)))
+	> *pattern_buf_size)
+      {
+	size_t current_offset = *pattern_buf_end - *pattern_buf;
+
+	*pattern_buf_size *= 2;
+	*pattern_buf = xrealloc (*pattern_buf, *pattern_buf_size);
+	*pattern_buf_end = *pattern_buf + current_offset;
+      }
+}
+
 /* Subroutine of find_command to simplify it.
    Parse the arguments of the "find" command.  */
 
@@ -61,8 +96,7 @@ parse_find_args (char *args, ULONGEST *max_countp,
   char *pattern_buf;
   /* Current size of search pattern buffer.
      We realloc space as needed.  */
-#define INITIAL_PATTERN_BUF_SIZE 100
-  ULONGEST pattern_buf_size = INITIAL_PATTERN_BUF_SIZE;
+  ULONGEST pattern_buf_size;
   /* Pointer to one past the last in-use part of pattern_buf.  */
   char *pattern_buf_end;
   ULONGEST pattern_len;
@@ -75,8 +109,7 @@ parse_find_args (char *args, ULONGEST *max_countp,
   if (args == NULL)
     error (_("Missing search parameters."));
 
-  pattern_buf = xmalloc (pattern_buf_size);
-  pattern_buf_end = pattern_buf;
+  allocate_pattern_buffer (&pattern_buf, &pattern_buf_end, &pattern_buf_size);
   old_cleanups = make_cleanup (free_current_contents, &pattern_buf);
 
   /* Get search granularity and/or max count if specified.
@@ -173,16 +206,8 @@ parse_find_args (char *args, ULONGEST *max_countp,
       v = parse_to_comma_and_eval (&s);
       val_bytes = TYPE_LENGTH (value_type (v));
 
-      /* Keep it simple and assume size == 'g' when watching for when we
-	 need to grow the pattern buf.  */
-      if ((pattern_buf_end - pattern_buf + max (val_bytes, sizeof (int64_t)))
-	  > pattern_buf_size)
-	{
-	  size_t current_offset = pattern_buf_end - pattern_buf;
-	  pattern_buf_size *= 2;
-	  pattern_buf = xrealloc (pattern_buf, pattern_buf_size);
-	  pattern_buf_end = pattern_buf + current_offset;
-	}
+      increase_pattern_buffer (&pattern_buf, &pattern_buf_end,
+			       &pattern_buf_size, val_bytes);
 
       if (size != '\0')
 	{
@@ -237,6 +262,45 @@ parse_find_args (char *args, ULONGEST *max_countp,
   discard_cleanups (old_cleanups);
 }
 
+/* Drives target_search_memory to sweep through the specified search space,
+   possibly in several iterations (with one call to this function for each
+   iteration).  *START_ADDR is the address where the search starts, and is
+   updated to the next starting address to continue the search.
+   *SEARCH_SPACE_LEN is the amount of bytes which will be searched, and is
+   updated for the next iteration. PATTERN_BUF holds the pattern to be searched
+   for, PATTERN_LEN is the size of the pattern in bytes.  If a match is found,
+   it's address is put in *FOUND_ADDR.
+
+   Returns 1 if found, 0 if not found, and -1 if there was an error requiring
+   halting of the search (e.g. memory read error).  */
+
+int
+search_memory (CORE_ADDR *start_addr, ULONGEST *search_space_len,
+	       const char *pattern_buf, ULONGEST pattern_len,
+	       CORE_ADDR *found_addr)
+{
+  /* Offset from start of this iteration to the next iteration.  */
+  ULONGEST next_iter_incr;
+  int found;
+    
+  found = target_search_memory (*start_addr, *search_space_len,
+				pattern_buf, pattern_len, found_addr);
+  if (found <= 0)
+    return found;
+
+  /* Begin next iteration at one byte past this match.  */
+  next_iter_incr = (*found_addr - *start_addr) + 1;
+
+  /* For robustness, we don't let search_space_len go -ve here.  */
+  if (*search_space_len >= next_iter_incr)
+    *search_space_len -= next_iter_incr;
+  else
+    *search_space_len = 0;
+  *start_addr += next_iter_incr;
+
+  return found;
+}
+
 static void
 find_command (char *args, int from_tty)
 {
@@ -267,12 +331,11 @@ find_command (char *args, int from_tty)
   while (search_space_len >= pattern_len
 	 && found_count < max_count)
     {
-      /* Offset from start of this iteration to the next iteration.  */
-      ULONGEST next_iter_incr;
       CORE_ADDR found_addr;
-      int found = target_search_memory (start_addr, search_space_len,
-					pattern_buf, pattern_len, &found_addr);
+      int found;
 
+      found = search_memory (&start_addr, &search_space_len, pattern_buf,
+			     pattern_len, &found_addr);
       if (found <= 0)
 	break;
 
@@ -280,16 +343,6 @@ find_command (char *args, int from_tty)
       printf_filtered ("\n");
       ++found_count;
       last_found_addr = found_addr;
-
-      /* Begin next iteration at one byte past this match.  */
-      next_iter_incr = (found_addr - start_addr) + 1;
-
-      /* For robustness, we don't let search_space_len go -ve here.  */
-      if (search_space_len >= next_iter_incr)
-	search_space_len -= next_iter_incr;
-      else
-	search_space_len = 0;
-      start_addr += next_iter_incr;
     }
 
   /* Record and print the results.  */
diff --git a/gdb/findvar.c b/gdb/findvar.c
index 8c027c9..d201f76 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -35,6 +35,7 @@
 #include "user-regs.h"
 #include "block.h"
 #include "objfiles.h"
+#include "dwarf2loc.h"
 
 /* Basic byte-swapping routines.  GDB has needed these for a long time...
    All extract a target-format integer at ADDR which is LEN bytes long.  */
@@ -394,27 +395,16 @@ 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, return a zero pointer.  */
+   If the variable cannot be found, return a zero pointer.
+   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)
 {
-  struct value *v;
   struct type *type = SYMBOL_TYPE (var);
   CORE_ADDR addr;
-  int len;
-
-  if (SYMBOL_CLASS (var) == LOC_COMPUTED
-      || SYMBOL_CLASS (var) == LOC_REGISTER)
-    /* These cases do not use V.  */
-    v = NULL;
-  else
-    {
-      v = allocate_value (type);
-      VALUE_LVAL (v) = lval_memory;	/* The most likely possibility.  */
-    }
-
-  len = TYPE_LENGTH (type);
 
   if (symbol_read_needs_frame (var))
     gdb_assert (frame);
@@ -422,32 +412,40 @@ read_var_value (struct symbol *var, struct frame_info *frame)
   switch (SYMBOL_CLASS (var))
     {
     case LOC_CONST:
-      /* Put the constant back in target format.  */
-      store_signed_integer (value_contents_raw (v), len,
-			    gdbarch_byte_order (get_type_arch (type)),
-			    (LONGEST) SYMBOL_VALUE (var));
-      VALUE_LVAL (v) = not_lval;
-      return v;
+      {
+	/* Put the constant back in target format.  */
+	struct value *v = allocate_value (type);
+	VALUE_LVAL (v) = not_lval;
+	store_signed_integer (value_contents_raw (v), TYPE_LENGTH (type),
+			      gdbarch_byte_order (get_type_arch (type)),
+			      (LONGEST) SYMBOL_VALUE (var));
+	return v;
+      }
 
     case LOC_LABEL:
-      /* Put the constant back in target format.  */
-      if (overlay_debugging)
-	{
-	  CORE_ADDR addr
-	    = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
-					SYMBOL_OBJ_SECTION (var));
-	  store_typed_address (value_contents_raw (v), type, addr);
-	}
-      else
-	store_typed_address (value_contents_raw (v), type,
-			      SYMBOL_VALUE_ADDRESS (var));
-      VALUE_LVAL (v) = not_lval;
-      return v;
+      {
+	/* Put the constant back in target format.  */
+	struct value *v = allocate_value (type);
+	VALUE_LVAL (v) = not_lval;
+	if (overlay_debugging)
+	  {
+	    CORE_ADDR addr
+	      = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
+					  SYMBOL_OBJ_SECTION (var));
+	    store_typed_address (value_contents_raw (v), type, addr);
+	  }
+	else
+	  store_typed_address (value_contents_raw (v), type,
+				SYMBOL_VALUE_ADDRESS (var));
+	return v;
+      }
 
     case LOC_CONST_BYTES:
       {
-	memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var), len);
+	struct value *v = allocate_value (type);
 	VALUE_LVAL (v) = not_lval;
+	memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var),
+		TYPE_LENGTH (type));
 	return v;
       }
 
@@ -489,12 +487,23 @@ read_var_value (struct symbol *var, struct frame_info *frame)
       break;
 
     case LOC_BLOCK:
-      if (overlay_debugging)
-	set_value_address (v, symbol_overlayed_address
-	  (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_OBJ_SECTION (var)));
-      else
-	set_value_address (v, BLOCK_START (SYMBOL_BLOCK_VALUE (var)));
-      return v;
+      {
+        CORE_ADDR addr;
+	struct value *v;
+
+	if (overlay_debugging)
+	  addr = symbol_overlayed_address
+	    (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_OBJ_SECTION (var));
+	else
+	  addr = BLOCK_START (SYMBOL_BLOCK_VALUE (var));
+	/* ADDR is set here for ALLOCATE_VALUE's CHECK_TYPEDEF for
+	   DW_OP_push_object_address.  */
+	object_address_set (addr);
+	v = allocate_value (type);
+	VALUE_LVAL (v) = lval_memory;
+	set_value_address (v, addr);
+	return v;
+      }
 
     case LOC_REGISTER:
     case LOC_REGPARM_ADDR:
@@ -513,7 +522,6 @@ read_var_value (struct symbol *var, struct frame_info *frame)
 	      error (_("Value of register variable not available."));
 
 	    addr = value_as_address (regval);
-	    VALUE_LVAL (v) = lval_memory;
 	  }
 	else
 	  {
@@ -556,18 +564,33 @@ read_var_value (struct symbol *var, struct frame_info *frame)
       break;
 
     case LOC_OPTIMIZED_OUT:
-      VALUE_LVAL (v) = not_lval;
-      set_value_optimized_out (v, 1);
-      return v;
+      {
+        struct value *v = allocate_value (type);
+
+	VALUE_LVAL (v) = not_lval;
+	set_value_optimized_out (v, 1);
+	return v;
+      }
 
     default:
       error (_("Cannot look up value of a botched symbol."));
       break;
     }
 
-  set_value_address (v, addr);
-  set_value_lazy (v, 1);
-  return v;
+  {
+    struct value *v;
+
+    /* ADDR is set here for ALLOCATE_VALUE's CHECK_TYPEDEF for
+       DW_OP_PUSH_OBJECT_ADDRESS.  */
+    object_address_set (addr);
+    v = allocate_value (type);
+    VALUE_LVAL (v) = lval_memory;
+    set_value_address (v, addr);
+
+    set_value_lazy (v, 1);
+
+    return v;
+  }
 }
 
 /* Install default attributes for register values.  */
@@ -604,10 +627,11 @@ struct value *
 value_from_register (struct type *type, int regnum, struct frame_info *frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  struct type *type1 = check_typedef (type);
   struct value *v;
 
-  if (gdbarch_convert_register_p (gdbarch, regnum, type1))
+  type = check_typedef (type);
+
+  if (gdbarch_convert_register_p (gdbarch, regnum, type))
     {
       /* The ISA/ABI need to something weird when obtaining the
          specified value from this register.  It might need to
@@ -621,7 +645,7 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
       VALUE_FRAME_ID (v) = get_frame_id (frame);
       VALUE_REGNUM (v) = regnum;
       gdbarch_register_to_value (gdbarch,
-				 frame, regnum, type1, value_contents_raw (v));
+				 frame, regnum, type, value_contents_raw (v));
     }
   else
     {
diff --git a/gdb/frame.c b/gdb/frame.c
index 7932b48..4e7c434 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1171,6 +1171,14 @@ has_stack_frames (void)
   if (ptid_equal (inferior_ptid, null_ptid))
     return 0;
 
+  /* FIXME: Workaround archer-tromey-python crash in
+     add_inferior_object->get_current_arch on FSF GDB update:
+     is_thread_state would assertion check here as
+     remote_start_remote->add_inferior_silent->observer_notify_new_inferior is
+     before remote_start_remote->add_thread_silent.  */
+  if (find_thread_ptid (inferior_ptid) == NULL)
+    return 0;
+
   /* Don't try to read from a dead thread.  */
   if (is_exited (inferior_ptid))
     return 0;
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
+
 set complaints 1
 
 b internal_error
diff --git a/gdb/gdbserver/linux-i386-low.c b/gdb/gdbserver/linux-i386-low.c
new file mode 100644
index 0000000..b95c1b1
--- /dev/null
+++ b/gdb/gdbserver/linux-i386-low.c
@@ -0,0 +1,210 @@
+/* GNU/Linux/i386 specific low level interface, for the remote server for GDB.
+   Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006,
+   2007, 2008, 2009 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 "server.h"
+#include "linux-low.h"
+#include "i387-fp.h"
+
+#include "gdb_proc_service.h"
+
+#include <sys/ptrace.h>
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#ifndef PTRACE_GET_THREAD_AREA
+#define PTRACE_GET_THREAD_AREA 25
+#endif
+
+/* Defined in auto-generated file reg-i386-linux.c.  */
+void init_registers_i386_linux (void);
+
+
+/* This module only supports access to the general purpose registers.  */
+
+#define i386_num_regs 16
+
+/* This stuff comes from i386-linux-nat.c.  */
+
+/* Mapping between the general-purpose registers in `struct user'
+   format and GDB's register array layout.  */
+static int i386_regmap[] = 
+{
+  EAX * 4, ECX * 4, EDX * 4, EBX * 4,
+  UESP * 4, EBP * 4, ESI * 4, EDI * 4,
+  EIP * 4, EFL * 4, CS * 4, SS * 4,
+  DS * 4, ES * 4, FS * 4, GS * 4
+};
+
+/* Called by libthread_db.  */
+
+ps_err_e
+ps_get_thread_area (const struct ps_prochandle *ph, 
+		    lwpid_t lwpid, int idx, void **base)
+{
+  unsigned int desc[4];
+
+  if (ptrace (PTRACE_GET_THREAD_AREA, lwpid,
+	      (void *) idx, (unsigned long) &desc) < 0)
+    return PS_ERR;
+
+  *(int *)base = desc[1];
+  return PS_OK;
+}
+
+static int
+i386_cannot_store_register (int regno)
+{
+  return (regno >= i386_num_regs);
+}
+
+static int
+i386_cannot_fetch_register (int regno)
+{
+  return (regno >= i386_num_regs);
+}
+
+
+#ifdef HAVE_PTRACE_GETREGS
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+
+static void
+i386_fill_gregset (void *buf)
+{
+  int i;
+
+  for (i = 0; i < i386_num_regs; i++)
+    collect_register (i, ((char *) buf) + i386_regmap[i]);
+
+  collect_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4);
+}
+
+static void
+i386_store_gregset (const void *buf)
+{
+  int i;
+
+  for (i = 0; i < i386_num_regs; i++)
+    supply_register (i, ((char *) buf) + i386_regmap[i]);
+
+  supply_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4);
+}
+
+static void
+i386_fill_fpregset (void *buf)
+{
+  i387_cache_to_fsave (buf);
+}
+
+static void
+i386_store_fpregset (const void *buf)
+{
+  i387_fsave_to_cache (buf);
+}
+
+static void
+i386_fill_fpxregset (void *buf)
+{
+  i387_cache_to_fxsave (buf);
+}
+
+static void
+i386_store_fpxregset (const void *buf)
+{
+  i387_fxsave_to_cache (buf);
+}
+
+#endif /* HAVE_PTRACE_GETREGS */
+
+struct regset_info target_regsets[] = {
+#ifdef HAVE_PTRACE_GETREGS
+  { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
+    GENERAL_REGS,
+    i386_fill_gregset, i386_store_gregset },
+# ifdef HAVE_PTRACE_GETFPXREGS
+  { PTRACE_GETFPXREGS, PTRACE_SETFPXREGS, sizeof (elf_fpxregset_t),
+    EXTENDED_REGS,
+    i386_fill_fpxregset, i386_store_fpxregset },
+# endif
+  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
+    FP_REGS,
+    i386_fill_fpregset, i386_store_fpregset },
+#endif /* HAVE_PTRACE_GETREGS */
+  { 0, 0, -1, -1, NULL, NULL }
+};
+
+static const unsigned char i386_breakpoint[] = { 0xCC };
+#define i386_breakpoint_len 1
+
+extern int debug_threads;
+
+static CORE_ADDR
+i386_get_pc ()
+{
+  unsigned long pc;
+
+  collect_register_by_name ("eip", &pc);
+
+  if (debug_threads)
+    fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc);
+  return pc;
+}
+
+static void
+i386_set_pc (CORE_ADDR newpc)
+{
+  if (debug_threads)
+    fprintf (stderr, "set pc to %08lx\n", (long) newpc);
+  supply_register_by_name ("eip", &newpc);
+}
+
+static int
+i386_breakpoint_at (CORE_ADDR pc)
+{
+  unsigned char c;
+
+  read_inferior_memory (pc, &c, 1);
+  if (c == 0xCC)
+    return 1;
+
+  return 0;
+}
+
+struct linux_target_ops the_low_target = {
+  init_registers_i386_linux,
+  i386_num_regs,
+  i386_regmap,
+  i386_cannot_fetch_register,
+  i386_cannot_store_register,
+  i386_get_pc,
+  i386_set_pc,
+  i386_breakpoint,
+  i386_breakpoint_len,
+  NULL,
+  1,
+  i386_breakpoint_at,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+};
diff --git a/gdb/gdbserver/linux-x86-64-low.c b/gdb/gdbserver/linux-x86-64-low.c
new file mode 100644
index 0000000..b8213f5
--- /dev/null
+++ b/gdb/gdbserver/linux-x86-64-low.c
@@ -0,0 +1,184 @@
+/* GNU/Linux/x86-64 specific low level interface, for the remote server
+   for GDB.
+   Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009
+   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 "server.h"
+#include "linux-low.h"
+#include "i387-fp.h"
+
+#include "gdb_proc_service.h"
+
+/* Defined in auto-generated file reg-x86-64-linux.c.  */
+void init_registers_x86_64_linux (void);
+
+#include <sys/reg.h>
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+
+/* This definition comes from prctl.h, but some kernels may not have it.  */
+#ifndef PTRACE_ARCH_PRCTL
+#define PTRACE_ARCH_PRCTL      30
+#endif
+
+/* The following definitions come from prctl.h, but may be absent
+   for certain configurations.  */
+#ifndef ARCH_GET_FS
+#define ARCH_SET_GS 0x1001
+#define ARCH_SET_FS 0x1002
+#define ARCH_GET_FS 0x1003
+#define ARCH_GET_GS 0x1004
+#endif
+
+static int x86_64_regmap[] = {
+  RAX * 8, RBX * 8, RCX * 8, RDX * 8,
+  RSI * 8, RDI * 8, RBP * 8, RSP * 8,
+  R8 * 8, R9 * 8, R10 * 8, R11 * 8,
+  R12 * 8, R13 * 8, R14 * 8, R15 * 8,
+  RIP * 8, EFLAGS * 8, CS * 8, SS * 8, 
+  DS * 8, ES * 8, FS * 8, GS * 8,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  ORIG_RAX * 8
+};
+
+#define X86_64_NUM_GREGS (sizeof(x86_64_regmap)/sizeof(int))
+
+/* Called by libthread_db.  */
+
+ps_err_e
+ps_get_thread_area (const struct ps_prochandle *ph,
+                    lwpid_t lwpid, int idx, void **base)
+{
+  switch (idx)
+    {
+    case FS:
+      if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
+	return PS_OK;
+      break;
+    case GS:
+      if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
+	return PS_OK;
+      break;
+    default:
+      return PS_BADADDR;
+    }
+  return PS_ERR;
+}
+
+static void
+x86_64_fill_gregset (void *buf)
+{
+  int i;
+
+  for (i = 0; i < X86_64_NUM_GREGS; i++)
+    if (x86_64_regmap[i] != -1)
+      collect_register (i, ((char *) buf) + x86_64_regmap[i]);
+}
+
+static void
+x86_64_store_gregset (const void *buf)
+{
+  int i;
+
+  for (i = 0; i < X86_64_NUM_GREGS; i++)
+    if (x86_64_regmap[i] != -1)
+      supply_register (i, ((char *) buf) + x86_64_regmap[i]);
+}
+
+static void
+x86_64_fill_fpregset (void *buf)
+{
+  i387_cache_to_fxsave (buf);
+}
+
+static void
+x86_64_store_fpregset (const void *buf)
+{
+  i387_fxsave_to_cache (buf);
+}
+
+struct regset_info target_regsets[] = {
+  { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
+    GENERAL_REGS,
+    x86_64_fill_gregset, x86_64_store_gregset },
+  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
+    FP_REGS,
+    x86_64_fill_fpregset, x86_64_store_fpregset },
+  { 0, 0, -1, -1, NULL, NULL }
+};
+
+static const unsigned char x86_64_breakpoint[] = { 0xCC };
+#define x86_64_breakpoint_len 1
+                
+extern int debug_threads;
+
+static CORE_ADDR
+x86_64_get_pc ()
+{
+  unsigned long pc;
+
+  collect_register_by_name ("rip", &pc);
+
+  if (debug_threads)
+    fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc);
+  return pc;
+}
+
+static void
+x86_64_set_pc (CORE_ADDR newpc)
+{
+  if (debug_threads)
+    fprintf (stderr, "set pc to %08lx\n", (long) newpc);
+  supply_register_by_name ("rip", &newpc);
+}
+
+static int
+x86_64_breakpoint_at (CORE_ADDR pc)
+{
+  unsigned char c;
+
+  read_inferior_memory (pc, &c, 1);
+  if (c == 0xCC)
+    return 1;
+
+  return 0;
+}
+
+struct linux_target_ops the_low_target = {
+  init_registers_x86_64_linux,
+  -1,
+  NULL,
+  NULL,
+  NULL,
+  x86_64_get_pc,
+  x86_64_set_pc,
+  x86_64_breakpoint,  
+  x86_64_breakpoint_len,
+  NULL,                                 
+  1,
+  x86_64_breakpoint_at,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+};
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index 79d33fe..d3b4fa1 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -185,6 +185,10 @@ struct thread_info
   /* True if this thread has been explicitly requested to stop.  */
   int stop_requested;
 
+  /* The initiating frame of a nexting operation, used for deciding
+     which exceptions to intercept.  */
+  struct frame_id initiating_frame;
+
   /* Private data used by the target vector implementation.  */
   struct private_thread_info *private;
 };
@@ -249,6 +253,9 @@ extern struct thread_info *any_thread_of_process (int pid);
 /* Change the ptid of thread OLD_PTID to NEW_PTID.  */
 void thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid);
 
+/* Prune dead threads from the list of threads.  */
+extern void prune_threads (void);
+
 /* Iterator function to call a user-provided callback function
    once for each known thread.  */
 typedef int (*thread_callback_func) (struct thread_info *, void *);
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 2f77dca..8146175 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -38,6 +38,9 @@
 #include "cp-abi.h"
 #include "gdb_assert.h"
 #include "hashtab.h"
+#include "observer.h"
+#include "dwarf2expr.h"
+#include "dwarf2loc.h"
 
 
 /* Floatformat pairs.  */
@@ -118,13 +121,31 @@ 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);
 
+/* A reference count structure for the type reference count map.  Each
+   type in a hierarchy of types is mapped to the same reference
+   count.  */
+struct type_refc_entry
+{
+  /* One type in the hierarchy.  Each type in the hierarchy gets its
+     own slot.  */
+  struct type *type;
+
+  /* A pointer to the shared reference count.  */
+  int *refc;
+};
+
+/* The hash table holding all discardable `struct type *' references.  */
+static htab_t type_discardable_table;
+
+/* Current type_discardable_check pass used for TYPE_DISCARDABLE_AGE.  */
+static int type_discardable_age_current;
 
 /* Allocate a new OBJFILE-associated type structure and fill it
    with some defaults.  Space for the type structure is allocated
    on the objfile's objfile_obstack.  */
 
 struct type *
-alloc_type (struct objfile *objfile)
+alloc_type (struct objfile *objfile, struct type *parent)
 {
   struct type *type;
 
@@ -148,6 +169,39 @@ alloc_type (struct objfile *objfile)
   return type;
 }
 
+/* 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 void
+set_type_as_discardable (struct type *type)
+{
+  void **slot;
+
+  gdb_assert (!TYPE_DISCARDABLE (type));
+
+  TYPE_DISCARDABLE (type) = 1;
+  TYPE_DISCARDABLE_AGE (type) = type_discardable_age_current;
+
+  slot = htab_find_slot (type_discardable_table, type, INSERT);
+  gdb_assert (!*slot);
+  *slot = type;
+}
+
+/* Allocate a new type like alloc_type but preserve for it the discardability
+   state of PARENT_TYPE.  */
+
+static struct type *
+alloc_type_as_parent (struct type *parent_type)
+{
+  struct type *new_type = alloc_type_copy (parent_type);
+
+  if (TYPE_DISCARDABLE (parent_type))
+    set_type_as_discardable (new_type);
+
+  return new_type;
+}
+
 /* Allocate a new GDBARCH-associated type structure and fill it
    with some defaults.  Space for the type structure is allocated
    on the heap.  */
@@ -184,7 +238,7 @@ struct type *
 alloc_type_copy (const struct type *type)
 {
   if (TYPE_OBJFILE_OWNED (type))
-    return alloc_type (TYPE_OWNER (type).objfile);
+    return alloc_type (TYPE_OWNER (type).objfile, (struct type *) type);
   else
     return alloc_type_arch (TYPE_OWNER (type).gdbarch);
 }
@@ -273,7 +327,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;
     }
@@ -350,7 +404,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;
     }
@@ -721,12 +775,13 @@ create_range_type (struct type *result_type, struct type *index_type,
     TYPE_TARGET_STUB (result_type) = 1;
   else
     TYPE_LENGTH (result_type) = TYPE_LENGTH (check_typedef (index_type));
-  TYPE_NFIELDS (result_type) = 2;
+  TYPE_NFIELDS (result_type) = 3;
   TYPE_FIELDS (result_type) = TYPE_ZALLOC (result_type,
 					   TYPE_NFIELDS (result_type)
 					   * sizeof (struct field));
   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;
@@ -826,26 +881,45 @@ 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_BOUND_IS_DWARF_BLOCK (range_type, 0)
+      || TYPE_RANGE_BOUND_IS_DWARF_BLOCK (range_type, 1)
+      || TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED (range_type) 
+      || TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED (range_type) 
+      || get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+    {
+      low_bound = 0;
+      high_bound = -1;
+    }
+
+  /* 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.  TYPE_TARGET_STUB needs to
+     be checked as it may have dependencies on DWARF blocks depending on
+     runtime information not available during the CREATE_ARRAY_TYPE time.  */
+  if (high_bound < low_bound || TYPE_TARGET_STUB (element_type))
+    TYPE_LENGTH (result_type) = 0;
+  else
+    {
+      CHECK_TYPEDEF (element_type);
+      TYPE_LENGTH (result_type) =
+	TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
+    }
+
   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;
+    }
 
   return result_type;
 }
@@ -1331,6 +1405,84 @@ 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.  */
+
+static CORE_ADDR
+type_length_get (struct type *type, struct type *target_type, int full_span)
+{
+  struct type *range_type;
+  int count;
+  CORE_ADDR byte_stride = 0;	/* `= 0' for a false GCC warning.  */
+  CORE_ADDR element_size;
+
+  if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+      && TYPE_CODE (type) != TYPE_CODE_STRING)
+    return TYPE_LENGTH (type);
+
+  /* Avoid executing TYPE_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_RANGE_LOWER_BOUND_IS_UNDEFINED (range_type)
+      || TYPE_RANGE_UPPER_BOUND_IS_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 %d..%d"),
+	     TYPE_NAME (type), TYPE_LOW_BOUND (range_type),
+	     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);
+	}
+    }
+  if (full_span)
+    return count * byte_stride;
+  if (target_type == NULL)
+    target_type = check_typedef (TYPE_TARGET_TYPE (type));
+  element_size = type_length_get (target_type, NULL, 1);
+  return (count - 1) * byte_stride + element_size;
+}
+
+/* Prepare TYPE after being read in by the backend.  Currently this function
+   only propagates the TYPE_DYNAMIC flag.  */
+
+void
+finalize_type (struct type *type)
+{
+  int i;
+
+  for (i = 0; i < TYPE_NFIELDS (type); ++i)
+    if (TYPE_FIELD_TYPE (type, i) && TYPE_DYNAMIC (TYPE_FIELD_TYPE (type, i)))
+      break;
+
+  /* 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;
+}
+
 /* Added by Bryan Boreham, Kewill, Sun Sep 17 18:07:17 1989.
 
    If this is a stubbed struct (i.e. declared as struct foo *), see if
@@ -1347,7 +1499,8 @@ stub_noname_complaint (void)
 /* 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
-   typedefs does not.  */
+   typedefs does not.  Still original passed TYPE will have TYPE_LENGTH
+   updated.  FIXME: Remove this dependency (only ada_to_fixed_type?).  */
 
 struct type *
 check_typedef (struct type *type)
@@ -1457,34 +1610,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))
+    {
+      htab_t copied_types;
+      struct type *type_old = type;
+
+      copied_types = create_copied_types_hash (NULL);
+      type = copy_type_recursive (type, copied_types);
+      htab_delete (copied_types);
+
+      gdb_assert (TYPE_DYNAMIC (type) == 0);
+    }
+
+  if (!currently_reading_symtab
+      && (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))
 	{
 	  /* Empty.  */
 	}
       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 int low_bound = TYPE_LOW_BOUND (range_type);
-	  const int high_bound = TYPE_HIGH_BOUND (range_type);
-	  int nb_elements;
-	
-	  if (high_bound < low_bound)
-	    nb_elements = 0;
-	  else
-	    nb_elements = high_bound - low_bound + 1;
-	
-	  TYPE_LENGTH (type) = nb_elements * TYPE_LENGTH (target_type);
+	     number of elements and the target type's length.  */
+	  TYPE_LENGTH (type) = type_length_get (type, target_type, 0);
 	  TYPE_TARGET_STUB (type) = 0;
 	}
       else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
@@ -1492,9 +1648,12 @@ check_typedef (struct type *type)
 	  TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
 	  TYPE_TARGET_STUB (type) = 0;
 	}
+      TYPE_DYNAMIC (type) = 0;
     }
+
   /* Cache TYPE_LENGTH for future use.  */
   TYPE_LENGTH (orig_type) = TYPE_LENGTH (type);
+
   return type;
 }
 
@@ -1716,7 +1875,7 @@ init_type (enum type_code code, int length, int flags,
 {
   struct type *type;
 
-  type = alloc_type (objfile);
+  type = alloc_type (objfile, NULL);
   TYPE_CODE (type) = code;
   TYPE_LENGTH (type) = length;
 
@@ -1760,6 +1919,10 @@ init_type (enum type_code code, int length, int flags,
     {
       INIT_CPLUS_SPECIFIC (type);
     }
+
+  if (!objfile)
+    type_incref (type);
+
   return type;
 }
 
@@ -2820,33 +2983,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)
+    {
+      /* 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);
+    }
 }
 
-/* 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;
@@ -2861,8 +3033,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;
@@ -2873,6 +3047,19 @@ copy_type_recursive (struct objfile *objfile,
   TYPE_OBJFILE_OWNED (new_type) = 0;
   TYPE_OWNER (new_type).gdbarch = get_type_arch (type);
 
+  /* 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);
+
+  /* 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;
+
   if (TYPE_NAME (type))
     TYPE_NAME (new_type) = xstrdup (TYPE_NAME (type));
   if (TYPE_TAG_NAME (type))
@@ -2881,12 +3068,45 @@ 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));
+
+      if (!dwarf_locexpr_baton_eval (TYPE_ALLOCATED (new_type)))
+        TYPE_NOT_ALLOCATED (new_type) = 1;
+      TYPE_ALLOCATED (new_type) = NULL;
+    }
+
+  if (TYPE_ASSOCIATED (new_type))
+    {
+      gdb_assert (!TYPE_NOT_ASSOCIATED (new_type));
+
+      if (!dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (new_type)))
+        TYPE_NOT_ASSOCIATED (new_type) = 1;
+      TYPE_ASSOCIATED (new_type) = NULL;
+    }
+
+  if (!TYPE_DATA_LOCATION_IS_ADDR (new_type)
+      && TYPE_DATA_LOCATION_DWARF_BLOCK (new_type))
+    {
+      if (TYPE_NOT_ALLOCATED (new_type)
+          || TYPE_NOT_ASSOCIATED (new_type))
+	TYPE_DATA_LOCATION_DWARF_BLOCK (new_type) = NULL;
+      else
+	{
+	  TYPE_DATA_LOCATION_IS_ADDR (new_type) = 1;
+	  TYPE_DATA_LOCATION_ADDR (new_type) = dwarf_locexpr_baton_eval
+				    (TYPE_DATA_LOCATION_DWARF_BLOCK (new_type));
+	}
+    }
+
   /* Copy the fields.  */
   if (TYPE_NFIELDS (type))
     {
       int i, nfields;
 
       nfields = TYPE_NFIELDS (type);
+      TYPE_NFIELDS (new_type) = nfields;
       TYPE_FIELDS (new_type) = XCALLOC (nfields, struct field);
       for (i = 0; i < nfields; i++)
 	{
@@ -2895,8 +3115,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));
@@ -2915,6 +3135,16 @@ copy_type_recursive (struct objfile *objfile,
 				  xstrdup (TYPE_FIELD_STATIC_PHYSNAME (type,
 								       i)));
 	      break;
+	    case FIELD_LOC_KIND_DWARF_BLOCK:
+	      /* `struct dwarf2_locexpr_baton' is too bound to its objfile so
+		 it is expected to be made constant by CHECK_TYPEDEF.  */
+	      if (TYPE_NOT_ALLOCATED (new_type)
+		  || TYPE_NOT_ASSOCIATED (new_type))
+		SET_FIELD_DWARF_BLOCK (TYPE_FIELD (new_type, i), NULL);
+	      else
+		SET_FIELD_BITPOS (TYPE_FIELD (new_type, i),
+		   dwarf_locexpr_baton_eval (TYPE_FIELD_DWARF_BLOCK (type, i)));
+	      break;
 	    default:
 	      internal_error (__FILE__, __LINE__,
 			      _("Unexpected type field location kind: %d"),
@@ -2923,17 +3153,30 @@ copy_type_recursive (struct objfile *objfile,
 	}
     }
 
+  /* Convert TYPE_RANGE_HIGH_BOUND_IS_COUNT into a regular bound.  */
+  if (TYPE_CODE (type) == TYPE_CODE_RANGE
+      && TYPE_RANGE_HIGH_BOUND_IS_COUNT (type))
+    {
+      TYPE_RANGE_HIGH_BOUND_IS_COUNT (new_type) = 0;
+      TYPE_HIGH_BOUND (new_type) = TYPE_LOW_BOUND (type)
+				   + TYPE_HIGH_BOUND (type) - 1;
+    }
+
+  /* Both FIELD_LOC_KIND_DWARF_BLOCK and TYPE_RANGE_HIGH_BOUND_IS_COUNT were
+     possibly converted.  */
+  TYPE_DYNAMIC (new_type) = 0;
+
   /* Copy pointers to other types.  */
   if (TYPE_TARGET_TYPE (type))
     TYPE_TARGET_TYPE (new_type) = 
-      copy_type_recursive (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);
   /* Maybe copy the type_specific bits.
 
      NOTE drow/2005-12-09: We do not copy the C++-specific bits like
@@ -2951,6 +3194,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.
    
@@ -2973,6 +3227,217 @@ copy_type (const struct type *type)
   return new_type;
 }
 
+/* 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) || !TYPE_CPLUS_SPECIFIC (type));
+
+  if (!(*iter) (type, data))
+    return;
+
+  /* Iterate all the type instances of this main_type.  */
+  type_iter = type;
+  do
+    {
+      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);
+
+  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 void
+delete_main_type (struct type *type)
+{
+  int i;
+
+  gdb_assert (TYPE_DISCARDABLE (type));
+  gdb_assert (TYPE_OBJFILE (type) == NULL);
+
+  xfree (TYPE_NAME (type));
+  xfree (TYPE_TAG_NAME (type));
+
+  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));
+
+  /* `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) || !TYPE_CPLUS_SPECIFIC (type));
+
+  xfree (TYPE_MAIN_TYPE (type));
+}
+
+/* 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_type_chain (struct type *type)
+{
+  struct type *type_iter, *type_iter_to_free;
+
+  gdb_assert (TYPE_DISCARDABLE (type));
+  gdb_assert (TYPE_OBJFILE (type) == NULL);
+
+  delete_main_type (type);
+
+  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);
+}
+
+/* Hash function for type_discardable_table.  */
+
+static hashval_t
+type_discardable_hash (const void *p)
+{
+  const struct type *type = p;
+
+  return htab_hash_pointer (TYPE_MAIN_TYPE (type));
+}
+
+/* Equality function for type_discardable_table.  */
+
+static int
+type_discardable_equal (const void *a, const void *b)
+{
+  const struct type *left = a;
+  const struct type *right = b;
+
+  return TYPE_MAIN_TYPE (left) == TYPE_MAIN_TYPE (right);
+}
+
+/* A helper for type_mark_used.  */
+
+static int
+type_mark_used_crawl (struct type *type, void *unused)
+{
+  if (!TYPE_DISCARDABLE (type))
+    return 0;
+
+  if (TYPE_DISCARDABLE_AGE (type) == type_discardable_age_current)
+    return 0;
+
+  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);
+}
+
+/* Increment the reference count for TYPE.  */
+
+void
+type_incref (struct type *type)
+{
+}
+
+/* Decrement the reference count for TYPE.  If TYPE has no more
+   references, delete it.  */
+
+void
+type_decref (struct type *type)
+{
+}
+
+/* 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);
+}
 
 /* Helper functions to initialize architecture-specific types.  */
 
@@ -3463,6 +3928,11 @@ void
 _initialize_gdbtypes (void)
 {
   gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init);
+
+  type_discardable_table = htab_create_alloc (20, type_discardable_hash,
+					     type_discardable_equal, NULL,
+					     xcalloc, xfree);
+
   objfile_type_data = register_objfile_data ();
 
   add_setshow_zinteger_cmd ("overload", no_class, &overload_debug, _("\
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index be6ed55..6a51a4e 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -137,6 +137,8 @@ enum type_code
 
     TYPE_CODE_DECFLOAT,		/* Decimal floating point.  */
 
+    TYPE_CODE_MODULE,		/* Fortran module.  */
+
     /* Internal function type.  */
     TYPE_CODE_INTERNAL_FUNCTION
   };
@@ -213,6 +215,11 @@ enum type_instance_flag_value
 
 #define TYPE_TARGET_STUB(t)	(TYPE_MAIN_TYPE (t)->flag_target_stub)
 
+/* 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
@@ -278,6 +285,48 @@ enum type_instance_flag_value
 #define TYPE_OWNER(t) TYPE_MAIN_TYPE(t)->owner
 #define TYPE_OBJFILE(t) (TYPE_OBJFILE_OWNED(t)? TYPE_OWNER(t).objfile : NULL)
 
+/* 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)
+
+/* 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.
  */
@@ -365,6 +414,13 @@ struct main_type
   unsigned int flag_nottext : 1;
   unsigned int flag_fixed_instance : 1;
   unsigned int flag_objfile_owned : 1;
+  unsigned int flag_discardable : 1;
+  unsigned int flag_discardable_age : 1;
+  unsigned int flag_dynamic : 1;
+  unsigned int flag_range_high_bound_is_count : 1;
+  unsigned int flag_not_allocated : 1;
+  unsigned int flag_not_associated : 1;
+  unsigned int flag_data_location_is_addr : 1;
 
   /* Number of fields described for this type.  This field appears at
      this location because it packs nicely here.  */
@@ -431,6 +487,20 @@ struct main_type
 
   struct type *target_type;
 
+  /* For DW_AT_data_location.  */
+  union
+    {
+      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.
@@ -538,6 +608,9 @@ struct main_type
        supporting multiple ABIs.  Right now this is only fetched from
        the Dwarf-2 DW_AT_calling_convention attribute.  */
     unsigned calling_convention;
+
+    /* For TYPE_CODE_MODULE, the list of symbols contained in the module.  */
+    struct block *module_block;
   } type_specific;
 };
 
@@ -812,9 +885,9 @@ extern void allocate_cplus_struct_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
@@ -823,23 +896,44 @@ extern void allocate_cplus_struct_type (struct type *);
 #define TYPE_NFIELDS(thistype) TYPE_MAIN_TYPE(thistype)->nfields
 #define TYPE_FIELDS(thistype) TYPE_MAIN_TYPE(thistype)->fields
 #define TYPE_TEMPLATE_ARGS(thistype) TYPE_CPLUS_SPECIFIC(thistype)->template_args
+#define TYPE_DATA_LOCATION_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_LOW_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 0)
 #define TYPE_HIGH_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 1)
-
-/* Moto-specific stuff for FORTRAN arrays */
-
-#define TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED(arraytype) \
-   (TYPE_FIELD_ARTIFICIAL(TYPE_INDEX_TYPE((arraytype)),1))
+#define TYPE_BYTE_STRIDE(range_type) TYPE_FIELD_BITPOS (range_type, 2)
+
+/* Whether we should use TYPE_FIELD_DWARF_BLOCK (and not TYPE_FIELD_BITPOS).  */
+#define TYPE_RANGE_BOUND_IS_DWARF_BLOCK(range_type, fieldno) \
+  (TYPE_FIELD_LOC_KIND (range_type, fieldno) == FIELD_LOC_KIND_DWARF_BLOCK)
+#define TYPE_RANGE_BOUND_SET_DWARF_BLOCK(range_type, fieldno) \
+  (TYPE_FIELD_LOC_KIND (range_type, fieldno) = FIELD_LOC_KIND_DWARF_BLOCK)
+#define TYPE_ARRAY_BOUND_IS_DWARF_BLOCK(array_type, fieldno) \
+  TYPE_RANGE_BOUND_IS_DWARF_BLOCK (TYPE_INDEX_TYPE (array_type), fieldno)
+
+/* Unbound arrays, such as GCC array[]; at end of struct.  */
+#define TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED(rangetype) \
+   TYPE_FIELD_ARTIFICIAL((rangetype),0)
+#define TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED(rangetype) \
+   TYPE_FIELD_ARTIFICIAL((rangetype),1)
 #define TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED(arraytype) \
-   (TYPE_FIELD_ARTIFICIAL(TYPE_INDEX_TYPE((arraytype)),0))
-
-#define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \
-   (TYPE_HIGH_BOUND(TYPE_INDEX_TYPE((arraytype))))
+   TYPE_RANGE_LOWER_BOUND_IS_UNDEFINED (TYPE_INDEX_TYPE (arraytype))
+#define TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED(arraytype) \
+   TYPE_RANGE_UPPER_BOUND_IS_UNDEFINED (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))
+#define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \
+  TYPE_HIGH_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++ */
 
@@ -855,6 +949,7 @@ extern void allocate_cplus_struct_type (struct type *);
 #define TYPE_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff
 #define TYPE_FLOATFORMAT(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.floatformat
 #define TYPE_CALLING_CONVENTION(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.calling_convention
+#define TYPE_MODULE_BLOCK(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.module_block
 #define TYPE_BASECLASS(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].type
 #define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses
 #define TYPE_BASECLASS_NAME(thistype,index) TYPE_MAIN_TYPE(thistype)->fields[index].name
@@ -1131,7 +1226,7 @@ extern const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN
    Use alloc_type_arch to allocate a type owned by an architecture.
    Use alloc_type_copy to allocate a type with the same owner as a
    pre-existing template type, no matter whether objfile or gdbarch.  */
-extern struct type *alloc_type (struct objfile *);
+extern struct type *alloc_type (struct objfile *, struct type *);
 extern struct type *alloc_type_arch (struct gdbarch *);
 extern struct type *alloc_type_copy (const struct type *);
 
@@ -1226,6 +1321,18 @@ extern struct type *create_array_type (struct type *, struct type *,
 				       struct type *);
 extern struct type *lookup_array_range_type (struct type *, int, int);
 
+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);
@@ -1262,6 +1369,8 @@ extern int get_discrete_bounds (struct type *, LONGEST *, LONGEST *);
 
 extern int is_ancestor (struct type *, struct type *);
 
+extern void type_mark_used (struct type *type);
+
 /* Overload resolution */
 
 #define LENGTH_MATCH(bv) ((bv)->rank[0])
@@ -1324,10 +1433,15 @@ extern void maintenance_print_type (char *, int);
 
 extern htab_t create_copied_types_hash (struct objfile *objfile);
 
-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);
 
 extern struct type *copy_type (const struct type *type);
 
+extern void free_all_types (void);
+
+extern void type_incref (struct type *type);
+
+extern void type_decref (struct type *type);
+
 #endif /* GDBTYPES_H */
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
index 0f9d44e..c910e88 100644
--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -26,6 +26,7 @@
 #include "demangle.h"
 #include "objfiles.h"
 #include "valprint.h"
+#include "c-lang.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -459,10 +460,8 @@ gnuv3_find_method_in (struct type *domain, CORE_ADDR voffset,
 		      LONGEST adjustment)
 {
   int i;
-  const char *physname;
 
   /* Search this class first.  */
-  physname = NULL;
   if (adjustment == 0)
     {
       int len;
@@ -590,15 +589,24 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
 	{
 	  char *demangled_name = cplus_demangle (physname,
 						 DMGL_ANSI | DMGL_PARAMS);
-	  if (demangled_name != NULL)
+	  fprintf_filtered (stream, "&virtual ");
+	  if (demangled_name == NULL)
+	    fputs_filtered (physname, stream);
+	  else
 	    {
-	      fprintf_filtered (stream, "&virtual ");
 	      fputs_filtered (demangled_name, stream);
 	      xfree (demangled_name);
-	      return;
 	    }
+	  return;
 	}
     }
+  else if (ptr_value != 0)
+    {
+      /* Found a non-virtual function: print out the type.  */
+      fputs_filtered ("(", stream);
+      c_print_type (type, "", stream, -1, 0);
+      fputs_filtered (") ", stream);
+    }
 
   /* We didn't find it; print the raw data.  */
   if (vbit)
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
index fe848ff..170e6cd 100644
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -586,6 +586,8 @@ i386_linux_store_inferior_registers (struct target_ops *ops,
 
 static unsigned long i386_linux_dr[DR_CONTROL + 1];
 
+/* Get debug register REGNUM value from only the one LWP of PTID.  */
+
 static unsigned long
 i386_linux_dr_get (ptid_t ptid, int regnum)
 {
@@ -614,6 +616,8 @@ i386_linux_dr_get (ptid_t ptid, int regnum)
   return value;
 }
 
+/* Set debug register REGNUM to VALUE in only the one LWP of PTID.  */
+
 static void
 i386_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
 {
@@ -630,6 +634,8 @@ i386_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
     perror_with_name (_("Couldn't write debug register"));
 }
 
+/* Set DR_CONTROL to ADDR in all LWPs of LWP_LIST.  */
+
 static void
 i386_linux_dr_set_control (unsigned long control)
 {
@@ -641,6 +647,8 @@ i386_linux_dr_set_control (unsigned long control)
     i386_linux_dr_set (ptid, DR_CONTROL, control);
 }
 
+/* Set address REGNUM (zero based) to ADDR in all LWPs of LWP_LIST.  */
+
 static void
 i386_linux_dr_set_addr (int regnum, CORE_ADDR addr)
 {
@@ -654,18 +662,55 @@ i386_linux_dr_set_addr (int regnum, CORE_ADDR addr)
     i386_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
 }
 
+/* Set address REGNUM (zero based) to zero in all LWPs of LWP_LIST.  */
+
 static void
 i386_linux_dr_reset_addr (int regnum)
 {
   i386_linux_dr_set_addr (regnum, 0);
 }
 
+/* Get DR_STATUS from only the one LWP of INFERIOR_PTID.  */
+
 static unsigned long
 i386_linux_dr_get_status (void)
 {
   return i386_linux_dr_get (inferior_ptid, DR_STATUS);
 }
 
+/* Unset VALUE bits in DR_STATUS in all LWPs of LWP_LIST.  */
+
+static void
+i386_linux_dr_unset_status (unsigned long mask)
+{
+  struct lwp_info *lp;
+  ptid_t ptid;
+
+  ALL_LWPS (lp, ptid)
+    {
+      unsigned long value;
+      
+      value = i386_linux_dr_get (ptid, DR_STATUS);
+      value &= ~mask;
+      i386_linux_dr_set (ptid, DR_STATUS, value);
+    }
+}
+
+/* See i386_dr_low_type.detach.  Do not use wrappers i386_linux_dr_set_control
+   or i386_linux_dr_reset_addr as they would modify the register cache
+   (i386_linux_dr).  */
+
+static void
+i386_linux_dr_detach (void)
+{
+  int regnum;
+
+  i386_linux_dr_set (inferior_ptid, DR_CONTROL, 0);
+  i386_linux_dr_unset_status (~0UL);
+  for (regnum = DR_FIRSTADDR; regnum <= DR_LASTADDR; regnum++)
+    i386_linux_dr_set (inferior_ptid, regnum, 0);
+}
+
 static void
 i386_linux_new_thread (ptid_t ptid)
 {
@@ -837,6 +882,8 @@ _initialize_i386_linux_nat (void)
   i386_dr_low.set_addr = i386_linux_dr_set_addr;
   i386_dr_low.reset_addr = i386_linux_dr_reset_addr;
   i386_dr_low.get_status = i386_linux_dr_get_status;
+  i386_dr_low.unset_status = i386_linux_dr_unset_status;
+  i386_dr_low.detach = i386_linux_dr_detach;
   i386_set_debug_register_length (4);
 
   /* Override the default ptrace resume method.  */
diff --git a/gdb/i386-nat.c b/gdb/i386-nat.c
index ab1bd8a..ee330b8 100644
--- a/gdb/i386-nat.c
+++ b/gdb/i386-nat.c
@@ -137,8 +137,11 @@ struct i386_dr_low_type i386_dr_low;
 #define I386_DR_GET_RW_LEN(i) \
   ((dr_control_mirror >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (i))) & 0x0f)
 
+/* Mask that this I'th watchpoint has triggered.  */
+#define I386_DR_WATCH_MASK(i)	(1 << (i))
+
 /* Did the watchpoint whose address is in the I'th register break?  */
-#define I386_DR_WATCH_HIT(i)	(dr_status_mirror & (1 << (i)))
+#define I386_DR_WATCH_HIT(i)	(dr_status_mirror & I386_DR_WATCH_MASK (i))
 
 /* A macro to loop over all debug registers.  */
 #define ALL_DEBUG_REGISTERS(i)	for (i = 0; i < DR_NADDR; i++)
@@ -358,6 +361,10 @@ i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
   i386_dr_low.set_addr (i, addr);
   i386_dr_low.set_control (dr_control_mirror);
 
+  /* Only a sanity check for leftover bits (set possibly only by inferior).  */
+  if (i386_dr_low.unset_status)
+    i386_dr_low.unset_status (I386_DR_WATCH_MASK (i));
+
   return 0;
 }
 
@@ -387,6 +394,11 @@ i386_remove_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
 	      i386_dr_low.set_control (dr_control_mirror);
 	      if (i386_dr_low.reset_addr)
 		i386_dr_low.reset_addr (i);
+
+	      /* Status must be already queried for each LWP.  Otherwise it will
+	         be lost in all-stop mode + breakpoint always-inserted off.  */
+	      if (i386_dr_low.unset_status)
+		i386_dr_low.unset_status (I386_DR_WATCH_MASK (i));
 	    }
 	  retval = 0;
 	}
@@ -520,6 +532,17 @@ i386_remove_watchpoint (CORE_ADDR addr, int len, int type)
   return retval;
 }
 
+/* See target_detach_watchpoints.  */
+
+static int
+i386_detach_watchpoints (void)
+{
+  if (i386_dr_low.detach)
+    i386_dr_low.detach ();
+
+  return 0;
+}
+
 /* Return non-zero if we can watch a memory region that starts at
    address ADDR and whose length is LEN bytes.  */
 
@@ -575,28 +598,7 @@ static int
 i386_stopped_by_watchpoint (void)
 {
   CORE_ADDR addr = 0;
-  return i386_stopped_data_address (&current_target, &addr);
-}
-
-/* Return non-zero if the inferior has some break/watchpoint that
-   triggered.  */
-
-static int
-i386_stopped_by_hwbp (void)
-{
-  int i;
-
-  dr_status_mirror = i386_dr_low.get_status ();
-  if (maint_show_dr)
-    i386_show_dr ("stopped_by_hwbp", 0, 0, hw_execute);
-
-  ALL_DEBUG_REGISTERS(i)
-    {
-      if (I386_DR_WATCH_HIT (i))
-	return 1;
-    }
-
-  return 0;
+  return target_stopped_data_address (&current_target, &addr);
 }
 
 /* Insert a hardware-assisted breakpoint at BP_TGT->placed_address.
@@ -690,6 +692,7 @@ i386_use_watchpoints (struct target_ops *t)
   t->to_stopped_data_address = i386_stopped_data_address;
   t->to_insert_watchpoint = i386_insert_watchpoint;
   t->to_remove_watchpoint = i386_remove_watchpoint;
+  t->to_detach_watchpoints = i386_detach_watchpoints;
   t->to_insert_hw_breakpoint = i386_insert_hw_breakpoint;
   t->to_remove_hw_breakpoint = i386_remove_hw_breakpoint;
 }
diff --git a/gdb/i386-nat.h b/gdb/i386-nat.h
index f49b9f6..cd31958 100644
--- a/gdb/i386-nat.h
+++ b/gdb/i386-nat.h
@@ -49,16 +49,23 @@ extern void i386_use_watchpoints (struct target_ops *);
    functions are:
 
       set_control              -- set the debug control (DR7)
-				  register to a given value
+				  register to a given value for all LWPs
 
       set_addr                 -- put an address into one debug
-				  register
+				  register for all LWPs
 
       reset_addr               -- reset the address stored in
-				  one debug register
+				  one debug register for all LWPs
 
       get_status               -- return the value of the debug
-				  status (DR6) register.
+				  status (DR6) register for current LWP
+
+      unset_status             -- unset the specified bits of the debug
+				  status (DR6) register for all LWPs
+
+      detach                   -- clear all debug registers of only the
+				  INFERIOR_PTID task without affecting any
+				  register caches.
 
    Additionally, the native file should set the debug_register_length
    field to 4 or 8 depending on the number of bytes used for
@@ -70,6 +77,8 @@ struct i386_dr_low_type
     void (*set_addr) (int, CORE_ADDR);
     void (*reset_addr) (int);
     unsigned long (*get_status) (void);
+    void (*unset_status) (unsigned long);
+    void (*detach) (void);
     int debug_register_length;
   };
 
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 9e98290..fab1892 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -801,7 +801,7 @@ nexti_command (char *count_string, int from_tty)
   step_1 (1, 1, count_string);
 }
 
-static void
+void
 delete_longjmp_breakpoint_cleanup (void *arg)
 {
   int thread = * (int *) arg;
@@ -841,10 +841,13 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
 
   if (!single_inst || skip_subroutines)		/* leave si command alone */
     {
+      struct thread_info *tp = inferior_thread ();
+
       if (in_thread_list (inferior_ptid))
  	thread = pid_to_thread_id (inferior_ptid);
 
       set_longjmp_breakpoint (thread);
+      tp->initiating_frame = get_frame_id (get_current_frame ());
 
       make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
     }
@@ -1193,6 +1196,15 @@ signal_command (char *signum_exp, int from_tty)
   proceed ((CORE_ADDR) -1, oursig, 0);
 }
 
+/* A continuation callback for until_next_command.  */
+
+static void
+until_next_continuation (void *arg)
+{
+  struct thread_info *tp = arg;
+  delete_longjmp_breakpoint (tp->num);
+}
+
 /* Proceed until we reach a different source line with pc greater than
    our current one or exit the function.  We skip calls in both cases.
 
@@ -1209,6 +1221,8 @@ until_next_command (int from_tty)
   struct symbol *func;
   struct symtab_and_line sal;
   struct thread_info *tp = inferior_thread ();
+  int thread = tp->num;
+  struct cleanup *old_chain;
 
   clear_proceed_status ();
   set_step_frame ();
@@ -1244,7 +1258,19 @@ until_next_command (int from_tty)
 
   tp->step_multi = 0;		/* Only one call to proceed */
 
+  set_longjmp_breakpoint (thread);
+  tp->initiating_frame = get_frame_id (frame);
+  old_chain = make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
+
   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
+
+  if (target_can_async_p () && is_running (inferior_ptid))
+    {
+      discard_cleanups (old_chain);
+      add_continuation (tp, until_next_continuation, tp, NULL);
+    }
+  else
+    do_cleanups (old_chain);
 }
 
 static void
@@ -1421,6 +1447,7 @@ finish_command_continuation (void *arg)
   if (bs != NULL && tp->proceed_to_finish)
     observer_notify_normal_stop (bs, 1 /* print frame */);
   delete_breakpoint (a->breakpoint);
+  delete_longjmp_breakpoint (inferior_thread ()->num);
 }
 
 static void
@@ -1504,6 +1531,7 @@ finish_forward (struct symbol *function, struct frame_info *frame)
   struct breakpoint *breakpoint;
   struct cleanup *old_chain;
   struct finish_command_continuation_args *cargs;
+  int thread = tp->num;
 
   sal = find_pc_line (get_frame_pc (frame), 0);
   sal.pc = get_frame_pc (frame);
@@ -1514,6 +1542,10 @@ finish_forward (struct symbol *function, struct frame_info *frame)
 
   old_chain = make_cleanup_delete_breakpoint (breakpoint);
 
+  set_longjmp_breakpoint (thread);
+  tp->initiating_frame = get_frame_id (frame);
+  make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
+
   tp->proceed_to_finish = 1;    /* We want stop_registers, please...  */
   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
 
diff --git a/gdb/inferior.h b/gdb/inferior.h
index f1b5d17..31add7d 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -272,6 +272,8 @@ extern void interrupt_target_command (char *args, int from_tty);
 
 extern void interrupt_target_1 (int all_threads);
 
+extern void delete_longjmp_breakpoint_cleanup (void *arg);
+
 extern void detach_command (char *, int);
 
 extern void notice_new_inferior (ptid_t, int, int);
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 1a83a25..2ee2164 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -45,6 +45,8 @@
 #include "language.h"
 #include "solib.h"
 #include "main.h"
+#include "dictionary.h"
+#include "block.h"
 #include "gdb_assert.h"
 #include "mi/mi-common.h"
 #include "event-top.h"
@@ -1782,6 +1784,8 @@ static void insert_step_resume_breakpoint_at_sal (struct gdbarch *gdbarch,
 						  struct symtab_and_line sr_sal,
 						  struct frame_id sr_id);
 static void insert_longjmp_resume_breakpoint (struct gdbarch *, CORE_ADDR);
+static void check_exception_resume (struct execution_control_state *,
+				    struct frame_info *, struct symbol *);
 
 static void stop_stepping (struct execution_control_state *ecs);
 static void prepare_to_wait (struct execution_control_state *ecs);
@@ -2687,6 +2691,10 @@ handle_inferior_event (struct execution_control_state *ecs)
 
       stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
 
+      /* Clear WATCHPOINT_TRIGGERED values from previous stop which could
+	 confuse bpstat_stop_status and bpstat_explains_signal.  */
+      watchpoints_triggered (&ecs->ws);
+
       ecs->event_thread->stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);
 
       ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
@@ -2724,6 +2732,10 @@ handle_inferior_event (struct execution_control_state *ecs)
 
       stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
 
+      /* Clear WATCHPOINT_TRIGGERED values from previous stop which could
+	 confuse bpstat_stop_status and bpstat_explains_signal.  */
+      watchpoints_triggered (&ecs->ws);
+
       /* This causes the eventpoints and symbol table to be reset.
          Must do this now, before trying to determine whether to
          stop.  */
@@ -3468,23 +3480,33 @@ process_event_stop_test:
 
 	ecs->event_thread->stepping_over_breakpoint = 1;
 
-	if (!gdbarch_get_longjmp_target_p (gdbarch)
-	    || !gdbarch_get_longjmp_target (gdbarch, frame, &jmp_buf_pc))
+	if (what.is_longjmp)
 	  {
-	    if (debug_infrun)
-	      fprintf_unfiltered (gdb_stdlog, "\
+	    if (!gdbarch_get_longjmp_target_p (gdbarch)
+		|| !gdbarch_get_longjmp_target (gdbarch,
+						frame, &jmp_buf_pc))
+	      {
+		if (debug_infrun)
+		  fprintf_unfiltered (gdb_stdlog, "\
 infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n");
-	    keep_going (ecs);
-	    return;
-	  }
+		keep_going (ecs);
+		return;
+	      }
 
-	/* We're going to replace the current step-resume breakpoint
-	   with a longjmp-resume breakpoint.  */
-	delete_step_resume_breakpoint (ecs->event_thread);
+	    /* We're going to replace the current step-resume breakpoint
+	       with a longjmp-resume breakpoint.  */
+	    delete_step_resume_breakpoint (ecs->event_thread);
 
-	/* Insert a breakpoint at resume address.  */
-	insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
+	    /* Insert a breakpoint at resume address.  */
+	    insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
+	  }
+	else
+	  {
+	    struct symbol *func = get_frame_function (frame);
 
+	    if (func)
+	      check_exception_resume (ecs, frame, func);
+	  }
 	keep_going (ecs);
 	return;
 
@@ -3496,6 +3518,53 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n");
 	gdb_assert (ecs->event_thread->step_resume_breakpoint != NULL);
 	delete_step_resume_breakpoint (ecs->event_thread);
 
+	if (!what.is_longjmp)
+	  {
+	    /* There are several cases to consider.
+	       
+	       1. The initiating frame no longer exists.  In this case
+	       we must stop, because the exception has gone too far.
+	       
+	       2. The initiating frame exists, and is the same as the
+	       current frame.
+	       
+	       2.1. If we are stepping, defer to the stepping logic.
+	       
+	       2.2. Otherwise, we are not stepping, so we are doing a
+	       "finish" and we have reached the calling frame.  So,
+	       stop.
+	       
+	       3. The initiating frame exists and is different from
+	       the current frame.  This means the exception has been
+	       caught beneath the initiating frame, so keep going.  */
+	    struct frame_info *init_frame
+	      = frame_find_by_id (ecs->event_thread->initiating_frame);
+	    if (init_frame)
+	      {
+		struct frame_id current_id
+		  = get_frame_id (get_current_frame ());
+		if (frame_id_eq (current_id,
+				 ecs->event_thread->initiating_frame))
+		  {
+		    if (ecs->event_thread->step_range_start)
+		      {
+			/* Case 2.1.  */
+			break;
+		      }
+		    else
+		      {
+			/* Case 2.2: fall through.  */
+		      }
+		  }
+		else
+		  {
+		    /* Case 3.  */
+		    keep_going (ecs);
+		    return;
+		  }
+	      }
+	  }
+
 	ecs->event_thread->stop_step = 1;
 	print_stop_reason (END_STEPPING_RANGE, 0);
 	stop_stepping (ecs);
@@ -4500,6 +4569,96 @@ insert_longjmp_resume_breakpoint (struct gdbarch *gdbarch, CORE_ADDR pc)
     set_momentary_breakpoint_at_pc (gdbarch, pc, bp_longjmp_resume);
 }
 
+/* Insert an exception resume breakpoint.  TP is the thread throwing
+   the exception.  The block B is the block of the unwinder debug hook
+   function.  FRAME is the frame corresponding to the call to this
+   function.  SYM is the symbol of the function argument holding the
+   target PC of the exception.  */
+
+static void
+insert_exception_resume_breakpoint (struct thread_info *tp,
+				    struct block *b,
+				    struct frame_info *frame,
+				    struct symbol *sym)
+{
+  struct gdb_exception e;
+
+  /* We want to ignore errors here.  */
+  TRY_CATCH (e, RETURN_MASK_ALL)
+    {
+      struct symbol *vsym;
+      struct value *value;
+      CORE_ADDR handler;
+      struct breakpoint *bp;
+
+      vsym = lookup_symbol (SYMBOL_LINKAGE_NAME (sym), b, VAR_DOMAIN, NULL);
+      value = read_var_value (vsym, frame);
+      handler = value_as_address (value);
+
+      /* We're going to replace the current step-resume breakpoint
+	 with an exception-resume breakpoint.  */
+      delete_step_resume_breakpoint (tp);
+
+      if (debug_infrun)
+	fprintf_unfiltered (gdb_stdlog,
+			    "infrun: exception resume at %lx\n",
+			    (unsigned long) handler);
+
+      bp = set_momentary_breakpoint_at_pc (get_frame_arch (frame),
+					   handler, bp_exception_resume);
+      inferior_thread ()->step_resume_breakpoint = bp;
+    }
+}
+
+/* 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 gdb_exception e;
+
+  TRY_CATCH (e, RETURN_MASK_ALL)
+    {
+      struct block *b;
+      struct dict_iterator iter;
+      struct symbol *sym;
+      int argno = 0;
+
+      /* The exception breakpoint is a thread-specific breakpoint on
+	 the unwinder's debug hook, declared as:
+	 
+	 void _Unwind_DebugHook (void *cfa, void *handler);
+	 
+	 The CFA argument indicates the frame to which control is
+	 about to be transferred.  HANDLER is the destination PC.
+	 
+	 We ignore the CFA and set a temporary breakpoint at HANDLER.
+	 This is not extremely efficient but it avoids issues in gdb
+	 with computing the DWARF CFA, and it also works even in weird
+	 cases such as throwing an exception from inside a signal
+	 handler.  */
+
+      b = SYMBOL_BLOCK_VALUE (func);
+      ALL_BLOCK_SYMBOLS (b, iter, sym)
+	{
+	  if (!SYMBOL_IS_ARGUMENT (sym))
+	    continue;
+
+	  if (argno == 0)
+	    ++argno;
+	  else
+	    {
+	      insert_exception_resume_breakpoint (ecs->event_thread,
+						  b, frame, sym);
+	      break;
+	    }
+	}
+    }
+}
+
 static void
 stop_stepping (struct execution_control_state *ecs)
 {
@@ -4568,6 +4727,8 @@ keep_going (struct execution_control_state *ecs)
 	    }
 	  if (e.reason < 0)
 	    {
+	      if (debug_infrun)
+		exception_fprintf (gdb_stdlog, e, "infrun: exception while inserting breakpoints: ");
 	      stop_stepping (ecs);
 	      return;
 	    }
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
index 6b68e7d..5095180 100644
--- a/gdb/jv-lang.c
+++ b/gdb/jv-lang.c
@@ -1121,6 +1121,7 @@ const struct exp_descriptor exp_descriptor_java =
 {
   print_subexp_standard,
   operator_length_standard,
+  operator_check_standard,
   op_name_standard,
   dump_subexp_body_standard,
   evaluate_subexp_java
diff --git a/gdb/language.h b/gdb/language.h
index c650e07..660fdf6 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -237,7 +237,6 @@ struct language_defn
        variables.  */
 
     struct symbol *(*la_lookup_symbol_nonlocal) (const char *,
-						 const char *,
 						 const struct block *,
 						 const domain_enum);
 
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 3e943a1..3b8956c 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -30,6 +30,7 @@
 #include "value.h"
 #include "completer.h"
 #include "cp-abi.h"
+#include "cp-support.h"
 #include "parser-defs.h"
 #include "block.h"
 #include "objc-lang.h"
@@ -839,13 +840,33 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
     }
   else if (paren_pointer != NULL)
     {
-      p = paren_pointer + 1;
+      /* We need to deal with method and function overloads
+	 with no parameters. Gdb and gcc (and who knows about other
+	 compilers) are very inconsistent with the keyword "void".
+	 Canonicalizing C++ types is insufficient in this case, since
+	 we still need to enforce the presence (or lack thereof) of
+	 "void". For simplicity, omit the keyword "void" if present. */
+      if (strncmp (paren_pointer - 5, "(void)", 6) == 0)
+	{
+	  char *a, *b;
+	  a = paren_pointer - 4;
+	  b = paren_pointer;
+	  while ((*(a++) = *(b++)) != '\0') ;
+	  *a = '\0';
+	  p = paren_pointer - 3;
+	}
+      else
+	p = paren_pointer + 1;
     }
   else
     {
       p = skip_quoted (*argptr);
     }
 
+  /* Make sure we keep important kewords like "const" */
+  if (strncmp (p, " const", 6) == 0)
+    p += 6;
+
   /* Keep any template parameters */
   if (*p == '<')
     p = find_template_name_end (p);
@@ -1257,7 +1278,10 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
       /* Move pointer ahead to next double-colon.  */
       while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\''))
 	{
-	  if (p[0] == '<')
+	  if (current_language->la_language == language_cplus
+	      && strncmp (p, "operator", 8) == 0)
+	    p += cp_validate_operator (p);
+	  else if (p[0] == '<')
 	    {
 	      temp_end = find_template_name_end (p);
 	      if (!temp_end)
@@ -1334,6 +1358,16 @@ decode_compound (char **argptr, int funfirstline, char ***canonical,
 	  while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':')
 	    p++;
 	  /* At this point p->"".  String ended.  */
+	  /* Nope. C++ operators could have spaces in them
+	     ("foo::operator <" or "foo::operator delete []").
+	     I apologize, this is a bit hacky... */
+	  if (current_language->la_language == language_cplus
+	      && *p == ' ' && p - 8 - *argptr + 1 > 0
+	      && strncmp (p - 8, "operator", 8) == 0)
+	    {
+	      /* The above loop has already swallowed "operator" */
+	      p += cp_validate_operator (p - 8) - 8;
+	    }
 	}
 
       /* Allocate our own copy of the substring between argptr and
@@ -1407,6 +1441,7 @@ lookup_prefix_sym (char **argptr, char *p)
 {
   char *p1;
   char *copy;
+  struct symbol *sym;
 
   /* Extract the class name.  */
   p1 = p;
@@ -1425,7 +1460,26 @@ lookup_prefix_sym (char **argptr, char *p)
   /* At this point p1->"::inA::fun", p->"inA::fun" copy->"AAA",
      argptr->"inA::fun" */
 
-  return lookup_symbol (copy, 0, STRUCT_DOMAIN, 0);
+  sym = lookup_symbol (copy, 0, STRUCT_DOMAIN, 0);
+  if (sym == NULL)
+    {
+      /* Typedefs are in VAR_DOMAIN so the above symbol lookup will
+	 fail when the user attempts to lookup a method of a class
+	 via a typedef'd name (NOT via the classes name, which is already
+	 handled in symbol_matches_domain).  So try the lookup again
+	 using VAR_DOMAIN (where typedefs live) and double-check that we
+	 found a struct/class type.  */
+      struct symbol *s = lookup_symbol (copy, 0, VAR_DOMAIN, 0);
+      if (s != NULL)
+	{
+	  struct type *t = SYMBOL_TYPE (s);
+	  CHECK_TYPEDEF (t);
+	  if (TYPE_CODE (t) == TYPE_CODE_STRUCT)
+	    return s;
+	}
+    }
+
+  return sym;
 }
 
 /* This finds the method COPY in the class whose type is T and whose
@@ -1780,7 +1834,7 @@ symbol_found (int funfirstline, char ***canonical, char *copy,
 	{
 	  struct blockvector *bv = BLOCKVECTOR (SYMBOL_SYMTAB (sym));
 	  struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-	  if (lookup_block_symbol (b, copy, NULL, VAR_DOMAIN) != NULL)
+	  if (lookup_block_symbol (b, copy, VAR_DOMAIN) != NULL)
 	    build_canonical_line_spec (values.sals, copy, canonical);
 	}
       return values;
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 98f6347..0907f03 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -1710,6 +1710,7 @@ resume_callback (struct lwp_info *lp, void *data)
       lp->stopped = 0;
       lp->step = 0;
       memset (&lp->siginfo, 0, sizeof (lp->siginfo));
+      lp->watchpoint_hit_set = 0;
     }
   else if (lp->stopped && debug_linux_nat)
     fprintf_unfiltered (gdb_stdlog, "RC: Not resuming sibling %s (has pending)\n",
@@ -1847,6 +1848,7 @@ linux_nat_resume (struct target_ops *ops,
 
   linux_ops->to_resume (linux_ops, ptid, step, signo);
   memset (&lp->siginfo, 0, sizeof (lp->siginfo));
+  lp->watchpoint_hit_set = 0;
 
   if (debug_linux_nat)
     fprintf_unfiltered (gdb_stdlog,
@@ -2286,6 +2288,78 @@ maybe_clear_ignore_sigint (struct lwp_info *lp)
     }
 }
 
+/* Fetch the possible triggered data watchpoint info and store it to LP.
+   The hardware data watchpoint trigger gets cleared during this fetch.  */
+
+static void
+save_sigtrap (struct lwp_info *lp)
+{
+  struct cleanup *old_chain;
+
+  /* linux_nat_stopped_data_address is not even installed in this case.  */
+  if (linux_ops->to_stopped_data_address == NULL)
+    return;
+
+  old_chain = save_inferior_ptid ();
+  inferior_ptid = lp->ptid;
+
+  lp->watchpoint_hit_set =
+    linux_ops->to_stopped_data_address (&current_target, &lp->watchpoint_hit);
+
+  do_cleanups (old_chain);
+}
+
+/* Wrap target_stopped_data_address where the GNU/Linux native target may be
+   directed by the watchpoint/debug register number.  Base the reported value
+   on the triggered data address instead.  During inferior stop the assignment
+   of watchpoint/debug registers may change making the register number specific
+   trigger info stale.  */
+
+static int
+linux_nat_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
+{
+  struct lwp_info *lp = find_lwp_pid (inferior_ptid);
+
+  gdb_assert (lp != NULL);
+
+  *addr_p = lp->watchpoint_hit;
+
+  return lp->watchpoint_hit_set;
+}
+
+/* In `set follow-fork-mode child' with multithreaded parent we need to detach
+   watchpoints from all the LWPs.  In such case INFERIOR_PTID will be the
+   non-threaded new child while LWP_LIST will still contain all the threads of
+   the parent being detached.  */
+
+static int
+linux_nat_detach_watchpoints (void)
+{
+  struct lwp_info *lp;
+  int found = 0, retval = 0;
+  ptid_t filter = pid_to_ptid (ptid_get_pid (inferior_ptid));
+  struct cleanup *old_chain = save_inferior_ptid ();
+
+  for (lp = lwp_list; lp; lp = lp->next)
+    if (ptid_match (lp->ptid, filter))
+      {
+	inferior_ptid = lp->ptid;
+	retval |= linux_ops->to_detach_watchpoints ();
+	found = 1;
+      }
+
+  do_cleanups (old_chain);
+
+  if (!found)
+    {
+      gdb_assert (!is_lwp (inferior_ptid));
+
+      retval |= linux_ops->to_detach_watchpoints ();
+    }
+
+  return retval;
+}
+
 /* Wait until LP is stopped.  */
 
 static int
@@ -2337,6 +2411,8 @@ stop_wait_callback (struct lwp_info *lp, void *data)
 	      /* Save the trap's siginfo in case we need it later.  */
 	      save_siginfo (lp);
 
+	      save_sigtrap (lp);
+
 	      /* Now resume this LWP and get the SIGSTOP event. */
 	      errno = 0;
 	      ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
@@ -2701,10 +2777,14 @@ linux_nat_filter_event (int lwpid, int status, int options)
       add_thread (lp->ptid);
     }
 
-  /* Save the trap's siginfo in case we need it later.  */
   if (WIFSTOPPED (status)
       && (WSTOPSIG (status) == SIGTRAP || WSTOPSIG (status) == TRAP_IS_SYSCALL))
-    save_siginfo (lp);
+    {
+      /* Save the trap's siginfo in case we need it later.  */
+      save_siginfo (lp);
+
+      save_sigtrap (lp);
+    }
 
   /* Handle GNU/Linux's extended waitstatus for trace events.
      It is necessary to check if WSTOPSIG is signaling that
@@ -4999,6 +5079,10 @@ linux_nat_add_target (struct target_ops *t)
   t->to_thread_alive = linux_nat_thread_alive;
   t->to_pid_to_str = linux_nat_pid_to_str;
   t->to_has_thread_control = tc_schedlock;
+  if (linux_ops->to_stopped_data_address)
+    t->to_stopped_data_address = linux_nat_stopped_data_address;
+  if (linux_ops->to_detach_watchpoints)
+    t->to_detach_watchpoints = linux_nat_detach_watchpoints;
 
   t->to_can_async_p = linux_nat_can_async_p;
   t->to_is_async_p = linux_nat_is_async_p;
diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
index eae74f3..73204fc 100644
--- a/gdb/linux-nat.h
+++ b/gdb/linux-nat.h
@@ -62,6 +62,12 @@ struct lwp_info
      be the address of a hardware watchpoint.  */
   struct siginfo siginfo;
 
+  /* WATCHPOINT_HIT_SET is non-zero if this LWP stopped with a trap and a data
+     watchpoint has been found as triggered.  In such case WATCHPOINT_HIT
+     contains data address of the triggered data watchpoint.  */
+  unsigned watchpoint_hit_set : 1;
+  CORE_ADDR watchpoint_hit;
+
   /* Non-zero if we expect a duplicated SIGINT.  */
   int ignore_sigint;
 
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index 88c7e5e..2d0b3ca 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -356,6 +356,7 @@ const struct exp_descriptor exp_descriptor_modula2 =
 {
   print_subexp_standard,
   operator_length_standard,
+  operator_check_standard,
   op_name_standard,
   dump_subexp_body_standard,
   evaluate_subexp_modula2
diff --git a/gdb/machoread.c b/gdb/machoread.c
index 5f9a0fe..66fa067 100644
--- a/gdb/machoread.c
+++ b/gdb/machoread.c
@@ -681,6 +681,7 @@ static struct sym_fns macho_sym_fns = {
   macho_new_init,               /* sym_new_init: init anything gbl to entire symtab */
   macho_symfile_init,           /* sym_init: read initial info, setup for sym_read() */
   macho_symfile_read,           /* sym_read: read a symbol file into symtab */
+  NULL,				/* sym_read_psymbols */
   macho_symfile_finish,         /* sym_finish: finished with file, cleanup */
   macho_symfile_offsets,        /* sym_offsets:  xlate external to internal form */
   NULL                          /* next: pointer to next struct sym_fns */
diff --git a/gdb/main.c b/gdb/main.c
index 55411a8..ac9a540 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -40,6 +40,7 @@
 #include "interps.h"
 #include "main.h"
 
+#include "python/python.h"
 #include "source.h"
 
 /* If nonzero, display time usage both at startup and for each command.  */
@@ -259,6 +260,8 @@ captured_main (void *data)
   char *cdarg = NULL;
   char *ttyarg = NULL;
 
+  int python_script = 0;
+
   /* These are static so that we can take their address in an initializer.  */
   static int print_help;
   static int print_version;
@@ -434,10 +437,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}
     };
 
-    while (1)
+    while (!python_script)
       {
 	int option_index;
 
@@ -455,6 +462,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;
@@ -631,7 +641,31 @@ extern int gdbtk_test (char *);
 	use_windows = 0;
       }
 
-    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);
+	  }
+
+	/* 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
@@ -864,7 +898,8 @@ Can't attach to process and specify a core file at the same time."));
   xfree (cmdarg);
 
   /* Read in the old history after all the command files have been read. */
-  init_history ();
+  if (!python_script)
+    init_history ();
 
   if (batch)
     {
@@ -893,13 +928,25 @@ Can't attach to process and specify a core file at the same time."));
 #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)
+#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.  */
 }
@@ -931,7 +978,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 (_("\
@@ -969,7 +1021,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/maint.c b/gdb/maint.c
index ecbae12..80fc36e 100644
--- a/gdb/maint.c
+++ b/gdb/maint.c
@@ -914,4 +914,12 @@ When enabled GDB is profiled."),
 			   show_maintenance_profile_p,
 			   &maintenance_set_cmdlist,
 			   &maintenance_show_cmdlist);
+  add_setshow_filename_cmd ("gdb_datadir", class_maintenance,
+                           &gdb_datadir, _("Set GDB's datadir path."),
+                           _("Show GDB's datadir path."),
+                           _("\
+When set, GDB uses the specified path to search for data files."),
+                           NULL, NULL,
+                           &maintenance_set_cmdlist,
+                           &maintenance_show_cmdlist);
 }
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index aac82e9..626292c 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -4802,7 +4802,7 @@ new_type (char *name)
 {
   struct type *t;
 
-  t = alloc_type (current_objfile);
+  t = alloc_type (current_objfile, NULL);
   TYPE_NAME (t) = name;
   TYPE_CPLUS_SPECIFIC (t) = (struct cplus_struct_type *) &cplus_struct_default;
   return t;
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index 0baaa83..94ebfeb 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -697,7 +697,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/mi/mi-main.c b/gdb/mi/mi-main.c
index 857a5d5..6181002 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -1130,7 +1130,7 @@ mi_cmd_list_features (char *command, char **argv, int argc)
       ui_out_field_string (uiout, NULL, "frozen-varobjs");
       ui_out_field_string (uiout, NULL, "pending-breakpoints");
       ui_out_field_string (uiout, NULL, "thread-info");
-      
+
 #if HAVE_PYTHON
       ui_out_field_string (uiout, NULL, "python");
 #endif
diff --git a/gdb/mipsread.c b/gdb/mipsread.c
index a84003f..924c1c5 100644
--- a/gdb/mipsread.c
+++ b/gdb/mipsread.c
@@ -394,6 +394,7 @@ static struct sym_fns ecoff_sym_fns =
   mipscoff_new_init,		/* sym_new_init: init anything gbl to entire symtab */
   mipscoff_symfile_init,	/* sym_init: read initial info, setup for sym_read() */
   mipscoff_symfile_read,	/* sym_read: read a symbol file into symtab */
+  NULL,				/* sym_read_psymbols */
   mipscoff_symfile_finish,	/* sym_finish: finished with file, cleanup */
   default_symfile_offsets,	/* sym_offsets: dummy FIXME til implem sym reloc */
   default_symfile_segments,	/* sym_segments: Get segment information from
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 1f7489f..b9a7ed6 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -459,12 +459,14 @@ free_objfile (struct objfile *objfile)
 
   unlink_objfile (objfile);
 
-  /* If we are going to free the runtime common objfile, mark it
-     as unallocated.  */
+  /* If we are going to free any existing OBJFILE reference, clear it.  */
 
   if (objfile == rt_common_objfile)
     rt_common_objfile = NULL;
 
+  if (objfile == symfile_objfile)
+    symfile_objfile = NULL;
+
   /* Before the symbol table code was redone to make it easier to
      selectively load and remove information particular to a specific
      linkage unit, gdb used to do these things whenever the monolithic
@@ -731,6 +733,20 @@ have_partial_symbols (void)
     if (objfile_has_partial_symbols (ofp))
       return 1;
   }
+
+  /* Try again, after reading partial symbols.  We do this in two
+     passes because objfiles are always added to the head of the list,
+     and there might be a later objfile for which we've already read
+     partial symbols.  */
+  ALL_OBJFILES (ofp)
+  {
+    require_partial_symbols (ofp);
+    if (ofp->psymtabs != NULL)
+      {
+	return 1;
+      }
+  }
+
   return 0;
 }
 
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index 62fa498..1fc9c6a 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -212,6 +212,11 @@ struct objfile
 
     struct partial_symtab *psymtabs;
 
+    /* An address map that can be used to quickly determine if an
+       address comes from this objfile.  This can be NULL.  */
+
+    struct addrmap *quick_addrmap;
+
     /* Map addresses to the entries of PSYMTABS.  It would be more efficient to
        have a map per the whole process but ADDRMAP cannot selectively remove
        its items during FREE_OBJFILE.  This mapping is already present even for
@@ -414,6 +419,15 @@ struct objfile
 
 #define OBJF_USERLOADED	(1 << 3)	/* User loaded */
 
+/* Set if we have tried to read partial symtabs for this objfile.
+   This is used to allow lazy reading of partial symtabs.  */
+
+#define OBJF_SYMTABS_READ (1 << 6)
+
+/* This flag is set for the main objfile.  */
+
+#define OBJF_MAIN (1 << 7)
+
 /* The object file that the main symbol table was loaded from (e.g. the
    argument to the "symbol-file" or "file" command).  */
 
@@ -568,6 +582,13 @@ extern void gdb_bfd_unref (struct bfd *abfd);
   ALL_OBJFILES (objfile)	 \
     ALL_OBJFILE_PSYMTABS (objfile, p)
 
+/* Like ALL_PSYMTABS, but ensure that partial symbols have been read
+   before examining the objfile.  */
+
+#define ALL_PSYMTABS_REQUIRED(objfile, p)			\
+  ALL_OBJFILES (objfile)					\
+    ALL_OBJFILE_PSYMTABS (require_partial_symbols (objfile), p)
+
 /* Traverse all minimal symbols in all objfiles.  */
 
 #define	ALL_MSYMBOLS(objfile, m) \
diff --git a/gdb/parse.c b/gdb/parse.c
index ef938e3..c243bd8 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -63,6 +63,7 @@ const struct exp_descriptor exp_descriptor_standard =
   {
     print_subexp_standard,
     operator_length_standard,
+    operator_check_standard,
     op_name_standard,
     dump_subexp_body_standard,
     evaluate_subexp_standard
@@ -837,6 +838,15 @@ operator_length_standard (struct expression *expr, int endpos,
       args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
       break;
 
+    case TYPE_INSTANCE:
+      oplen = 4 + longest_to_int (expr->elts[endpos - 2].longconst);
+      args = 1;
+      break;
+
+    case TYPE_INSTANCE_LOOKUP:
+      oplen = 3;
+      break;
+
     case OP_OBJC_MSGCALL:	/* Objective C message (method) call */
       oplen = 4;
       args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
@@ -1355,6 +1365,150 @@ parser_fprintf (FILE *x, const char *y, ...)
   va_end (args);
 }
 
+/* Implementation of the exp_descriptor method operator_check.  */
+
+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)
+{
+  const union exp_element *const elts = exp->elts;
+  struct type *type = NULL;
+  struct objfile *objfile = NULL;
+
+  /* Extended operators should have been already handled by exp_descriptor
+     iterate method of its specific language.  */
+  gdb_assert (elts[pos].opcode < OP_EXTENDED0);
+
+  /* Track the callers of write_exp_elt_type for this table.  */
+
+  switch (elts[pos].opcode)
+    {
+    case BINOP_VAL:
+    case OP_COMPLEX:
+    case OP_DECFLOAT:
+    case OP_DOUBLE:
+    case OP_LONG:
+    case OP_SCOPE:
+    case OP_TYPE:
+    case UNOP_CAST:
+    case UNOP_MAX:
+    case UNOP_MEMVAL:
+    case UNOP_MIN:
+      type = elts[pos + 1].type;
+      break;
+
+    case UNOP_MEMVAL_TLS:
+      objfile = elts[pos + 1].objfile;
+      type = elts[pos + 2].type;
+      break;
+
+    case OP_VAR_VALUE:
+      {
+	const struct block *const block = elts[pos + 1].block;
+	const struct symbol *const symbol = elts[pos + 2].symbol;
+	const struct obj_section *const section = SYMBOL_OBJ_SECTION (symbol);
+
+	/* Check objfile where the variable itself is placed.  */
+	if (section && objfile_func && (*objfile_func) (section->objfile, data))
+	  return 1;
+
+	/* Check objfile where is placed the code touching the variable.  */
+	objfile = block_objfile (block);
+
+	type = SYMBOL_TYPE (symbol);
+      }
+      break;
+    }
+
+  /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL.  */
+
+  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_func) (objfile, data))
+    return 1;
+
+  return 0;
+}
+
+/* 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)
+{
+  int endpos;
+  const union exp_element *const elts = exp->elts;
+
+  for (endpos = exp->nelts; endpos > 0; )
+    {
+      int pos, args, oplen = 0;
+
+      exp->language_defn->la_exp_desc->operator_length (exp, endpos,
+							&oplen, &args);
+      gdb_assert (oplen > 0);
+
+      pos = endpos - oplen;
+      if (exp->language_defn->la_exp_desc->operator_check (exp, pos, type_func,
+							   objfile_func, data))
+	return 1;
+
+      endpos = pos;
+    }
+
+  return 0;
+}
+
+/* Helper for exp_uses_objfile.  */
+
+static int
+exp_uses_objfile_iter (struct objfile *exp_objfile, void *objfile_voidp)
+{
+  struct objfile *objfile = objfile_voidp;
+
+  return exp_objfile == objfile;
+}
+
+/* Return 1 if EXP uses OBJFILE (and will become dangling when OBJFILE
+   is unloaded), otherwise return 0.  */
+
+int
+exp_uses_objfile (struct expression *exp, struct objfile *objfile)
+{
+  return exp_iterate (exp, NULL, exp_uses_objfile_iter, objfile);
+}
+
+/* Helper for exp_types_mark_used.  */
+
+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);
+}
+
 void
 _initialize_parse (void)
 {
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index cbda9c3..a07e6f2 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -189,6 +189,13 @@ extern void operator_length (struct expression *, int, int *, int *);
 
 extern void operator_length_standard (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);
+
 extern char *op_name_standard (enum exp_opcode);
 
 extern struct type *follow_types (struct type *);
@@ -267,6 +274,20 @@ struct exp_descriptor
        the number of subexpressions it takes.  */
     void (*operator_length) (struct expression*, int, int*, int *);
 
+    /* Call TYPE_FUNC and OBJFILE_FUNC for any TYPE and OBJFILE found being
+       referenced by the single operator of EXP at position POS.  Operator
+       parameters are located at positive (POS + number) offsets in EXP.
+       The functions should never be called with NULL TYPE or NULL OBJFILE.
+       Functions should get passed an arbitrary caller supplied DATA pointer.
+       If any of the functions returns non-zero value then (any other) non-zero
+       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);
+
     /* Name of this operator for dumping purposes.  */
     char *(*op_name) (enum exp_opcode);
 
@@ -299,4 +320,8 @@ extern void print_subexp_standard (struct expression *, int *,
 
 extern void parser_fprintf (FILE *, const char *, ...) ATTR_FORMAT (printf, 2 ,3);
 
+extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile);
+
+extern void exp_types_mark_used (struct expression *exp);
+
 #endif /* PARSER_DEFS_H */
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index 47b74ad..22fb2fc 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -1391,6 +1391,24 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw)
   return 0;
 }
 
+/* See target_detach_watchpoints.  Do not use wrapper
+   ppc_linux_remove_watchpoint as it would modify the register cache
+   (saved_dabr_value).  */
+
+static int
+ppc_linux_detach_watchpoints (void)
+{
+  pid_t tid;
+
+  tid = TIDGET (inferior_ptid);
+  if (tid == 0)
+    tid = PIDGET (inferior_ptid);
+
+  if (ptrace (PTRACE_SET_DEBUGREG, tid, NULL, NULL) < 0)
+    return -1;
+  return 0;
+}
+
 static void
 ppc_linux_new_thread (ptid_t ptid)
 {
@@ -1648,6 +1666,7 @@ _initialize_ppc_linux_nat (void)
   t->to_region_ok_for_hw_watchpoint = ppc_linux_region_ok_for_hw_watchpoint;
   t->to_insert_watchpoint = ppc_linux_insert_watchpoint;
   t->to_remove_watchpoint = ppc_linux_remove_watchpoint;
+  t->to_detach_watchpoints = ppc_linux_detach_watchpoints;
   t->to_stopped_by_watchpoint = ppc_linux_stopped_by_watchpoint;
   t->to_stopped_data_address = ppc_linux_stopped_data_address;
   t->to_watchpoint_addr_within_range = ppc_linux_watchpoint_addr_within_range;
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 5d8b936..fb0a455 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -46,7 +46,6 @@
 #include "exceptions.h"
 #include "observer.h"
 #include "solist.h"
-#include "solib.h"
 #include "parser-defs.h"
 #include "charset.h"
 
@@ -900,6 +899,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))
     {
@@ -1396,6 +1400,22 @@ x_command (char *exp, int from_tty)
 	set_internalvar (lookup_internalvar ("__"), last_examine_value);
     }
 }
+
+/* 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);
+}
+
 
 
 /* Add an expression to the auto-display chain.
@@ -1798,50 +1818,6 @@ disable_display_command (char *args, int from_tty)
       }
 }
 
-/* Return 1 if D uses SOLIB (and will become dangling when SOLIB
-   is unloaded), otherwise return 0.  */
-
-static int
-display_uses_solib_p (const struct display *d,
-		      const struct so_list *solib)
-{
-  int endpos;
-  struct expression *const exp = d->exp;
-  const union exp_element *const elts = exp->elts;
-
-  if (d->block != NULL
-      && solib_contains_address_p (solib, d->block->startaddr))
-    return 1;
-
-  for (endpos = exp->nelts; endpos > 0; )
-    {
-      int i, args, oplen = 0;
-
-      exp->language_defn->la_exp_desc->operator_length (exp, endpos,
-							&oplen, &args);
-      gdb_assert (oplen > 0);
-
-      i = endpos - oplen;
-      if (elts[i].opcode == OP_VAR_VALUE)
-	{
-	  const struct block *const block = elts[i + 1].block;
-	  const struct symbol *const symbol = elts[i + 2].symbol;
-	  const struct obj_section *const section =
-	    SYMBOL_OBJ_SECTION (symbol);
-
-	  if (block != NULL
-	      && solib_contains_address_p (solib, block->startaddr))
-	    return 1;
-
-	  if (section && section->objfile == solib->objfile)
-	    return 1;
-	}
-      endpos -= oplen;
-    }
-
-  return 0;
-}
-
 /* display_chain items point to blocks and expressions.  Some expressions in
    turn may point to symbols.
    Both symbols and blocks are obstack_alloc'd on objfile_stack, and are
@@ -1853,18 +1829,20 @@ display_uses_solib_p (const struct display *d,
 static void
 clear_dangling_display_expressions (struct so_list *solib)
 {
+  struct objfile *objfile = solib->objfile;
   struct display *d;
-  struct objfile *objfile = NULL;
 
-  for (d = display_chain; d; d = d->next)
-    {
-      if (d->exp && display_uses_solib_p (d, solib))
-	{
-	  xfree (d->exp);
-	  d->exp = NULL;
-	  d->block = NULL;
-	}
-    }
+  if (objfile == NULL)
+    return;
+
+  for (d = display_chain; d != NULL; d = d->next)
+    if (block_objfile (d->block) == objfile
+	|| (d->exp && exp_uses_objfile (d->exp, objfile)))
+      {
+	xfree (d->exp);
+	d->exp = NULL;
+	d->block = NULL;
+      }
 }
 
 
@@ -2749,4 +2727,6 @@ Show printing of source filename and line number with <symbol>."), NULL,
 			   NULL,
 			   show_print_symbol_filename,
 			   &setprintlist, &showprintlist);
+
+  observer_attach_mark_used (print_types_mark_used);
 }
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
+# (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/>.
+
+class FrameIterator:
+    """An iterator that iterates over frames."""
+
+    def __init__ (self, frame):
+        "Initialize a FrameIterator.  FRAME is the starting frame."
+        self.frame = frame
+
+    def __iter__ (self):
+        return self
+
+    def next (self):
+        result = self.frame
+        if result is None:
+            raise StopIteration
+        self.frame = result.older ()
+        return result
diff --git a/gdb/python/lib/gdb/FrameWrapper.py b/gdb/python/lib/gdb/FrameWrapper.py
new file mode 100644
index 0000000..39f8246
--- /dev/null
+++ b/gdb/python/lib/gdb/FrameWrapper.py
@@ -0,0 +1,112 @@
+# Wrapper API for 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
+# (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/>.
+
+import gdb
+
+# FIXME: arguably all this should be on Frame somehow.
+class FrameWrapper:
+    def __init__ (self, frame):
+        self.frame = frame;
+
+    def write_symbol (self, stream, sym, block):
+        if len (sym.linkage_name):
+            nsym, is_field_of_this = gdb.lookup_symbol (sym.linkage_name, block)
+            if nsym.addr_class != gdb.SYMBOL_LOC_REGISTER:
+                sym = nsym
+
+        stream.write (sym.print_name + "=")
+        try:
+            val = self.frame.read_var (sym)
+            if val != None:
+                val = str (val)
+        # FIXME: would be nice to have a more precise exception here.
+        except RuntimeError, text:
+            val = text
+        if val == None:
+            stream.write ("???")
+        else:
+            stream.write (str (val))
+
+    def print_frame_locals (self, stream, func):
+        if not func:
+            return
+
+        first = True
+        block = func.value
+
+        for sym in block:
+            if sym.is_argument:
+                continue;
+
+            self.write_symbol (stream, sym, block)
+            stream.write ('\n')
+
+    def print_frame_args (self, stream, func):
+        if not func:
+            return
+
+        first = True
+        block = func.value
+
+        for sym in block:
+            if not sym.is_argument:
+                continue;
+
+            if not first:
+                stream.write (", ")
+
+            self.write_symbol (stream, sym, block)
+            first = False
+
+    # FIXME: this should probably just be a method on gdb.Frame.
+    # But then we need stream wrappers.
+    def describe (self, stream, full):
+        if self.frame.type () == gdb.DUMMY_FRAME:
+            stream.write (" <function called from gdb>\n")
+        elif self.frame.type () == gdb.SIGTRAMP_FRAME:
+            stream.write (" <signal handler called>\n")
+        else:
+            sal = self.frame.find_sal ()
+            pc = self.frame.pc ()
+            name = self.frame.name ()
+            if not name:
+                name = "??"
+            if pc != sal.pc or not sal.symtab:
+                stream.write (" 0x%08x in" % pc)
+            stream.write (" " + name + " (")
+
+            func = self.frame.function ()
+            self.print_frame_args (stream, func)
+
+            stream.write (")")
+
+            if sal.symtab and sal.symtab.filename:
+                stream.write (" at " + sal.symtab.filename)
+                stream.write (":" + str (sal.line))
+
+            if not self.frame.name () or (not sal.symtab or not sal.symtab.filename):
+                lib = gdb.solib_address (pc)
+                if lib:
+                    stream.write (" from " + lib)
+
+            stream.write ("\n")
+
+            if full:
+                self.print_frame_locals (stream, func)
+
+    def __getattr__ (self, name):
+        return getattr (self.frame, name)
diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py
new file mode 100644
index 0000000..b375c68
--- /dev/null
+++ b/gdb/python/lib/gdb/__init__.py
@@ -0,0 +1,19 @@
+# Startup code.
+
+# Copyright (C) 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/>.
+
+# Load the require command by default.
+import gdb.command.require
diff --git a/gdb/python/lib/gdb/backtrace.py b/gdb/python/lib/gdb/backtrace.py
new file mode 100644
index 0000000..2baab5f
--- /dev/null
+++ b/gdb/python/lib/gdb/backtrace.py
@@ -0,0 +1,42 @@
+# Filtering backtrace.
+
+# Copyright (C) 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/>.
+
+import gdb
+import itertools
+
+# Our only exports.
+__all__ = ['push_frame_filter', 'create_frame_filter']
+
+frame_filter = None
+
+def push_frame_filter (constructor):
+    """Register a new backtrace filter class with the 'backtrace' command.
+The filter will be passed an iterator as an argument.  The iterator
+will return gdb.Frame-like objects.  The filter should in turn act as
+an iterator returning such objects."""
+    global frame_filter
+    if frame_filter == None:
+        frame_filter = constructor
+    else:
+        frame_filter = lambda iterator: constructor (frame_filter (iterator))
+
+def create_frame_filter (iter):
+    global frame_filter
+    if frame_filter is None:
+        return iter
+    return frame_filter (iter)
+
diff --git a/gdb/python/lib/gdb/command/__init__.py b/gdb/python/lib/gdb/command/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/gdb/python/lib/gdb/command/__init__.py
@@ -0,0 +1 @@
+
diff --git a/gdb/python/lib/gdb/command/alias.py b/gdb/python/lib/gdb/command/alias.py
new file mode 100644
index 0000000..96b6618
--- /dev/null
+++ b/gdb/python/lib/gdb/command/alias.py
@@ -0,0 +1,59 @@
+# Alias command.
+
+# Copyright (C) 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/>.
+
+import gdb
+
+class AliasImplementation (gdb.Command):
+    def __init__ (self, name, real, doc):
+        # Have to set __doc__ before the super init call.
+        # It would be nice if gdb's help looked up __doc__ dynamically.
+        self.__doc__ = doc
+        # Note: no good way to complete :(
+        super (AliasImplementation, self).__init__ (name, gdb.COMMAND_NONE)
+        self.real = real
+
+    def invoke(self, arg, from_tty):
+        gdb.execute (self.real + ' ' + arg, from_tty)
+
+class AliasCommand (gdb.Command):
+    """Alias one command to another.
+In the simplest form, the first word is the name of the alias, and
+the remaining words are the the expansion.
+An '=' by itself can be used to define a multi-word alias; words
+before the '=' are the name of the new command."""
+
+    def __init__ (self):
+        # Completion is not quite right here.
+        super (AliasCommand, self).__init__ ("alias", gdb.COMMAND_NONE,
+                                             gdb.COMPLETE_COMMAND)
+
+    def invoke (self, arg, from_tty):
+        self.dont_repeat ()
+        # Without some form of quoting we can't alias a multi-word
+        # command to another command.
+        args = arg.split()
+        try:
+            start = args.index ('=')
+            end = start + 1
+        except ValueError:
+            start = 1
+            end = 1
+        target = " ".join(args[end:])
+        AliasImplementation (" ".join (args[0:start]), target,
+                             "This command is an alias for '%s'." % target)
+
+AliasCommand()
diff --git a/gdb/python/lib/gdb/command/backtrace.py b/gdb/python/lib/gdb/command/backtrace.py
new file mode 100644
index 0000000..ec9a527
--- /dev/null
+++ b/gdb/python/lib/gdb/command/backtrace.py
@@ -0,0 +1,106 @@
+# New backtrace command.
+
+# 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
+# (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/>.
+
+import gdb
+import gdb.backtrace
+import itertools
+from gdb.FrameIterator import FrameIterator
+from gdb.FrameWrapper import FrameWrapper
+import sys
+
+class ReverseBacktraceParameter (gdb.Parameter):
+    """The new-backtrace command can show backtraces in 'reverse' order.
+This means that the innermost frame will be printed last.
+Note that reverse backtraces are more expensive to compute."""
+
+    set_doc = "Enable or disable reverse backtraces."
+    show_doc = "Show whether backtraces will be printed in reverse order."
+
+    def __init__(self):
+        gdb.Parameter.__init__ (self, "reverse-backtrace",
+                                gdb.COMMAND_STACK, gdb.PARAM_BOOLEAN)
+        # Default to compatibility with gdb.
+        self.value = False
+
+class FilteringBacktrace (gdb.Command):
+    """Print backtrace of all stack frames, or innermost COUNT frames.
+With a negative argument, print outermost -COUNT frames.
+Use of the 'full' qualifier also prints the values of the local variables.
+Use of the 'raw' qualifier avoids any filtering by loadable modules.
+"""
+
+    def __init__ (self):
+        # FIXME: this is not working quite well enough to replace
+        # "backtrace" yet.
+        gdb.Command.__init__ (self, "new-backtrace", gdb.COMMAND_STACK)
+        self.reverse = ReverseBacktraceParameter()
+
+    def reverse_iter (self, iter):
+        result = []
+        for item in iter:
+            result.append (item)
+        result.reverse()
+        return result
+
+    def final_n (self, iter, x):
+        result = []
+        for item in iter:
+            result.append (item)
+        return result[x:]
+
+    def invoke (self, arg, from_tty):
+        i = 0
+        count = 0
+        filter = True
+        full = False
+
+        for word in arg.split (" "):
+            if word == '':
+                continue
+            elif word == 'raw':
+                filter = False
+            elif word == 'full':
+                full = True
+            else:
+                count = int (word)
+
+        # FIXME: provide option to start at selected frame
+        # However, should still number as if starting from newest
+	newest_frame = gdb.selected_thread ().newest_frame ()
+        iter = itertools.imap (FrameWrapper,
+                               FrameIterator (newest_frame))
+        if filter:
+            iter = gdb.backtrace.create_frame_filter (iter)
+
+        # Now wrap in an iterator that numbers the frames.
+        iter = itertools.izip (itertools.count (0), iter)
+
+        # Reverse if the user wanted that.
+        if self.reverse.value:
+            iter = self.reverse_iter (iter)
+
+        # Extract sub-range user wants.
+        if count < 0:
+            iter = self.final_n (iter, count)
+        elif count > 0:
+            iter = itertools.islice (iter, 0, count)
+
+        for pair in iter:
+            sys.stdout.write ("#%-2d" % pair[0])
+            pair[1].describe (sys.stdout, full)
+
+FilteringBacktrace()
diff --git a/gdb/python/lib/gdb/command/ignore_errors.py b/gdb/python/lib/gdb/command/ignore_errors.py
new file mode 100644
index 0000000..6fa48ff
--- /dev/null
+++ b/gdb/python/lib/gdb/command/ignore_errors.py
@@ -0,0 +1,37 @@
+# Ignore errors in user commands.
+
+# Copyright (C) 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/>.
+
+import gdb
+
+class IgnoreErrorsCommand (gdb.Command):
+    """Execute a single command, ignoring all errors.
+Only one-line commands are supported.
+This is primarily useful in scripts."""
+
+    def __init__ (self):
+        super (IgnoreErrorsCommand, self).__init__ ("ignore-errors",
+                                                    gdb.COMMAND_OBSCURE,
+                                                    # FIXME...
+                                                    gdb.COMPLETE_COMMAND)
+
+    def invoke (self, arg, from_tty):
+        try:
+            gdb.execute (arg, from_tty)
+        except:
+            pass
+
+IgnoreErrorsCommand ()
diff --git a/gdb/python/lib/gdb/command/pahole.py b/gdb/python/lib/gdb/command/pahole.py
new file mode 100644
index 0000000..21a0bf0
--- /dev/null
+++ b/gdb/python/lib/gdb/command/pahole.py
@@ -0,0 +1,75 @@
+# pahole command for gdb
+
+# 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
+# (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/>.
+
+import gdb
+
+class Pahole (gdb.Command):
+    """Show the holes in a structure.
+This command takes a single argument, a type name.
+It prints the type and displays comments showing where holes are."""
+
+    def __init__ (self):
+        super (Pahole, self).__init__ ("pahole", gdb.COMMAND_NONE,
+                                       gdb.COMPLETE_SYMBOL)
+
+    def pahole (self, type, level, name):
+        if name is None:
+            name = ''
+        tag = type.tag
+        if tag is None:
+            tag = ''
+        print '%sstruct %s {' % (' ' * (2 * level), tag)
+        bitpos = 0
+        for field in type.fields ():
+            # Skip static fields.
+            if not hasattr (field, ('bitpos')):
+                continue
+
+            ftype = field.type.strip_typedefs()
+
+            if bitpos != field.bitpos:
+                hole = field.bitpos - bitpos
+                print '  /* XXX %d bit hole, try to pack */' % hole
+                bitpos = field.bitpos
+            if field.bitsize > 0:
+                fieldsize = field.bitsize
+            else:
+                # TARGET_CHAR_BIT here...
+                fieldsize = 8 * ftype.sizeof
+
+            # TARGET_CHAR_BIT
+            print ' /* %3d %3d */' % (int (bitpos / 8), int (fieldsize / 8)),
+            bitpos = bitpos + fieldsize
+
+            if ftype.code == gdb.TYPE_CODE_STRUCT:
+                self.pahole (ftype, level + 1, field.name)
+            else:
+                print ' ' * (2 + 2 * level),
+                print '%s %s' % (str (ftype), field.name)
+
+        print ' ' * (14 + 2 * level),
+        print '} %s' % name
+
+    def invoke (self, arg, from_tty):
+        type = gdb.lookup_type (arg)
+        type = type.strip_typedefs ()
+        if type.code != gdb.TYPE_CODE_STRUCT:
+            raise TypeError, '%s is not a struct type' % arg
+        print ' ' * 14,
+        self.pahole (type, 0, '')
+
+Pahole()
diff --git a/gdb/python/lib/gdb/command/require.py b/gdb/python/lib/gdb/command/require.py
new file mode 100644
index 0000000..1fbc1e8
--- /dev/null
+++ b/gdb/python/lib/gdb/command/require.py
@@ -0,0 +1,57 @@
+# Demand-loading commands.
+
+# 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
+# (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/>.
+
+import gdb
+import os
+
+class RequireCommand (gdb.Command):
+    """Prefix command for requiring features."""
+
+    def __init__ (self):
+        super (RequireCommand, self).__init__ ("require",
+                                               gdb.COMMAND_SUPPORT,
+                                               gdb.COMPLETE_NONE,
+                                               True)
+
+class RequireSubcommand (gdb.Command):
+    """Demand-load a command by name."""
+
+    def __init__ (self, name):
+        self.__doc__ = "Demand-load a %s by name." % name
+        super (RequireSubcommand, self).__init__ ("require %s" % name,
+                                                  gdb.COMMAND_SUPPORT)
+        self.name = name
+
+    def invoke (self, arg, from_tty):
+        for cmd in arg.split():
+            exec ('import gdb.' + self.name + '.' + cmd, globals ())
+
+    def complete (self, text, word):
+        dir = gdb.pythondir + '/gdb/' + self.name
+        result = []
+        for file in os.listdir(dir):
+            if not file.startswith (word) or not file.endswith ('.py'):
+                continue
+            feature = file[0:-3]
+            if feature == 'require' or feature == '__init__':
+                continue
+            result.append (feature)
+        return result
+
+RequireCommand()
+RequireSubcommand("command")
+RequireSubcommand("function")
diff --git a/gdb/python/lib/gdb/command/save_breakpoints.py b/gdb/python/lib/gdb/command/save_breakpoints.py
new file mode 100644
index 0000000..6143187
--- /dev/null
+++ b/gdb/python/lib/gdb/command/save_breakpoints.py
@@ -0,0 +1,65 @@
+# Save breakpoints.
+
+# 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
+# (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/>.
+
+from __future__ import with_statement
+import gdb
+
+class SavePrefixCommand (gdb.Command):
+  "Prefix command for saving things."
+
+  def __init__ (self):
+    super (SavePrefixCommand, self).__init__ ("save",
+                                              gdb.COMMAND_SUPPORT,
+                                              gdb.COMPLETE_NONE, True)
+
+class SaveBreakpointsCommand (gdb.Command):
+    """Save the current breakpoints to a file.
+This command takes a single argument, a file name.
+The breakpoints can be restored using the 'source' command."""
+
+    def __init__ (self):
+        super (SaveBreakpointsCommand, self).__init__ ("save breakpoints",
+                                                       gdb.COMMAND_SUPPORT,
+                                                       gdb.COMPLETE_FILENAME)
+
+    def invoke (self, arg, from_tty):
+        self.dont_repeat ()
+        bps = gdb.breakpoints ()
+        if bps is None:
+            raise RuntimeError, 'No breakpoints to save'
+        with open (arg.strip (), 'w') as f:
+            for bp in bps:
+                print >> f, "break", bp.location,
+                if bp.thread is not None:
+                    print >> f, " thread", bp.thread,
+                if bp.condition is not None:
+                    print >> f, " if", bp.condition,
+                print >> f
+                if not bp.enabled:
+                    print >> f, "disable $bpnum"
+                # Note: we don't save the ignore count; there doesn't
+                # seem to be much point.
+                commands = bp.commands
+                if commands is not None:
+                    print >> f, "commands"
+                    # Note that COMMANDS has a trailing newline.
+                    print >> f, commands,
+                    print >> f, "end"
+                print >> f
+
+SavePrefixCommand ()
+SaveBreakpointsCommand ()
diff --git a/gdb/python/lib/gdb/command/upto.py b/gdb/python/lib/gdb/command/upto.py
new file mode 100644
index 0000000..faf54ed
--- /dev/null
+++ b/gdb/python/lib/gdb/command/upto.py
@@ -0,0 +1,129 @@
+# upto command.
+
+# Copyright (C) 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/>.
+
+import gdb
+import re
+from gdb.FrameIterator import FrameIterator
+from gdb.FrameWrapper import FrameWrapper
+
+class UptoPrefix (gdb.Command):
+    def __init__ (self):
+        super (UptoPrefix, self).__init__ ("upto", gdb.COMMAND_STACK,
+                                           prefix = True)
+
+class UptoImplementation (gdb.Command):
+    def __init__ (self, subcommand):
+        super (UptoImplementation, self).__init__ ("upto " + subcommand,
+                                                   gdb.COMMAND_STACK)
+
+    def search (self):
+        saved = gdb.selected_frame ()
+        iter = FrameIterator (saved)
+        found = False
+        try:
+            for frame in iter:
+                frame.select ()
+                try:
+                    if self.filter (frame):
+                        wrapper = FrameWrapper (frame)
+                        wrapper.describe (sys.stdout, False)
+                        return
+                except:
+                    pass
+        except:
+            pass
+        saved.select ()
+        raise RuntimeError, 'Could not find a matching frame'
+
+    def invoke (self, arg, from_tty):
+        self.rx = re.compile (arg)
+        self.search ()
+
+class UptoSymbolCommand (UptoImplementation):
+    """Select and print some calling stack frame, based on symbol.
+The argument is a regular expression.  This command moves up the
+stack, stopping at the first frame whose symbol matches the regular
+expression."""
+
+    def __init__ (self):
+        super (UptoSymbolCommand, self).__init__ ("symbol")
+
+    def filter (self, frame):
+        name = frame.name ()
+        if name is not None:
+            if self.rx.search (name) is not None:
+                return True
+        return False
+
+class UptoSourceCommand (UptoImplementation):
+    """Select and print some calling stack frame, based on source file.
+The argument is a regular expression.  This command moves up the
+stack, stopping at the first frame whose source file name matches the
+regular expression."""
+
+    def __init__ (self):
+        super (UptoSourceCommand, self).__init__ ("source")
+
+    def filter (self, frame):
+        name = frame.find_sal ().symtab.filename
+        if name is not None:
+            if self.rx.search (name) is not None:
+                return True
+        return False
+
+class UptoObjectCommand (UptoImplementation):
+    """Select and print some calling stack frame, based on object file.
+The argument is a regular expression.  This command moves up the
+stack, stopping at the first frame whose object file name matches the
+regular expression."""
+
+    def __init__ (self):
+        super (UptoObjectCommand, self).__init__ ("object")
+
+    def filter (self, frame):
+        name = frame.find_sal ().symtab.objfile.filename
+        if name is not None:
+            if self.rx.search (name) is not None:
+                return True
+        return False
+
+class UptoWhereCommand (UptoImplementation):
+    """Select and print some calling stack frame, based on expression.
+The argument is an expression.  This command moves up the stack,
+parsing and evaluating the expression in each frame.  This stops when
+the expression evaluates to a non-zero (true) value."""
+
+    def __init__ (self):
+        super (UptoWhereCommand, self).__init__ ("where")
+
+    def filter (self, frame):
+        try:
+            if gdb.parse_and_eval (self.expression):
+                return True
+        except:
+            pass
+        return False
+
+    def invoke (self, arg, from_tty):
+        self.expression = arg
+        self.search ()
+
+UptoPrefix ()
+UptoSymbolCommand ()
+UptoSourceCommand ()
+UptoObjectCommand ()
+UptoWhereCommand ()
diff --git a/gdb/python/lib/gdb/function/__init__.py b/gdb/python/lib/gdb/function/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/gdb/python/lib/gdb/function/__init__.py
@@ -0,0 +1 @@
+
diff --git a/gdb/python/lib/gdb/function/caller_is.py b/gdb/python/lib/gdb/function/caller_is.py
new file mode 100644
index 0000000..2b9c5c7
--- /dev/null
+++ b/gdb/python/lib/gdb/function/caller_is.py
@@ -0,0 +1,58 @@
+# Caller-is functions.
+
+# Copyright (C) 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/>.
+
+import gdb
+import re
+
+class CallerIs (gdb.Function):
+    """Return True if the calling function's name is equal to a string.
+This function takes one or two arguments.
+The first argument is the name of a function; if the calling function's
+name is equal to this argument, this function returns True.
+The optional second argument tells this function how many stack frames
+to traverse to find the calling function.  The default is 1."""
+
+    def __init__ (self):
+        super (CallerIs, self).__init__ ("caller_is")
+
+    def invoke (self, name, nframes = 1):
+        frame = gdb.selected_frame ()
+        while nframes > 0:
+            frame = frame.older ()
+            nframes = nframes - 1
+        return frame.name () == name.string ()
+
+class CallerMatches (gdb.Function):
+    """Return True if the calling function's name matches a string.
+This function takes one or two arguments.
+The first argument is a regular expression; if the calling function's
+name is matched by this argument, this function returns True.
+The optional second argument tells this function how many stack frames
+to traverse to find the calling function.  The default is 1."""
+
+    def __init__ (self):
+        super (CallerMatches, self).__init__ ("caller_matches")
+
+    def invoke (self, name, nframes = 1):
+        frame = gdb.selected_frame ()
+        while nframes > 0:
+            frame = frame.older ()
+            nframes = nframes - 1
+        return re.match (name.string (), frame.name ()) is not None
+
+CallerIs()
+CallerMatches()
diff --git a/gdb/python/lib/gdb/function/in_scope.py b/gdb/python/lib/gdb/function/in_scope.py
new file mode 100644
index 0000000..debb3bb
--- /dev/null
+++ b/gdb/python/lib/gdb/function/in_scope.py
@@ -0,0 +1,47 @@
+# In-scope function.
+
+# Copyright (C) 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/>.
+
+import gdb
+
+class InScope (gdb.Function):
+    """Return True if all the given variables or macros are in scope.
+Takes one argument for each variable name to be checked."""
+
+    def __init__ (self):
+	super (InScope, self).__init__ ("in_scope")
+
+    def invoke (self, *vars):
+        if len (vars) == 0:
+	    raise TypeError, "in_scope takes at least one argument"
+
+        # gdb.Value isn't hashable so it can't be put in a map.
+	# Convert to string first.
+	wanted = set (map (lambda x: x.string (), vars))
+	found = set ()
+	block = gdb.selected_frame ().block ()
+	while block:
+	    for sym in block:
+		if (sym.is_argument or sym.is_constant
+		      or sym.is_function or sym.is_variable):
+		    if sym.name in wanted:
+			found.add (sym.name)
+
+	    block = block.superblock
+
+	return wanted == found
+
+InScope ()
diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c
new file mode 100644
index 0000000..8019e9d
--- /dev/null
+++ b/gdb/python/py-block.c
@@ -0,0 +1,265 @@
+/* Python interface to blocks.
+
+   Copyright (C) 2008 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 "block.h"
+#include "dictionary.h"
+#include "symtab.h"
+#include "python-internal.h"
+
+typedef struct {
+  PyObject_HEAD
+  struct block *block;
+} block_object;
+
+typedef struct {
+  PyObject_HEAD
+  struct dictionary *dict;
+  struct dict_iterator iter;
+  int initialized_p;
+} block_syms_iterator_object;
+
+static PyTypeObject block_syms_iterator_object_type;
+
+static PyObject *
+blpy_iter (PyObject *self)
+{
+  block_syms_iterator_object *block_iter_obj;
+
+  block_iter_obj = PyObject_New (block_syms_iterator_object,
+			    &block_syms_iterator_object_type);
+  if (block_iter_obj == NULL)
+    {
+      PyErr_SetString (PyExc_MemoryError,
+		       "Could not allocate iterator object.");
+      return NULL;
+    }
+
+  block_iter_obj->dict = BLOCK_DICT (((block_object *) self)->block);
+  block_iter_obj->initialized_p = 0;
+
+  return (PyObject *) block_iter_obj;
+}
+
+static PyObject *
+blpy_get_start (PyObject *self, void *closure)
+{
+  block_object *self_block = (block_object *) self;
+
+  return PyLong_FromUnsignedLongLong (BLOCK_START (self_block->block));
+}
+
+static PyObject *
+blpy_get_end (PyObject *self, void *closure)
+{
+  block_object *self_block = (block_object *) self;
+
+  return PyLong_FromUnsignedLongLong (BLOCK_END (self_block->block));
+}
+
+static PyObject *
+blpy_get_function (PyObject *self, void *closure)
+{
+  block_object *self_block = (block_object *) self;
+  struct symbol *sym;
+
+  sym = BLOCK_FUNCTION (self_block->block);
+  if (sym)
+    return symbol_to_symbol_object (sym);
+
+  Py_RETURN_NONE;
+}
+
+static PyObject *
+blpy_get_superblock (PyObject *self, void *closure)
+{
+  block_object *self_block = (block_object *) self;
+  struct block *block;
+
+  block = BLOCK_SUPERBLOCK (self_block->block);
+  if (block)
+    return block_to_block_object (block);
+
+  Py_RETURN_NONE;
+}
+
+PyObject *
+block_to_block_object (struct block *block)
+{
+  block_object *block_obj;
+
+  block_obj = PyObject_New (block_object, &block_object_type);
+  if (block_obj == NULL)
+    {
+      PyErr_SetString (PyExc_MemoryError, "Could not allocate block object.");
+      return NULL;
+    }
+
+  block_obj->block = block;
+
+  return (PyObject *) block_obj;
+}
+
+struct block *
+block_object_to_block (PyObject *obj)
+{
+  if (! PyObject_TypeCheck (obj, &block_object_type))
+    return NULL;
+  return ((block_object *) obj)->block;
+}
+
+static PyObject *
+blpy_block_syms_iter (PyObject *self)
+{
+  return self;
+}
+
+static PyObject *
+blpy_block_syms_iternext (PyObject *self)
+{
+  block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) self;
+  struct symbol *sym;
+
+  if (!iter_obj->initialized_p)
+    {
+      sym = dict_iterator_first (iter_obj->dict,  &(iter_obj->iter));
+      iter_obj->initialized_p = 1;
+    }
+  else
+    sym = dict_iterator_next (&(iter_obj->iter));
+
+  return (sym == NULL)? NULL : symbol_to_symbol_object (sym);
+}
+
+/* Return the innermost lexical block containing the specified pc value,
+   or 0 if there is none.  */
+
+PyObject *
+gdbpy_block_for_pc (PyObject *self, PyObject *args)
+{
+  unsigned PY_LONG_LONG pc;
+  struct block *block;
+  PyObject *sym_obj;
+
+  if (!PyArg_ParseTuple (args, "K", &pc))
+    return NULL;
+
+  block = block_for_pc (pc);
+  if (block)
+    return block_to_block_object (block);
+
+  Py_RETURN_NONE;
+}
+
+void
+gdbpy_initialize_blocks (void)
+{
+  block_object_type.tp_new = PyType_GenericNew;
+  if (PyType_Ready (&block_object_type) < 0)
+    return;
+
+  block_syms_iterator_object_type.tp_new = PyType_GenericNew;
+  if (PyType_Ready (&block_syms_iterator_object_type) < 0)
+    return;
+
+  Py_INCREF (&block_object_type);
+  PyModule_AddObject (gdb_module, "Block", (PyObject *) &block_object_type);
+
+  Py_INCREF (&block_syms_iterator_object_type);
+  PyModule_AddObject (gdb_module, "BlockIterator",
+		      (PyObject *) &block_syms_iterator_object_type);
+}
+
+
+
+static PyGetSetDef block_object_getset[] = {
+  { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
+  { "end", blpy_get_end, NULL, "End address of the block.", NULL },
+  { "function", blpy_get_function, NULL,
+    "Symbol that names the block, or None.", NULL },
+  { "superblock", blpy_get_superblock, NULL,
+    "Block containing the block, or None.", NULL },
+  { NULL }  /* Sentinel */
+};
+
+PyTypeObject block_object_type = {
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Block",			  /*tp_name*/
+  sizeof (block_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  0,				  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  0,				  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
+  "GDB block object",		  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  blpy_iter,			  /* tp_iter */
+  0,				  /* tp_iternext */
+  0,				  /* tp_methods */
+  0,				  /* tp_members */
+  block_object_getset		  /* tp_getset */
+};
+
+static PyTypeObject block_syms_iterator_object_type = {
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.BlockIterator",		  /*tp_name*/
+  sizeof (block_syms_iterator_object),	      /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  0,				  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  0,				  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
+  "GDB block syms iterator object",	      /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  blpy_block_syms_iter,		  /* tp_iter */
+  blpy_block_syms_iternext,	  /* tp_iternext */
+  0				  /* tp_methods */
+};
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
new file mode 100644
index 0000000..afa9526
--- /dev/null
+++ b/gdb/python/py-breakpoint.c
@@ -0,0 +1,665 @@
+/* Python interface to breakpoints
+
+   Copyright (C) 2008, 2009 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 "value.h"
+#include "exceptions.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "breakpoint.h"
+#include "gdbcmd.h"
+#include "gdbthread.h"
+#include "observer.h"
+
+
+/* From breakpoint.c.  */
+extern struct breakpoint *breakpoint_chain;
+
+
+typedef struct breakpoint_object breakpoint_object;
+
+static PyTypeObject breakpoint_object_type;
+
+/* A dynamically allocated vector of breakpoint objects.  Each
+   breakpoint has a number.  A breakpoint is valid if its slot in this
+   vector is non-null.  When a breakpoint is deleted, we drop our
+   reference to it and zero its slot; this is how we let the Python
+   object have a lifetime which is independent from that of the gdb
+   breakpoint.  */
+static breakpoint_object **bppy_breakpoints;
+
+/* Number of slots in bppy_breakpoints.  */
+static int bppy_slots;
+
+/* Number of live breakpoints.  */
+static int bppy_live;
+
+/* Variables used to pass information between the Breakpoint
+   constructor and the breakpoint-created hook function.  */
+static breakpoint_object *bppy_pending_object;
+
+struct breakpoint_object
+{
+  PyObject_HEAD
+
+  /* The breakpoint number according to gdb.  */
+  int number;
+
+  /* The gdb breakpoint object, or NULL if the breakpoint has been
+     deleted.  */
+  struct breakpoint *bp;
+};
+
+/* Evaluate to true if the breakpoint NUM is valid, false otherwise.  */
+#define BPPY_VALID_P(Num)			\
+    ((Num) >= 0					\
+     && (Num) < bppy_slots			\
+     && bppy_breakpoints[Num] != NULL)
+
+/* Require that BREAKPOINT be a valid breakpoint ID; throw a Python
+   exception if it is invalid.  */
+#define BPPY_REQUIRE_VALID(Breakpoint)					\
+    do {								\
+      if (! BPPY_VALID_P ((Breakpoint)->number))			\
+	return PyErr_Format (PyExc_RuntimeError, "breakpoint %d is invalid", \
+			     (Breakpoint)->number);			\
+    } while (0)
+
+/* Require that BREAKPOINT be a valid breakpoint ID; throw a Python
+   exception if it is invalid.  This macro is for use in setter functions.  */
+#define BPPY_SET_REQUIRE_VALID(Breakpoint)				\
+    do {								\
+      if (! BPPY_VALID_P ((Breakpoint)->number))			\
+        {								\
+	  PyErr_Format (PyExc_RuntimeError, "breakpoint %d is invalid", \
+			(Breakpoint)->number);				\
+	  return -1;							\
+	}								\
+    } while (0)
+
+/* Python function which checks the validity of a breakpoint object.  */
+static PyObject *
+bppy_is_valid (PyObject *self, PyObject *args)
+{
+  if (((breakpoint_object *) self)->bp)
+    Py_RETURN_TRUE;
+  Py_RETURN_FALSE;
+}
+
+/* Python function to test whether or not the breakpoint is enabled.  */
+static PyObject *
+bppy_get_enabled (PyObject *self, void *closure)
+{
+  if (! ((breakpoint_object *) self)->bp)
+    Py_RETURN_FALSE;
+  /* Not clear what we really want here.  */
+  if (((breakpoint_object *) self)->bp->enable_state == bp_enabled)
+    Py_RETURN_TRUE;
+  Py_RETURN_FALSE;
+}
+
+/* Python function to test whether or not the breakpoint is silent.  */
+static PyObject *
+bppy_get_silent (PyObject *self, void *closure)
+{
+  BPPY_REQUIRE_VALID ((breakpoint_object *) self);
+  if (((breakpoint_object *) self)->bp->silent)
+    Py_RETURN_TRUE;
+  Py_RETURN_FALSE;
+}
+
+/* Python function to set the enabled state of a breakpoint.  */
+static int
+bppy_set_enabled (PyObject *self, PyObject *newvalue, void *closure)
+{
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+  int cmp;
+
+  BPPY_SET_REQUIRE_VALID (self_bp);
+
+  if (newvalue == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError, "cannot delete `enabled' attribute");
+      return -1;
+    }
+  else if (! PyBool_Check (newvalue))
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "the value of `enabled' must be a boolean");
+      return -1;
+    }
+
+  cmp = PyObject_IsTrue (newvalue);
+  if (cmp < 0)
+    return -1;
+  else if (cmp == 1)
+    enable_breakpoint (self_bp->bp);
+  else 
+    disable_breakpoint (self_bp->bp);
+  return 0;
+}
+
+/* Python function to set the 'silent' state of a breakpoint.  */
+static int
+bppy_set_silent (PyObject *self, PyObject *newvalue, void *closure)
+{
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+  int cmp;
+
+  BPPY_SET_REQUIRE_VALID (self_bp);
+
+  if (newvalue == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError, "cannot delete `silent' attribute");
+      return -1;
+    }
+  else if (! PyBool_Check (newvalue))
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "the value of `silent' must be a boolean");
+      return -1;
+    }
+
+  cmp = PyObject_IsTrue (newvalue);
+  if (cmp < 0)
+    return -1;
+  else
+    self_bp->bp->silent = cmp;
+
+  return 0;
+}
+
+/* Python function to set the thread of a breakpoint.  */
+static int
+bppy_set_thread (PyObject *self, PyObject *newvalue, void *closure)
+{
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+  int id;
+
+  BPPY_SET_REQUIRE_VALID (self_bp);
+
+  if (newvalue == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError, "cannot delete `thread' attribute");
+      return -1;
+    }
+  else if (PyInt_Check (newvalue))
+    {
+      id = (int) PyInt_AsLong (newvalue);
+      if (! valid_thread_id (id))
+	{
+	  PyErr_SetString (PyExc_RuntimeError, "invalid thread id");
+	  return -1;
+	}
+    }
+  else if (newvalue == Py_None)
+    id = -1;
+  else
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "the value of `thread' must be an integer or None");
+      return -1;
+    }
+
+  self_bp->bp->thread = id;
+
+  return 0;
+}
+
+/* Python function to set the ignore count of a breakpoint.  */
+static int
+bppy_set_ignore_count (PyObject *self, PyObject *newvalue, void *closure)
+{
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+  long value;
+
+  BPPY_SET_REQUIRE_VALID (self_bp);
+
+  if (newvalue == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "cannot delete `ignore_count' attribute");
+      return -1;
+    }
+  else if (! PyInt_Check (newvalue))
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "the value of `ignore_count' must be an integer");
+      return -1;
+    }
+
+  value = PyInt_AsLong (newvalue);
+  if (value < 0)
+    value = 0;
+  set_ignore_count (self_bp->number, (int) value, 0);
+
+  return 0;
+}
+
+/* Python function to set the hit count of a breakpoint.  */
+static int
+bppy_set_hit_count (PyObject *self, PyObject *newvalue, void *closure)
+{
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+
+  BPPY_SET_REQUIRE_VALID (self_bp);
+
+  if (newvalue == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError, "cannot delete `hit_count' attribute");
+      return -1;
+    }
+  else if (! PyInt_Check (newvalue) || PyInt_AsLong (newvalue) != 0)
+    {
+      PyErr_SetString (PyExc_AttributeError,
+		       "the value of `hit_count' must be zero");
+      return -1;
+    }
+
+  self_bp->bp->hit_count = 0;
+
+  return 0;
+}
+
+/* Python function to get the location of a breakpoint.  */
+static PyObject *
+bppy_get_location (PyObject *self, void *closure)
+{
+  char *str;
+
+  BPPY_REQUIRE_VALID ((breakpoint_object *) self);
+  str = ((breakpoint_object *) self)->bp->addr_string;
+  /* FIXME: watchpoints?  tracepoints?  */
+  if (! str)
+    str = "";
+  return PyString_Decode (str, strlen (str), host_charset (), NULL);
+}
+
+/* Python function to get the condition expression of a breakpoint.  */
+static PyObject *
+bppy_get_condition (PyObject *self, void *closure)
+{
+  char *str;
+  BPPY_REQUIRE_VALID ((breakpoint_object *) self);
+
+  str = ((breakpoint_object *) self)->bp->cond_string;
+  if (! str)
+    Py_RETURN_NONE;
+  return PyString_Decode (str, strlen (str), host_charset (), NULL);
+}
+
+static int
+bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure)
+{
+  char *exp;
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+  volatile struct gdb_exception except;
+
+  BPPY_SET_REQUIRE_VALID (self_bp);
+
+  if (newvalue == NULL)
+    {
+      PyErr_SetString (PyExc_TypeError, "cannot delete `condition' attribute");
+      return -1;
+    }
+  else if (newvalue == Py_None)
+    exp = "";
+  else
+    {
+      exp = python_string_to_host_string (newvalue);
+      if (exp == NULL)
+	return -1;
+    }
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      set_breakpoint_condition (self_bp->bp, exp, 0);
+    }
+  GDB_PY_SET_HANDLE_EXCEPTION (except);
+
+  return 0;
+}
+
+/* Python function to get the commands attached to a breakpoint.  */
+static PyObject *
+bppy_get_commands (PyObject *self, void *closure)
+{
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+  long length;
+  volatile struct gdb_exception except;
+  struct ui_file *string_file;
+  struct cleanup *chain;
+  PyObject *result;
+  char *cmdstr;
+
+  BPPY_REQUIRE_VALID (self_bp);
+
+  if (! self_bp->bp->commands)
+    Py_RETURN_NONE;
+
+  string_file = mem_fileopen ();
+  chain = make_cleanup_ui_file_delete (string_file);
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      /* FIXME: this can fail.  Maybe we need to be making a new
+	 ui_out object here?  */
+      ui_out_redirect (uiout, string_file);
+      print_command_lines (uiout, self_bp->bp->commands, 0);
+      ui_out_redirect (uiout, NULL);
+    }
+  cmdstr = ui_file_xstrdup (string_file, &length);
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  result = PyString_Decode (cmdstr, strlen (cmdstr), host_charset (), NULL);
+  do_cleanups (chain);
+  xfree (cmdstr);
+  return result;
+}
+
+/* Python function to get the breakpoint's number.  */
+static PyObject *
+bppy_get_number (PyObject *self, void *closure)
+{
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+
+  BPPY_REQUIRE_VALID (self_bp);
+
+  return PyInt_FromLong (self_bp->number);
+}
+
+/* Python function to get the breakpoint's thread ID.  */
+static PyObject *
+bppy_get_thread (PyObject *self, void *closure)
+{
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+
+  BPPY_REQUIRE_VALID (self_bp);
+
+  if (self_bp->bp->thread == -1)
+    Py_RETURN_NONE;
+
+  return PyInt_FromLong (self_bp->bp->thread);
+}
+
+/* Python function to get the breakpoint's hit count.  */
+static PyObject *
+bppy_get_hit_count (PyObject *self, void *closure)
+{
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+
+  BPPY_REQUIRE_VALID (self_bp);
+
+  return PyInt_FromLong (self_bp->bp->hit_count);
+}
+
+/* Python function to get the breakpoint's ignore count.  */
+static PyObject *
+bppy_get_ignore_count (PyObject *self, void *closure)
+{
+  breakpoint_object *self_bp = (breakpoint_object *) self;
+
+  BPPY_REQUIRE_VALID (self_bp);
+
+  return PyInt_FromLong (self_bp->bp->ignore_count);
+}
+
+/* Python function to create a new breakpoint.  */
+static PyObject *
+bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
+{
+  PyObject *result;
+  char *spec;
+  volatile struct gdb_exception except;
+
+  /* FIXME: allow condition, thread, temporary, ... ? */
+  if (! PyArg_ParseTuple (args, "s", &spec))
+    return NULL;
+  result = subtype->tp_alloc (subtype, 0);
+  if (! result)
+    return NULL;
+  bppy_pending_object = (breakpoint_object *) result;
+  bppy_pending_object->number = -1;
+  bppy_pending_object->bp = NULL;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      set_breakpoint (python_gdbarch, spec, NULL, 0, 0, -1, 0,
+		      AUTO_BOOLEAN_TRUE, 1);
+    }
+  if (except.reason < 0)
+    {
+      subtype->tp_free (result);
+      return PyErr_Format (except.reason == RETURN_QUIT
+			     ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
+			     "%s", except.message);
+    }
+
+  BPPY_REQUIRE_VALID ((breakpoint_object *) result);
+  return result;
+}
+
+
+
+/* Static function to return a tuple holding all breakpoints.  */
+
+PyObject *
+gdbpy_breakpoints (PyObject *self, PyObject *args)
+{
+  PyObject *result;
+
+  if (bppy_live == 0)
+    Py_RETURN_NONE;
+
+  result = PyTuple_New (bppy_live);
+  if (result)
+    {
+      int i, out = 0;
+      for (i = 0; out < bppy_live; ++i)
+	{
+	  if (! bppy_breakpoints[i])
+	    continue;
+	  Py_INCREF (bppy_breakpoints[i]);
+	  PyTuple_SetItem (result, out, (PyObject *) bppy_breakpoints[i]);
+	  ++out;
+	}
+    }
+  return result;
+}
+
+
+
+/* Event callback functions.  */
+
+/* Callback that is used when a breakpoint is created.  This function
+   will create a new Python breakpoint object.  */
+static void
+gdbpy_breakpoint_created (int num)
+{
+  breakpoint_object *newbp;
+  struct breakpoint *bp;
+  PyGILState_STATE state;
+
+  if (num < 0)
+    return;
+
+  for (bp = breakpoint_chain; bp; bp = bp->next)
+    if (bp->number == num)
+      break;
+  if (! bp)
+    return;
+
+  if (num >= bppy_slots)
+    {
+      int old = bppy_slots;
+      bppy_slots = bppy_slots * 2 + 10;
+      bppy_breakpoints
+	= (breakpoint_object **) xrealloc (bppy_breakpoints,
+					   (bppy_slots
+					    * sizeof (breakpoint_object *)));
+      memset (&bppy_breakpoints[old], 0,
+	      (bppy_slots - old) * sizeof (PyObject *));
+    }
+
+  ++bppy_live;
+
+  state = PyGILState_Ensure ();
+
+  if (bppy_pending_object)
+    {
+      newbp = bppy_pending_object;
+      bppy_pending_object = NULL;
+    }
+  else
+    newbp = PyObject_New (breakpoint_object, &breakpoint_object_type);
+  if (newbp)
+    {
+      PyObject *hookfn;
+
+      newbp->number = num;
+      newbp->bp = bp;
+      bppy_breakpoints[num] = newbp;
+
+      hookfn = gdbpy_get_hook_function ("new_breakpoint");
+      if (hookfn)
+	{
+	  PyObject *result;
+	  result = PyObject_CallFunctionObjArgs (hookfn, newbp, NULL);
+	  if (result)
+	    {
+	      Py_DECREF (result);
+	    }
+	  Py_DECREF (hookfn);
+	}
+    }
+
+  /* Just ignore errors here.  */
+  PyErr_Clear ();
+
+  PyGILState_Release (state);
+}
+
+/* Callback that is used when a breakpoint is deleted.  This will
+   invalidate the corresponding Python object.  */
+static void
+gdbpy_breakpoint_deleted (int num)
+{
+  PyGILState_STATE state;
+
+  state = PyGILState_Ensure ();
+  if (BPPY_VALID_P (num))
+    {
+      bppy_breakpoints[num]->bp = NULL;
+      Py_DECREF (bppy_breakpoints[num]);
+      bppy_breakpoints[num] = NULL;
+      --bppy_live;
+    }
+  PyGILState_Release (state);
+}
+
+
+
+/* Initialize the Python breakpoint code.  */
+void
+gdbpy_initialize_breakpoints (void)
+{
+  breakpoint_object_type.tp_new = bppy_new;
+  if (PyType_Ready (&breakpoint_object_type) < 0)
+    return;
+
+  Py_INCREF (&breakpoint_object_type);
+  PyModule_AddObject (gdb_module, "Breakpoint",
+		      (PyObject *) &breakpoint_object_type);
+
+  observer_attach_breakpoint_created (gdbpy_breakpoint_created);
+  observer_attach_breakpoint_deleted (gdbpy_breakpoint_deleted);
+}
+
+
+
+static PyGetSetDef breakpoint_object_getset[] = {
+  { "enabled", bppy_get_enabled, bppy_set_enabled,
+    "Boolean telling whether the breakpoint is enabled.", NULL },
+  { "silent", bppy_get_silent, bppy_set_silent,
+    "Boolean telling whether the breakpoint is silent.", NULL },
+  { "thread", bppy_get_thread, bppy_set_thread,
+    "Thread ID for the breakpoint.\n\
+If the value is a thread ID (integer), then this is a thread-specific breakpoint.\n\
+If the value is None, then this breakpoint not thread-specific.\n\
+No other type of value can be used.", NULL },
+  { "ignore_count", bppy_get_ignore_count, bppy_set_ignore_count,
+    "Number of times this breakpoint should be automatically continued.",
+    NULL },
+  { "number", bppy_get_number, NULL,
+    "Breakpoint's number assigned by GDB.", NULL },
+  { "hit_count", bppy_get_hit_count, bppy_set_hit_count,
+    "Number of times the breakpoint has been hit.\n\
+Can be set to zero to clear the count. No other value is valid\n\
+when setting this property.", NULL },
+  { "location", bppy_get_location, NULL,
+    "Location of the breakpoint, as specified by the user.", NULL},
+  { "condition", bppy_get_condition, bppy_set_condition,
+    "Condition of the breakpoint, as specified by the user,\
+or None if no condition set."},
+  { "commands", bppy_get_commands, NULL,
+    "Commands of the breakpoint, as specified by the user."},
+  { NULL }  /* Sentinel.  */
+};
+
+static PyMethodDef breakpoint_object_methods[] =
+{
+  { "is_valid", bppy_is_valid, METH_NOARGS,
+    "Return true if this breakpoint is valid, false if not." },
+  { NULL } /* Sentinel.  */
+};
+
+static PyTypeObject breakpoint_object_type =
+{
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Breakpoint",		  /*tp_name*/
+  sizeof (breakpoint_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  0,				  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  0,				  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB breakpoint object",	  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  breakpoint_object_methods,	  /* tp_methods */
+  0,				  /* tp_members */
+  breakpoint_object_getset	  /* tp_getset */
+};
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index 528aca6..04b3fd1 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -49,8 +49,7 @@ static struct cmdpy_completer completers[] =
 
 #define N_COMPLETERS (sizeof (completers) / sizeof (completers[0]))
 
-/* A gdb command.  For the time being only ordinary commands (not
-   set/show commands) are allowed.  */
+/* A gdb command.  */
 struct cmdpy_object
 {
   PyObject_HEAD
@@ -70,7 +69,6 @@ typedef struct cmdpy_object cmdpy_object;
 
 static PyTypeObject cmdpy_object_type;
 
-
 /* Constants used by this module.  */
 static PyObject *invoke_cst;
 static PyObject *complete_cst;
@@ -263,10 +261,13 @@ cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
    *BASE_LIST is set to the final prefix command's list of
    *sub-commands.
    
+   START_LIST is the list in which the search starts.
+   
    This function returns the xmalloc()d name of the new command.  On
    error sets the Python error and returns NULL.  */
-static char *
-parse_command_name (char *text, struct cmd_list_element ***base_list)
+char *
+gdbpy_parse_command_name (char *text, struct cmd_list_element ***base_list,
+			  struct cmd_list_element **start_list)
 {
   struct cmd_list_element *elt;
   int len = strlen (text);
@@ -299,7 +300,7 @@ parse_command_name (char *text, struct cmd_list_element ***base_list)
     ;
   if (i < 0)
     {
-      *base_list = &cmdlist;
+      *base_list = start_list;
       return result;
     }
 
@@ -308,7 +309,7 @@ parse_command_name (char *text, struct cmd_list_element ***base_list)
   prefix_text[i + 1] = '\0';
 
   text = prefix_text;
-  elt = lookup_cmd_1 (&text, cmdlist, NULL, 1);
+  elt = lookup_cmd_1 (&text, *start_list, NULL, 1);
   if (!elt || elt == (struct cmd_list_element *) -1)
     {
       PyErr_Format (PyExc_RuntimeError, _("could not find command prefix %s"),
@@ -399,7 +400,7 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
       return -1;
     }
 
-  cmd_name = parse_command_name (name, &cmd_list);
+  cmd_name = gdbpy_parse_command_name (name, &cmd_list, &cmdlist);
   if (! cmd_name)
     return -1;
 
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index 279415c..5d8ce0a 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -202,10 +202,59 @@ frapy_pc (PyObject *self, PyObject *args)
   return PyLong_FromUnsignedLongLong (pc);
 }
 
+/* Implementation of gdb.Frame.block (self) -> gdb.Block.
+   Returns the frame's code block.  */
+
+static PyObject *
+frapy_block (PyObject *self, PyObject *args)
+{
+  struct frame_info *frame;
+  struct block *block = NULL;
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
+
+      block = block_for_pc (get_frame_address_in_block (frame));
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  if (block)
+    return block_to_block_object (block);
+
+  Py_RETURN_NONE;
+}
+
+
+/* Implementation of gdb.Frame.function (self) -> gdb.Symbol.
+   Returns the symbol for the function corresponding to this frame.  */
+
+static PyObject *
+frapy_function (PyObject *self, PyObject *args)
+{
+  struct symbol *sym = NULL;
+  struct frame_info *frame;
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
+
+      sym = find_pc_function (get_frame_address_in_block (frame));
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  if (sym)
+    return symbol_to_symbol_object (sym);
+
+  Py_RETURN_NONE;
+}
+
 /* Convert a frame_info struct to a Python Frame object.
    Sets a Python exception and returns NULL on error.  */
 
-static frame_object *
+PyObject *
 frame_info_to_frame_object (struct frame_info *frame)
 {
   frame_object *frame_obj;
@@ -235,7 +284,7 @@ frame_info_to_frame_object (struct frame_info *frame)
 
   frame_obj->gdbarch = get_frame_arch (frame);
 
-  return frame_obj;
+  return (PyObject *) frame_obj;
 }
 
 /* Implementation of gdb.Frame.older (self) -> gdb.Frame.
@@ -296,7 +345,30 @@ frapy_newer (PyObject *self, PyObject *args)
   return next_obj;
 }
 
-/* Implementation of gdb.Frame.read_var_value (self, variable) -> gdb.Value.
+/* Implementation of gdb.Frame.find_sal (self) -> gdb.Symtab_and_line.
+   Returns the frame's symtab and line.  */
+
+static PyObject *
+frapy_find_sal (PyObject *self, PyObject *args)
+{
+  struct frame_info *frame;
+  struct symtab_and_line sal;
+  volatile struct gdb_exception except;
+  PyObject *sal_obj = NULL;   /* Initialize to appease gcc warning.  */
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
+
+      find_frame_sal (frame, &sal);
+      sal_obj = symtab_and_line_to_sal_object (sal);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  return sal_obj;
+}
+
+/* Implementation of gdb.Frame.read_var (self, variable) -> gdb.Value.
    Returns the value of the given variable in this frame.  The argument must be
    a string.  Returns None if GDB can't find the specified variable.  */
 
@@ -312,7 +384,9 @@ frapy_read_var (PyObject *self, PyObject *args)
   if (!PyArg_ParseTuple (args, "O", &sym_obj))
     return NULL;
 
-  if (gdbpy_is_string (sym_obj))
+  if (PyObject_TypeCheck (sym_obj, &symbol_object_type))
+    var = symbol_object_to_symbol (sym_obj);
+  else if (gdbpy_is_string (sym_obj))
     {
       char *var_name;
       struct block *block = NULL;
@@ -365,6 +439,25 @@ frapy_read_var (PyObject *self, PyObject *args)
   Py_RETURN_NONE;
 }
 
+/* Select this frame.  */
+
+static PyObject *
+frapy_select (PyObject *self, PyObject *args)
+{
+  struct frame_info *fi;
+  frame_object *frame = (frame_object *) self;
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      FRAPY_REQUIRE_VALID (frame, fi);
+      select_frame (fi);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  Py_RETURN_NONE;
+}
+
 /* Implementation of gdb.selected_frame () -> gdb.Frame.
    Returns the selected frame object.  */
 
@@ -372,7 +465,7 @@ PyObject *
 gdbpy_selected_frame (PyObject *self, PyObject *args)
 {
   struct frame_info *frame;
-  frame_object *frame_obj = NULL;   /* Initialize to appease gcc warning.  */
+  PyObject *frame_obj = NULL;   /* Initialize to appease gcc warning.  */
   volatile struct gdb_exception except;
 
   TRY_CATCH (except, RETURN_MASK_ALL)
@@ -382,7 +475,7 @@ gdbpy_selected_frame (PyObject *self, PyObject *args)
     }
   GDB_PY_HANDLE_EXCEPTION (except);
 
-  return (PyObject *) frame_obj;
+  return frame_obj;
 }
 
 /* Implementation of gdb.stop_reason_string (Integer) -> String.
@@ -484,15 +577,26 @@ Return the reason why it's not possible to find frames older than this." },
   { "pc", frapy_pc, METH_NOARGS,
     "pc () -> Long.\n\
 Return the frame's resume address." },
+  { "block", frapy_block, METH_NOARGS,
+    "block () -> gdb.Block.\n\
+Return the frame's code block." },
+  { "function", frapy_function, METH_NOARGS,
+    "function () -> gdb.Symbol.\n\
+Returns the symbol for the function corresponding to this frame." },
   { "older", frapy_older, METH_NOARGS,
     "older () -> gdb.Frame.\n\
 Return the frame that called this frame." },
   { "newer", frapy_newer, METH_NOARGS,
     "newer () -> gdb.Frame.\n\
 Return the frame called by this frame." },
+  { "find_sal", frapy_find_sal, METH_NOARGS,
+    "find_sal () -> gdb.Symtab_and_line.\n\
+Return the frame's symtab and line." },
   { "read_var", frapy_read_var, METH_VARARGS,
     "read_var (variable) -> gdb.Value.\n\
 Return the value of the variable in this frame." },
+  { "select", frapy_select, METH_NOARGS,
+    "Select this frame as the user's current frame." },
   {NULL}  /* Sentinel */
 };
 
diff --git a/gdb/python/py-hooks.c b/gdb/python/py-hooks.c
new file mode 100644
index 0000000..a3140bc
--- /dev/null
+++ b/gdb/python/py-hooks.c
@@ -0,0 +1,50 @@
+/* Notifications from gdb to Python
+
+   Copyright (C) 2008 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 "cli/cli-decode.h"
+#include "charset.h"
+#include "python.h"
+#include "python-internal.h"
+#include "observer.h"
+
+PyObject *
+gdbpy_get_hook_function (const char *name)
+{
+  PyObject *hooks;
+  PyObject *result;
+
+  if (! PyObject_HasAttrString (gdb_module, "hooks"))
+    return NULL;
+  hooks = PyObject_GetAttrString (gdb_module, "hooks");
+  if (! hooks)
+    return NULL;
+  /* The cast is because the Python function doesn't declare const argument.
+     This is a problem in Python version 2.4, but not in 2.5.  */
+  if (! PyObject_HasAttrString (hooks, (char *) name))
+    {
+      Py_DECREF (hooks);
+      return NULL;
+    }
+  /* The cast is because the Python function doesn't declare const argument.
+     This is a problem in Python version 2.4, but not in 2.5.  */
+  result = PyObject_GetAttrString (hooks, (char *) name);
+  Py_DECREF (hooks);
+  return result;
+}
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
new file mode 100644
index 0000000..5e90cc2
--- /dev/null
+++ b/gdb/python/py-inferior.c
@@ -0,0 +1,926 @@
+/* Python interface to inferiors.
+
+   Copyright (C) 2009 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 "exceptions.h"
+#include "gdbcore.h"
+#include "gdbthread.h"
+#include "inferior.h"
+#include "observer.h"
+#include "python-internal.h"
+#include "arch-utils.h"
+#include "language.h"
+
+struct threadlist_entry {
+  thread_object *thread_obj;
+  struct threadlist_entry *next;
+};
+
+typedef struct
+{
+  PyObject_HEAD
+
+  /* The inferior we represent.  */
+  struct inferior *inferior;
+
+  /* thread_object instances under this inferior.  This list owns a reference
+     to each object it contains. */
+  struct threadlist_entry *threads;
+
+  /* Number of threads in the list.  */
+  int nthreads;
+} inferior_object;
+
+static PyTypeObject inferior_object_type;
+
+typedef struct {
+  PyObject_HEAD
+  void *buffer;
+
+  /* These are kept just for mbpy_str.  */
+  CORE_ADDR addr;
+  CORE_ADDR length;
+} membuf_object;
+
+static PyTypeObject membuf_object_type;
+
+/* Require that INFERIOR be a valid inferior ID.  */
+#define INFPY_REQUIRE_VALID(Inferior)				\
+  do {								\
+    if (!Inferior->inferior)					\
+      {								\
+	PyErr_SetString (PyExc_RuntimeError,			\
+			 "inferior no longer exists");	        \
+	return NULL;						\
+      }								\
+  } while (0)
+
+struct inflist_entry {
+  inferior_object *inf_obj;
+  struct inflist_entry *next;
+};
+
+
+
+/* Inferior objects list.  */
+
+/* List containing inferior_objects.  This list owns a reference to each
+   object it contains.  */
+static struct inflist_entry *inferior_list;
+
+static int ninferiors;
+
+
+/* An observer callback function that is called when an inferior has
+   been created.  Creates a corresponding Python object for the inferior
+   and adds it to the list.  */
+static void
+add_inferior_object (int pid)
+{
+  struct inferior *inf = find_inferior_pid (pid);
+  inferior_object *inf_obj;
+  struct inflist_entry *entry;
+  struct cleanup *cleanup;
+
+  if (!inf)
+    {
+      warning (_("Can't create Python Inferior object."));
+      return;
+    }
+
+  cleanup = ensure_python_env (get_current_arch (), current_language);
+
+  inf_obj = PyObject_New (inferior_object, &inferior_object_type);
+  if (!inf_obj)
+    {
+      warning (_("Can't create Python Inferior object."));
+      gdbpy_print_stack ();
+      do_cleanups (cleanup);
+      return;
+    }
+
+  inf_obj->inferior = inf;
+  inf_obj->threads = NULL;
+  inf_obj->nthreads = 0;
+
+  entry = xmalloc (sizeof (struct inflist_entry));
+  entry->inf_obj = inf_obj;
+  entry->next = inferior_list;
+
+  inferior_list = entry;
+
+  ninferiors++;
+
+  do_cleanups (cleanup);
+}
+
+/* An observer callback function that is called when an inferior has
+   been deleted.  Removes the corresponding Python object from the
+   inferior list, and removes the list's reference to the object.  */
+static void
+delete_inferior_object (int pid)
+{
+  PyGILState_STATE state;
+  struct inflist_entry **inf_entry, *inf_tmp;
+  struct threadlist_entry *th_entry, *th_tmp;
+
+  /* Find inferior_object for the given PID.  */
+  for (inf_entry = &inferior_list; *inf_entry != NULL;
+       inf_entry = &(*inf_entry)->next)
+    if ((*inf_entry)->inf_obj->inferior->pid == pid)
+      break;
+
+  if (!*inf_entry)
+    return;
+
+  state = PyGILState_Ensure ();
+
+  inf_tmp = *inf_entry;
+  inf_tmp->inf_obj->inferior = NULL;
+
+  /* Deallocate threads list.  */
+  for (th_entry = inf_tmp->inf_obj->threads; th_entry != NULL;)
+    {
+      Py_DECREF (th_entry->thread_obj);
+
+      th_tmp = th_entry;
+      th_entry = th_entry->next;
+      xfree (th_tmp);
+    }
+
+  inf_tmp->inf_obj->nthreads = 0;
+
+  *inf_entry = (*inf_entry)->next;
+  Py_DECREF (inf_tmp->inf_obj);
+  xfree (inf_tmp);
+
+  ninferiors--;
+
+  PyGILState_Release (state);
+}
+
+/* Finds the Python Inferior object for the given pid.  Returns a borrowed
+   reference.  */
+PyObject *
+find_inferior_object (int pid)
+{
+  struct inflist_entry *p;
+
+  for (p = inferior_list; p != NULL; p = p->next)
+    if (p->inf_obj->inferior->pid == pid)
+      return (PyObject *) p->inf_obj;
+
+  return NULL;
+}
+
+/* Finds the Python InferiorThread object for the given ptid.  Returns a
+   borrowed reference.  */
+thread_object *
+find_thread_object (ptid_t ptid)
+{
+  int pid;
+  struct inflist_entry *p;
+  struct threadlist_entry *q;
+
+  pid = PIDGET (ptid);
+  for (p = inferior_list; p != NULL; p = p->next)
+    if (p->inf_obj->inferior->pid == pid)
+      for (q = p->inf_obj->threads; q != NULL; q = q->next)
+	if (ptid_equal (q->thread_obj->thread->ptid, ptid))
+	  return q->thread_obj;
+
+  return NULL;
+}
+
+
+
+/* Inferior object.  */
+
+static void
+add_thread_object (struct thread_info *tp)
+{
+  PyGILState_STATE state;
+  thread_object *thread_obj;
+  inferior_object *inf_obj;
+  struct threadlist_entry *entry;
+
+  state = PyGILState_Ensure ();
+
+  thread_obj = create_thread_object (tp);
+  if (!thread_obj)
+    {
+      warning (_("Can't create Python InferiorThread object."));
+      gdbpy_print_stack ();
+      PyGILState_Release (state);
+      return;
+    }
+
+  inf_obj = (inferior_object *) thread_obj->inf_obj;
+
+  entry = xmalloc (sizeof (struct threadlist_entry));
+  entry->thread_obj = thread_obj;
+  entry->next = inf_obj->threads;
+
+  inf_obj->threads = entry;
+  inf_obj->nthreads++;
+
+  PyGILState_Release (state);
+}
+
+static void
+delete_thread_object (struct thread_info *tp, int ignore)
+{
+  PyGILState_STATE state;
+  inferior_object *inf_obj;
+  thread_object *thread_obj;
+  struct threadlist_entry **entry, *tmp;
+
+  inf_obj = (inferior_object *) find_inferior_object (PIDGET(tp->ptid));
+  if (!inf_obj)
+    return;
+
+  /* Find thread entry in its inferior's thread_list.  */
+  for (entry = &inf_obj->threads; *entry != NULL; entry = &(*entry)->next)
+    if ((*entry)->thread_obj->thread == tp)
+      break;
+
+  if (!*entry)
+    return;
+
+  state = PyGILState_Ensure ();
+
+  tmp = *entry;
+  tmp->thread_obj->thread = NULL;
+
+  *entry = (*entry)->next;
+  inf_obj->nthreads--;
+
+  Py_DECREF (tmp->thread_obj);
+  xfree (tmp);
+
+
+  PyGILState_Release (state);
+}
+
+static PyObject *
+infpy_threads (PyObject *self, PyObject *args)
+{
+  int i;
+  struct threadlist_entry *entry;
+  inferior_object *inf_obj = (inferior_object *) self;
+  PyObject *tuple;
+
+  INFPY_REQUIRE_VALID (inf_obj);
+
+
+  tuple = PyTuple_New (inf_obj->nthreads);
+  if (!tuple)
+    return NULL;
+
+  /* The list is in reverse order of thread age (i.e., newest comes first),
+     is this a problem?  */
+  for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads;
+       i++, entry = entry->next)
+    {
+      Py_INCREF (entry->thread_obj);
+      PyTuple_SET_ITEM (tuple, i, (PyObject *) entry->thread_obj);
+    }
+
+  return tuple;
+}
+
+static PyObject *
+infpy_get_num (PyObject *self, void *closure)
+{
+  inferior_object *inf = (inferior_object *) self;
+
+  INFPY_REQUIRE_VALID (inf);
+
+  return PyLong_FromLong (inf->inferior->num);
+}
+
+static PyObject *
+infpy_get_pid (PyObject *self, void *closure)
+{
+  inferior_object *inf = (inferior_object *) self;
+
+  INFPY_REQUIRE_VALID (inf);
+
+  return PyLong_FromLong (inf->inferior->pid);
+}
+
+static PyObject *
+infpy_get_was_attached (PyObject *self, void *closure)
+{
+  inferior_object *inf = (inferior_object *) self;
+  INFPY_REQUIRE_VALID (inf);
+  if (inf->inferior->attach_flag)
+    Py_RETURN_TRUE;
+  Py_RETURN_FALSE;
+}
+
+
+
+/* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
+   Returns a list of all inferiors.  */
+
+PyObject *
+gdbpy_inferiors (PyObject *unused, PyObject *unused2)
+{
+  int i;
+  struct inflist_entry *entry;
+  PyObject *tuple;
+
+  tuple = PyTuple_New (ninferiors);
+  if (!tuple)
+    return NULL;
+
+  /* The list is in reverse order of inferior age (i.e., newest comes first),
+     is this a problem?  */
+  for (i = 0, entry = inferior_list; i < ninferiors; i++, entry = entry->next)
+    {
+      Py_INCREF (entry->inf_obj);
+      PyTuple_SET_ITEM (tuple, i, (PyObject *) entry->inf_obj);
+    }
+
+  return tuple;
+}
+
+
+
+/* Membuf and memory manipulation.  */
+
+/* Implementation of gdb.read_memory (address, length).
+   Returns a Python buffer object with LENGTH bytes of the inferior's memory
+   at ADDRESS. Both arguments are integers.  */
+
+static PyObject *
+infpy_read_memory (PyObject *self, PyObject *args)
+{
+  int error = 0;
+  CORE_ADDR addr, length;
+  void *buffer = NULL;
+  membuf_object *membuf_obj;
+  PyObject *addr_obj, *length_obj;
+  struct cleanup *cleanups;
+  volatile struct gdb_exception except;
+
+  if (! PyArg_ParseTuple (args, "OO", &addr_obj, &length_obj))
+    return NULL;
+
+  cleanups = make_cleanup (null_cleanup, NULL);
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      if (!get_addr_from_python (addr_obj, &addr)
+	  || !get_addr_from_python (length_obj, &length))
+	{
+	  error = 1;
+	  break;
+	}
+
+      buffer = xmalloc (length);
+      make_cleanup (xfree, buffer);
+
+      read_memory (addr, buffer, length);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  if (error)
+    {
+      do_cleanups (cleanups);
+      return NULL;
+    }
+
+  membuf_obj = PyObject_New (membuf_object, &membuf_object_type);
+  if (membuf_obj == NULL)
+    {
+      PyErr_SetString (PyExc_MemoryError,
+		       "Could not allocate memory buffer object.");
+      do_cleanups (cleanups);
+      return NULL;
+    }
+
+  discard_cleanups (cleanups);
+
+  membuf_obj->buffer = buffer;
+  membuf_obj->addr = addr;
+  membuf_obj->length = length;
+
+  return PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
+				       Py_END_OF_BUFFER);
+}
+
+/* Implementation of gdb.write_memory (address, buffer [, length]).
+   Writes the contents of BUFFER (a Python object supporting the read buffer
+   protocol) at ADDRESS in the inferior's memory.  Write LENGTH bytes from
+   BUFFER, or its entire contents if the argument is not provided.  The
+   function returns nothing.  */
+
+static PyObject *
+infpy_write_memory (PyObject *self, PyObject *args)
+{
+  int buf_len, error = 0;
+  const char *buffer;
+  CORE_ADDR addr, length;
+  PyObject *addr_obj, *length_obj = NULL;
+  volatile struct gdb_exception except;
+
+  if (! PyArg_ParseTuple (args, "Os#|O", &addr_obj, &buffer, &buf_len,
+			  &length_obj))
+    return NULL;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      if (!get_addr_from_python (addr_obj, &addr))
+	{
+	  error = 1;
+	  break;
+	}
+      
+      if (!length_obj)
+	length = buf_len;
+      else if (!get_addr_from_python (length_obj, &length))
+	{
+	  error = 1;
+	  break;
+	}
+
+      write_memory (addr, buffer, length);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  if (error)
+    return NULL;
+
+  Py_RETURN_NONE;
+}
+
+/* Destructor of Membuf objects.  */
+
+static void
+mbpy_dealloc (PyObject *self)
+{
+  xfree (((membuf_object *) self)->buffer);
+  self->ob_type->tp_free (self);
+}
+
+/* Return a description of the Membuf object.  */
+
+static PyObject *
+mbpy_str (PyObject *self)
+{
+  membuf_object *membuf_obj = (membuf_object *) self;
+
+  return PyString_FromFormat ("memory buffer for address %s, %s bytes long",
+			      paddress (python_gdbarch, membuf_obj->addr),
+			      pulongest (membuf_obj->length));
+}
+
+static Py_ssize_t
+get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
+{
+  membuf_object *membuf_obj = (membuf_object *) self;
+
+  if (segment)
+    {
+      PyErr_SetString (PyExc_SystemError,
+		       "The memory buffer supports only one segment.");
+      return -1;
+    }
+
+  *ptrptr = membuf_obj->buffer;
+
+  return membuf_obj->length;
+}
+
+static Py_ssize_t
+get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
+{
+  return get_read_buffer (self, segment, ptrptr);
+}
+
+static Py_ssize_t
+get_seg_count (PyObject *self, Py_ssize_t *lenp)
+{
+  if (lenp)
+    *lenp = ((membuf_object *) self)->length;
+
+  return 1;
+}
+
+static Py_ssize_t
+get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
+{
+  void *ptr = NULL;
+  Py_ssize_t ret;
+
+  ret = get_read_buffer (self, segment, &ptr);
+  *ptrptr = (char *) ptr;
+
+  return ret;
+}
+
+/* Adds GDB value V to the pattern buffer in *PATTERN_BUF.  If SIZE is not zero,
+   it specifies the number of bytes from V to copy to *PATTERN_BUF.  The
+   function increases the size of *PATTERN_BUF as necessary, adjusting
+   *PATTERN_BUF_END and *PATTERN_BUF_SIZE in the process.  */
+
+static void
+add_value_pattern (struct value *v, int size, char **pattern_buf,
+		   char **pattern_buf_end, ULONGEST *pattern_buf_size)
+{
+  int val_bytes;
+
+  if (size)
+    {
+      LONGEST x = value_as_long (v);
+
+      if (size == 1)
+	*(*pattern_buf_end)++ = x;
+      else
+	{
+	  put_bits (x, *pattern_buf_end, size * 8,
+		    gdbarch_byte_order (python_gdbarch) == BFD_ENDIAN_BIG);
+	  *pattern_buf_end += size;
+	}
+    }
+  else
+   {
+     val_bytes = TYPE_LENGTH (value_type (v));
+
+     increase_pattern_buffer (pattern_buf, pattern_buf_end,
+			      pattern_buf_size, val_bytes);
+
+     memcpy (*pattern_buf_end, value_contents_raw (v), val_bytes);
+     *pattern_buf_end += val_bytes;
+   }
+}
+
+/* This function does the actual work of constructing the pattern buffer from
+   OBJ.  If OBJ is an object which implements the read buffer protocol (such
+   as a string, a byte array or gdb.Membuf), then its contents are directly
+   copied to *PATTERN_BUF.  If it is a list, then this function is recursively
+   called for each of its elements.  If OBJ is an object which can be converted
+   to a GDB value, then the contents of the value are copied to PATTERN_BUF.
+   If SIZE is different than zero, then it limits the number of bytes which
+   are copied to the buffer in case OBJ is converted to a GDB value.  That
+   means that SIZE influences only Python scalars and gdb.Value objects.
+   The function increases the size of *PATTERN_BUF as necessary, adjusting
+   *PATTERN_BUF_END and *PATTERN_BUF_SIZE in the process.
+
+   Returns 1 on success or 0 on failure, with a Python exception set.  This
+   function can also throw GDB exceptions.  */
+
+static int
+add_pattern_element (PyObject *obj, int size, char **pattern_buf,
+		     char **pattern_buf_end, ULONGEST *pattern_buf_size)
+{
+  if (PyObject_CheckReadBuffer (obj))
+    {
+      /* Handle string, Unicode string, byte array, gdb.Membuf and any other
+         object implementing the buffer protocol.  The SIZE parameter is
+	 ignored in this case.  */
+
+      Py_ssize_t val_bytes;
+      const void *buffer;
+
+      if (PyObject_AsReadBuffer (obj, &buffer, &val_bytes) == -1)
+	return 0;
+
+      increase_pattern_buffer (pattern_buf, pattern_buf_end,
+			       pattern_buf_size, val_bytes);
+
+      memcpy (*pattern_buf_end, buffer, val_bytes);
+      *pattern_buf_end += val_bytes;
+    }
+  else if (gdbpy_is_value_object (obj))
+    add_value_pattern (value_object_to_value (obj), size, pattern_buf,
+		       pattern_buf_end, pattern_buf_size);
+  else if (PySequence_Check (obj))
+    {
+      /* Handle lists and tuples.  */
+
+      Py_ssize_t i, num_objs;
+
+      num_objs = PySequence_Size (obj);
+      for (i = 0; i < num_objs; i++)
+	if (!add_pattern_element (PySequence_GetItem (obj, i), size,
+				  pattern_buf, pattern_buf_end,
+				  pattern_buf_size))
+	  return 0;
+    }
+  else
+    {
+      /* See if we can convert from a Python object to a GDB value.  */
+
+      struct value *v = convert_value_from_python (obj);
+
+      if (v)
+	add_value_pattern (v, size, pattern_buf, pattern_buf_end,
+			   pattern_buf_size);
+      else
+	return 0;
+    }
+
+  return 1;
+}
+
+/* Constructs the search pattern from OBJ, putting it in *PATTERN_BUFP, and its
+   size in *PATTERN_LENP.  See the function add_pattern_element to learn how
+   the search pattern is obtained from OBJ.
+
+   Returns 1 on success or 0 on failure, with a Python exception set.  This
+   function can also throw GDB exceptions.  */
+
+static int
+get_search_pattern (PyObject *obj, int size, char **pattern_bufp,
+		    ULONGEST *pattern_lenp)
+{
+  /* Buffer to hold the search pattern.  */
+  char *pattern_buf;
+  /* Current size of search pattern buffer.
+     We realloc space as needed.  */
+  ULONGEST pattern_buf_size;
+  /* Pointer to one past the last in-use part of pattern_buf.  */
+  char *pattern_buf_end;
+  struct cleanup *old_cleanups;
+
+  allocate_pattern_buffer (&pattern_buf, &pattern_buf_end, &pattern_buf_size);
+  old_cleanups = make_cleanup (free_current_contents, &pattern_buf);
+
+  if (!add_pattern_element (obj, size, &pattern_buf, &pattern_buf_end,
+			    &pattern_buf_size))
+    {
+      do_cleanups (old_cleanups);
+
+      return 0;
+    }
+
+  *pattern_bufp = pattern_buf;
+  *pattern_lenp = pattern_buf_end - pattern_buf;
+
+  discard_cleanups (old_cleanups);
+
+  return 1;
+}
+
+/* Implementation of
+   gdb.search_memory (address, length, pattern [, size] [, max_count]).
+   The third argument may be either a pattern, or a list or tupple of patterns
+   to be searched.  Size is the size in bytes of each search query value, either
+   1, 2, 4 or 8.  Returns a list of the addresses where matches were found.  */
+
+static PyObject *
+infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
+{
+  int size = 0;
+  unsigned int found_count = 0;
+  long max_count = 0;
+  CORE_ADDR start_addr, length;
+  char *pattern_buf;
+  static char *keywords[] = { "address", "length", "pattern", "size",
+			      "max_count", NULL };
+  ULONGEST pattern_len, search_space_len;
+  PyObject *pattern, *list = NULL, *start_addr_obj, *length_obj;
+  volatile struct gdb_exception except;
+
+  if (! PyArg_ParseTupleAndKeywords (args, kw, "OOO|il", keywords,
+				     &start_addr_obj, &length_obj, &pattern,
+				     &size, &max_count))
+    return NULL;
+
+  if (!max_count)
+    max_count = LONG_MAX;
+
+  if (size != 0 && size != 1 && size != 2 && size != 4 && size != 8)
+    {
+      PyErr_SetString (PyExc_ValueError, "invalid pattern size");
+      return NULL;
+    }
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      if (get_addr_from_python (start_addr_obj, &start_addr)
+	  && get_addr_from_python (length_obj, &length))
+	{
+	  if (!length)
+	    {
+	      PyErr_SetString (PyExc_ValueError, "empty search range");
+	      break;
+	    }
+	  /* Watch for overflows.  */
+	  else if (length > CORE_ADDR_MAX
+		   || (start_addr + length - 1) < start_addr)
+	    {
+	      PyErr_SetString (PyExc_ValueError, "search range too large");
+	      break;
+	    }
+
+	  search_space_len = length;
+
+	  if (get_search_pattern (pattern, size, &pattern_buf, &pattern_len))
+	    {
+	      /* Any cleanups get automatically executed on an exception.  */
+	      struct cleanup *cleanups = make_cleanup (xfree, pattern_buf);
+
+	      list = PyList_New (0);
+
+	      while (search_space_len >= pattern_len && found_count < max_count)
+		{
+		  CORE_ADDR found_addr;
+		  int found;
+
+		  found = search_memory (&start_addr, &search_space_len,
+					 pattern_buf, pattern_len, &found_addr);
+		  if (found <= 0)
+		    break;
+
+		  PyList_Append (list, PyLong_FromUnsignedLong (found_addr));
+		  ++found_count;
+		}
+
+	      do_cleanups (cleanups);
+	    }
+	}
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  return list;
+}
+
+
+
+void
+gdbpy_initialize_inferior (void)
+{
+  if (PyType_Ready (&inferior_object_type) < 0)
+    return;
+
+  Py_INCREF (&inferior_object_type);
+  PyModule_AddObject (gdb_module, "Inferior",
+		      (PyObject *) &inferior_object_type);
+
+  inferior_list = NULL;
+  ninferiors = 0;
+
+  observer_attach_new_inferior (add_inferior_object);
+  observer_attach_inferior_exit (delete_inferior_object);
+  observer_attach_new_thread (add_thread_object);
+  observer_attach_thread_exit (delete_thread_object);
+
+  if (PyType_Ready (&membuf_object_type) < 0)
+    return;
+
+  Py_INCREF (&membuf_object_type);
+  PyModule_AddObject (gdb_module, "Membuf", (PyObject *) &membuf_object_type);
+}
+
+
+
+static PyGetSetDef inferior_object_getset[] =
+{
+  { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
+  { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
+    NULL },
+  { "was_attached", infpy_get_was_attached, NULL,
+    "True if the inferior was created using 'attach'.", NULL },
+
+  { NULL }
+};
+
+static PyMethodDef inferior_object_methods[] =
+{
+  { "threads", infpy_threads, METH_NOARGS,
+    "Return all the threads of this inferior." },
+
+  { "read_memory", infpy_read_memory, METH_VARARGS,
+    "read_memory (address, length) -> buffer\n\
+Return a buffer object for reading from the inferior's memory." },
+  { "write_memory", infpy_write_memory, METH_VARARGS,
+    "write_memory (address, buffer [, length])\n\
+Write the given buffer object to the inferior's memory." },
+  { "search_memory", (PyCFunction) infpy_search_memory, METH_VARARGS | METH_KEYWORDS,
+    "search_memory (address, length, pattern [, size] [, max_count]) -> list\n\
+Return a list with the addresses where matches were found." },
+
+  { NULL }
+};
+
+static PyTypeObject inferior_object_type =
+{
+  PyObject_HEAD_INIT (NULL)
+  0,				  /* ob_size */
+  "gdb.Inferior",		  /* tp_name */
+  sizeof (inferior_object),	  /* tp_basicsize */
+  0,				  /* tp_itemsize */
+  0,				  /* tp_dealloc */
+  0,				  /* tp_print */
+  0,				  /* tp_getattr */
+  0,				  /* tp_setattr */
+  0,				  /* tp_compare */
+  0,				  /* tp_repr */
+  0,				  /* tp_as_number */
+  0,				  /* tp_as_sequence */
+  0,				  /* tp_as_mapping */
+  0,				  /* tp_hash  */
+  0,				  /* tp_call */
+  0,				  /* tp_str */
+  0,				  /* tp_getattro */
+  0,				  /* tp_setattro */
+  0,				  /* tp_as_buffer */
+  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /* tp_flags */
+  "GDB inferior object",	  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  inferior_object_methods,	  /* tp_methods */
+  0,				  /* tp_members */
+  inferior_object_getset,	  /* tp_getset */
+  0,				  /* tp_base */
+  0,				  /* tp_dict */
+  0,				  /* tp_descr_get */
+  0,				  /* tp_descr_set */
+  0,				  /* tp_dictoffset */
+  0,				  /* tp_init */
+  0				  /* tp_alloc */
+};
+
+
+
+/* Python doesn't provide a decent way to get compatibility here.  */
+#if HAVE_LIBPYTHON2_4
+#define CHARBUFFERPROC_NAME getcharbufferproc
+#else
+#define CHARBUFFERPROC_NAME charbufferproc
+#endif
+
+static PyBufferProcs buffer_procs = {
+  get_read_buffer,
+  get_write_buffer,
+  get_seg_count,
+  /* The cast here works around a difference between Python 2.4 and
+     Python 2.5.  */
+  (CHARBUFFERPROC_NAME) get_char_buffer
+};
+
+static PyTypeObject membuf_object_type = {
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Membuf",			  /*tp_name*/
+  sizeof (membuf_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  mbpy_dealloc,			  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  mbpy_str,			  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  &buffer_procs,		  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB memory buffer object", 	  /*tp_doc*/
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  0,				  /* tp_methods */
+  0,				  /* tp_members */
+  0,				  /* tp_getset */
+  0,				  /* tp_base */
+  0,				  /* tp_dict */
+  0,				  /* tp_descr_get */
+  0,				  /* tp_descr_set */
+  0,				  /* tp_dictoffset */
+  0,				  /* tp_init */
+  0,				  /* tp_alloc */
+  PyType_GenericNew		  /* tp_new */
+};
diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c
new file mode 100644
index 0000000..21e4eab
--- /dev/null
+++ b/gdb/python/py-infthread.c
@@ -0,0 +1,285 @@
+/* Python interface to inferior threads.
+
+   Copyright (C) 2009 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 "exceptions.h"
+#include "gdbthread.h"
+#include "inferior.h"
+#include "python-internal.h"
+
+static PyTypeObject thread_object_type;
+
+/* Require that INFERIOR be a valid inferior ID.  */
+#define THPY_REQUIRE_VALID(Thread)				\
+  do {								\
+    if (!Thread->thread)					\
+      {								\
+	PyErr_SetString (PyExc_RuntimeError,			\
+			 "thread no longer exists");	        \
+	return NULL;						\
+      }								\
+  } while (0)
+
+
+
+thread_object *
+create_thread_object (struct thread_info *tp)
+{
+  thread_object *thread_obj;
+  
+  thread_obj = PyObject_New (thread_object, &thread_object_type);
+  if (!thread_obj)
+    return NULL;
+
+  thread_obj->thread = tp;
+  thread_obj->inf_obj = find_inferior_object (PIDGET (tp->ptid));
+  Py_INCREF (thread_obj->inf_obj);
+
+  return thread_obj;
+}
+
+
+
+static void
+thpy_dealloc (PyObject *self)
+{
+  Py_DECREF (((thread_object *) self)->inf_obj);
+  self->ob_type->tp_free (self);
+}
+
+static PyObject *
+thpy_get_num (PyObject *self, void *closure)
+{
+  thread_object *thread_obj = (thread_object *) self;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  return PyLong_FromLong (thread_obj->thread->num);
+}
+
+
+
+/* Implementation of Inferior.frames () -> (gdb.Frame, ...).
+   Returns a tuple of all frame objects.  */
+PyObject *
+thpy_frames (PyObject *self, PyObject *args)
+{
+  int result = 0;
+  struct frame_info *frame;
+  PyObject *frame_obj;
+  PyObject *list, *tuple;
+  thread_object *thread_obj = (thread_object *) self;
+  struct cleanup *cleanup;
+  volatile struct gdb_exception except;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  list = PyList_New (0);
+  if (list == NULL)
+    {
+      PyErr_SetString (PyExc_MemoryError, "Could not allocate frames list.");
+      return NULL;
+    }
+
+  cleanup = make_cleanup_restore_current_thread ();
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      switch_to_thread (thread_obj->thread->ptid);
+
+      for (frame = get_current_frame (); frame; frame = get_prev_frame (frame))
+	{
+	  frame_obj = frame_info_to_frame_object (frame);
+	  if (frame_obj == NULL)
+	    {
+	      Py_DECREF (list);
+	      list = NULL;
+	      break;
+	    }
+
+	  PyList_Append (list, frame_obj);
+	}
+    }
+  if (except.reason < 0)
+    {
+      Py_DECREF (list);
+      return PyErr_Format (except.reason == RETURN_QUIT
+			   ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
+			   "%s", except.message);
+    }
+
+  do_cleanups (cleanup);
+
+  if (list)
+    {
+      tuple = PyList_AsTuple (list);
+      Py_DECREF (list);
+    }
+  else
+    tuple = NULL;
+
+  return tuple;
+}
+
+/* Implementation of InferiorThread.newest_frame () -> gdb.Frame.
+   Returns the newest frame object.  */
+PyObject *
+thpy_newest_frame (PyObject *self, PyObject *args)
+{
+  struct frame_info *frame;
+  PyObject *frame_obj = NULL;   /* Initialize to appease gcc warning.  */
+  thread_object *thread_obj = (thread_object *) self;
+  struct cleanup *cleanup;
+  volatile struct gdb_exception except;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  cleanup = make_cleanup_restore_current_thread ();
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      switch_to_thread (thread_obj->thread->ptid);
+
+      frame = get_current_frame ();
+      frame_obj = frame_info_to_frame_object (frame);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  do_cleanups (cleanup);
+
+  return frame_obj;
+}
+
+/* Implementation of InferiorThread.switch ().
+   Makes this the GDB selected thread.  */
+static PyObject *
+thpy_switch (PyObject *self, PyObject *args)
+{
+  thread_object *thread_obj = (thread_object *) self;
+  struct cleanup *cleanup;
+  volatile struct gdb_exception except;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      switch_to_thread (thread_obj->thread->ptid);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  Py_RETURN_NONE;
+}
+
+
+
+/* Implementation of gdb.selected_thread () -> gdb.InferiorThread.
+   Returns the selected thread object.  */
+PyObject *
+gdbpy_selected_thread (PyObject *self, PyObject *args)
+{
+  PyObject *thread_obj;
+  
+  thread_obj = (PyObject *) find_thread_object (inferior_ptid);
+  if (thread_obj)
+    {
+      Py_INCREF (thread_obj);
+      return thread_obj;
+    }
+
+  Py_RETURN_NONE;
+}
+
+
+
+void
+gdbpy_initialize_thread (void)
+{
+  if (PyType_Ready (&thread_object_type) < 0)
+    return;
+
+  Py_INCREF (&thread_object_type);
+  PyModule_AddObject (gdb_module, "InferiorThread",
+		      (PyObject *) &thread_object_type);
+}
+
+
+
+static PyGetSetDef thread_object_getset[] =
+{
+  { "num", thpy_get_num, NULL, "ID of the thread, as assigned by GDB.", NULL },
+
+  { NULL }
+};
+
+static PyMethodDef thread_object_methods[] =
+{
+  { "frames", thpy_frames, METH_NOARGS,
+    "frames () -> (gdb.Frame, ...)\n\
+Return a tuple containing all frames in the thread." },
+  { "newest_frame", thpy_newest_frame, METH_NOARGS,
+    "newest_frame () -> gdb.Frame\n\
+Return the newest frame in the thread." },
+  { "switch", thpy_switch, METH_NOARGS,
+    "switch ()\n\
+Makes this the GDB selected thread." },
+
+  { NULL }
+};
+
+static PyTypeObject thread_object_type =
+{
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.InferiorThread",		  /*tp_name*/
+  sizeof (thread_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  thpy_dealloc,			  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  0,				  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
+  "GDB thread object",		  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  thread_object_methods,	  /* tp_methods */
+  0,				  /* tp_members */
+  thread_object_getset,		  /* tp_getset */
+  0,				  /* tp_base */
+  0,				  /* tp_dict */
+  0,				  /* tp_descr_get */
+  0,				  /* tp_descr_set */
+  0,				  /* tp_dictoffset */
+  0,				  /* tp_init */
+  0				  /* tp_alloc */
+};
diff --git a/gdb/python/py-membuf.c b/gdb/python/py-membuf.c
new file mode 100644
index 0000000..7bc294c
--- /dev/null
+++ b/gdb/python/py-membuf.c
@@ -0,0 +1,268 @@
+/* Python interface to the inferior memory.
+
+   Copyright (C) 2008, 2009 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 "exceptions.h"
+#include "gdbcore.h"
+#include "python-internal.h"
+
+typedef struct {
+  PyObject_HEAD
+  void *buffer;
+
+  /* These are kept just for mbpy_str.  */
+  CORE_ADDR addr;
+  CORE_ADDR length;
+} membuf_object;
+
+static PyTypeObject membuf_object_type;
+
+/* Implementation of gdb.read_memory (address, length).
+   Returns a Python buffer object with LENGTH bytes of the inferior's memory
+   at ADDRESS. Both arguments are integers.  */
+
+PyObject *
+gdbpy_read_memory (PyObject *self, PyObject *args)
+{
+  int error = 0;
+  CORE_ADDR addr, length;
+  void *buffer = NULL;
+  membuf_object *membuf_obj;
+  PyObject *addr_obj, *length_obj;
+  struct cleanup *cleanups = NULL;
+  volatile struct gdb_exception except;
+
+  if (! PyArg_ParseTuple (args, "OO", &addr_obj, &length_obj))
+    return NULL;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      if (!get_addr_from_python (addr_obj, &addr)
+	  || !get_addr_from_python (length_obj, &length))
+	{
+	  error = 1;
+	  break;
+	}
+
+      buffer = xmalloc (length);
+      cleanups = make_cleanup (xfree, buffer);
+
+      read_memory (addr, buffer, length);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  if (error)
+    return NULL;
+
+  discard_cleanups (cleanups);
+
+  membuf_obj = PyObject_New (membuf_object, &membuf_object_type);
+  if (membuf_obj == NULL)
+    {
+      xfree (buffer);
+      PyErr_SetString (PyExc_MemoryError,
+		       "Could not allocate memory buffer object.");
+      return NULL;
+    }
+
+  membuf_obj->buffer = buffer;
+  membuf_obj->addr = addr;
+  membuf_obj->length = length;
+
+  return PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
+				       Py_END_OF_BUFFER);
+}
+
+/* Implementation of gdb.write_memory (address, buffer [, length]).
+   Writes the contents of BUFFER (a Python object supporting the read buffer
+   protocol) at ADDRESS in the inferior's memory.  Write LENGTH bytes from
+   BUFFER, or its entire contents if the argument is not provided.  The
+   function returns nothing.  */
+
+PyObject *
+gdbpy_write_memory (PyObject *self, PyObject *args)
+{
+  int buf_len, error = 0;
+  const char *buffer;
+  CORE_ADDR addr, length;
+  PyObject *addr_obj, *length_obj = NULL;
+  volatile struct gdb_exception except;
+
+  if (! PyArg_ParseTuple (args, "Os#|O", &addr_obj, &buffer, &buf_len,
+			  &length_obj))
+    return NULL;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      if (!get_addr_from_python (addr_obj, &addr))
+	{
+	  error = 1;
+	  break;
+	}
+      
+      if (!length_obj)
+	length = buf_len;
+      else if (!get_addr_from_python (length_obj, &length))
+	{
+	  error = 1;
+	  break;
+	}
+
+      write_memory (addr, buffer, length);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  if (error)
+    return NULL;
+
+  Py_RETURN_NONE;
+}
+
+/* Destructor of Membuf objects.  */
+
+static void
+mbpy_dealloc (PyObject *self)
+{
+  xfree (((membuf_object *) self)->buffer);
+  self->ob_type->tp_free (self);
+}
+
+/* Return a description of the Membuf object.  */
+
+static PyObject *
+mbpy_str (PyObject *self)
+{
+  membuf_object *membuf_obj = (membuf_object *) self;
+
+  return PyString_FromFormat ("memory buffer for address %s, %s bytes long",
+			      paddress (membuf_obj->addr),
+			      pulongest (membuf_obj->length));
+}
+
+static Py_ssize_t
+get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
+{
+  membuf_object *membuf_obj = (membuf_object *) self;
+
+  if (segment)
+    {
+      PyErr_SetString (PyExc_SystemError,
+		       "The memory buffer supports only one segment.");
+      return -1;
+    }
+
+  *ptrptr = membuf_obj->buffer;
+
+  return membuf_obj->length;
+}
+
+static Py_ssize_t
+get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
+{
+  return get_read_buffer (self, segment, ptrptr);
+}
+
+static Py_ssize_t
+get_seg_count (PyObject *self, Py_ssize_t *lenp)
+{
+  if (lenp)
+    *lenp = ((membuf_object *) self)->length;
+
+  return 1;
+}
+
+static Py_ssize_t
+get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
+{
+  void *ptr = NULL;
+  Py_ssize_t ret;
+
+  ret = get_read_buffer (self, segment, &ptr);
+  *ptrptr = (char *) ptr;
+
+  return ret;
+}
+
+/* Python doesn't provide a decent way to get compatibility here.  */
+#if HAVE_LIBPYTHON2_4
+#define CHARBUFFERPROC_NAME getcharbufferproc
+#else
+#define CHARBUFFERPROC_NAME charbufferproc
+#endif
+
+static PyBufferProcs buffer_procs = {
+  get_read_buffer,
+  get_write_buffer,
+  get_seg_count,
+  /* The cast here works around a difference between Python 2.4 and
+     Python 2.5.  */
+  (CHARBUFFERPROC_NAME) get_char_buffer
+};
+
+static PyTypeObject membuf_object_type = {
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Membuf",			  /*tp_name*/
+  sizeof (membuf_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  mbpy_dealloc,			  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  mbpy_str,			  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  &buffer_procs,		  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB memory buffer object", 	  /*tp_doc*/
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  0,				  /* tp_methods */
+  0,				  /* tp_members */
+  0,				  /* tp_getset */
+  0,				  /* tp_base */
+  0,				  /* tp_dict */
+  0,				  /* tp_descr_get */
+  0,				  /* tp_descr_set */
+  0,				  /* tp_dictoffset */
+  0,				  /* tp_init */
+  0,				  /* tp_alloc */
+  PyType_GenericNew		  /* tp_new */
+};
+
+void
+gdbpy_initialize_membuf (void)
+{
+  if (PyType_Ready (&membuf_object_type) < 0)
+    return;
+
+  Py_INCREF (&membuf_object_type);
+  PyModule_AddObject (gdb_module, "Membuf", (PyObject *) &membuf_object_type);
+}
diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c
new file mode 100644
index 0000000..1f591a8
--- /dev/null
+++ b/gdb/python/py-param.c
@@ -0,0 +1,606 @@
+/* gdb parameters implemented in Python
+
+   Copyright (C) 2008, 2009 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 "value.h"
+#include "exceptions.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "gdbcmd.h"
+#include "cli/cli-decode.h"
+#include "completer.h"
+
+/* Parameter constants and their values.  */
+struct parm_constant
+{
+  char *name;
+  int value;
+};
+
+struct parm_constant parm_constants[] =
+{
+  { "PARAM_BOOLEAN", var_boolean },
+  { "PARAM_AUTO_BOOLEAN", var_auto_boolean },
+  { "PARAM_UINTEGER", var_uinteger },
+  { "PARAM_INTEGER", var_integer },
+  { "PARAM_STRING", var_string },
+  { "PARAM_STRING_NOESCAPE", var_string_noescape },
+  { "PARAM_OPTIONAL_FILENAME", var_optional_filename },
+  { "PARAM_FILENAME", var_filename },
+  { "PARAM_ZINTEGER", var_zinteger },
+  { "PARAM_ENUM", var_enum },
+  { NULL, 0 }
+};
+
+/* A union that can hold anything described by enum var_types.  */
+union parmpy_variable
+{
+  /* Hold an integer value, for boolean and integer types.  */
+  int intval;
+
+  /* Hold an auto_boolean.  */
+  enum auto_boolean autoboolval;
+
+  /* Hold an unsigned integer value, for uinteger.  */
+  unsigned int uintval;
+
+  /* Hold a string, for the various string types.  */
+  char *stringval;
+
+  /* Hold a string, for enums.  */
+  const char *cstringval;
+};
+
+/* A gdb parameter.  */
+struct parmpy_object
+{
+  PyObject_HEAD
+
+  /* The type of the parameter.  */
+  enum var_types type;
+
+  /* The value of the parameter.  */
+  union parmpy_variable value;
+
+  /* For an enum command, the possible values.  The vector is
+     allocated with xmalloc, as is each element.  It is
+     NULL-terminated.  */
+  const char **enumeration;
+};
+
+typedef struct parmpy_object parmpy_object;
+
+static PyTypeObject parmpy_object_type;
+
+/* Some handy string constants.  */
+static PyObject *set_doc_cst;
+static PyObject *show_doc_cst;
+
+
+
+/* Get an attribute.  */
+static PyObject *
+get_attr (PyObject *obj, PyObject *attr_name)
+{
+  if (PyString_Check (attr_name)
+      && ! strcmp (PyString_AsString (attr_name), "value"))
+    {
+      parmpy_object *self = (parmpy_object *) obj;
+      return gdbpy_parameter_value (self->type, &self->value);
+    }
+
+  return PyObject_GenericGetAttr (obj, attr_name);
+}
+
+/* Set a parameter value from a Python value.  Return 0 on success, -1
+   on failure.  */
+static int
+set_parameter_value (parmpy_object *self, PyObject *value)
+{
+  int cmp;
+
+  switch (self->type)
+    {
+    case var_string:
+    case var_string_noescape:
+    case var_optional_filename:
+    case var_filename:
+      if (! gdbpy_is_string (value)
+	  && (self->type == var_filename
+	      || value != Py_None))
+	{
+	  PyErr_SetString (PyExc_RuntimeError, "string required");
+	  return -1;
+	}
+      if (self->value.stringval)
+	xfree (self->value.stringval);
+      if (value == Py_None)
+	{
+	  if (self->type == var_optional_filename)
+	    self->value.stringval = xstrdup ("");
+	  else
+	    self->value.stringval = NULL;
+	}
+      else
+	self->value.stringval = python_string_to_host_string (value);
+      break;
+
+    case var_enum:
+      {
+	int i;
+	char *str;
+
+	if (! gdbpy_is_string (value))
+	  {
+	    PyErr_SetString (PyExc_RuntimeError, "string required");
+	    return -1;
+	  }
+
+	str = python_string_to_host_string (value);
+	for (i = 0; self->enumeration[i]; ++i)
+	  if (! strcmp (self->enumeration[i], str))
+	    break;
+	xfree (str);
+	if (! self->enumeration[i])
+	  {
+	    PyErr_SetString (PyExc_RuntimeError,
+			     "value must be member of enumeration");
+	    return -1;
+	  }
+	self->value.cstringval = self->enumeration[i];
+	break;
+      }
+
+    case var_boolean:
+      if (! PyBool_Check (value))
+	{
+	  PyErr_SetString (PyExc_RuntimeError, "boolean required");
+	  return -1;
+	}
+      cmp = PyObject_IsTrue (value);
+      if (cmp < 0) 
+	  return -1;
+      self->value.intval = cmp;
+      break;
+
+    case var_auto_boolean:
+      if (! PyBool_Check (value) && value != Py_None)
+	{
+	  PyErr_SetString (PyExc_RuntimeError,
+			   "boolean or None required");
+	  return -1;
+	}
+
+      if (value == Py_None)
+	self->value.autoboolval = AUTO_BOOLEAN_AUTO;
+      else
+	{
+	  cmp = PyObject_IsTrue (value);
+	  if (cmp < 0 )
+	    return -1;	  
+	  if (cmp == 1)
+	    self->value.autoboolval = AUTO_BOOLEAN_TRUE;
+	  else 
+	    self->value.autoboolval = AUTO_BOOLEAN_FALSE;
+
+	  break;
+	}
+
+    case var_integer:
+    case var_zinteger:
+    case var_uinteger:
+      {
+	long l;
+	int ok;
+
+	if (! PyInt_Check (value))
+	  {
+	    PyErr_SetString (PyExc_RuntimeError, "value must be integer");
+	    return -1;
+	  }
+
+	l = PyInt_AsLong (value);
+	if (self->type == var_uinteger)
+	  {
+	    ok = (l >= 0 && l <= UINT_MAX);
+	    if (l == 0)
+	      l = UINT_MAX;
+	  }
+	else if (self->type == var_integer)
+	  {
+	    ok = (l >= INT_MIN && l <= INT_MAX);
+	    if (l == 0)
+	      l = INT_MAX;
+	  }
+	else
+	  ok = (l >= INT_MIN && l <= INT_MAX);
+
+	if (! ok)
+	  {
+	    PyErr_SetString (PyExc_RuntimeError, "range exceeded");
+	    return -1;
+	  }
+
+	self->value.intval = (int) l;
+	break;
+      }
+
+    default:
+      PyErr_SetString (PyExc_RuntimeError, "programmer error: unhandled type");
+      return -1;
+    }
+
+  return 0;
+}
+
+/* Set an attribute.  */
+static int
+set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
+{
+  if (PyString_Check (attr_name)
+      && ! strcmp (PyString_AsString (attr_name), "value"))
+    {
+      if (!val)
+	{
+	  PyErr_SetString (PyExc_RuntimeError,
+			   "cannot delete a parameter's value");
+	  return -1;
+	}
+      return set_parameter_value ((parmpy_object *) obj, val);
+    }
+
+  return PyObject_GenericSetAttr (obj, attr_name, val);
+}
+
+
+
+/* A helper function that dispatches to the appropriate add_setshow
+   function.  */
+static void
+add_setshow_generic (int parmclass, enum command_class cmdclass,
+		     char *cmd_name, parmpy_object *self,
+		     char *set_doc, char *show_doc, char *help_doc,
+		     struct cmd_list_element **set_list,
+		     struct cmd_list_element **show_list)
+{
+  switch (parmclass)
+    {
+    case var_boolean:
+      add_setshow_boolean_cmd (cmd_name, cmdclass, &self->value.intval,
+			       set_doc, show_doc, help_doc,
+			       NULL, NULL, set_list, show_list);
+      break;
+
+    case var_auto_boolean:
+      add_setshow_auto_boolean_cmd (cmd_name, cmdclass,
+				    &self->value.autoboolval,
+				    set_doc, show_doc, help_doc,
+				    NULL, NULL, set_list, show_list);
+      break;
+
+    case var_uinteger:
+      add_setshow_uinteger_cmd (cmd_name, cmdclass, &self->value.uintval,
+				set_doc, show_doc, help_doc,
+				NULL, NULL, set_list, show_list);
+      break;
+
+    case var_integer:
+      add_setshow_integer_cmd (cmd_name, cmdclass, &self->value.intval,
+			       set_doc, show_doc, help_doc,
+			       NULL, NULL, set_list, show_list);
+      break;
+
+    case var_string:
+      add_setshow_string_cmd (cmd_name, cmdclass, &self->value.stringval,
+			      set_doc, show_doc, help_doc,
+			      NULL, NULL, set_list, show_list);
+      break;
+
+    case var_string_noescape:
+      add_setshow_string_noescape_cmd (cmd_name, cmdclass,
+				       &self->value.stringval,
+				       set_doc, show_doc, help_doc,
+				       NULL, NULL, set_list, show_list);
+      break;
+
+    case var_optional_filename:
+      add_setshow_optional_filename_cmd (cmd_name, cmdclass,
+					 &self->value.stringval,
+					 set_doc, show_doc, help_doc,
+					 NULL, NULL, set_list, show_list);
+      break;
+
+    case var_filename:
+      add_setshow_filename_cmd (cmd_name, cmdclass, &self->value.stringval,
+				set_doc, show_doc, help_doc,
+				NULL, NULL, set_list, show_list);
+      break;
+
+    case var_zinteger:
+      add_setshow_zinteger_cmd (cmd_name, cmdclass, &self->value.intval,
+				set_doc, show_doc, help_doc,
+				NULL, NULL, set_list, show_list);
+      break;
+
+    case var_enum:
+      add_setshow_enum_cmd (cmd_name, cmdclass, self->enumeration,
+			    &self->value.cstringval,
+			    set_doc, show_doc, help_doc,
+			    NULL, NULL, set_list, show_list);
+      /* Initialize the value, just in case.  */
+      self->value.cstringval = self->enumeration[0];
+      break;
+    }
+}
+
+/* A helper which computes enum values.  Returns 1 on success, 0 on
+   error.  */
+static int
+compute_enum_values (parmpy_object *self, PyObject *enum_values)
+{
+  Py_ssize_t size, i;
+
+  if (! enum_values)
+    {
+      PyErr_SetString (PyExc_RuntimeError,
+		       "enumeration required for PARAM_ENUM");
+      return 0;
+    }
+
+  if (! PySequence_Check (enum_values))
+    {
+      PyErr_SetString (PyExc_RuntimeError, "enumeration is not a sequence");
+      return 0;
+    }
+
+  size = PySequence_Size (enum_values);
+  if (size < 0)
+    return 0;
+  if (size == 0)
+    {
+      PyErr_SetString (PyExc_RuntimeError, "empty enumeration");
+      return 0;
+    }
+
+  self->enumeration = xmalloc ((size + 1) * sizeof (char *));
+  memset (self->enumeration, 0, (size + 1) * sizeof (char *));
+
+  for (i = 0; i < size; ++i)
+    {
+      PyObject *item = PySequence_GetItem (enum_values, i);
+      if (! item)
+	return 0;
+      if (! gdbpy_is_string (item))
+	{
+	  PyErr_SetString (PyExc_RuntimeError, "enumeration item not a string");
+	  return 0;
+	}
+      self->enumeration[i] = python_string_to_host_string (item);
+    }
+
+  return 1;
+}
+
+/* A helper function which returns a documentation string for an
+   object.  */
+static char *
+get_doc_string (PyObject *object, PyObject *attr)
+{
+  char *result = NULL;
+  if (PyObject_HasAttr (object, attr))
+    {
+      PyObject *ds_obj = PyObject_GetAttr (object, attr);
+      if (ds_obj && gdbpy_is_string (ds_obj))
+	result = python_string_to_host_string (ds_obj);
+    }
+  if (! result)
+    result = xstrdup ("This command is not documented.");
+  return result;
+}
+
+/* Object initializer; sets up gdb-side structures for command.
+
+   Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM])
+
+   NAME is the name of the parameter.  It may consist of multiple
+   words, in which case the final word is the name of the new command,
+   and earlier words must be prefix commands.
+
+   CMDCLASS is the kind of command.  It should be one of the COMMAND_*
+   constants defined in the gdb module.
+
+   PARMCLASS is the type of the parameter.  It should be one of the
+   PARAM_* constants defined in the gdb module.
+
+   If PARMCLASS is PARAM_ENUM, then the final argument should be a
+   collection of strings.  These strings are the valid values for this
+   parameter.
+
+   The documentation for the parameter is taken from the doc string
+   for the python class.
+   
+*/
+static int
+parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
+{
+  parmpy_object *obj = (parmpy_object *) self;
+  char *name;
+  char *set_doc, *show_doc, *doc;
+  char *cmd_name;
+  int parmclass, cmdtype;
+  PyObject *enum_values = NULL;
+  struct cmd_list_element *cmd_list;
+  struct cmd_list_element **set_list, **show_list;
+  volatile struct gdb_exception except;
+
+  if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass,
+			  &enum_values))
+    return -1;
+
+  if (cmdtype != no_class && cmdtype != class_run
+      && cmdtype != class_vars && cmdtype != class_stack
+      && cmdtype != class_files && cmdtype != class_support
+      && cmdtype != class_info && cmdtype != class_breakpoint
+      && cmdtype != class_trace && cmdtype != class_obscure
+      && cmdtype != class_maintenance)
+    {
+      PyErr_Format (PyExc_RuntimeError, "invalid command class argument");
+      return -1;
+    }
+
+  if (parmclass != var_boolean && parmclass != var_auto_boolean
+      && parmclass != var_uinteger && parmclass != var_integer
+      && parmclass != var_string && parmclass != var_string_noescape
+      && parmclass != var_optional_filename && parmclass != var_filename
+      && parmclass != var_zinteger && parmclass != var_enum)
+    {
+      PyErr_SetString (PyExc_RuntimeError, "invalid parameter class argument");
+      return -1;
+    }
+
+  if (enum_values && parmclass != var_enum)
+    {
+      PyErr_SetString (PyExc_RuntimeError,
+		       "only PARAM_ENUM accepts a fourth argument");
+      return -1;
+    }
+  if (parmclass == var_enum)
+    {
+      if (! compute_enum_values (obj, enum_values))
+	return -1;
+    }
+
+  obj->type = (enum var_types) parmclass;
+  memset (&obj->value, 0, sizeof (obj->value));
+  obj->enumeration = NULL;
+
+  cmd_name = gdbpy_parse_command_name (name, &set_list, &setlist);
+  if (! cmd_name)
+    return -1;
+  xfree (cmd_name);
+  cmd_name = gdbpy_parse_command_name (name, &show_list, &showlist);
+  if (! cmd_name)
+    return -1;
+
+  /* FIXME: there is no way to register a destructor function for
+     set/show commands.  So, these are leaked.  */
+  set_doc = get_doc_string (self, set_doc_cst);
+  show_doc = get_doc_string (self, show_doc_cst);
+  doc = get_doc_string (self, gdbpy_doc_cst);
+
+  Py_INCREF (self);
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      add_setshow_generic (parmclass, (enum command_class) cmdtype,
+			   cmd_name, obj,
+			   set_doc, show_doc,
+			   doc, set_list, show_list);
+    }
+  if (except.reason < 0)
+    {
+      xfree (cmd_name);
+      xfree (set_doc);
+      xfree (show_doc);
+      xfree (doc);
+      Py_DECREF (self);
+      PyErr_Format (except.reason == RETURN_QUIT
+		    ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
+		    "%s", except.message);
+      return -1;
+    }
+  return 0;
+}
+
+
+
+/* Initialize the 'parameters' module.  */
+void
+gdbpy_initialize_parameters (void)
+{
+  int i;
+
+  if (PyType_Ready (&parmpy_object_type) < 0)
+    return;
+
+  set_doc_cst = PyString_FromString ("set_doc");
+  if (! set_doc_cst)
+    return;
+  show_doc_cst = PyString_FromString ("show_doc");
+  if (! show_doc_cst)
+    return;
+
+  for (i = 0; parm_constants[i].name; ++i)
+    {
+      if (PyModule_AddIntConstant (gdb_module,
+				   parm_constants[i].name,
+				   parm_constants[i].value) < 0)
+	return;
+    }
+
+  Py_INCREF (&parmpy_object_type);
+  PyModule_AddObject (gdb_module, "Parameter",
+		      (PyObject *) &parmpy_object_type);
+}
+
+
+
+static PyTypeObject parmpy_object_type =
+{
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Parameter",		  /*tp_name*/
+  sizeof (parmpy_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  0,				  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  0,				  /*tp_str*/
+  get_attr,			  /*tp_getattro*/
+  set_attr,			  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  "GDB parameter object",	  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  0,				  /* tp_methods */
+  0,				  /* tp_members */
+  0,				  /* tp_getset */
+  0,				  /* tp_base */
+  0,				  /* tp_dict */
+  0,				  /* tp_descr_get */
+  0,				  /* tp_descr_set */
+  0,				  /* tp_dictoffset */
+  parmpy_init,			  /* tp_init */
+  0,				  /* tp_alloc */
+  PyType_GenericNew		  /* tp_new */
+};
diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c
index 5d696c8..a6348ba 100644
--- a/gdb/python/py-prettyprint.c
+++ b/gdb/python/py-prettyprint.c
@@ -121,6 +121,7 @@ find_pretty_printer (PyObject *value)
   
   return function;
 }
+
 /* Pretty-print a single value, via the printer object PRINTER.
    If the function returns a string, a PyObject containing the string
    is returned.  Otherwise, if the function returns a value,
@@ -141,10 +142,15 @@ pretty_print_one_value (PyObject *printer, struct value **out_value)
 	  if (! gdbpy_is_string (result))
 	    {
 	      *out_value = convert_value_from_python (result);
-	      if (PyErr_Occurred ())
-		*out_value = NULL;
-	      Py_DECREF (result);
-	      result = NULL;
+ 	      if (PyErr_Occurred ())
+ 		*out_value = NULL;
+	      else
+		/* We must increment the value's refcount, because we
+		   are about to decref RESULT, and this may result in
+		   the value being destroyed.  */
+		value_incref (*out_value);
+ 	      Py_DECREF (result);
+ 	      result = NULL;
 	    }
 	}
     }
@@ -556,14 +562,7 @@ gdbpy_get_varobj_pretty_printer (struct value *value)
 {
   PyObject *val_obj;
   PyObject *pretty_printer = NULL;
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
-    {
-      value = value_copy (value);
-    }
-  GDB_PY_HANDLE_EXCEPTION (except);
-  
   val_obj = value_to_value_object (value);
   if (! val_obj)
     return NULL;
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
new file mode 100644
index 0000000..03d43c1
--- /dev/null
+++ b/gdb/python/py-symbol.c
@@ -0,0 +1,336 @@
+/* Python interface to symbols.
+
+   Copyright (C) 2008, 2009 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 "block.h"
+#include "exceptions.h"
+#include "frame.h"
+#include "symtab.h"
+#include "python-internal.h"
+
+typedef struct {
+  PyObject_HEAD
+  struct symbol *symbol;
+} symbol_object;
+
+
+static PyObject *
+sympy_str (PyObject *self)
+{
+  int ret;
+  char *s;
+  PyObject *result;
+
+  ret = asprintf (&s, "symbol for %s",
+		  SYMBOL_PRINT_NAME (((symbol_object *) self)->symbol));
+  if (ret < 0)
+    Py_RETURN_NONE;
+
+  result = PyString_FromString (s);
+  xfree (s);
+
+  return result;
+}
+
+static PyObject *
+sympy_get_value (PyObject *self, void *closure)
+{
+  symbol_object *self_sym = (symbol_object *) self;
+
+  switch (SYMBOL_CLASS (self_sym->symbol))
+    {
+    case LOC_BLOCK:
+      return block_to_block_object (SYMBOL_BLOCK_VALUE (self_sym->symbol));
+    }
+
+  PyErr_SetString (PyExc_NotImplementedError,
+		   "Symbol type not yet supported in Python scripts.");
+  return NULL;
+}
+
+static PyObject *
+sympy_get_symtab (PyObject *self, void *closure)
+{
+  symbol_object *self_sym = (symbol_object *) self;
+
+  return symtab_to_symtab_object (SYMBOL_SYMTAB (self_sym->symbol));
+}
+
+static PyObject *
+sympy_get_name (PyObject *self, void *closure)
+{
+  symbol_object *self_sym = (symbol_object *) self;
+
+  return PyString_FromString (SYMBOL_NATURAL_NAME (self_sym->symbol));
+}
+
+static PyObject *
+sympy_get_linkage_name (PyObject *self, void *closure)
+{
+  symbol_object *self_sym = (symbol_object *) self;
+
+  return PyString_FromString (SYMBOL_LINKAGE_NAME (self_sym->symbol));
+}
+
+static PyObject *
+sympy_get_print_name (PyObject *self, void *closure)
+{
+  symbol_object *self_sym = (symbol_object *) self;
+
+  return PyString_FromString (SYMBOL_PRINT_NAME (self_sym->symbol));
+}
+
+static PyObject *
+sympy_get_addr_class (PyObject *self, void *closure)
+{
+  symbol_object *self_sym = (symbol_object *) self;
+
+  return PyInt_FromLong (SYMBOL_CLASS (self_sym->symbol));
+}
+
+static PyObject *
+sympy_is_argument (PyObject *self, void *closure)
+{
+  symbol_object *self_sym = (symbol_object *) self;
+
+  return PyBool_FromLong (SYMBOL_IS_ARGUMENT (self_sym->symbol));
+}
+
+static PyObject *
+sympy_is_constant (PyObject *self, void *closure)
+{
+  symbol_object *self_sym = (symbol_object *) self;
+  enum address_class class = SYMBOL_CLASS (self_sym->symbol);
+
+  return PyBool_FromLong (class == LOC_CONST || class == LOC_CONST_BYTES);
+}
+
+static PyObject *
+sympy_is_function (PyObject *self, void *closure)
+{
+  symbol_object *self_sym = (symbol_object *) self;
+  enum address_class class = SYMBOL_CLASS (self_sym->symbol);
+
+  return PyBool_FromLong (class == LOC_BLOCK);
+}
+
+static PyObject *
+sympy_is_variable (PyObject *self, void *closure)
+{
+  symbol_object *self_sym = (symbol_object *) self;
+  enum address_class class = SYMBOL_CLASS (self_sym->symbol);
+
+  return PyBool_FromLong (!SYMBOL_IS_ARGUMENT (self_sym->symbol)
+      && (class == LOC_LOCAL || class == LOC_REGISTER || class == LOC_STATIC
+	  || class == LOC_COMPUTED || class == LOC_OPTIMIZED_OUT));
+}
+
+PyObject *
+symbol_to_symbol_object (struct symbol *sym)
+{
+  symbol_object *sym_obj;
+
+  sym_obj = PyObject_New (symbol_object, &symbol_object_type);
+  if (sym_obj == NULL)
+    {
+      PyErr_SetString (PyExc_MemoryError, "Could not allocate symbol object.");
+      return NULL;
+    }
+
+  sym_obj->symbol = sym;
+
+  return (PyObject *) sym_obj;
+}
+
+struct symbol *
+symbol_object_to_symbol (PyObject *obj)
+{
+  if (! PyObject_TypeCheck (obj, &symbol_object_type))
+    return NULL;
+  return ((symbol_object *) obj)->symbol;
+}
+
+/* Implementation of
+   gdb.lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)
+   A tuple with 2 elements is always returned.  The first is the symbol
+   object or None, the second is a boolean with the value of
+   is_a_field_of_this (see comment in lookup_symbol_in_language).  */
+
+PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw)
+{
+  int domain = VAR_DOMAIN, is_a_field_of_this = 0;
+  const char *name;
+  static char *keywords[] = { "name", "block", "domain", NULL };
+  struct symbol *symbol;
+  PyObject *block_obj = NULL, *ret_tuple, *sym_obj, *bool_obj;
+  struct block *block = NULL;
+
+  if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!i", keywords, &name,
+				     &block_object_type, &block_obj, &domain))
+    return NULL;
+
+  if (block_obj)
+    block = block_object_to_block (block_obj);
+  else
+    {
+      struct frame_info *selected_frame;
+      volatile struct gdb_exception except;
+
+      TRY_CATCH (except, RETURN_MASK_ALL)
+	{
+	  selected_frame  = get_selected_frame (_("No frame selected."));
+	  block = block_for_pc (get_frame_address_in_block (selected_frame));
+	}
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+
+  symbol = lookup_symbol (name, block, domain, &is_a_field_of_this);
+
+  ret_tuple = PyTuple_New (2);
+  if (!ret_tuple)
+    {
+      PyErr_SetString (PyExc_MemoryError, "Could not allocate tuple object.");
+      return NULL;
+    }
+
+  if (symbol)
+    {
+      sym_obj = symbol_to_symbol_object (symbol);
+      if (!sym_obj)
+	{
+	  Py_DECREF (ret_tuple);
+	  return NULL;
+	}
+    }
+  else
+    {
+      sym_obj = Py_None;
+      Py_INCREF (Py_None);
+    }
+  PyTuple_SET_ITEM (ret_tuple, 0, sym_obj);
+
+  bool_obj = is_a_field_of_this? Py_True : Py_False;
+  Py_INCREF (bool_obj);
+  PyTuple_SET_ITEM (ret_tuple, 1, bool_obj);
+
+  return ret_tuple;
+}
+
+void
+gdbpy_initialize_symbols (void)
+{
+  if (PyType_Ready (&symbol_object_type) < 0)
+    return;
+
+  /* FIXME: These would probably be best exposed as class attributes of Symbol,
+     but I don't know how to do it except by messing with the type's dictionary.
+     That seems too messy.  */
+  /* FIXME 2: Some of these were removed from GDB since I first wrote this code,
+     so it's probably a good idea not to expose them to Python.  */
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_UNDEF", LOC_UNDEF);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_CONST", LOC_CONST);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_STATIC", LOC_STATIC);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REGISTER", LOC_REGISTER);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_ARG", LOC_ARG);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REF_ARG", LOC_REF_ARG);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_LOCAL", LOC_LOCAL);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_TYPEDEF", LOC_TYPEDEF);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_LABEL", LOC_LABEL);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_BLOCK", LOC_BLOCK);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_CONST_BYTES",
+			   LOC_CONST_BYTES);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_UNRESOLVED", LOC_UNRESOLVED);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_OPTIMIZED_OUT",
+			   LOC_OPTIMIZED_OUT);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_COMPUTED", LOC_COMPUTED);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REGPARM_ADDR",
+			   LOC_REGPARM_ADDR);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_UNDEF_DOMAIN", UNDEF_DOMAIN);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_VAR_DOMAIN", VAR_DOMAIN);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_STRUCT_DOMAIN", STRUCT_DOMAIN);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_LABEL_DOMAIN", LABEL_DOMAIN);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_VARIABLES_DOMAIN",
+			   VARIABLES_DOMAIN);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_FUNCTIONS_DOMAIN",
+			   FUNCTIONS_DOMAIN);
+  PyModule_AddIntConstant (gdb_module, "SYMBOL_TYPES_DOMAIN", TYPES_DOMAIN);
+
+  Py_INCREF (&symbol_object_type);
+  PyModule_AddObject (gdb_module, "Symbol", (PyObject *) &symbol_object_type);
+}
+
+
+
+static PyGetSetDef symbol_object_getset[] = {
+  { "value", sympy_get_value, NULL, "Value of the symbol.", NULL },
+  { "symtab", sympy_get_symtab, NULL,
+    "Symbol table in which the symbol appears.", NULL },
+  { "name", sympy_get_name, NULL,
+    "Name of the symbol, as it appears in the source code.", NULL },
+  { "linkage_name", sympy_get_linkage_name, NULL,
+    "Name of the symbol, as used by the linker (i.e., may be mangled).", NULL },
+  { "print_name", sympy_get_print_name, NULL,
+    "Name of the symbol in a form suitable for output.\n\
+This is either name or linkage_name, depending on whether the user asked GDB\n\
+to display demangled or mangled names.", NULL },
+  { "addr_class", sympy_get_addr_class, NULL, "Address class of the symbol." },
+  { "is_argument", sympy_is_argument, NULL,
+    "True if the symbol is an argument of a function." },
+  { "is_constant", sympy_is_constant, NULL,
+    "True if the symbol is a constant." },
+  { "is_function", sympy_is_function, NULL,
+    "True if the symbol is a function or method." },
+  { "is_variable", sympy_is_variable, NULL,
+    "True if the symbol is a variable." },
+  { NULL }  /* Sentinel */
+};
+
+PyTypeObject symbol_object_type = {
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Symbol",			  /*tp_name*/
+  sizeof (symbol_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  0,				  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  sympy_str,			  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB symbol object",		  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  0,				  /* tp_methods */
+  0,				  /* tp_members */
+  symbol_object_getset		  /* tp_getset */
+};
diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c
new file mode 100644
index 0000000..830e586
--- /dev/null
+++ b/gdb/python/py-symtab.c
@@ -0,0 +1,322 @@
+/* Python interface to symbol tables.
+
+   Copyright (C) 2008, 2009 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 "charset.h"
+#include "symtab.h"
+#include "source.h"
+#include "python-internal.h"
+
+typedef struct {
+  PyObject_HEAD
+  struct symtab *symtab;
+} symtab_object;
+
+static PyTypeObject symtab_object_type;
+
+typedef struct {
+  PyObject_HEAD
+  symtab_object *symtab;
+  struct symtab_and_line *sal;
+} sal_object;
+
+static PyTypeObject sal_object_type;
+
+
+static PyObject *
+stpy_str (PyObject *self)
+{
+  int ret;
+  char *s;
+  PyObject *result;
+
+  ret = asprintf (&s, "symbol table for %s",
+		  ((symtab_object *) self)->symtab->filename);
+  if (ret < 0)
+    Py_RETURN_NONE;
+
+  result = PyString_FromString (s);
+  xfree (s);
+
+  return result;
+}
+
+static PyObject *
+stpy_get_filename (PyObject *self, void *closure)
+{
+  symtab_object *self_symtab = (symtab_object *) self;
+  PyObject *str_obj;
+
+  /* FIXME: Can symtab->filename really be NULL?  */
+  if (self_symtab->symtab->filename)
+    str_obj = PyString_Decode (self_symtab->symtab->filename,
+			       strlen (self_symtab->symtab->filename),
+			       host_charset (), NULL);
+  else
+    {
+      str_obj = Py_None;
+      Py_INCREF (Py_None);
+    }
+
+  return str_obj;
+}
+
+static PyObject *
+stpy_get_objfile (PyObject *self, void *closure)
+{
+  symtab_object *self_symtab = (symtab_object *) self;
+  PyObject *result = objfile_to_objfile_object (self_symtab->symtab->objfile);
+  Py_INCREF (result);
+  return result;
+}
+
+static PyObject *
+stpy_fullname (PyObject *self, PyObject *args)
+{
+  char *fullname;
+
+  fullname = symtab_to_fullname (((symtab_object *) self)->symtab);
+  if (fullname)
+    return PyString_Decode (fullname, strlen (fullname), host_charset (), NULL);
+
+  Py_RETURN_NONE;
+}
+
+static PyObject *
+salpy_str (PyObject *self)
+{
+  int ret;
+  char *s, *filename;
+  sal_object *sal_obj;
+  PyObject *result;
+
+  sal_obj = (sal_object *) self;
+  filename = (sal_obj->symtab == (symtab_object *) Py_None)? "<unknown>" :
+					   sal_obj->symtab->symtab->filename;
+  ret = asprintf (&s, "symbol and line for %s, line %d", filename,
+		  sal_obj->sal->line);
+  if (ret < 0)
+    Py_RETURN_NONE;
+
+  result = PyString_FromString (s);
+  xfree (s);
+
+  return result;
+}
+
+static PyObject *
+salpy_get_pc (PyObject *self, void *closure)
+{
+  return PyLong_FromUnsignedLongLong (((sal_object *) self)->sal->pc);
+}
+
+static PyObject *
+salpy_get_line (PyObject *self, void *closure)
+{
+  return PyLong_FromUnsignedLongLong (((sal_object *) self)->sal->line);
+}
+
+static PyObject *
+salpy_get_symtab (PyObject *self, void *closure)
+{
+  sal_object *self_sal = (sal_object *) self;
+
+  Py_INCREF (self_sal->symtab);
+
+  return (PyObject *) self_sal->symtab;
+}
+
+static void 
+salpy_dealloc (PyObject *self)
+{
+  sal_object *self_sal = (sal_object *) self;
+
+  Py_DECREF (self_sal->symtab);
+  xfree (self_sal->sal);
+  self_sal->ob_type->tp_free (self);
+}
+
+PyObject *
+symtab_and_line_to_sal_object (struct symtab_and_line sal)
+{
+  sal_object *sal_obj;
+  symtab_object *symtab_obj;
+
+  sal_obj = PyObject_New (sal_object, &sal_object_type);
+  if (sal_obj == NULL)
+    {
+      PyErr_SetString (PyExc_MemoryError,
+		       "Could not allocate Symtab_and_line object.");
+      return NULL;
+    }
+
+  if (sal.symtab)
+    {
+      symtab_obj = (symtab_object *) symtab_to_symtab_object (sal.symtab);
+      if (symtab_obj == NULL)
+	{
+	  Py_DECREF (sal_obj);
+	  return NULL;
+	}
+
+      symtab_obj->symtab = sal.symtab;
+    }
+  else
+    {
+      symtab_obj = (symtab_object *) Py_None;
+      Py_INCREF (Py_None);
+    }
+
+  sal_obj->sal = (struct symtab_and_line *)
+				    xmalloc (sizeof (struct symtab_and_line));
+  *(sal_obj->sal) = sal;
+  sal_obj->symtab = symtab_obj;
+
+  return (PyObject *) sal_obj;
+}
+
+PyObject *
+symtab_to_symtab_object (struct symtab *symtab)
+{
+  symtab_object *symtab_obj;
+  
+  symtab_obj = PyObject_New (symtab_object, &symtab_object_type);
+  if (symtab_obj == NULL)
+    {
+      PyErr_SetString (PyExc_MemoryError,
+	  "Could not allocate Symtab object.");
+
+      return NULL;
+    }
+
+  symtab_obj->symtab = symtab;
+
+  return (PyObject *) symtab_obj;
+}
+
+void
+gdbpy_initialize_symtabs (void)
+{
+  symtab_object_type.tp_new = PyType_GenericNew;
+  if (PyType_Ready (&symtab_object_type) < 0)
+    return;
+
+  sal_object_type.tp_new = PyType_GenericNew;
+  if (PyType_Ready (&sal_object_type) < 0)
+    return;
+
+  Py_INCREF (&symtab_object_type);
+  PyModule_AddObject (gdb_module, "Symtab", (PyObject *) &symtab_object_type);
+
+  Py_INCREF (&sal_object_type);
+  PyModule_AddObject (gdb_module, "Symtab_and_line",
+		      (PyObject *) &sal_object_type);
+}
+
+
+
+static PyGetSetDef symtab_object_getset[] = {
+  { "filename", stpy_get_filename, NULL,
+    "The symbol table's source filename.", NULL },
+  { "objfile", stpy_get_objfile, NULL, "The symtab's objfile.",
+    NULL },
+  {NULL}  /* Sentinel */
+};
+
+static PyMethodDef symtab_object_methods[] = {
+  { "fullname", stpy_fullname, METH_NOARGS,
+    "Return the symtab's full source filename." },
+  {NULL}  /* Sentinel */
+};
+
+static PyTypeObject symtab_object_type = {
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Symtab",			  /*tp_name*/
+  sizeof (symtab_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  0,				  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  stpy_str,			  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB symtab object",		  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  symtab_object_methods,	  /* tp_methods */
+  0,				  /* tp_members */
+  symtab_object_getset		  /* tp_getset */
+};
+
+static PyGetSetDef sal_object_getset[] = {
+  { "symtab", salpy_get_symtab, NULL, "Symtab object.", NULL },
+  { "pc", salpy_get_pc, NULL, "Return the symtab_and_line's pc.", NULL },
+  { "line", salpy_get_line, NULL,
+    "Return the symtab_and_line's line.", NULL },
+  {NULL}  /* Sentinel */
+};
+
+static PyTypeObject sal_object_type = {
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Symtab_and_line",	  /*tp_name*/
+  sizeof (sal_object),		  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  salpy_dealloc,		  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  salpy_str,			  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB symtab_and_line object",	  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  0,				  /* tp_methods */
+  0,				  /* tp_members */
+  sal_object_getset		  /* tp_getset */
+};
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 590d90a..f512248 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -27,6 +27,8 @@
 #include "demangle.h"
 #include "objfiles.h"
 #include "language.h"
+#include "observer.h"
+#include "gdb_assert.h"
 
 typedef struct pyty_type_object
 {
@@ -35,11 +37,17 @@ typedef struct pyty_type_object
 
   /* If a Type object is associated with an objfile, it is kept on a
      doubly-linked list, rooted in the objfile.  This lets us copy the
-     underlying struct type when the objfile is deleted.  */
+     underlying struct type when the objfile is deleted.
+
+     With NULL objfile Type still can be doubly-linked in the list
+     PYTY_OBJECTS_DISCARDABLE.  */
   struct pyty_type_object *prev;
   struct pyty_type_object *next;
 } type_object;
 
+/* First element of a doubly-linked list of TYPE_DISCARDABLE Types.  */
+static type_object *pyty_objects_discardable;
+
 static PyTypeObject type_object_type;
 
 /* A Field object.  */
@@ -169,6 +177,11 @@ convert_field (struct type *type, int field)
   if (PyObject_SetAttrString (result, "artificial", arg) < 0)
     goto failarg;
 
+  arg = field < TYPE_N_BASECLASSES (type) ? Py_True : Py_False;
+  Py_INCREF (arg);
+  if (PyObject_SetAttrString (result, "is_base_class", arg) < 0)
+    goto failarg;
+
   arg = PyLong_FromLong (TYPE_FIELD_BITSIZE (type, field));
   if (!arg)
     goto fail;
@@ -361,7 +374,7 @@ typy_get_sizeof (PyObject *self, void *closure)
 }
 
 static struct type *
-typy_lookup_typename (char *type_name)
+typy_lookup_typename (char *type_name, struct block *block)
 {
   struct type *type = NULL;
   volatile struct gdb_exception except;
@@ -375,7 +388,7 @@ typy_lookup_typename (char *type_name)
 	type = lookup_enum (type_name + 5, NULL);
       else
 	type = lookup_typename (python_language, python_gdbarch,
-				type_name, NULL, 0);
+				type_name, block, 0);
     }
   if (except.reason < 0)
     {
@@ -389,7 +402,8 @@ typy_lookup_typename (char *type_name)
 }
 
 static struct type *
-typy_lookup_type (struct demangle_component *demangled)
+typy_lookup_type (struct demangle_component *demangled,
+		  struct block *block)
 {
   struct type *type;
   char *type_name;
@@ -404,7 +418,7 @@ typy_lookup_type (struct demangle_component *demangled)
       || demangled_type == DEMANGLE_COMPONENT_CONST
       || demangled_type == DEMANGLE_COMPONENT_VOLATILE)
     {
-      type = typy_lookup_type (demangled->u.s_binary.left);
+      type = typy_lookup_type (demangled->u.s_binary.left, block);
       if (! type)
 	return NULL;
 
@@ -422,7 +436,7 @@ typy_lookup_type (struct demangle_component *demangled)
     }
 
   type_name = cp_comp_to_string (demangled, 10);
-  type = typy_lookup_typename (type_name);
+  type = typy_lookup_typename (type_name, block);
   xfree (type_name);
 
   return type;
@@ -436,10 +450,23 @@ typy_template_argument (PyObject *self, PyObject *args)
   struct demangle_component *demangled;
   const char *err;
   struct type *argtype;
+  struct block *block = NULL;
+  PyObject *block_obj = NULL;
 
-  if (! PyArg_ParseTuple (args, "i", &argno))
+  if (! PyArg_ParseTuple (args, "i|O", &argno, &block_obj))
     return NULL;
 
+  if (block_obj)
+    {
+      block = block_object_to_block (block_obj);
+      if (! block)
+	{
+	  PyErr_SetString (PyExc_RuntimeError,
+			   "second argument must be block");
+	  return NULL;
+	}
+    }
+
   type = check_typedef (type);
   if (TYPE_CODE (type) == TYPE_CODE_REF)
     type = check_typedef (TYPE_TARGET_TYPE (type));
@@ -482,7 +509,7 @@ typy_template_argument (PyObject *self, PyObject *args)
       return NULL;
     }
 
-  argtype = typy_lookup_type (demangled->u.s_binary.left);
+  argtype = typy_lookup_type (demangled->u.s_binary.left, block);
   if (! argtype)
     return NULL;
 
@@ -524,8 +551,59 @@ typy_str (PyObject *self)
 
 
 
+/* Key associated with each objfile pointing to the first element of
+   a doubly-linked list of Types associated with this objfile.  */
 static const struct objfile_data *typy_objfile_data_key;
 
+/* Link TYPE_OBJ to its appropriate list.  Either to its objfile associated one
+   or at least to the global list for TYPE_DISCARDABLE Types.  Permanent types
+   do not get linked anywhere.  */
+static void
+typy_link (type_object *type_obj)
+{
+  type_obj->prev = NULL;
+
+  if (type_obj->type && TYPE_OBJFILE (type_obj->type))
+    {
+      struct objfile *objfile = TYPE_OBJFILE (type_obj->type);
+
+      type_obj->next = objfile_data (objfile, typy_objfile_data_key);
+      if (type_obj->next)
+	type_obj->next->prev = type_obj;
+      set_objfile_data (objfile, typy_objfile_data_key, type_obj);
+    }
+  else if (type_obj->type && TYPE_DISCARDABLE (type_obj->type))
+    {
+      type_obj->next = pyty_objects_discardable;
+      if (type_obj->next)
+	type_obj->next->prev = type_obj;
+      pyty_objects_discardable = type_obj;
+    }
+  else
+    type_obj->next = NULL;
+}
+
+/* Unlink TYPE_OBJ from its current list.  Permanent types are not linked
+   anywhere and this function has no effect on them.  */
+static void
+typy_unlink (type_object *type_obj)
+{
+  if (type_obj->prev)
+    type_obj->prev->next = type_obj->next;
+  else if (type_obj->type && TYPE_OBJFILE (type_obj->type))
+    {
+      /* Must reset head of list.  */
+      struct objfile *objfile = TYPE_OBJFILE (type_obj->type);
+
+      set_objfile_data (objfile, typy_objfile_data_key, type_obj->next);
+    }
+  else if (pyty_objects_discardable == type_obj)
+    pyty_objects_discardable = type_obj->next;
+
+  if (type_obj->next)
+    type_obj->next->prev = type_obj->prev;
+}
+
 static void
 save_objfile_types (struct objfile *objfile, void *datum)
 {
@@ -543,12 +621,13 @@ save_objfile_types (struct objfile *objfile, void *datum)
     {
       type_object *next = obj->next;
 
-      htab_empty (copied_types);
+      gdb_assert (TYPE_OBJFILE (obj->type) == objfile);
+      typy_unlink (obj);
 
-      obj->type = copy_type_recursive (objfile, obj->type, copied_types);
+      obj->type = copy_type_recursive (obj->type, copied_types);
 
-      obj->next = NULL;
-      obj->prev = NULL;
+      gdb_assert (TYPE_OBJFILE (obj->type) == NULL);
+      typy_link (obj);
 
       obj = next;
     }
@@ -559,41 +638,25 @@ save_objfile_types (struct objfile *objfile, void *datum)
 }
 
 static void
-set_type (type_object *obj, struct type *type)
+typy_dealloc (PyObject *obj)
 {
-  obj->type = type;
-  obj->prev = NULL;
-  if (type && TYPE_OBJFILE (type))
-    {
-      struct objfile *objfile = TYPE_OBJFILE (type);
+  type_object *type_obj = (type_object *) obj;
 
-      obj->next = objfile_data (objfile, typy_objfile_data_key);
-      if (obj->next)
-	obj->next->prev = obj;
-      set_objfile_data (objfile, typy_objfile_data_key, obj);
-    }
-  else
-    obj->next = NULL;
+  typy_unlink (type_obj);
+
+  type_obj->ob_type->tp_free (obj);
 }
 
+/* Call type_mark_used for any TYPEs referenced from this GDB source file.  */
 static void
-typy_dealloc (PyObject *obj)
+typy_types_mark_used (void)
 {
-  type_object *type = (type_object *) obj;
-
-  if (type->prev)
-    type->prev->next = type->next;
-  else if (type->type && TYPE_OBJFILE (type->type))
-    {
-      /* Must reset head of list.  */
-      struct objfile *objfile = TYPE_OBJFILE (type->type);
-      if (objfile)
-	set_objfile_data (objfile, typy_objfile_data_key, type->next);
-    }
-  if (type->next)
-    type->next->prev = type->prev;
+  type_object *type_obj;
 
-  type->ob_type->tp_free (type);
+  for (type_obj = pyty_objects_discardable;
+       type_obj != NULL;
+       type_obj = type_obj->next)
+    type_mark_used (type_obj->type);
 }
 
 /* Create a new Type referring to TYPE.  */
@@ -604,7 +667,10 @@ type_to_type_object (struct type *type)
 
   type_obj = PyObject_New (type_object, &type_object_type);
   if (type_obj)
-    set_type (type_obj, type);
+    {
+      type_obj->type = type;
+      typy_link (type_obj);
+    }
 
   return (PyObject *) type_obj;
 }
@@ -623,14 +689,28 @@ type_object_to_type (PyObject *obj)
 PyObject *
 gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw)
 {
-  static char *keywords[] = { "name", NULL };
+  static char *keywords[] = { "name", "block", NULL };
   char *type_name = NULL;
   struct type *type = NULL;
+  PyObject *block_obj = NULL;
+  struct block *block = NULL;
 
-  if (! PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &type_name))
+  if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O", keywords,
+				     &type_name, &block_obj))
     return NULL;
 
-  type = typy_lookup_typename (type_name);
+  if (block_obj)
+    {
+      block = block_object_to_block (block_obj);
+      if (! block)
+	{
+	  PyErr_SetString (PyExc_RuntimeError,
+			   "'block' argument must be a Block");
+	  return NULL;
+	}
+    }
+
+  type = typy_lookup_typename (type_name, block);
   if (! type)
     return NULL;
 
@@ -664,6 +744,8 @@ gdbpy_initialize_types (void)
 
   Py_INCREF (&field_object_type);
   PyModule_AddObject (gdb_module, "Field", (PyObject *) &field_object_type);
+
+  observer_attach_mark_used (typy_types_mark_used);
 }
 
 
diff --git a/gdb/python/py-utils.c b/gdb/python/py-utils.c
index 49c0437..84a476e 100644
--- a/gdb/python/py-utils.c
+++ b/gdb/python/py-utils.c
@@ -19,6 +19,7 @@
 
 #include "defs.h"
 #include "charset.h"
+#include "value.h"
 #include "python-internal.h"
 
 
@@ -219,3 +220,48 @@ gdbpy_is_string (PyObject *obj)
 {
   return PyString_Check (obj) || PyUnicode_Check (obj);
 }
+
+/* Converts OBJ to a CORE_ADDR value.
+
+   Returns 1 on success or 0 on failure, with a Python exception set.  This
+   function can also throw GDB exceptions.  */
+
+int
+get_addr_from_python (PyObject *obj, CORE_ADDR *addr)
+{
+  if (gdbpy_is_value_object (obj))
+    *addr = value_as_address (value_object_to_value (obj));
+  else if (PyLong_Check (obj))
+    {
+      /* Assume CORE_ADDR corresponds to unsigned long.  */
+      *addr = PyLong_AsUnsignedLong (obj);
+      if (PyErr_Occurred () != NULL)
+	return 0;
+    }
+  else if (PyInt_Check (obj))
+    {
+      long val;
+
+      /* Assume CORE_ADDR corresponds to unsigned long.  */
+      val = PyInt_AsLong (obj);
+
+      if (val >= 0)
+	*addr = val;
+      else
+      {
+	/* If no error ocurred, VAL is indeed negative.  */
+	if (PyErr_Occurred () != NULL)
+	  return 0;
+
+	PyErr_SetString (PyExc_ValueError, "negative address");
+	return 0;
+      }
+    }
+  else
+    {
+      PyErr_SetString (PyExc_TypeError, "invalid type for address");
+      return 0;
+    }
+
+  return 1;
+}
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 3d88aa3..9fa1c44 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -25,6 +25,7 @@
 #include "language.h"
 #include "dfp.h"
 #include "valprint.h"
+#include "observer.h"
 
 #ifdef HAVE_PYTHON
 
@@ -43,6 +44,10 @@
 /* Python's long type corresponds to C's long long type.  */
 #define builtin_type_pylong builtin_type (python_gdbarch)->builtin_long_long
 
+/* Python's long type corresponds to C's long long type.  Unsigned version.  */
+#define builtin_type_upylong builtin_type \
+  (python_gdbarch)->builtin_unsigned_long_long
+
 #define builtin_type_pybool \
   language_bool_type (python_language, python_gdbarch)
 
@@ -324,7 +329,18 @@ valpy_getitem (PyObject *self, PyObject *key)
 	     type.  */
 	  struct value *idx = convert_value_from_python (key);
 	  if (idx != NULL)
-	    res_val = value_subscript (tmp, value_as_long (idx));
+	    {
+	      /* Check the value's type is something that can be accessed via
+		 a subscript.  */
+	      struct type *type;
+	      tmp = coerce_ref (tmp);
+	      type = check_typedef (value_type (tmp));
+	      if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+		  && TYPE_CODE (type) != TYPE_CODE_PTR)
+		  error( _("Cannot subscript requested type"));
+	      else
+		res_val = value_subscript (tmp, value_as_long (idx));
+	    }
 	}
     }
 
@@ -891,7 +907,34 @@ convert_value_from_python (PyObject *obj)
 	{
 	  LONGEST l = PyLong_AsLongLong (obj);
 
-	  if (! PyErr_Occurred ())
+	  if (PyErr_Occurred ())
+	    {
+	      /* If the error was an overflow, we can try converting to
+	         ULONGEST instead.  */
+	      if (PyErr_ExceptionMatches (PyExc_OverflowError))
+		{
+		  PyObject *etype, *evalue, *etraceback, *zero;
+
+		  PyErr_Fetch (&etype, &evalue, &etraceback);
+		  zero = PyInt_FromLong (0);
+
+		  /* Check whether obj is positive.  */
+		  if (PyObject_RichCompareBool (obj, zero, Py_GT) > 0)
+		    {
+		      ULONGEST ul;
+
+		      ul = PyLong_AsUnsignedLongLong (obj);
+		      if (! PyErr_Occurred ())
+			value = value_from_ulongest (builtin_type_upylong, ul);
+		    }
+		  else
+		    /* There's nothing we can do.  */
+		    PyErr_Restore (etype, evalue, etraceback);
+
+		  Py_DECREF (zero);
+		}
+	    }
+	  else
 	    value = value_from_longest (builtin_type_pylong, l);
 	}
       else if (PyFloat_Check (obj))
@@ -950,6 +993,25 @@ gdbpy_history (PyObject *self, PyObject *args)
   return value_to_value_object (res_val);
 }
 
+/* Call type_mark_used for any TYPEs referenced from this GDB source file.  */
+
+static void
+python_types_mark_used (void)
+{
+  value_object *iter;
+
+  for (iter = values_in_python; iter; iter = iter->next)
+    type_mark_used (value_type (iter->value));
+}
+
+/* Returns 1 in OBJ is a gdb.Value object, 0 otherwise.  */
+
+int
+gdbpy_is_value_object (PyObject *obj)
+{
+  return PyObject_TypeCheck (obj, &value_object_type);
+}
+
 void
 gdbpy_initialize_values (void)
 {
@@ -960,6 +1022,8 @@ gdbpy_initialize_values (void)
   PyModule_AddObject (gdb_module, "Value", (PyObject *) &value_object_type);
 
   values_in_python = NULL;
+
+  observer_attach_mark_used (python_types_mark_used);
 }
 
 
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 67a78af..47662d9 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -61,33 +61,76 @@ typedef int Py_ssize_t;
 #define PyEval_ReleaseLock() 0
 #endif
 
+#include "command.h"
+
+struct block;
+struct symbol;
+struct symtab_and_line;
 struct value;
 struct language_defn;
 
 extern PyObject *gdb_module;
+extern PyTypeObject block_object_type;
 extern PyTypeObject value_object_type;
+extern PyTypeObject symbol_object_type;
+
+/* Used in python-inferior.c.  */
+typedef struct
+{
+  PyObject_HEAD
+
+  /* The thread we represent.  */
+  struct thread_info *thread;
+
+  /* The Inferior object to which this thread belongs.  */
+  PyObject *inf_obj;
+} thread_object;
 
 PyObject *gdbpy_history (PyObject *self, PyObject *args);
+PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
 PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
+PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw);
 PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args);
+PyObject *gdbpy_block_for_pc (PyObject *self, PyObject *args);
 PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw);
+PyObject *gdbpy_inferiors (PyObject *unused, PyObject *unused2);
+PyObject *gdbpy_selected_thread (PyObject *self, PyObject *args);
 
+PyObject *symtab_and_line_to_sal_object (struct symtab_and_line sal);
+PyObject *symtab_to_symtab_object (struct symtab *symtab);
+PyObject *symbol_to_symbol_object (struct symbol *sym);
+PyObject *block_to_block_object (struct block *block);
 PyObject *value_to_value_object (struct value *v);
 PyObject *type_to_type_object (struct type *);
 PyObject *objfile_to_objfile_object (struct objfile *);
+PyObject *frame_info_to_frame_object (struct frame_info *frame);
+thread_object *create_thread_object (struct thread_info *tp);
+thread_object *find_thread_object (ptid_t ptid);
+PyObject *find_inferior_object (int pid);
 
 PyObject *objfpy_get_printers (PyObject *, void *);
 
+struct block *block_object_to_block (PyObject *obj);
+struct symbol *symbol_object_to_symbol (PyObject *obj);
 struct value *value_object_to_value (PyObject *self);
 struct value *convert_value_from_python (PyObject *obj);
 struct type *type_object_to_type (PyObject *obj);
 
+PyObject *gdbpy_get_hook_function (const char *);
+
 void gdbpy_initialize_values (void);
+void gdbpy_initialize_breakpoints (void);
 void gdbpy_initialize_frames (void);
+void gdbpy_initialize_symtabs (void);
 void gdbpy_initialize_commands (void);
+void gdbpy_initialize_symbols (void);
 void gdbpy_initialize_types (void);
+void gdbpy_initialize_blocks (void);
 void gdbpy_initialize_functions (void);
 void gdbpy_initialize_objfile (void);
+void gdbpy_initialize_parameters (void);
+void gdbpy_initialize_thread (void);
+void gdbpy_initialize_inferior (void);
 
 struct cleanup *make_cleanup_py_decref (PyObject *py);
 
@@ -97,6 +140,12 @@ struct cleanup *ensure_python_env (struct gdbarch *gdbarch,
 extern struct gdbarch *python_gdbarch;
 extern const struct language_defn *python_language;
 
+char *gdbpy_parse_command_name (char *text,
+				struct cmd_list_element ***base_list,
+				struct cmd_list_element **start_list);
+
+PyObject *gdbpy_parameter_value (enum var_types, void *);
+
 /* Use this after a TRY_EXCEPT to throw the appropriate Python
    exception.  */
 #define GDB_PY_HANDLE_EXCEPTION(Exception)				\
@@ -107,6 +156,19 @@ extern const struct language_defn *python_language;
 			     "%s", Exception.message);			\
     } while (0)
 
+/* Use this after a TRY_EXCEPT to throw the appropriate Python
+   exception.  This macro is for use inside setter functions.  */
+#define GDB_PY_SET_HANDLE_EXCEPTION(Exception)				\
+    do {								\
+      if (Exception.reason < 0)						\
+        {								\
+	  PyErr_Format (Exception.reason == RETURN_QUIT			\
+			? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \
+			"%s", Exception.message);			\
+	  return -1;							\
+	}								\
+    } while (0)
+
 
 void gdbpy_print_stack (void);
 
@@ -118,17 +180,22 @@ char *python_string_to_host_string (PyObject *obj);
 PyObject *target_string_to_unicode (const gdb_byte *str, int length);
 int gdbpy_is_string (PyObject *obj);
 
+int gdbpy_is_value_object (PyObject *obj);
+
 /* Note that these are declared here, and not in python.h with the
    other pretty-printer functions, because they refer to PyObject.  */
 PyObject *apply_varobj_pretty_printer (PyObject *print_obj,
 				       struct value **replacement);
 PyObject *gdbpy_get_varobj_pretty_printer (struct value *value);
+PyObject *gdbpy_instantiate_printer (PyObject *cons, PyObject *value);
 char *gdbpy_get_display_hint (PyObject *printer);
 PyObject *gdbpy_default_visualizer (PyObject *self, PyObject *args);
 
-extern PyObject *gdbpy_doc_cst;
 extern PyObject *gdbpy_children_cst;
 extern PyObject *gdbpy_to_string_cst;
 extern PyObject *gdbpy_display_hint_cst;
+extern PyObject *gdbpy_doc_cst;
+
+int get_addr_from_python (PyObject *obj, CORE_ADDR *addr);
 
 #endif /* GDB_PYTHON_INTERNAL_H */
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 254bd28..5a2a9ae 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -27,6 +27,7 @@
 #include "observer.h"
 #include "value.h"
 #include "language.h"
+#include "event-loop.h"
 
 #include <ctype.h>
 
@@ -45,11 +46,18 @@ static int gdbpy_auto_load = 1;
 #include "cli/cli-decode.h"
 #include "charset.h"
 #include "top.h"
+#include "solib.h"
 #include "exceptions.h"
 #include "python-internal.h"
+#include "linespec.h"
+#include "symtab.h"
+#include "source.h"
 #include "version.h"
+#include "inferior.h"
+#include "gdbthread.h"
 #include "target.h"
 #include "gdbthread.h"
+#include "event-top.h"
 
 static PyMethodDef GdbMethods[];
 
@@ -197,10 +205,10 @@ python_command (char *arg, int from_tty)
    NULL (and set a Python exception) on error.  Helper function for
    get_parameter.  */
 
-static PyObject *
-parameter_to_python (struct cmd_list_element *cmd)
+PyObject *
+gdbpy_parameter_value (enum var_types type, void *var)
 {
-  switch (cmd->var_type)
+  switch (type)
     {
     case var_string:
     case var_string_noescape:
@@ -208,7 +216,7 @@ parameter_to_python (struct cmd_list_element *cmd)
     case var_filename:
     case var_enum:
       {
-	char *str = * (char **) cmd->var;
+	char *str = * (char **) var;
 	if (! str)
 	  str = "";
 	return PyString_Decode (str, strlen (str), host_charset (), NULL);
@@ -216,7 +224,7 @@ parameter_to_python (struct cmd_list_element *cmd)
 
     case var_boolean:
       {
-	if (* (int *) cmd->var)
+	if (* (int *) var)
 	  Py_RETURN_TRUE;
 	else
 	  Py_RETURN_FALSE;
@@ -224,7 +232,7 @@ parameter_to_python (struct cmd_list_element *cmd)
 
     case var_auto_boolean:
       {
-	enum auto_boolean ab = * (enum auto_boolean *) cmd->var;
+	enum auto_boolean ab = * (enum auto_boolean *) var;
 	if (ab == AUTO_BOOLEAN_TRUE)
 	  Py_RETURN_TRUE;
 	else if (ab == AUTO_BOOLEAN_FALSE)
@@ -234,15 +242,15 @@ parameter_to_python (struct cmd_list_element *cmd)
       }
 
     case var_integer:
-      if ((* (int *) cmd->var) == INT_MAX)
+      if ((* (int *) var) == INT_MAX)
 	Py_RETURN_NONE;
       /* Fall through.  */
     case var_zinteger:
-      return PyLong_FromLong (* (int *) cmd->var);
+      return PyLong_FromLong (* (int *) var);
 
     case var_uinteger:
       {
-	unsigned int val = * (unsigned int *) cmd->var;
+	unsigned int val = * (unsigned int *) var;
 	if (val == UINT_MAX)
 	  Py_RETURN_NONE;
 	return PyLong_FromUnsignedLong (val);
@@ -280,7 +288,7 @@ gdbpy_parameter (PyObject *self, PyObject *args)
 
   if (! cmd->var)
     return PyErr_Format (PyExc_RuntimeError, "`%s' is not a parameter", arg);
-  return parameter_to_python (cmd);
+  return gdbpy_parameter_value (cmd->var_type, cmd->var);
 }
 
 /* A Python function which evaluates a string using the gdb CLI.  */
@@ -319,6 +327,233 @@ execute_gdb_command (PyObject *self, PyObject *args)
   Py_RETURN_NONE;
 }
 
+/* Implementation of gdb.solib_address (Long) -> String.
+   Returns the name of the shared library holding a given address, or None.  */
+
+static PyObject *
+gdbpy_solib_address (PyObject *self, PyObject *args)
+{
+  unsigned long long pc;
+  char *soname;
+  PyObject *str_obj;
+
+  if (!PyArg_ParseTuple (args, "K", &pc))
+    return NULL;
+
+  soname = solib_name_from_address (pc);
+  if (soname)
+    str_obj = PyString_Decode (soname, strlen (soname), host_charset (), NULL);
+  else
+    {
+      str_obj = Py_None;
+      Py_INCREF (Py_None);
+    }
+
+  return str_obj;
+}
+
+/* A Python function which is a wrapper for decode_line_1.  */
+
+static PyObject *
+gdbpy_decode_line (PyObject *self, PyObject *args)
+{
+  struct symtabs_and_lines sals = { NULL, 0 }; /* Initialize to appease gcc.  */
+  struct symtab_and_line sal;
+  char *arg = NULL;
+  int free_sals = 0, i;
+  PyObject *result = NULL;
+  volatile struct gdb_exception except;
+
+  if (! PyArg_ParseTuple (args, "|s", &arg))
+    return NULL;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      if (arg)
+	{
+	  char *copy;
+
+	  arg = strdup (arg);
+	  copy = arg;
+
+	  sals = decode_line_1 (&copy, 0, 0, 0, 0, 0);
+	  free_sals = 1;
+	}
+      else
+	{
+	  set_default_source_symtab_and_line ();
+	  sal = get_current_source_symtab_and_line ();
+	  sals.sals = &sal;
+	  sals.nelts = 1;
+	}
+    }
+  if (arg)
+    xfree (arg);
+
+  if (except.reason < 0)
+    {
+      if (free_sals)
+	xfree (sals.sals);
+      /* We know this will always throw.  */
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+
+  if (sals.nelts)
+    {
+      result = PyTuple_New (sals.nelts);
+      for (i = 0; i < sals.nelts; ++i)
+	{
+	  PyObject *obj;
+	  char *str;
+
+	  obj = symtab_and_line_to_sal_object (sals.sals[i]);
+	  if (! obj)
+	    {
+	      Py_DECREF (result);
+	      result = NULL;
+	      break;
+	    }
+
+	  PyTuple_SetItem (result, i, obj);
+	}
+    }
+
+  if (free_sals)
+    xfree (sals.sals);
+
+  if (result)
+    return result;
+  Py_RETURN_NONE;
+}
+
+/* Parse a string and evaluate it as an expression.  */
+static PyObject *
+gdbpy_parse_and_eval (PyObject *self, PyObject *args)
+{
+  char *expr_str;
+  struct value *result = NULL;
+  volatile struct gdb_exception except;
+
+  if (!PyArg_ParseTuple (args, "s", &expr_str))
+    return NULL;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      result = parse_and_eval (expr_str);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  return value_to_value_object (result);
+}
+
+
+
+/* Posting and handling events.  */
+
+/* A single event.  */
+struct gdbpy_event
+{
+  /* The Python event.  This is just a callable object.  */
+  PyObject *event;
+  /* The next event.  */
+  struct gdbpy_event *next;
+};
+
+/* All pending events.  */
+static struct gdbpy_event *gdbpy_event_list;
+/* The final link of the event list.  */
+static struct gdbpy_event **gdbpy_event_list_end;
+
+/* We use a file handler, and not an async handler, so that we can
+   wake up the main thread even when it is blocked in poll().  */
+static int gdbpy_event_fds[2];
+
+/* The file handler callback.  This reads from the internal pipe, and
+   then processes the Python event queue.  This will always be run in
+   the main gdb thread.  */
+static void
+gdbpy_run_events (int err, gdb_client_data ignore)
+{
+  PyGILState_STATE state;
+  char buffer[100];
+  int r;
+
+  state = PyGILState_Ensure ();
+
+  /* Just read whatever is available on the fd.  It is relatively
+     harmless if there are any bytes left over.  */
+  r = read (gdbpy_event_fds[0], buffer, sizeof (buffer));
+
+  while (gdbpy_event_list)
+    {
+      /* Dispatching the event might push a new element onto the event
+	 loop, so we update here "atomically enough".  */
+      struct gdbpy_event *item = gdbpy_event_list;
+      gdbpy_event_list = gdbpy_event_list->next;
+      if (gdbpy_event_list == NULL)
+	gdbpy_event_list_end = &gdbpy_event_list;
+
+      /* Ignore errors.  */
+      PyObject_CallObject (item->event, NULL);
+
+      Py_DECREF (item->event);
+      xfree (item);
+    }
+
+  PyGILState_Release (state);
+}
+
+/* Submit an event to the gdb thread.  */
+static PyObject *
+gdbpy_post_event (PyObject *self, PyObject *args)
+{
+  struct gdbpy_event *event;
+  PyObject *func;
+  int wakeup;
+
+  if (!PyArg_ParseTuple (args, "O", &func))
+    return NULL;
+
+  if (!PyCallable_Check (func))
+    {
+      PyErr_SetString (PyExc_RuntimeError, "Posted event is not callable");
+      return NULL;
+    }
+
+  Py_INCREF (func);
+
+  /* From here until the end of the function, we have the GIL, so we
+     can operate on our global data structures without worrying.  */
+  wakeup = gdbpy_event_list == NULL;
+
+  event = XNEW (struct gdbpy_event);
+  event->event = func;
+  event->next = NULL;
+  *gdbpy_event_list_end = event;
+  gdbpy_event_list_end = &event->next;
+
+  /* Wake up gdb when needed.  */
+  if (wakeup)
+    {
+      char c = 'q';		/* Anything. */
+      if (write (gdbpy_event_fds[1], &c, 1) != 1)
+        return PyErr_SetFromErrno (PyExc_IOError);
+    }
+
+  Py_RETURN_NONE;
+}
+
+/* Initialize the Python event handler.  */
+static void
+gdbpy_initialize_events (void)
+{
+  if (!pipe (gdbpy_event_fds))
+    {
+      gdbpy_event_list_end = &gdbpy_event_list;
+      add_file_handler (gdbpy_event_fds[0], gdbpy_run_events, NULL);
+    }
+}
+
 
 
 /* Printing.  */
@@ -357,6 +592,69 @@ gdbpy_print_stack (void)
 
 
 
+/* Script interface.  */
+
+/* True if 'gdb -P' was used, false otherwise.  */
+static int running_python_script;
+
+/* True if we are currently in a call to 'gdb.cli', false otherwise.  */
+static int in_cli;
+
+/* Enter the command loop.  */
+
+static PyObject *
+gdbpy_cli (PyObject *unused1, PyObject *unused2)
+{
+  if (! running_python_script || in_cli)
+    return PyErr_Format (PyExc_RuntimeError, "cannot invoke CLI recursively");
+
+  in_cli = 1;
+  cli_command_loop ();
+  in_cli = 0;
+
+  Py_RETURN_NONE;
+}
+
+/* Set up the Python argument vector and evaluate a script.  This is
+   used to implement 'gdb -P'.  */
+
+void
+run_python_script (int argc, char **argv)
+{
+  FILE *input;
+  PyGILState_STATE state;
+
+  /* We never free this, since we plan to exit at the end.  */
+  state = PyGILState_Ensure ();
+
+  running_python_script = 1;
+  PySys_SetArgv (argc - 1, argv + 1);
+  input = fopen (argv[0], "r");
+  if (! input)
+    {
+      fprintf (stderr, "could not open %s: %s\n", argv[0], strerror (errno));
+      exit (1);
+    }
+  PyRun_SimpleFile (input, argv[0]);
+  fclose (input);
+  exit (0);
+}
+
+void
+source_python_script (FILE *stream, char *file)
+{
+  PyGILState_STATE state;
+
+  state = PyGILState_Ensure ();
+
+  PyRun_SimpleFile (stream, file);
+
+  fclose (stream);
+  PyGILState_Release (state);
+}
+
+
+
 /* The "current" objfile.  This is set when gdb detects that a new
    objfile has been loaded.  It is only set for the duration of a call
    to gdbpy_new_objfile; it is NULL at other times.  */
@@ -501,6 +799,13 @@ eval_python_from_control_command (struct command_line *cmd)
   error (_("Python scripting is not supported in this copy of GDB."));
 }
 
+void
+source_python_script (FILE *stream)
+{
+  fclose (stream);
+  error (_("Python scripting is not supported in this copy of GDB."));
+}
+
 #endif /* HAVE_PYTHON */
 
 
@@ -592,13 +897,27 @@ Enables or disables auto-loading of Python code when an object is opened."),
   PyModule_AddStringConstant (gdb_module, "VERSION", (char*) version);
   PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", (char*) host_name);
   PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name);
+#ifdef PYTHONDIR
+  PyModule_AddStringConstant (gdb_module, "pythondir", PYTHONDIR);
+#else
+  if (gdb_datadir)
+    PyModule_AddStringConstant (gdb_module, "datadir", gdb_datadir);
+#endif
 
   gdbpy_initialize_values ();
+  gdbpy_initialize_breakpoints ();
   gdbpy_initialize_frames ();
+  gdbpy_initialize_symtabs ();
   gdbpy_initialize_commands ();
+  gdbpy_initialize_symbols ();
+  gdbpy_initialize_blocks ();
   gdbpy_initialize_functions ();
   gdbpy_initialize_types ();
+  gdbpy_initialize_parameters ();
   gdbpy_initialize_objfile ();
+  gdbpy_initialize_thread ();
+  gdbpy_initialize_inferior ();
+  gdbpy_initialize_events ();
 
   PyRun_SimpleString ("import gdb");
   PyRun_SimpleString ("gdb.pretty_printers = []");
@@ -634,6 +953,15 @@ class GdbOutputFile:\n\
 \n\
 sys.stderr = GdbOutputFile()\n\
 sys.stdout = GdbOutputFile()\n\
+if hasattr (gdb, 'datadir'):\n\
+  gdb.pythondir = gdb.datadir + '/python'\n\
+if hasattr (gdb, 'pythondir'):\n\
+  sys.path.insert(0, gdb.pythondir)\n\
+  gdb.__path__ = [gdb.pythondir + '/gdb']\n\
+  from os.path import exists\n\
+  ipy = gdb.pythondir + '/gdb/__init__.py'\n\
+  if exists (ipy):\n\
+    execfile (ipy)\n\
 ");
 
   /* Release the GIL while gdb runs.  */
@@ -653,9 +981,14 @@ static PyMethodDef GdbMethods[] =
     "Get a value from history" },
   { "execute", execute_gdb_command, METH_VARARGS,
     "Execute a gdb command" },
+  { "cli", gdbpy_cli, METH_NOARGS,
+    "Enter the gdb CLI" },
   { "parameter", gdbpy_parameter, METH_VARARGS,
     "Return a gdb parameter's value" },
 
+  { "breakpoints", gdbpy_breakpoints, METH_NOARGS,
+    "Return a tuple of all breakpoint objects" },
+
   { "default_visualizer", gdbpy_default_visualizer, METH_VARARGS,
     "Find the default visualizer for a Value." },
 
@@ -676,6 +1009,37 @@ Return a string explaining unwind stop reason." },
     "lookup_type (name [, block]) -> type\n\
 Return a Type corresponding to the given name." },
 
+  { "lookup_symbol", (PyCFunction) gdbpy_lookup_symbol,
+    METH_VARARGS | METH_KEYWORDS,
+    "lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)\n\
+Return a tuple with the symbol corresponding to the given name (or None) and\n\
+a boolean indicating if name is a field of the current implied argument\n\
+`this' (when the current language is object-oriented)." },
+  { "solib_address", gdbpy_solib_address, METH_VARARGS,
+    "solib_address (Long) -> String.\n\
+Return the name of the shared library holding a given address, or None." },
+
+  { "block_for_pc", gdbpy_block_for_pc, METH_VARARGS,
+    "Return the block containing the given pc value, or None." },
+
+  { "decode_line", gdbpy_decode_line, METH_VARARGS,
+    "Decode a string argument the way that 'break' or 'edit' does.\n\
+Return a tuple holding the file name (or None) and line number (or None).\n\
+Note: may later change to return an object." },
+
+  { "selected_thread", gdbpy_selected_thread, METH_NOARGS,
+    "selected_thread () -> gdb.InferiorThread.\n\
+Return the selected thread object." },
+  { "inferiors", gdbpy_inferiors, METH_NOARGS,
+    "inferiors () -> (gdb.Inferior, ...).\n\
+Return a tuple containing all inferiors." },
+
+  { "parse_and_eval", gdbpy_parse_and_eval, METH_VARARGS,
+    "Parse a string as an expression, evaluate it, and return the result." },
+
+  { "post_event", gdbpy_post_event, METH_VARARGS,
+    "Post an event into gdb's event loop." },
+
   { "write", gdbpy_write, METH_VARARGS,
     "Write a string using gdb's filtered stream." },
   { "flush", gdbpy_flush, METH_NOARGS,
diff --git a/gdb/python/python.h b/gdb/python/python.h
index e970180..bbb6184 100644
--- a/gdb/python/python.h
+++ b/gdb/python/python.h
@@ -24,6 +24,10 @@
 
 void eval_python_from_control_command (struct command_line *);
 
+void source_python_script (FILE *stream, char *file);
+
+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/scm-lang.c b/gdb/scm-lang.c
index de34894..07518b0 100644
--- a/gdb/scm-lang.c
+++ b/gdb/scm-lang.c
@@ -233,6 +233,7 @@ const struct exp_descriptor exp_descriptor_scm =
 {
   print_subexp_standard,
   operator_length_standard,
+  operator_check_standard,
   op_name_standard,
   dump_subexp_body_standard,
   evaluate_exp
diff --git a/gdb/scm-valprint.c b/gdb/scm-valprint.c
index cc3319a..d0d4702 100644
--- a/gdb/scm-valprint.c
+++ b/gdb/scm-valprint.c
@@ -62,9 +62,9 @@ scm_inferior_print (struct type *type, LONGEST value, struct ui_file *stream,
     {
       /* XXX: Should we cache these symbols?  */
       gdb_output_sym =
-	lookup_symbol_global ("gdb_output", NULL, NULL, VAR_DOMAIN);
+	lookup_symbol_global ("gdb_output", NULL, VAR_DOMAIN);
       gdb_output_len_sym =
-	lookup_symbol_global ("gdb_output_length", NULL, NULL, VAR_DOMAIN);
+	lookup_symbol_global ("gdb_output_length", NULL, VAR_DOMAIN);
 
       if ((gdb_output_sym == NULL) || (gdb_output_len_sym == NULL))
 	ret = -1;
diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c
index 8b96a6f..9428d92 100644
--- a/gdb/solib-darwin.c
+++ b/gdb/solib-darwin.c
@@ -389,7 +389,6 @@ darwin_relocate_section_addresses (struct so_list *so,
 static struct symbol *
 darwin_lookup_lib_symbol (const struct objfile *objfile,
 			  const char *name,
-			  const char *linkage_name,
 			  const domain_enum domain)
 {
   return NULL;
diff --git a/gdb/solib-spu.c b/gdb/solib-spu.c
index 19e3212..9f06fa9 100644
--- a/gdb/solib-spu.c
+++ b/gdb/solib-spu.c
@@ -334,16 +334,13 @@ spu_bfd_open (char *pathname)
 static struct symbol *
 spu_lookup_lib_symbol (const struct objfile *objfile,
 		       const char *name,
-		       const char *linkage_name,
 		       const domain_enum domain)
 {
   if (bfd_get_arch (objfile->obfd) == bfd_arch_spu)
-    return lookup_global_symbol_from_objfile (objfile, name, linkage_name,
-					      domain);
+    return lookup_global_symbol_from_objfile (objfile, name, domain);
 
   if (svr4_so_ops.lookup_lib_global_symbol != NULL)
-    return svr4_so_ops.lookup_lib_global_symbol (objfile, name, linkage_name,
-						 domain);
+    return svr4_so_ops.lookup_lib_global_symbol (objfile, name, domain);
   return NULL;
 }
 
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 6cfaa85..68aadc0 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1908,15 +1908,13 @@ struct target_so_ops svr4_so_ops;
 static struct symbol *
 elf_lookup_lib_symbol (const struct objfile *objfile,
 		       const char *name,
-		       const char *linkage_name,
 		       const domain_enum domain)
 {
   if (objfile->obfd == NULL
      || scan_dyntag (DT_SYMBOLIC, objfile->obfd, NULL) != 1)
     return NULL;
 
-  return lookup_global_symbol_from_objfile
-		(objfile, name, linkage_name, domain);
+  return lookup_global_symbol_from_objfile (objfile, name, domain);
 }
 
 extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
diff --git a/gdb/solib.c b/gdb/solib.c
index c7fd0fc..6f31852 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1127,13 +1127,12 @@ show_auto_solib_add (struct ui_file *file, int from_tty,
 struct symbol *
 solib_global_lookup (const struct objfile *objfile,
 		     const char *name,
-		     const char *linkage_name,
 		     const domain_enum domain)
 {
   struct target_so_ops *ops = solib_ops (target_gdbarch);
 
   if (ops->lookup_lib_global_symbol != NULL)
-    return ops->lookup_lib_global_symbol (objfile, name, linkage_name, domain);
+    return ops->lookup_lib_global_symbol (objfile, name, domain);
   return NULL;
 }
 
diff --git a/gdb/solist.h b/gdb/solist.h
index 63a6ba0..005e8f7 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -114,7 +114,6 @@ struct target_so_ops
     /* Hook for looking up global symbols in a library-specific way.  */
     struct symbol * (*lookup_lib_global_symbol) (const struct objfile *objfile,
 						 const char *name,
-						 const char *linkage_name,
 						 const domain_enum domain);
 
     /* Given two so_list objects, one from the GDB thread list
@@ -146,7 +145,6 @@ extern struct target_so_ops *current_target_so_ops;
 /* Handler for library-specific global symbol lookup in solib.c.  */
 struct symbol *solib_global_lookup (const struct objfile *objfile,
 				    const char *name,
-				    const char *linkage_name,
 				    const domain_enum domain);
 
 #endif
diff --git a/gdb/somread.c b/gdb/somread.c
index 36a2b28..4d5bda9 100644
--- a/gdb/somread.c
+++ b/gdb/somread.c
@@ -435,6 +435,7 @@ static struct sym_fns som_sym_fns =
   som_new_init,			/* sym_new_init: init anything gbl to entire symtab */
   som_symfile_init,		/* sym_init: read initial info, setup for sym_read() */
   som_symfile_read,		/* sym_read: read a symbol file into symtab */
+  NULL,				/* sym_read_psymbols */
   som_symfile_finish,		/* sym_finish: finished with file, cleanup */
   som_symfile_offsets,		/* sym_offsets:  Translate ext. to int. relocation */
   default_symfile_segments,	/* sym_segments: Get segment information from
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index 7e7ab9c..a014b7a 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -1839,7 +1839,7 @@ spu_catch_start (struct objfile *objfile)
       struct symbol *sym;
       struct symtab_and_line sal;
 
-      sym = lookup_block_symbol (block, "main", NULL, VAR_DOMAIN);
+      sym = lookup_block_symbol (block, "main", VAR_DOMAIN);
       if (sym)
 	{
 	  fixup_symbol_section (sym, objfile);
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index e62bb15..ad6568e 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -322,7 +322,7 @@ dbx_alloc_type (int typenums[2], struct objfile *objfile)
 
   if (typenums[0] == -1)
     {
-      return (alloc_type (objfile));
+      return (alloc_type (objfile, NULL));
     }
 
   type_addr = dbx_lookup_type (typenums, objfile);
@@ -332,7 +332,7 @@ dbx_alloc_type (int typenums[2], struct objfile *objfile)
      We will fill it in later if we find out how.  */
   if (*type_addr == 0)
     {
-      *type_addr = alloc_type (objfile);
+      *type_addr = alloc_type (objfile, NULL);
     }
 
   return (*type_addr);
diff --git a/gdb/stack.c b/gdb/stack.c
index 1c37801..594eb16 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1308,24 +1308,24 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
   else
     count = -1;
 
-  if (info_verbose)
-    {
-      struct partial_symtab *ps;
-
-      /* Read in symbols for all of the frames.  Need to do this in a
-         separate pass so that "Reading in symbols for xxx" messages
-         don't screw up the appearance of the backtrace.  Also if
-         people have strong opinions against reading symbols for
-         backtrace this may have to be an option.  */
-      i = count;
-      for (fi = trailing; fi != NULL && i--; fi = get_prev_frame (fi))
-	{
-	  QUIT;
-	  ps = find_pc_psymtab (get_frame_address_in_block (fi));
-	  if (ps)
-	    PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in.  */
-	}
-    }
+  {
+    struct partial_symtab *ps;
+
+    /* Read in symbols for all of the frames.  Need to do this
+       unconditionally to ensure that psymbols are read.  Also need to
+       do this in a separate pass so that "Reading in symbols for xxx"
+       messages don't screw up the appearance of the backtrace.  Also
+       if people have strong opinions against reading symbols for
+       backtrace this may have to be an option.  */
+    i = count;
+    for (fi = trailing; fi != NULL && i--; fi = get_prev_frame (fi))
+      {
+	QUIT;
+	ps = find_pc_psymtab (get_frame_address_in_block (fi));
+	if (info_verbose && ps)
+	  PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in.  */
+      }
+  }
 
   for (i = 0, fi = trailing; fi && count--; i++, fi = get_prev_frame (fi))
     {
@@ -1473,6 +1473,8 @@ print_block_frame_locals (struct block *b, struct frame_info *frame,
 	case LOC_COMPUTED:
 	  if (SYMBOL_IS_ARGUMENT (sym))
 	    break;
+	  if (SYMBOL_DOMAIN (sym) == COMMON_BLOCK_DOMAIN)
+	    break;
 	  values_printed = 1;
 	  print_variable_and_value (NULL, sym, frame, stream, 4 * num_tabs);
 	  break;
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 2f3441c..776066d 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -921,6 +921,17 @@ new_symfile_objfile (struct objfile *objfile, int add_flags)
   clear_complaints (&symfile_complaints, 0, add_flags & SYMFILE_VERBOSE);
 }
 
+/* A helper function which returns true if OBJFILE has any debug
+   symbols, and false otherwise.  */
+static int
+has_any_debug_symbols (struct objfile *objfile)
+{
+  return (objfile->psymtabs || objfile->quick_addrmap
+	  || (objfile->separate_debug_objfile
+	      && (objfile->separate_debug_objfile->psymtabs
+		  || objfile->separate_debug_objfile->quick_addrmap)));
+}
+
 /* Process a symbol file, as either the main file or as a dynamically
    loaded file.
 
@@ -958,13 +969,16 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
   /* Give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
 
-  if ((have_full_symbols () || have_partial_symbols ())
-      && (add_flags & SYMFILE_MAINLINE)
+  if ((add_flags & SYMFILE_MAINLINE)
+      && (have_full_symbols () || have_partial_symbols ())
       && from_tty
+      && (have_full_symbols () || have_partial_symbols ())
       && !query (_("Load new symbol table from \"%s\"? "), name))
     error (_("Not confirmed."));
 
   objfile = allocate_objfile (abfd, flags);
+  if (add_flags & SYMFILE_MAINLINE)
+    objfile->flags |= OBJF_MAIN;
   discard_cleanups (my_cleanups);
 
   if (addrs)
@@ -997,6 +1011,8 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
 
   if ((flags & OBJF_READNOW) || readnow_symbol_files)
     {
+      require_partial_symbols (objfile);
+
       if (from_tty || info_verbose)
 	{
 	  printf_unfiltered (_("expanding to full symbols..."));
@@ -1015,7 +1031,7 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
   /* If the file has its own symbol tables it has no separate debug info.
      `.dynsym'/`.symtab' go to MSYMBOLS, `.debug_info' goes to SYMTABS/PSYMTABS.
      `.gnu_debuglink' may no longer be present with `.note.gnu.build-id'.  */
-  if (objfile->psymtabs == NULL)
+  if (!has_any_debug_symbols (objfile))
     debugfile = find_separate_debug_file (objfile);
   if (debugfile)
     {
@@ -1039,9 +1055,10 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
       xfree (debugfile);
     }
 
+  /* has_any_debug_symbols is not fully compatible with the former calls which
+     would just be needlessly expensive here.  */
   if ((from_tty || info_verbose)
-      && !objfile_has_partial_symbols (objfile)
-      && !objfile_has_full_symbols (objfile))
+      && !has_any_debug_symbols (objfile))
     {
       wrap_here ("");
       printf_unfiltered (_("(no debugging symbols found)..."));
@@ -1150,7 +1167,9 @@ symbol_file_clear (int from_tty)
      descriptors as well.  */
   no_shared_libraries (NULL, from_tty);
 
-  symfile_objfile = NULL;
+  /* free_objfile should have cleared it.  */
+  gdb_assert (symfile_objfile == NULL);
+
   if (from_tty)
     printf_unfiltered (_("No symbol file now.\n"));
 }
@@ -2422,14 +2441,15 @@ reread_symbols (void)
 	         zero is OK since dbxread.c also does what it needs to do if
 	         objfile->global_psymbols.size is 0.  */
 	      (*objfile->sf->sym_read) (objfile, 0);
-	      if (!objfile_has_partial_symbols (objfile)
-		  && !objfile_has_full_symbols (objfile))
+	      if (!has_any_debug_symbols (objfile))
 		{
 		  wrap_here ("");
 		  printf_unfiltered (_("(no debugging symbols found)\n"));
 		  wrap_here ("");
 		}
 
+	      objfile->flags &= ~OBJF_SYMTABS_READ;
+
 	      /* We're done reading the symbol file; finish off complaints.  */
 	      clear_complaints (&symfile_complaints, 0, 1);
 
@@ -2727,7 +2747,7 @@ allocate_symtab (char *filename, struct objfile *objfile)
 }
 
 struct partial_symtab *
-allocate_psymtab (char *filename, struct objfile *objfile)
+allocate_psymtab (const char *filename, struct objfile *objfile)
 {
   struct partial_symtab *psymtab;
 
@@ -3041,7 +3061,8 @@ again2:
 
 struct partial_symtab *
 start_psymtab_common (struct objfile *objfile,
-		      struct section_offsets *section_offsets, char *filename,
+		      struct section_offsets *section_offsets,
+		      const char *filename,
 		      CORE_ADDR textlow, struct partial_symbol **global_syms,
 		      struct partial_symbol **static_syms)
 {
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 8c9249c..bf9d9e7 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -140,6 +140,12 @@ struct sym_fns
 
   void (*sym_read) (struct objfile *, int);
 
+  /* Read the partial symbols for an objfile.  This may be NULL, in
+     which case gdb assumes that sym_read already read the partial
+     symbols.  */
+
+  void (*sym_read_psymbols) (struct objfile *);
+
   /* Called when we are finished with an objfile.  Should do all
      cleanup that is specific to the object file format for the
      particular objfile.  */
@@ -266,7 +272,7 @@ extern void free_section_addr_info (struct section_addr_info *);
 
 extern struct partial_symtab *start_psymtab_common (struct objfile *,
 						    struct section_offsets *,
-						    char *, CORE_ADDR,
+						    const char *, CORE_ADDR,
 						    struct partial_symbol **,
 						    struct partial_symbol **);
 
@@ -309,7 +315,7 @@ extern int auto_solib_limit;
 
 extern void set_initial_language (void);
 
-extern struct partial_symtab *allocate_psymtab (char *, struct objfile *);
+extern struct partial_symtab *allocate_psymtab (const char *, struct objfile *);
 
 extern void discard_psymtab (struct partial_symtab *);
 
@@ -378,7 +384,7 @@ void free_symfile_segment_data (struct symfile_segment_data *data);
 /* From dwarf2read.c */
 
 extern int dwarf2_has_info (struct objfile *);
-
+extern void dwarf2_create_quick_addrmap (struct objfile *);
 extern void dwarf2_build_psymtabs (struct objfile *, int);
 extern void dwarf2_build_frame_info (struct objfile *);
 
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index eb35369..dfd8c8c 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -1128,7 +1128,7 @@ maintenance_check_symtabs (char *ignore, int from_tty)
     while (length--)
       {
 	sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
-				   NULL, SYMBOL_DOMAIN (*psym));
+				   SYMBOL_DOMAIN (*psym));
 	if (!sym)
 	  {
 	    printf_filtered ("Static symbol `");
@@ -1145,7 +1145,7 @@ maintenance_check_symtabs (char *ignore, int from_tty)
     while (length--)
       {
 	sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
-				   NULL, SYMBOL_DOMAIN (*psym));
+				   SYMBOL_DOMAIN (*psym));
 	if (!sym)
 	  {
 	    printf_filtered ("Global symbol `");
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 8d9d72c..82e0163 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -42,6 +42,7 @@
 #include "ada-lang.h"
 #include "p-lang.h"
 #include "addrmap.h"
+#include "cp-support.h"
 
 #include "hashtab.h"
 
@@ -85,7 +86,6 @@ static int find_line_common (struct linetable *, int, int *);
 char *operator_chars (char *p, char **end);
 
 static struct symbol *lookup_symbol_aux (const char *name,
-					 const char *linkage_name,
 					 const struct block *block,
 					 const domain_enum domain,
 					 enum language language,
@@ -93,20 +93,19 @@ static struct symbol *lookup_symbol_aux (const char *name,
 
 static
 struct symbol *lookup_symbol_aux_local (const char *name,
-					const char *linkage_name,
 					const struct block *block,
-					const domain_enum domain);
+					const domain_enum domain,
+					enum language language,
+					int *is_a_field_of_this);
 
 static
 struct symbol *lookup_symbol_aux_symtabs (int block_index,
 					  const char *name,
-					  const char *linkage_name,
 					  const domain_enum domain);
 
 static
 struct symbol *lookup_symbol_aux_psymtabs (int block_index,
 					   const char *name,
-					   const char *linkage_name,
 					   const domain_enum domain);
 
 static int file_matches (char *, char **, int);
@@ -271,7 +270,7 @@ lookup_partial_symtab (const char *name)
       make_cleanup (xfree, real_path);
     }
 
-  ALL_PSYMTABS (objfile, pst)
+  ALL_PSYMTABS_REQUIRED (objfile, pst)
   {
     if (FILENAME_CMP (name, pst->filename) == 0)
       {
@@ -414,7 +413,8 @@ symbol_init_language_specific (struct general_symbol_info *gsymbol,
   gsymbol->language = language;
   if (gsymbol->language == language_cplus
       || gsymbol->language == language_java
-      || gsymbol->language == language_objc)
+      || gsymbol->language == language_objc
+      || gsymbol->language == language_fortran)
     {
       gsymbol->language_specific.cplus_specific.demangled_name = NULL;
     }
@@ -474,7 +474,7 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol,
       || gsymbol->language == language_auto)
     {
       demangled =
-        cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
+        cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
       if (demangled != NULL)
 	{
 	  gsymbol->language = language_cplus;
@@ -633,6 +633,7 @@ symbol_natural_name (const struct general_symbol_info *gsymbol)
     case language_cplus:
     case language_java:
     case language_objc:
+    case language_fortran:
       if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
 	return gsymbol->language_specific.cplus_specific.demangled_name;
       break;
@@ -658,6 +659,7 @@ symbol_demangled_name (const struct general_symbol_info *gsymbol)
     case language_cplus:
     case language_java:
     case language_objc:
+    case language_fortran:
       if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
 	return gsymbol->language_specific.cplus_specific.demangled_name;
       break;
@@ -868,7 +870,13 @@ find_pc_sect_psymtab (CORE_ADDR pc, struct obj_section *section)
      than the later used TEXTLOW/TEXTHIGH one.  */
 
   ALL_OBJFILES (objfile)
-    if (objfile->psymtabs_addrmap != NULL)
+  {
+    if (objfile->quick_addrmap)
+      {
+	if (!addrmap_find (objfile->quick_addrmap, pc))
+	  continue;
+      }
+    if (require_partial_symbols (objfile)->psymtabs_addrmap != NULL)
       {
 	struct partial_symtab *pst;
 
@@ -901,6 +909,7 @@ find_pc_sect_psymtab (CORE_ADDR pc, struct obj_section *section)
 	    return pst;
 	  }
       }
+  }
 
   /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs
      which still have no corresponding full SYMTABs read.  But it is not
@@ -1168,6 +1177,22 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
   return psym;
 }
 
+/* Ensure that the partial symbols for OBJFILE have been loaded.  This
+   function always returns its argument, as a convenience.  */
+
+struct objfile *
+require_partial_symbols (struct objfile *objfile)
+{
+  if ((objfile->flags & OBJF_SYMTABS_READ) == 0)
+    {
+      objfile->flags |= OBJF_SYMTABS_READ;
+
+      if (objfile->sf->sym_read_psymbols)
+	(*objfile->sf->sym_read_psymbols) (objfile);
+    }
+  return objfile;
+}
+
 /* Find the definition for a specified symbol name NAME
    in domain DOMAIN, visible from lexical block BLOCK.
    Returns the struct symbol pointer, or zero if no symbol is found.
@@ -1194,10 +1219,14 @@ lookup_symbol_in_language (const char *name, const struct block *block,
 {
   char *demangled_name = NULL;
   const char *modified_name = NULL;
-  const char *mangled_name = NULL;
   struct symbol *returnval;
   struct cleanup *cleanup = make_cleanup (null_cleanup, 0);
 
+  if(strncmp(name, "::", 2) == 0){/* this must be a global name */
+    name = name+2;
+    block = NULL;
+  }
+  
   modified_name = name;
 
   /* If we are using C++ or Java, demangle the name before doing a lookup, so
@@ -1207,7 +1236,6 @@ lookup_symbol_in_language (const char *name, const struct block *block,
       demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
       if (demangled_name)
 	{
-	  mangled_name = name;
 	  modified_name = demangled_name;
 	  make_cleanup (xfree, demangled_name);
 	}
@@ -1229,7 +1257,6 @@ lookup_symbol_in_language (const char *name, const struct block *block,
 		      		       DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
       if (demangled_name)
 	{
-	  mangled_name = name;
 	  modified_name = demangled_name;
 	  make_cleanup (xfree, demangled_name);
 	}
@@ -1248,8 +1275,8 @@ lookup_symbol_in_language (const char *name, const struct block *block,
       modified_name = copy;
     }
 
-  returnval = lookup_symbol_aux (modified_name, mangled_name, block,
-				 domain, lang, is_a_field_of_this);
+  returnval = lookup_symbol_aux (modified_name, block, domain, lang,
+				 is_a_field_of_this);
   do_cleanups (cleanup);
 
   return returnval;
@@ -1273,9 +1300,9 @@ lookup_symbol (const char *name, const struct block *block,
    well.  */
 
 static struct symbol *
-lookup_symbol_aux (const char *name, const char *linkage_name,
-		   const struct block *block, const domain_enum domain,
-		   enum language language, int *is_a_field_of_this)
+lookup_symbol_aux (const char *name, const struct block *block,
+		   const domain_enum domain, enum language language,
+		   int *is_a_field_of_this)
 {
   struct symbol *sym;
   const struct language_defn *langdef;
@@ -1291,55 +1318,19 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
   /* Search specified block and its superiors.  Don't search
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
-  sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
+  sym = lookup_symbol_aux_local (name, block, domain, language, is_a_field_of_this);
   if (sym != NULL)
     return sym;
 
-  /* If requested to do so by the caller and if appropriate for LANGUAGE,
-     check to see if NAME is a field of `this'. */
-
-  langdef = language_def (language);
-
-  if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
-      && block != NULL)
-    {
-      struct symbol *sym = NULL;
-      /* 'this' is only defined in the function's block, so find the
-	 enclosing function block.  */
-      for (; block && !BLOCK_FUNCTION (block);
-	   block = BLOCK_SUPERBLOCK (block));
-
-      if (block && !dict_empty (BLOCK_DICT (block)))
-	sym = lookup_block_symbol (block, langdef->la_name_of_this,
-				   NULL, VAR_DOMAIN);
-      if (sym)
-	{
-	  struct type *t = sym->type;
-
-	  /* I'm not really sure that type of this can ever
-	     be typedefed; just be safe.  */
-	  CHECK_TYPEDEF (t);
-	  if (TYPE_CODE (t) == TYPE_CODE_PTR
-	      || TYPE_CODE (t) == TYPE_CODE_REF)
-	    t = TYPE_TARGET_TYPE (t);
-
-	  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
-	      && TYPE_CODE (t) != TYPE_CODE_UNION)
-	    error (_("Internal error: `%s' is not an aggregate"),
-		   langdef->la_name_of_this);
-
-	  if (check_field (t, name))
-	    {
-	      *is_a_field_of_this = 1;
-	      return NULL;
-	    }
-	}
-    }
+  /* this symbol was found to be a member variable
+     do not perform the global search. */
+  if (is_a_field_of_this && *is_a_field_of_this)
+    return NULL;
 
   /* Now do whatever is appropriate for LANGUAGE to look
      up static and global variables.  */
-
-  sym = langdef->la_lookup_symbol_nonlocal (name, linkage_name, block, domain);
+  langdef = language_def (language);
+  sym = langdef->la_lookup_symbol_nonlocal (name, block, domain);
   if (sym != NULL)
     return sym;
 
@@ -1349,11 +1340,11 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
      desired name as a file-level static, then do psymtab-to-symtab
      conversion on the fly and return the found symbol. */
 
-  sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, linkage_name, domain);
+  sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, domain);
   if (sym != NULL)
     return sym;
 
-  sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, linkage_name, domain);
+  sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, domain);
   if (sym != NULL)
     return sym;
 
@@ -1364,30 +1355,81 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
    Don't search STATIC_BLOCK or GLOBAL_BLOCK.  */
 
 static struct symbol *
-lookup_symbol_aux_local (const char *name, const char *linkage_name,
-			 const struct block *block,
-			 const domain_enum domain)
+lookup_symbol_aux_local (const char *name, const struct block *block,
+			 const domain_enum domain, enum language language,
+			 int *is_a_field_of_this)
 {
   struct symbol *sym;
-  const struct block *static_block = block_static_block (block);
+  const struct block *global_block = block_global_block (block);
+  const struct block *block_iterator = block;
+  const struct language_defn *langdef;
+
+  langdef = language_def (language);
 
   /* Check if either no block is specified or it's a global block.  */
 
-  if (static_block == NULL)
+  if (global_block == NULL)
     return NULL;
 
-  while (block != static_block)
+  while (block_iterator != global_block)
     {
-      sym = lookup_symbol_aux_block (name, linkage_name, block, domain);
+
+      sym = lookup_symbol_aux_block (name, block_iterator, domain);
+
       if (sym != NULL)
 	return sym;
-
-      if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
-	break;
-      block = BLOCK_SUPERBLOCK (block);
+    
+      if (language == language_cplus )
+        {
+          sym = cp_lookup_symbol_imports (block_scope (block_iterator), name,
+                                          block_iterator, domain, 1, 1);
+
+          if (sym != NULL)
+            return sym;
+        }
+
+      if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
+	  && BLOCK_FUNCTION (block_iterator))
+        {
+          if (!dict_empty (BLOCK_DICT (block_iterator)))
+            {
+              sym = lookup_block_symbol (block_iterator,
+					 langdef->la_name_of_this,
+					 VAR_DOMAIN);
+
+
+              if (sym)
+                {
+                  struct type *t = sym->type;
+
+                  /* I'm not really sure that type of this can ever
+                     be typedefed; just be safe.  */
+                  CHECK_TYPEDEF (t);
+                  if (TYPE_CODE (t) == TYPE_CODE_PTR
+                      || TYPE_CODE (t) == TYPE_CODE_REF)
+                      t = TYPE_TARGET_TYPE (t);
+
+                  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+                      && TYPE_CODE (t) != TYPE_CODE_UNION)
+                    error (_("Internal error: `%s' is not an aggregate"),
+                        langdef->la_name_of_this);
+
+                  if (check_field (t, name))
+                    {
+                      *is_a_field_of_this = 1;
+                      return NULL;
+                    }
+                }
+            }
+        }
+
+      if (BLOCK_FUNCTION (block_iterator) != NULL && block_inlined_p (block_iterator))
+        break;
+
+      block_iterator = BLOCK_SUPERBLOCK (block_iterator);
     }
 
-  /* We've reached the edge of the function without finding a result.  */
+  /* We've reached the global block without finding a result.  */
 
   return NULL;
 }
@@ -1416,13 +1458,12 @@ lookup_objfile_from_block (const struct block *block)
    block_found appropriately.  */
 
 struct symbol *
-lookup_symbol_aux_block (const char *name, const char *linkage_name,
-			 const struct block *block,
+lookup_symbol_aux_block (const char *name, const struct block *block,
 			 const domain_enum domain)
 {
   struct symbol *sym;
 
-  sym = lookup_block_symbol (block, name, linkage_name, domain);
+  sym = lookup_block_symbol (block, name, domain);
   if (sym)
     {
       block_found = block;
@@ -1438,7 +1479,6 @@ lookup_symbol_aux_block (const char *name, const char *linkage_name,
 struct symbol *
 lookup_global_symbol_from_objfile (const struct objfile *objfile,
 				   const char *name,
-				   const char *linkage_name,
 				   const domain_enum domain)
 {
   struct symbol *sym;
@@ -1452,7 +1492,7 @@ lookup_global_symbol_from_objfile (const struct objfile *objfile,
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-    sym = lookup_block_symbol (block, name, linkage_name, domain);
+    sym = lookup_block_symbol (block, name, domain);
     if (sym)
       {
 	block_found = block;
@@ -1461,23 +1501,23 @@ lookup_global_symbol_from_objfile (const struct objfile *objfile,
   }
 
   /* Now go through psymtabs.  */
+  require_partial_symbols ((struct objfile *) objfile);
   ALL_OBJFILE_PSYMTABS (objfile, ps)
   {
     if (!ps->readin
-	&& lookup_partial_symbol (ps, name, linkage_name,
-				  1, domain))
+	&& lookup_partial_symbol (ps, name, 1, domain))
       {
 	s = PSYMTAB_TO_SYMTAB (ps);
 	bv = BLOCKVECTOR (s);
 	block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-	sym = lookup_block_symbol (block, name, linkage_name, domain);
+	sym = lookup_block_symbol (block, name, domain);
 	return fixup_symbol_section (sym, (struct objfile *)objfile);
       }
   }
 
   if (objfile->separate_debug_objfile)
     return lookup_global_symbol_from_objfile (objfile->separate_debug_objfile,
-					      name, linkage_name, domain);
+					      name, domain);
 
   return NULL;
 }
@@ -1488,8 +1528,7 @@ lookup_global_symbol_from_objfile (const struct objfile *objfile,
    static symbols.  */
 
 static struct symbol *
-lookup_symbol_aux_symtabs (int block_index,
-			   const char *name, const char *linkage_name,
+lookup_symbol_aux_symtabs (int block_index, const char *name,
 			   const domain_enum domain)
 {
   struct symbol *sym;
@@ -1502,7 +1541,7 @@ lookup_symbol_aux_symtabs (int block_index,
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, block_index);
-    sym = lookup_block_symbol (block, name, linkage_name, domain);
+    sym = lookup_block_symbol (block, name, domain);
     if (sym)
       {
 	block_found = block;
@@ -1520,7 +1559,6 @@ lookup_symbol_aux_symtabs (int block_index,
 
 static struct symbol *
 lookup_symbol_aux_psymtabs (int block_index, const char *name,
-			    const char *linkage_name,
 			    const domain_enum domain)
 {
   struct symbol *sym;
@@ -1531,16 +1569,15 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name,
   struct symtab *s;
   const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
 
-  ALL_PSYMTABS (objfile, ps)
+  ALL_PSYMTABS_REQUIRED (objfile, ps)
   {
     if (!ps->readin
-	&& lookup_partial_symbol (ps, name, linkage_name,
-				  psymtab_index, domain))
+	&& lookup_partial_symbol (ps, name, psymtab_index, domain))
       {
 	s = PSYMTAB_TO_SYMTAB (ps);
 	bv = BLOCKVECTOR (s);
 	block = BLOCKVECTOR_BLOCK (bv, block_index);
-	sym = lookup_block_symbol (block, name, linkage_name, domain);
+	sym = lookup_block_symbol (block, name, domain);
 	if (!sym)
 	  {
 	    /* This shouldn't be necessary, but as a last resort try
@@ -1557,7 +1594,7 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name,
 	    block = BLOCKVECTOR_BLOCK (bv,
 				       block_index == GLOBAL_BLOCK ?
 				       STATIC_BLOCK : GLOBAL_BLOCK);
-	    sym = lookup_block_symbol (block, name, linkage_name, domain);
+	    sym = lookup_block_symbol (block, name, domain);
 	    if (!sym)
 	      error (_("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>)."),
 		     block_index == GLOBAL_BLOCK ? "global" : "static",
@@ -1576,7 +1613,6 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name,
 
 struct symbol *
 basic_lookup_symbol_nonlocal (const char *name,
-			      const char *linkage_name,
 			      const struct block *block,
 			      const domain_enum domain)
 {
@@ -1610,11 +1646,11 @@ basic_lookup_symbol_nonlocal (const char *name,
      than that one, so I don't think we should worry about that for
      now.  */
 
-  sym = lookup_symbol_static (name, linkage_name, block, domain);
+  sym = lookup_symbol_static (name, block, domain);
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_global (name, linkage_name, block, domain);
+  return lookup_symbol_global (name, block, domain);
 }
 
 /* Lookup a symbol in the static block associated to BLOCK, if there
@@ -1622,14 +1658,13 @@ basic_lookup_symbol_nonlocal (const char *name,
 
 struct symbol *
 lookup_symbol_static (const char *name,
-		      const char *linkage_name,
 		      const struct block *block,
 		      const domain_enum domain)
 {
   const struct block *static_block = block_static_block (block);
 
   if (static_block != NULL)
-    return lookup_symbol_aux_block (name, linkage_name, static_block, domain);
+    return lookup_symbol_aux_block (name, static_block, domain);
   else
     return NULL;
 }
@@ -1639,7 +1674,6 @@ lookup_symbol_static (const char *name,
 
 struct symbol *
 lookup_symbol_global (const char *name,
-		      const char *linkage_name,
 		      const struct block *block,
 		      const domain_enum domain)
 {
@@ -1649,15 +1683,15 @@ lookup_symbol_global (const char *name,
   /* Call library-specific lookup procedure.  */
   objfile = lookup_objfile_from_block (block);
   if (objfile != NULL)
-    sym = solib_global_lookup (objfile, name, linkage_name, domain);
+    sym = solib_global_lookup (objfile, name, domain);
   if (sym != NULL)
     return sym;
 
-  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name, domain);
+  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, domain);
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name, domain);
+  return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, domain);
 }
 
 int
@@ -1681,14 +1715,11 @@ symbol_matches_domain (enum language symbol_language,
 }
 
 /* Look, in partial_symtab PST, for symbol whose natural name is NAME.
-   If LINKAGE_NAME is non-NULL, check in addition that the symbol's
-   linkage name matches it.  Check the global symbols if GLOBAL, the
-   static symbols if not */
+   Check the global symbols if GLOBAL, the static symbols if not. */
 
 struct partial_symbol *
 lookup_partial_symbol (struct partial_symtab *pst, const char *name,
-		       const char *linkage_name, int global,
-		       domain_enum domain)
+		       int global, domain_enum domain)
 {
   struct partial_symbol *temp;
   struct partial_symbol **start, **psym;
@@ -1740,9 +1771,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
 	internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
 
       while (top <= real_top
-	     && (linkage_name != NULL
-		 ? strcmp (SYMBOL_LINKAGE_NAME (*top), linkage_name) == 0
-		 : SYMBOL_MATCHES_SEARCH_NAME (*top,name)))
+	     && SYMBOL_MATCHES_SEARCH_NAME (*top, name))
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
 				     SYMBOL_DOMAIN (*top), domain))
@@ -1759,15 +1788,9 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
       for (psym = start; psym < start + length; psym++)
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
-				     SYMBOL_DOMAIN (*psym), domain))
-	    {
-	      if (linkage_name != NULL
-		  ? strcmp (SYMBOL_LINKAGE_NAME (*psym), linkage_name) == 0
-		  : SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
-		{
-		  return (*psym);
-		}
-	    }
+				     SYMBOL_DOMAIN (*psym), domain)
+	      && SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
+	    return (*psym);
 	}
     }
 
@@ -1809,22 +1832,25 @@ basic_lookup_transparent_type (const char *name)
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-    sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
     if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
       {
 	return SYMBOL_TYPE (sym);
       }
   }
 
-  ALL_PSYMTABS (objfile, ps)
+  /* FIXME: .debug_pubnames should be read in.
+     
+     One may also try to the first pass without the require_partial_symbols
+     call but that would behave nondeterministically.  */
+  ALL_PSYMTABS_REQUIRED (objfile, ps)
   {
-    if (!ps->readin && lookup_partial_symbol (ps, name, NULL,
-					      1, STRUCT_DOMAIN))
+    if (!ps->readin && lookup_partial_symbol (ps, name, 1, STRUCT_DOMAIN))
       {
 	s = PSYMTAB_TO_SYMTAB (ps);
 	bv = BLOCKVECTOR (s);
 	block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-	sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+	sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
 	if (!sym)
 	  {
 	    /* This shouldn't be necessary, but as a last resort
@@ -1833,7 +1859,7 @@ basic_lookup_transparent_type (const char *name)
 	     * the psymtab gets it wrong in some cases.
 	     */
 	    block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-	    sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+	    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
 	    if (!sym)
 	      error (_("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n\
@@ -1857,21 +1883,26 @@ basic_lookup_transparent_type (const char *name)
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-    sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
     if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
       {
 	return SYMBOL_TYPE (sym);
       }
   }
 
-  ALL_PSYMTABS (objfile, ps)
+  /* FIXME: Something like .debug_pubnames containing also static symbols
+     should be read in.  Compiler needs to be taught to generate it first.
+     
+     One may also try to the first pass without the require_partial_symbols
+     call but that would behave nondeterministically.  */
+  ALL_PSYMTABS_REQUIRED (objfile, ps)
   {
-    if (!ps->readin && lookup_partial_symbol (ps, name, NULL, 0, STRUCT_DOMAIN))
+    if (!ps->readin && lookup_partial_symbol (ps, name, 0, STRUCT_DOMAIN))
       {
 	s = PSYMTAB_TO_SYMTAB (ps);
 	bv = BLOCKVECTOR (s);
 	block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-	sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+	sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
 	if (!sym)
 	  {
 	    /* This shouldn't be necessary, but as a last resort
@@ -1880,7 +1911,7 @@ basic_lookup_transparent_type (const char *name)
 	     * the psymtab gets it wrong in some cases.
 	     */
 	    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-	    sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+	    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
 	    if (!sym)
 	      error (_("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n\
@@ -1905,9 +1936,23 @@ find_main_psymtab (void)
   struct partial_symtab *pst;
   struct objfile *objfile;
 
-  ALL_PSYMTABS (objfile, pst)
+  ALL_OBJFILES (objfile)
+  {
+    if ((objfile->flags & OBJF_MAIN) == 0)
+      continue;
+    require_partial_symbols (objfile);
+    ALL_OBJFILE_PSYMTABS (objfile, pst)
+    {
+      if (lookup_partial_symbol (pst, main_name (), 1, VAR_DOMAIN))
+	{
+	  return pst;
+	}
+    }
+  }
+
+  ALL_PSYMTABS_REQUIRED (objfile, pst)
   {
-    if (lookup_partial_symbol (pst, main_name (), NULL, 1, VAR_DOMAIN))
+    if (lookup_partial_symbol (pst, main_name (), 1, VAR_DOMAIN))
       {
 	return (pst);
       }
@@ -1925,14 +1970,10 @@ find_main_psymtab (void)
    search on the symbols.  Each symbol which is marked as being a ObjC/C++
    symbol (language_cplus or language_objc set) has both the encoded and
    non-encoded names tested for a match.
-
-   If LINKAGE_NAME is non-NULL, verify that any symbol we find has this
-   particular mangled name.
 */
 
 struct symbol *
 lookup_block_symbol (const struct block *block, const char *name,
-		     const char *linkage_name,
 		     const domain_enum domain)
 {
   struct dict_iterator iter;
@@ -1945,9 +1986,7 @@ lookup_block_symbol (const struct block *block, const char *name,
 	   sym = dict_iter_name_next (name, &iter))
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
-				     SYMBOL_DOMAIN (sym), domain)
-	      && (linkage_name != NULL
-		  ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
+				     SYMBOL_DOMAIN (sym), domain))
 	    return sym;
 	}
       return NULL;
@@ -1967,9 +2006,7 @@ lookup_block_symbol (const struct block *block, const char *name,
 	   sym = dict_iter_name_next (name, &iter))
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
-				     SYMBOL_DOMAIN (sym), domain)
-	      && (linkage_name != NULL
-		  ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
+				     SYMBOL_DOMAIN (sym), domain))
 	    {
 	      sym_found = sym;
 	      if (!SYMBOL_IS_ARGUMENT (sym))
@@ -3172,7 +3209,7 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
      matching the regexp.  That way we don't have to reproduce all of
      the machinery below. */
 
-  ALL_PSYMTABS (objfile, ps)
+  ALL_PSYMTABS_REQUIRED (objfile, ps)
   {
     struct partial_symbol **bound, **gbound, **sbound;
     int keep_going = 1;
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 740d4e0..461ff95 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -171,9 +171,6 @@ extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *);
 #define SYMBOL_SECTION(symbol)		(symbol)->ginfo.section
 #define SYMBOL_OBJ_SECTION(symbol)	(symbol)->ginfo.obj_section
 
-#define SYMBOL_CPLUS_DEMANGLED_NAME(symbol)	\
-  (symbol)->ginfo.language_specific.cplus_specific.demangled_name
-
 /* Initializes the language dependent portion of a symbol
    depending upon the language for the symbol. */
 #define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \
@@ -394,7 +391,13 @@ typedef enum domain_enum_tag
   FUNCTIONS_DOMAIN,
 
   /* All defined types */
-  TYPES_DOMAIN
+  TYPES_DOMAIN,
+
+  /* Fortran common blocks.  Their naming must be separate from VAR_DOMAIN.  */
+  COMMON_BLOCK_DOMAIN,
+
+  /* Fortran module.  Their naming must be separate.  */
+  MODULE_DOMAIN
 }
 domain_enum;
 
@@ -990,7 +993,6 @@ extern struct symbol *lookup_symbol (const char *, const struct block *,
    that can't think of anything better to do.  */
 
 extern struct symbol *basic_lookup_symbol_nonlocal (const char *,
-						    const char *,
 						    const struct block *,
 						    const domain_enum);
 
@@ -1001,7 +1003,6 @@ extern struct symbol *basic_lookup_symbol_nonlocal (const char *,
    is one; do nothing if BLOCK is NULL or a global block.  */
 
 extern struct symbol *lookup_symbol_static (const char *name,
-					    const char *linkage_name,
 					    const struct block *block,
 					    const domain_enum domain);
 
@@ -1009,7 +1010,6 @@ extern struct symbol *lookup_symbol_static (const char *name,
    necessary).  */
 
 extern struct symbol *lookup_symbol_global (const char *name,
-					    const char *linkage_name,
 					    const struct block *block,
 					    const domain_enum domain);
 
@@ -1018,21 +1018,18 @@ extern struct symbol *lookup_symbol_global (const char *name,
    will fix up the symbol if necessary.  */
 
 extern struct symbol *lookup_symbol_aux_block (const char *name,
-					       const char *linkage_name,
 					       const struct block *block,
 					       const domain_enum domain);
 
 /* Lookup a partial symbol.  */
 
 extern struct partial_symbol *lookup_partial_symbol (struct partial_symtab *,
-						     const char *,
 						     const char *, int,
 						     domain_enum);
 
 /* lookup a symbol by name, within a specified block */
 
 extern struct symbol *lookup_block_symbol (const struct block *, const char *,
-					   const char *,
 					   const domain_enum);
 
 /* lookup a [struct, union, enum] by name, within a specified block */
@@ -1062,6 +1059,8 @@ extern void clear_pc_function_cache (void);
 
 /* from symtab.c: */
 
+struct objfile *require_partial_symbols (struct objfile *);
+
 /* lookup partial symbol table by filename */
 
 extern struct partial_symtab *lookup_partial_symtab (const char *);
@@ -1356,7 +1355,6 @@ extern /*const */ char *main_name (void);
 /* Check global symbols in objfile.  */
 struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile,
 						  const char *name,
-						  const char *linkage_name,
 						  const domain_enum domain);
 
 extern struct symtabs_and_lines
diff --git a/gdb/target.c b/gdb/target.c
index e5d14fd..37fab72 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -124,6 +124,8 @@ static int debug_to_insert_watchpoint (CORE_ADDR, int, int);
 
 static int debug_to_remove_watchpoint (CORE_ADDR, int, int);
 
+static int debug_to_detach_watchpoints (void);
+
 static int debug_to_stopped_by_watchpoint (void);
 
 static int debug_to_stopped_data_address (struct target_ops *, CORE_ADDR *);
@@ -622,6 +624,7 @@ update_current_target (void)
       INHERIT (to_remove_hw_breakpoint, t);
       INHERIT (to_insert_watchpoint, t);
       INHERIT (to_remove_watchpoint, t);
+      INHERIT (to_detach_watchpoints, t);
       INHERIT (to_stopped_data_address, t);
       INHERIT (to_have_steppable_watchpoint, t);
       INHERIT (to_have_continuable_watchpoint, t);
@@ -733,6 +736,9 @@ update_current_target (void)
   de_fault (to_remove_watchpoint,
 	    (int (*) (CORE_ADDR, int, int))
 	    return_minus_one);
+  de_fault (to_detach_watchpoints,
+	    (int (*) (void))
+	    return_zero);
   de_fault (to_stopped_by_watchpoint,
 	    (int (*) (void))
 	    return_zero);
@@ -3173,6 +3179,19 @@ debug_to_remove_watchpoint (CORE_ADDR addr, int len, int type)
   return retval;
 }
 
+static int
+debug_to_detach_watchpoints (void)
+{
+  int retval;
+
+  retval = debug_target.to_detach_watchpoints ();
+
+  fprintf_unfiltered (gdb_stdlog,
+		      "target_detach_watchpoints () = %ld\n",
+		      (unsigned long) retval);
+  return retval;
+}
+
 static void
 debug_to_terminal_init (void)
 {
@@ -3420,6 +3439,7 @@ setup_target_debug (void)
   current_target.to_remove_hw_breakpoint = debug_to_remove_hw_breakpoint;
   current_target.to_insert_watchpoint = debug_to_insert_watchpoint;
   current_target.to_remove_watchpoint = debug_to_remove_watchpoint;
+  current_target.to_detach_watchpoints = debug_to_detach_watchpoints;
   current_target.to_stopped_by_watchpoint = debug_to_stopped_by_watchpoint;
   current_target.to_stopped_data_address = debug_to_stopped_data_address;
   current_target.to_watchpoint_addr_within_range = debug_to_watchpoint_addr_within_range;
diff --git a/gdb/target.h b/gdb/target.h
index b1cb852..adff946 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -395,6 +395,7 @@ struct target_ops
     int (*to_remove_hw_breakpoint) (struct gdbarch *, struct bp_target_info *);
     int (*to_remove_watchpoint) (CORE_ADDR, int, int);
     int (*to_insert_watchpoint) (CORE_ADDR, int, int);
+    int (*to_detach_watchpoints) (void);
     int (*to_stopped_by_watchpoint) (void);
     int to_have_steppable_watchpoint;
     int to_have_continuable_watchpoint;
@@ -1166,6 +1167,15 @@ extern char *normal_pid_to_str (ptid_t ptid);
 #define	target_remove_watchpoint(addr, len, type)	\
      (*current_target.to_remove_watchpoint) (addr, len, type)
 
+/* Clear all debug registers without affecting any register caches.  Function
+   acts on INFERIOR_PTID which should be the forked-off process, either the
+   non-threaded child one or the threaded parent one, depending on `set
+   follow-fork-mode'.  Both watchpoints and hardware breakpoints get removed.
+   Return 0 on success, -1 on failure.  */
+
+#define	target_detach_watchpoints()	\
+     (*current_target.to_detach_watchpoints) ()
+
 #define target_insert_hw_breakpoint(gdbarch, bp_tgt) \
      (*current_target.to_insert_hw_breakpoint) (gdbarch, bp_tgt)
 
@@ -1203,6 +1213,20 @@ extern int target_search_memory (CORE_ADDR start_addr,
                                  ULONGEST pattern_len,
                                  CORE_ADDR *found_addrp);
 
+/* Utility functions which can be used by search_memory implementations.  */
+
+void allocate_pattern_buffer (char **pattern_bufp, char **pattern_buf_end,
+			      ULONGEST *pattern_buf_size);
+
+void increase_pattern_buffer (char **pattern_bufp, char **pattern_buf_end,
+			      ULONGEST *pattern_buf_size, int val_bytes);
+
+int search_memory (CORE_ADDR *start_addr, ULONGEST *search_space_len,
+		   const char *pattern_buf, ULONGEST pattern_len,
+		   CORE_ADDR *found_addr);
+
+void put_bits (bfd_uint64_t data, char *buf, int bits, bfd_boolean big_p);
+
 /* Command logging facility.  */
 
 #define target_log_command(p)						\
@@ -1322,6 +1346,14 @@ extern struct target_ops *find_target_beneath (struct target_ops *);
 
 extern char *target_get_osdata (const char *type);
 
+/* Read OS data object of type TYPE from the target, and return it in
+   XML format.  The result is NUL-terminated and returned as a string,
+   allocated using xmalloc.  If an error occurs or the transfer is
+   unsupported, NULL is returned.  Empty objects are returned as
+   allocated but empty strings.  */
+
+extern char *target_get_osdata (const char *type);
+
 
 /* Stuff that should be shared among the various remote targets.  */
 
diff --git a/gdb/testsuite/gdb.arch/powerpc-power7.exp b/gdb/testsuite/gdb.arch/powerpc-power7.exp
new file mode 100644
index 0000000..ae301db
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-power7.exp
@@ -0,0 +1,175 @@
+# 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.  
+
+# Test PowerPC Power7 instructions disassembly.
+
+if {![istarget "powerpc*-*-*"]} then {
+    verbose "Skipping PowerPC Power7 instructions disassembly."
+    return
+}
+
+set testfile "powerpc-power7"
+set srcfile ${testfile}.s
+set objfile ${objdir}/${subdir}/${testfile}.o
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] != "" } {
+    untested "PowerPC Power7 instructions disassembly"
+    return -1
+}
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${objfile}
+ 
+
+# Disassemble the function.
+
+set test "disass func"
+gdb_test_multiple $test $test {
+    -re "\r\nDump of assembler code for function func:(\r\n.*\r\n)End of assembler dump.\r\n$gdb_prompt $" {
+	set func $expect_out(1,string)
+	pass $test
+    }
+}
+
+proc instr_to_patt {offset instr} {
+    # 0x0000000000000018 <func+24>:	stxvd2x vs43,r4,r5
+    return ".*\r\n[string map {0x 0x0*} $offset] <func\\+?\[0-9\]*>:\[ \t\]*[string map [list { } "\[ \t\]+" . {\.}] $instr]\[ \t\]*\r\n.*"
+}
+
+# KFAIL strings would not exist if -Many would print the same as -Mpower7.
+# That means the power7 form should be the preferred one.
+# http://sourceware.org/ml/gdb-patches/2009-03/threads.html#00020
+
+proc func_check {offset instr {kfail ""}} {
+    global func
+
+    set test "Found $offset: $instr"
+    if [regexp -nocase -line [instr_to_patt $offset $instr] $func] {
+	pass $test
+    } elseif {$kfail != "" && [regexp -nocase -line [instr_to_patt $offset $kfail] $func]} {
+	kfail gdb/NNNN $test
+    } else {
+	fail $test
+    }
+}
+
+func_check   0x0 "lxvd2x  vs3,r4,r5"
+func_check   0x4 "lxvd2ux vs3,r4,r5"
+func_check   0x8 "lxvd2x  vs43,r4,r5"
+func_check   0xc "lxvd2ux vs43,r4,r5"
+func_check  0x10 "stxvd2x vs3,r4,r5"
+func_check  0x14 "stxvd2ux vs3,r4,r5"
+func_check  0x18 "stxvd2x vs43,r4,r5"
+func_check  0x1c "stxvd2ux vs43,r4,r5"
+func_check  0x20 "xxmrghd vs3,vs4,vs5"
+func_check  0x24 "xxmrghd vs43,vs44,vs45"
+func_check  0x28 "xxmrgld vs3,vs4,vs5"
+func_check  0x2c "xxmrgld vs43,vs44,vs45"
+func_check  0x30 "xxmrghd vs3,vs4,vs5"
+func_check  0x34 "xxmrghd vs43,vs44,vs45"
+func_check  0x38 "xxmrgld vs3,vs4,vs5"
+func_check  0x3c "xxmrgld vs43,vs44,vs45"
+func_check  0x40 "xxpermdi vs3,vs4,vs5,1"
+func_check  0x44 "xxpermdi vs43,vs44,vs45,1"
+func_check  0x48 "xxpermdi vs3,vs4,vs5,2"
+func_check  0x4c "xxpermdi vs43,vs44,vs45,2"
+func_check  0x50 "xvmovdp vs3,vs4"
+func_check  0x54 "xvmovdp vs43,vs44"
+func_check  0x58 "xvmovdp vs3,vs4"
+func_check  0x5c "xvmovdp vs43,vs44"
+func_check  0x60 "xvcpsgndp vs3,vs4,vs5"
+func_check  0x64 "xvcpsgndp vs43,vs44,vs45"
+func_check  0x68 "wait"
+func_check  0x6c "wait"
+func_check  0x70 "waitrsv"
+func_check  0x74 "waitrsv"
+func_check  0x78 "waitimpl"
+func_check  0x7c "waitimpl"
+func_check  0x80 "doze"
+func_check  0x84 "nap"
+func_check  0x88 "sleep"
+func_check  0x8c "rvwinkle"
+func_check  0x90 "prtyw   r3,r4"
+func_check  0x94 "prtyd   r13,r14"
+func_check  0x98 "mfcfar  r10"           "mfspr   r10,28"
+func_check  0x9c "mtcfar  r11"           "mtspr   28,r11"
+func_check  0xa0 "cmpb    r3,r4,r5"
+func_check  0xa4 "lwzcix  r10,r11,r12"
+func_check  0xa8 "dadd    f16,f17,f18"
+func_check  0xac "daddq   f20,f22,f24"
+func_check  0xb0 "dss     3"
+func_check  0xb4 "dssall"
+func_check  0xb8 "dst     r5,r4,1"
+func_check  0xbc "dstt    r8,r7,0"
+func_check  0xc0 "dstst   r5,r6,3"
+func_check  0xc4 "dststt  r4,r5,2"
+func_check  0xc8 "divwe   r10,r11,r12"
+func_check  0xcc "divwe.  r11,r12,r13"
+func_check  0xd0 "divweo  r12,r13,r14"
+func_check  0xd4 "divweo. r13,r14,r15"
+func_check  0xd8 "divweu  r10,r11,r12"
+func_check  0xdc "divweu. r11,r12,r13"
+func_check  0xe0 "divweuo r12,r13,r14"
+func_check  0xe4 "divweuo. r13,r14,r15"
+func_check  0xe8 "bpermd  r7,r17,r27"
+func_check  0xec "popcntw r10,r20"
+func_check  0xf0 "popcntd r10,r20"
+func_check  0xf4 "ldbrx   r20,r21,r22"
+func_check  0xf8 "stdbrx  r20,r21,r22"
+func_check  0xfc "lfiwzx  f10,0,r10"
+func_check 0x100 "lfiwzx  f10,r9,r10"
+func_check 0x104 "fcfids  f4,f5"
+func_check 0x108 "fcfids. f4,f5"
+func_check 0x10c "fcfidus f4,f5"
+func_check 0x110 "fcfidus. f4,f5"
+func_check 0x114 "fctiwu  f4,f5"
+func_check 0x118 "fctiwu. f4,f5"
+func_check 0x11c "fctiwuz f4,f5"
+func_check 0x120 "fctiwuz. f4,f5"
+func_check 0x124 "fctidu  f4,f5"
+func_check 0x128 "fctidu. f4,f5"
+func_check 0x12c "fctiduz f4,f5"
+func_check 0x130 "fctiduz. f4,f5"
+func_check 0x134 "fcfidu  f4,f5"
+func_check 0x138 "fcfidu. f4,f5"
+func_check 0x13c "ftdiv   cr0,f10,f11"
+func_check 0x140 "ftdiv   cr7,f10,f11"
+func_check 0x144 "ftsqrt  cr0,f10"
+func_check 0x148 "ftsqrt  cr7,f10"
+func_check 0x14c "dcbtt   r8,r9"         "dcbt    16,r8,r9"
+func_check 0x150 "dcbtstt r8,r9"         "dcbtst  16,r8,r9"
+func_check 0x154 "dcffix  f10,f12"
+func_check 0x158 "dcffix. f20,f22"
+func_check 0x15c "lbarx   r10,r11,r12"
+func_check 0x160 "lbarx   r10,r11,r12"
+func_check 0x164 "lbarx   r10,r11,r12,1"
+func_check 0x168 "lharx   r20,r21,r22"
+func_check 0x16c "lharx   r20,r21,r22"
+func_check 0x170 "lharx   r20,r21,r22,1"
+func_check 0x174 "stbcx.  r10,r11,r12"
+func_check 0x178 "sthcx.  r10,r11,r12"
+func_check 0x17c "fre     f14,f15"
+func_check 0x180 "fre.    f14,f15"
+func_check 0x184 "fres    f14,f15"
+func_check 0x188 "fres.   f14,f15"
+func_check 0x18c "frsqrte f14,f15"
+func_check 0x190 "frsqrte. f14,f15"
+func_check 0x194 "frsqrtes f14,f15"
+func_check 0x198 "frsqrtes. f14,f15"
+func_check 0x19c "isel    r2,r3,r4,28"
diff --git a/gdb/testsuite/gdb.arch/powerpc-power7.s b/gdb/testsuite/gdb.arch/powerpc-power7.s
new file mode 100644
index 0000000..98b2e79
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-power7.s
@@ -0,0 +1,107 @@
+	.text
+	.globl	func
+func:
+	.long	0x7c642e98	/*   0: lxvd2x  vs3,r4,r5         */
+	.long	0x7c642ed8	/*   4: lxvd2ux vs3,r4,r5         */
+	.long	0x7d642e99	/*   8: lxvd2x  vs43,r4,r5        */
+	.long	0x7d642ed9	/*   c: lxvd2ux vs43,r4,r5        */
+	.long	0x7c642f98	/*  10: stxvd2x vs3,r4,r5         */
+	.long	0x7c642fd8	/*  14: stxvd2ux vs3,r4,r5        */
+	.long	0x7d642f99	/*  18: stxvd2x vs43,r4,r5        */
+	.long	0x7d642fd9	/*  1c: stxvd2ux vs43,r4,r5       */
+	.long	0xf0642850	/*  20: xxmrghd vs3,vs4,vs5       */
+	.long	0xf16c6857	/*  24: xxmrghd vs43,vs44,vs45    */
+	.long	0xf0642b50	/*  28: xxmrgld vs3,vs4,vs5       */
+	.long	0xf16c6b57	/*  2c: xxmrgld vs43,vs44,vs45    */
+	.long	0xf0642850	/*  30: xxmrghd vs3,vs4,vs5       */
+	.long	0xf16c6857	/*  34: xxmrghd vs43,vs44,vs45    */
+	.long	0xf0642b50	/*  38: xxmrgld vs3,vs4,vs5       */
+	.long	0xf16c6b57	/*  3c: xxmrgld vs43,vs44,vs45    */
+	.long	0xf0642950	/*  40: xxpermdi vs3,vs4,vs5,1    */
+	.long	0xf16c6957	/*  44: xxpermdi vs43,vs44,vs45,1 */
+	.long	0xf0642a50	/*  48: xxpermdi vs3,vs4,vs5,2    */
+	.long	0xf16c6a57	/*  4c: xxpermdi vs43,vs44,vs45,2 */
+	.long	0xf0642780	/*  50: xvmovdp vs3,vs4           */
+	.long	0xf16c6787	/*  54: xvmovdp vs43,vs44         */
+	.long	0xf0642780	/*  58: xvmovdp vs3,vs4           */
+	.long	0xf16c6787	/*  5c: xvmovdp vs43,vs44         */
+	.long	0xf0642f80	/*  60: xvcpsgndp vs3,vs4,vs5     */
+	.long	0xf16c6f87	/*  64: xvcpsgndp vs43,vs44,vs45  */
+	.long	0x7c00007c	/*  68: wait                      */
+	.long	0x7c00007c	/*  6c: wait                      */
+	.long	0x7c20007c	/*  70: waitrsv                   */
+	.long	0x7c20007c	/*  74: waitrsv                   */
+	.long	0x7c40007c	/*  78: waitimpl                  */
+	.long	0x7c40007c	/*  7c: waitimpl                  */
+	.long	0x4c000324	/*  80: doze                      */
+	.long	0x4c000364	/*  84: nap                       */
+	.long	0x4c0003a4	/*  88: sleep                     */
+	.long	0x4c0003e4	/*  8c: rvwinkle                  */
+	.long	0x7c830134	/*  90: prtyw   r3,r4             */
+	.long	0x7dcd0174	/*  94: prtyd   r13,r14           */
+	.long	0x7d5c02a6	/*  98: mfcfar  r10               */
+	.long	0x7d7c03a6	/*  9c: mtcfar  r11               */
+	.long	0x7c832bf8	/*  a0: cmpb    r3,r4,r5          */
+	.long	0x7d4b662a	/*  a4: lwzcix  r10,r11,r12       */
+	.long	0xee119004	/*  a8: dadd    f16,f17,f18       */
+	.long	0xfe96c004	/*  ac: daddq   f20,f22,f24       */
+	.long	0x7c60066c	/*  b0: dss     3                 */
+	.long	0x7e00066c	/*  b4: dssall                    */
+	.long	0x7c2522ac	/*  b8: dst     r5,r4,1           */
+	.long	0x7e083aac	/*  bc: dstt    r8,r7,0           */
+	.long	0x7c6532ec	/*  c0: dstst   r5,r6,3           */
+	.long	0x7e442aec	/*  c4: dststt  r4,r5,2           */
+	.long	0x7d4b6356	/*  c8: divwe   r10,r11,r12       */
+	.long	0x7d6c6b57	/*  cc: divwe.  r11,r12,r13       */
+	.long	0x7d8d7756	/*  d0: divweo  r12,r13,r14       */
+	.long	0x7dae7f57	/*  d4: divweo. r13,r14,r15       */
+	.long	0x7d4b6316	/*  d8: divweu  r10,r11,r12       */
+	.long	0x7d6c6b17	/*  dc: divweu. r11,r12,r13       */
+	.long	0x7d8d7716	/*  e0: divweuo r12,r13,r14       */
+	.long	0x7dae7f17	/*  e4: divweuo. r13,r14,r15      */
+	.long	0x7e27d9f8	/*  e8: bpermd  r7,r17,r27        */
+	.long	0x7e8a02f4	/*  ec: popcntw r10,r20           */
+	.long	0x7e8a03f4	/*  f0: popcntd r10,r20           */
+	.long	0x7e95b428	/*  f4: ldbrx   r20,r21,r22       */
+	.long	0x7e95b528	/*  f8: stdbrx  r20,r21,r22       */
+	.long	0x7d4056ee	/*  fc: lfiwzx  f10,0,r10         */
+	.long	0x7d4956ee	/* 100: lfiwzx  f10,r9,r10        */
+	.long	0xec802e9c	/* 104: fcfids  f4,f5             */
+	.long	0xec802e9d	/* 108: fcfids. f4,f5             */
+	.long	0xec802f9c	/* 10c: fcfidus f4,f5             */
+	.long	0xec802f9d	/* 110: fcfidus. f4,f5            */
+	.long	0xfc80291c	/* 114: fctiwu  f4,f5             */
+	.long	0xfc80291d	/* 118: fctiwu. f4,f5             */
+	.long	0xfc80291e	/* 11c: fctiwuz f4,f5             */
+	.long	0xfc80291f	/* 120: fctiwuz. f4,f5            */
+	.long	0xfc802f5c	/* 124: fctidu  f4,f5             */
+	.long	0xfc802f5d	/* 128: fctidu. f4,f5             */
+	.long	0xfc802f5e	/* 12c: fctiduz f4,f5             */
+	.long	0xfc802f5f	/* 130: fctiduz. f4,f5            */
+	.long	0xfc802f9c	/* 134: fcfidu  f4,f5             */
+	.long	0xfc802f9d	/* 138: fcfidu. f4,f5             */
+	.long	0xfc0a5900	/* 13c: ftdiv   cr0,f10,f11       */
+	.long	0xff8a5900	/* 140: ftdiv   cr7,f10,f11       */
+	.long	0xfc005140	/* 144: ftsqrt  cr0,f10           */
+	.long	0xff805140	/* 148: ftsqrt  cr7,f10           */
+	.long	0x7e084a2c	/* 14c: dcbtt   r8,r9             */
+	.long	0x7e0849ec	/* 150: dcbtstt r8,r9             */
+	.long	0xed406644	/* 154: dcffix  f10,f12           */
+	.long	0xee80b645	/* 158: dcffix. f20,f22           */
+	.long	0x7d4b6068	/* 15c: lbarx   r10,r11,r12       */
+	.long	0x7d4b6068	/* 160: lbarx   r10,r11,r12       */
+	.long	0x7d4b6069	/* 164: lbarx   r10,r11,r12,1     */
+	.long	0x7e95b0e8	/* 168: lharx   r20,r21,r22       */
+	.long	0x7e95b0e8	/* 16c: lharx   r20,r21,r22       */
+	.long	0x7e95b0e9	/* 170: lharx   r20,r21,r22,1     */
+	.long	0x7d4b656d	/* 174: stbcx.  r10,r11,r12       */
+	.long	0x7d4b65ad	/* 178: sthcx.  r10,r11,r12       */
+	.long	0xfdc07830	/* 17c: fre     f14,f15           */
+	.long	0xfdc07831	/* 180: fre.    f14,f15           */
+	.long	0xedc07830	/* 184: fres    f14,f15           */
+	.long	0xedc07831	/* 188: fres.   f14,f15           */
+	.long	0xfdc07834	/* 18c: frsqrte f14,f15           */
+	.long	0xfdc07835	/* 190: frsqrte. f14,f15          */
+	.long	0xedc07834	/* 194: frsqrtes f14,f15          */
+	.long	0xedc07835	/* 198: frsqrtes. f14,f15         */
+	.long	0x7c43271e	/* 19c: isel    r2,r3,r4,28       */
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 98d4d35..f98a656 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 71ce4aa..af0e5f8 100644
--- a/gdb/testsuite/gdb.base/arrayidx.exp
+++ b/gdb/testsuite/gdb.base/arrayidx.exp
@@ -59,4 +59,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/help.exp b/gdb/testsuite/gdb.base/help.exp
index d76cc36..496ff18 100644
--- a/gdb/testsuite/gdb.base/help.exp
+++ b/gdb/testsuite/gdb.base/help.exp
@@ -606,7 +606,7 @@ gdb_test "help stepi" "Step one instruction exactly\.\[\r\n\]+Argument N means d
 gdb_test "help signal" "Continue program giving it signal.*" "help signal"
 # test help source
 # vxgdb reads .vxgdbinit
-gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Optional -v switch \\(before the filename\\) causes each command in\[\r\n\]+FILE to be echoed as it is executed\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when GDB is started\." "help source"
+gdb_test "help source" "Read commands from a file named FILE\.\[\r\n\]+Optional -v switch \\(before the filename\\) causes each command in\[\r\n\]+FILE to be echoed as it is executed\.\[\r\n\]+Note that the file \"\[^\"\]*\" is read automatically in this way\[\r\n\]+when GDB is started\.\[\r\n\]+Optional -p switch \\(before the filename\\) causes FILE to be evaluated\[\r\n\]+as Python code\." "help source"
 # test help stack
 test_class_help "stack" {
     "Examining the stack\..*\[\r\n\]+"
diff --git a/gdb/testsuite/gdb.base/lineno-makeup-func.c b/gdb/testsuite/gdb.base/lineno-makeup-func.c
new file mode 100644
index 0000000..1a0220e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/lineno-makeup-func.c
@@ -0,0 +1,21 @@
+/* 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/>.  */
+
+void
+func (void)
+{
+}
diff --git a/gdb/testsuite/gdb.base/lineno-makeup.c b/gdb/testsuite/gdb.base/lineno-makeup.c
new file mode 100644
index 0000000..bb20e98
--- /dev/null
+++ b/gdb/testsuite/gdb.base/lineno-makeup.c
@@ -0,0 +1,35 @@
+/* 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/>.  */
+
+/* DW_AT_low_pc-DW_AT_high_pc should cover the function without line number
+   information (.debug_line) so we cannot use an external object file.
+   
+   It must not be just a label as it would alias on the next function even for
+   correct GDB.  Therefore some stub data must be placed there.
+   
+   We need to provide a real stub function body as at least s390
+   (s390_analyze_prologue) would skip the whole body till reaching `main'.  */
+
+extern void func (void);
+asm ("func: .incbin \"gdb.base/lineno-makeup-func.bin\"");
+
+int
+main (void)
+{
+  func ();
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/lineno-makeup.exp b/gdb/testsuite/gdb.base/lineno-makeup.exp
new file mode 100644
index 0000000..0c75b84
--- /dev/null
+++ b/gdb/testsuite/gdb.base/lineno-makeup.exp
@@ -0,0 +1,78 @@
+# 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 testfile "lineno-makeup"
+set srcfuncfile ${testfile}-func.c
+set srcfile ${testfile}.c
+set objfuncfile ${objdir}/${subdir}/${testfile}-func.o
+set binfuncfile ${objdir}/${subdir}/${testfile}-func.bin
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfuncfile}" "${objfuncfile}" object {}] != "" } {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+set objcopy [catch "exec objcopy -O binary --only-section .text ${objfuncfile} ${binfuncfile}" output]
+verbose -log "objcopy=$objcopy: $output"
+if { $objcopy != 0 } {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+set binfuncfilesize [file size $binfuncfile]
+verbose -log "file size $binfuncfile = $binfuncfilesize"
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set b_addr ""
+set test "break func"
+gdb_test_multiple $test $test {
+    -re "Breakpoint \[0-9\]+ at (0x\[0-9a-f\]+)\r\n$gdb_prompt $" {
+	set b_addr $expect_out(1,string)
+	pass $test
+    }
+    -re "Breakpoint \[0-9\]+ at (0x\[0-9a-f\]+): .*\r\n$gdb_prompt $" {
+	set b_addr $expect_out(1,string)
+	fail $test
+    }
+}
+verbose -log "b_addr=<$b_addr>"
+
+set p_addr ""
+set test "print func"
+gdb_test_multiple $test $test {
+    -re "\\$\[0-9\]+ = {<text variable, no debug info>} (0x\[0-9a-f\]+) <func>\r\n$gdb_prompt $" {
+	set p_addr $expect_out(1,string)
+	pass $test
+    }
+}
+verbose -log "p_addr=<$p_addr>"
+
+set test "break address belongs to func"
+if {$b_addr == $p_addr} {
+    pass "$test (exact match)"
+} else {
+    set skip [expr $b_addr - $p_addr]
+    if {$skip > 0 && $skip < $binfuncfilesize} {
+	pass "$test (prologue skip by $skip bytes)"
+    } else {
+	fail $test
+    }
+}
diff --git a/gdb/testsuite/gdb.base/macscp.exp b/gdb/testsuite/gdb.base/macscp.exp
index 55c4d31..df25d3c 100644
--- a/gdb/testsuite/gdb.base/macscp.exp
+++ b/gdb/testsuite/gdb.base/macscp.exp
@@ -33,6 +33,14 @@ if [test_compiler_info gcc*] {
     lappend options additional_flags=-g3
 }
 
+# Workaround ccache making lineno non-zero for command-line definitions.
+if {[find_gcc] == "gcc" && [file executable "/usr/bin/gcc"]} {
+    set result [catch "exec which gcc" output]
+    if {$result == 0 && [string first "/ccache/" $output] >= -1} {
+       lappend options "compiler=/usr/bin/gcc"
+    }
+}
+
 # Generate the intermediate object file.  This is required by Darwin to
 # have access to the .debug_macinfo section.
 if  {[gdb_compile "${srcdir}/${subdir}/macscp1.c" "${objfile}" \
diff --git a/gdb/testsuite/gdb.base/radix.exp b/gdb/testsuite/gdb.base/radix.exp
index 750fd23..dfdb929 100644
--- a/gdb/testsuite/gdb.base/radix.exp
+++ b/gdb/testsuite/gdb.base/radix.exp
@@ -162,13 +162,6 @@ gdb_test "set radix" \
     "Input and output radices now set to decimal 10, hex a, octal 12\." \
     "Reset radices"
 
-gdb_test "set input-radix 0" \
-    "Nonsense input radix ``decimal 0''; input radix unchanged\\." \
-    "Reject input-radix 0"
-gdb_test "show input-radix" \
-    "Default input radix for entering numbers is 10\\." \
-    "Input radix unchanged after rejecting 0"
-
 gdb_test "set input-radix 1" \
     "Nonsense input radix ``decimal 1''; input radix unchanged\\." \
     "Reject input-radix 1"
diff --git a/gdb/testsuite/gdb.base/valgrind-attach.c b/gdb/testsuite/gdb.base/valgrind-attach.c
new file mode 100644
index 0000000..84b57db
--- /dev/null
+++ b/gdb/testsuite/gdb.base/valgrind-attach.c
@@ -0,0 +1,28 @@
+/* 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/>.  */
+
+#include <stdlib.h>
+
+int
+main (void)
+{
+  int *a = malloc (1);
+
+  a[10] = 0;		/* crash-here */
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/valgrind-attach.exp b/gdb/testsuite/gdb.base/valgrind-attach.exp
new file mode 100644
index 0000000..1f9b26e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/valgrind-attach.exp
@@ -0,0 +1,94 @@
+# 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 testfile valgrind-attach
+set shfile ${testfile}.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
+}
+
+gdb_exit
+gdb_stop_suppressing_tests;
+
+set VALGRIND "valgrind"
+
+# Syntax for ${shfile} is: <binfile> <valgrind> <db-command-arguments>
+set VALGRIND_SPAWN "sh ${srcdir}/${subdir}/${shfile} $binfile $VALGRIND $GDB $INTERNAL_GDBFLAGS $GDBFLAGS [host_info gdb_opts]"
+
+set test "spawn valgrind"
+verbose "Spawning $VALGRIND_SPAWN"
+
+if [info exists gdb_spawn_id] {
+    fail $test
+    return -1
+}
+
+if ![is_remote host] {
+    if { [which $VALGRIND] == 0 } then {
+	untested "Couldn't find $VALGRIND"
+	return -1
+    }
+}
+set res [remote_spawn host "$VALGRIND_SPAWN"]
+if { $res < 0 || $res == "" } {
+    perror "Spawning $VALGRIND_SPAWN failed."
+    return -1
+}
+set gdb_spawn_id -1;
+
+gdb_expect {
+    -re "---- Attach to debugger \\? --- \\\[Return/N/n/Y/y/C/c\\\] ---- $" {
+	pass $test
+    }
+    eof {
+	perror "(eof) $VALGRIND never initialized"
+	remote_close host
+	return -1
+    }
+    timeout {
+	perror "(timeout) $VALGRIND never initialized"
+	remote_close host
+	return -1
+    }
+}
+send_gdb "y\n"
+
+set test "spawn gdb"
+set test2 "crash line caught"
+gdb_expect {
+    -re "starting debugger with cmd:.* in main .* crash-here .*\[\r\n\]$gdb_prompt $" {
+	pass $test
+	pass $test2
+    }
+    -re "starting debugger with cmd:.*\[\r\n\]$gdb_prompt $" {
+	pass $test
+	fail $test2
+    }
+    eof {
+	perror "(eof) $GDB never initialized"
+	remote_close host
+	return -1
+    }
+    timeout {
+	perror "(timeout) $GDB never initialized"
+	remote_close host
+	return -1
+    }
+}
+
+remote_close host
diff --git a/gdb/testsuite/gdb.base/valgrind-attach.sh b/gdb/testsuite/gdb.base/valgrind-attach.sh
new file mode 100755
index 0000000..f02c6f7
--- /dev/null
+++ b/gdb/testsuite/gdb.base/valgrind-attach.sh
@@ -0,0 +1,20 @@
+#! /bin/sh
+
+# 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/>.
+
+BINFILE="$1"; shift
+VALGRIND="$1"; shift
+"$VALGRIND" --db-attach=yes --db-command="$* %f %p" "$BINFILE"
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
new file mode 100644
index 0000000..7203a48
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-overflow.exp
@@ -0,0 +1,108 @@
+# 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]
+
+set mb_reserve 10
+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
new file mode 100644
index 0000000..e1f3ed1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla.c
@@ -0,0 +1,55 @@
+/* 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 <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);
+}
+
+void
+foo (int size)
+{
+  char temp1[size];
+  char temp3[48];
+
+  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..5da7378
--- /dev/null
+++ 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 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
+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
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] {
+    untested vla
+    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_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.base/watchpoint-hw.c b/gdb/testsuite/gdb.base/watchpoint-hw.c
index 8da9af5..e2de53a 100644
--- a/gdb/testsuite/gdb.base/watchpoint-hw.c
+++ b/gdb/testsuite/gdb.base/watchpoint-hw.c
@@ -20,5 +20,11 @@ int watchee;
 int
 main (void)
 {
+  volatile int dummy;
+
+  dummy = watchee;
+  dummy = 1;
+  dummy = 2;	/* break-at-exit */
+
   return 0;
 }
diff --git a/gdb/testsuite/gdb.base/watchpoint-hw.exp b/gdb/testsuite/gdb.base/watchpoint-hw.exp
index a2bb731..d74d6c7 100644
--- a/gdb/testsuite/gdb.base/watchpoint-hw.exp
+++ b/gdb/testsuite/gdb.base/watchpoint-hw.exp
@@ -21,19 +21,12 @@ if {(![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"]
     return
 }
 
-set testfile watchpoint-hw
-set srcfile ${testfile}.c
-set binfile ${objdir}/${subdir}/${testfile}
-if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
-    untested "Couldn't compile test program"
+set test watchpoint-hw
+set srcfile ${test}.c
+if { [prepare_for_testing ${test}.exp ${test} ${srcfile}] } {
     return -1
 }
 
-gdb_exit
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
-gdb_load ${binfile}
-
 # Create the watchpoint before the inferior gets started.  Now the native CPU
 # target is still not active and its `to_can_use_hw_breakpoint' is not
 # installed, therefore only a software watchpoint gets created.
@@ -43,10 +36,40 @@ gdb_test "watch watchee" "atchpoint 1: watchee"
 # `runto_main' or `runto main' would delete the watchpoint created above.
 
 if { [gdb_start_cmd] < 0 } {
-    untested start
+    untested ${test}.exp
     return -1
 }
 gdb_test "" "main .* at .*" "start"
 
 # Check it is really a `hw'-watchpoint.
 gdb_test "info watchpoints" "1 *hw watchpoint .* watchee"
+
+# Before the inferior gets started we would get:
+# 	Target does not support this type of hardware watchpoint.
+gdb_test "delete 1"
+gdb_test "rwatch watchee"
+
+set breakline [gdb_get_line_number "break-at-exit"]
+gdb_breakpoint $breakline
+
+gdb_test "continue" "Continuing.\r\nHardware read watchpoint 3: watchee\r\n\r\nValue = 0\r\n.*"
+
+# Here should be no repeated notification of the read watchpoint.
+gdb_test "continue" \
+	 "Continuing\\.\[ \r\n\]+Breakpoint \[0-9\]+, .*break-at-exit.*" \
+	 "continue to break-at-exit after rwatch"
+
+clean_restart ${test}
+
+if ![runto_main] {
+    untested ${test}.exp
+    return -1
+}
+
+gdb_test "hbreak ${srcfile}:${breakline}" \
+	 "Hardware assisted breakpoint 2 at 0x\[0-9a-f\]+: file .*${srcfile}, line ${breakline}\\." \
+	 "hbreak"
+
+gdb_test "continue" \
+	 "Continuing\\.\[ \r\n\]+Breakpoint \[0-9\]+, .*break-at-exit.*" \
+	 "continue to break-at-exit after hbreak"
diff --git a/gdb/testsuite/gdb.cp/Makefile.in b/gdb/testsuite/gdb.cp/Makefile.in
index 0a087c7..b4880f2 100644
--- a/gdb/testsuite/gdb.cp/Makefile.in
+++ b/gdb/testsuite/gdb.cp/Makefile.in
@@ -4,7 +4,7 @@ srcdir = @srcdir@
 EXECUTABLES = ambiguous annota2 anon-union cplusfuncs cttiadd \
 	derivation inherit local member-ptr method misc \
         overload ovldbreak ref-typ ref-typ2 templates userdef virtfunc namespace \
-	ref-types ref-params method2 pr9594 gdb2495
+	ref-types ref-params method2 pr9594 gdb2495 gdb9593
 
 all info install-info dvi install uninstall installcheck check:
 	@echo "Nothing to be done for $@..."
diff --git a/gdb/testsuite/gdb.cp/cp-relocate.exp b/gdb/testsuite/gdb.cp/cp-relocate.exp
index 4095ccf..03c07d5 100644
--- a/gdb/testsuite/gdb.cp/cp-relocate.exp
+++ b/gdb/testsuite/gdb.cp/cp-relocate.exp
@@ -30,7 +30,7 @@ proc get_func_address { func } {
     global gdb_prompt hex
 
     set rfunc [string_to_regexp $func]
-    gdb_test_multiple "print '${func}'" "get address of ${func}" {
+    gdb_test_multiple "print ${func}" "get address of ${func}" {
 	-re "\\\$\[0-9\]+ = \\{.*\\} (0|($hex) <${rfunc}>)\[\r\n\]+${gdb_prompt} $" {
 	    # $1 = {int ()} 0x24 <function_bar>
 	    # But if the function is at zero, the name may be omitted.
@@ -130,7 +130,7 @@ gdb_test "add-symbol-file ${binfile} 0 -s ${func1_sec} 0x10000 -s ${func2_sec} 0
 	"y"
 
 # Make sure the function addresses were updated.
-gdb_test "break *'$func1_name'" \
+gdb_test "break *$func1_name" \
     "Breakpoint $decimal at 0x1....: file .*"
-gdb_test "break *'$func2_name'" \
+gdb_test "break *$func2_name" \
     "Breakpoint $decimal at 0x2....: file .*"
diff --git a/gdb/testsuite/gdb.cp/cplusfuncs.cc b/gdb/testsuite/gdb.cp/cplusfuncs.cc
index 7f033d6..1a50a32 100644
--- a/gdb/testsuite/gdb.cp/cplusfuncs.cc
+++ b/gdb/testsuite/gdb.cp/cplusfuncs.cc
@@ -191,6 +191,12 @@ char *	dm_type_char_star (char * p)		{ return p; }
 int	dm_type_foo_ref (foo & foo)		{ return foo.ifoo; }
 int *	dm_type_int_star (int * p)		{ return p; }
 long *	dm_type_long_star (long * p)		{ return p; }
+int	dm_type_short (short i)			{ return i; }
+int	dm_type_long (long i)			{ return i; }
 int	dm_type_unsigned_int (unsigned int i)	{ return i; }
+int	dm_type_unsigned_short (unsigned short i)	{ return i; }
+int	dm_type_unsigned_long (unsigned long i)	{ return i; }
 int	dm_type_void (void)			{ return 0; }
 void *	dm_type_void_star (void * p)		{ return p; }
+typedef int myint;
+int	dm_type_typedef (myint i)		{ return i; }
diff --git a/gdb/testsuite/gdb.cp/cplusfuncs.exp b/gdb/testsuite/gdb.cp/cplusfuncs.exp
index 5e08768..8c8e038 100644
--- a/gdb/testsuite/gdb.cp/cplusfuncs.exp
+++ b/gdb/testsuite/gdb.cp/cplusfuncs.exp
@@ -66,9 +66,25 @@ set dm_type_unsigned_int	"unsigned"
 set dm_type_void		""
 set dm_type_void_star		"void*"
 
+# Some other vagaries of GDB's type printing machinery.  The integer types
+# may have unsigned before or after their length, and may have "int"
+# appended.  The char* conversion operator may have name "char*" even if
+# the type is "char *", because the name comes from the debug information
+# and the type from GDB.  Function types may not see through typedefs.
+
+set dm_type_short		"short"
+set dm_type_long		"long"
+set dm_type_unsigned_short	"unsigned short"
+set dm_type_unsigned_long	"unsigned long"
+set dm_operator_char_star	"char*"
+set dm_operator_char_star_quoted	"char\\*"
+set dm_type_typedef		0
+
 proc probe_demangler { } {
     global gdb_prompt
     global dm_operator_comma
+    global dm_operator_char_star
+    global dm_operator_char_star_quoted
     global dm_type_char_star
     global dm_type_char_star_quoted
     global dm_type_foo_ref
@@ -77,6 +93,11 @@ proc probe_demangler { } {
     global dm_type_unsigned_int
     global dm_type_void
     global dm_type_void_star
+    global dm_type_short
+    global dm_type_unsigned_short
+    global dm_type_long
+    global dm_type_unsigned_long
+    global dm_type_typedef
 
     send_gdb "print &'foo::operator,(foo&)'\n"
     gdb_expect {
@@ -97,6 +118,26 @@ proc probe_demangler { } {
 	}
     }
 
+    send_gdb "print &'foo::operator char*()'\n"
+    gdb_expect {
+	-re ".*foo::operator char \\*\\(void\\).*\r\n$gdb_prompt $" {
+	    # v2 demangler or GDB type printer
+	    set dm_operator_char_star "char *"
+	    set dm_operator_char_star_quoted "char \\*"
+	    pass "detect dm_operator_char_star"
+	}
+	-re ".*foo::operator char\\*\\(\\).*\r\n$gdb_prompt $" {
+	    # v3 demangler
+	    pass "detect dm_operator_char_star"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_operator_char_star"
+	}
+	timeout {
+	    fail "detect dm_operator_char_star"
+	}
+    }
+
     send_gdb "print &'dm_type_char_star'\n"
     gdb_expect {
 	-re ".*dm_type_char_star\\(char \\*\\).*\r\n$gdb_prompt $" {
@@ -166,6 +207,11 @@ proc probe_demangler { } {
 	    # v3 demangler
 	    pass "detect dm_type_long_star"
 	}
+	-re ".*dm_type_long_star\\(long int \\*\\).*\r\n$gdb_prompt $" {
+	    # GCC v3 and GDB's type printer
+	    set dm_type_long_star "long int *"
+	    pass "detect dm_type_long_star"
+	}
 	-re ".*$gdb_prompt $" {
 	    fail "detect dm_type_long_star"
 	}
@@ -230,6 +276,101 @@ proc probe_demangler { } {
 	    fail "detect dm_type_void_star (timeout)"
 	}
     }
+
+    send_gdb "print &'dm_type_short'\n"
+    gdb_expect {
+	-re ".*dm_type_short\\(short\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_short"
+	}
+	-re ".*dm_type_short\\(short int\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_short "short int"
+	    pass "detect dm_type_short"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_short"
+	}
+	timeout {
+	    fail "detect dm_type_short (timeout)"
+	}
+    }
+
+    send_gdb "print &'dm_type_unsigned_short'\n"
+    gdb_expect {
+	-re ".*dm_type_unsigned_short\\(unsigned short\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_unsigned_short"
+	}
+	-re ".*dm_type_unsigned_short\\(short unsigned int\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_unsigned_short "short unsigned int"
+	    pass "detect dm_type_unsigned_short"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_unsigned_short"
+	}
+	timeout {
+	    fail "detect dm_type_unsigned_short (timeout)"
+	}
+    }
+
+    send_gdb "print &'dm_type_long'\n"
+    gdb_expect {
+	-re ".*dm_type_long\\(long\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_long"
+	}
+	-re ".*dm_type_long\\(long int\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_long "long int"
+	    pass "detect dm_type_long"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_long"
+	}
+	timeout {
+	    fail "detect dm_type_long (timeout)"
+	}
+    }
+
+    send_gdb "print &'dm_type_unsigned_long'\n"
+    gdb_expect {
+	-re ".*dm_type_unsigned_long\\(unsigned long\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_unsigned_long"
+	}
+	-re ".*dm_type_unsigned_long\\(long unsigned int\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_unsigned_long "long unsigned int"
+	    pass "detect dm_type_unsigned_long"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_unsigned_long"
+	}
+	timeout {
+	    fail "detect dm_type_unsigned_long (timeout)"
+	}
+    }
+
+    send_gdb "print &'dm_type_typedef'\n"
+    gdb_expect {
+	-re ".*dm_type_typedef\\(int\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_typedef"
+	}
+	-re ".*dm_type_typedef\\(myint\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_typedef 1
+	    pass "detect dm_type_typedef"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_typedef"
+	}
+	timeout {
+	    fail "detect dm_type_typedef (timeout)"
+	}
+    }
 }
 
 #
@@ -345,8 +486,9 @@ proc print_addr { name } {
 
 proc test_lookup_operator_functions {} {
     global dm_operator_comma
+    global dm_operator_char_star
     global dm_type_char_star
-    global dm_type_char_star_quoted
+    global dm_operator_char_star_quoted
     global dm_type_foo_ref
     global dm_type_void
     global dm_type_void_star
@@ -404,8 +546,8 @@ proc test_lookup_operator_functions {} {
 
     info_func "operator int("	"int foo::operator int($dm_type_void);"
     info_func "operator()("	"void foo::operator()($dm_type_foo_ref);"
-    info_func "operator $dm_type_char_star_quoted\(" \
-				"char *foo::operator $dm_type_char_star\($dm_type_void);"
+    info_func "operator $dm_operator_char_star_quoted\(" \
+				"char *foo::operator $dm_operator_char_star\($dm_type_void);"
 
 }
 
@@ -420,6 +562,7 @@ proc test_paddr_operator_functions {} {
     global dm_type_unsigned_int
     global dm_type_void
     global dm_type_void_star
+    global dm_operator_char_star
 
     print_addr "foo::operator*($dm_type_foo_ref)"
     print_addr "foo::operator%($dm_type_foo_ref)"
@@ -470,7 +613,7 @@ proc test_paddr_operator_functions {} {
     }
 
     print_addr "foo::operator int($dm_type_void)"
-    print_addr "foo::operator $dm_type_char_star\($dm_type_void)"
+    print_addr "foo::operator $dm_operator_char_star\($dm_type_void)"
 }
 
 #
@@ -480,17 +623,21 @@ proc test_paddr_operator_functions {} {
 proc test_paddr_overloaded_functions {} {
     global dm_type_unsigned_int
     global dm_type_void
+    global dm_type_short
+    global dm_type_unsigned_short
+    global dm_type_long
+    global dm_type_unsigned_long
 
     print_addr "overload1arg($dm_type_void)"
     print_addr "overload1arg(char)"
     print_addr "overload1arg(signed char)"
     print_addr "overload1arg(unsigned char)"
-    print_addr "overload1arg(short)"
-    print_addr "overload1arg(unsigned short)"
+    print_addr "overload1arg($dm_type_short)"
+    print_addr "overload1arg($dm_type_unsigned_short)"
     print_addr "overload1arg(int)"
     print_addr "overload1arg($dm_type_unsigned_int)"
-    print_addr "overload1arg(long)"
-    print_addr "overload1arg(unsigned long)"
+    print_addr "overload1arg($dm_type_long)"
+    print_addr "overload1arg($dm_type_unsigned_long)"
     print_addr "overload1arg(float)"
     print_addr "overload1arg(double)"
 
@@ -513,17 +660,31 @@ proc test_paddr_hairy_functions {} {
     global dm_type_char_star
     global dm_type_int_star
     global dm_type_long_star
+    global dm_type_typedef
 
     print_addr_2 "hairyfunc1" "hairyfunc1(int)"
-    print_addr_2 "hairyfunc2" "hairyfunc2(int (*)($dm_type_char_star))"
-    print_addr_2 "hairyfunc3" "hairyfunc3(int (*)(short (*)($dm_type_long_star)))"
-    print_addr_2 "hairyfunc4" "hairyfunc4(int (*)(short (*)($dm_type_char_star)))"
-
-    # gdb-gnats bug gdb/19:
-    # "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7"
-    print_addr_2_kfail "hairyfunc5" "hairyfunc5(int (*(*)($dm_type_char_star))(long))" "hairyfunc5(int (*)(long) (*)(char*))" "gdb/19"
-    print_addr_2_kfail "hairyfunc6" "hairyfunc6(int (*(*)($dm_type_int_star))(long))" "hairyfunc6(int (*)(long) (*)(int*))" "gdb/19"
-    print_addr_2_kfail "hairyfunc7" "hairyfunc7(int (*(*)(int (*)($dm_type_char_star)))(long))" "hairyfunc7(int (*)(long) (*)(int (*)(char*)))" "gdb/19"
+
+    if {$dm_type_typedef == 0} {
+	print_addr_2 "hairyfunc2" "hairyfunc2(int (*)($dm_type_char_star))"
+	print_addr_2 "hairyfunc3" "hairyfunc3(int (*)(short (*)($dm_type_long_star)))"
+	print_addr_2 "hairyfunc4" "hairyfunc4(int (*)(short (*)($dm_type_char_star)))"
+
+	# gdb-gnats bug gdb/19:
+	# "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7"
+	print_addr_2_kfail "hairyfunc5" "hairyfunc5(int (*(*)($dm_type_char_star))(long))" "hairyfunc5(int (*)(long) (*)(char*))" "gdb/19"
+	print_addr_2_kfail "hairyfunc6" "hairyfunc6(int (*(*)($dm_type_int_star))(long))" "hairyfunc6(int (*)(long) (*)(int*))" "gdb/19"
+	print_addr_2_kfail "hairyfunc7" "hairyfunc7(int (*(*)(int (*)($dm_type_char_star)))(long))" "hairyfunc7(int (*)(long) (*)(int (*)(char*)))" "gdb/19"
+    } else {
+	print_addr_2 "hairyfunc2" "hairyfunc2(PFPc_i)"
+	print_addr_2 "hairyfunc3" "hairyfunc3(PFPFPl_s_i)"
+	print_addr_2 "hairyfunc4" "hairyfunc4(PFPFPc_s_i)"
+
+	# gdb-gnats bug gdb/19:
+	# "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7"
+	print_addr_2 "hairyfunc5" "hairyfunc5(PFPc_PFl_i)"
+	print_addr_2 "hairyfunc6" "hairyfunc6(PFPi_PFl_i)"
+	print_addr_2 "hairyfunc7" "hairyfunc7(PFPFPc_i_PFl_i)"
+    }
 }
 
 proc do_tests {} {
diff --git a/gdb/testsuite/gdb.cp/expand-sals.exp b/gdb/testsuite/gdb.cp/expand-sals.exp
index 3c302c3..cd0496d 100644
--- a/gdb/testsuite/gdb.cp/expand-sals.exp
+++ b/gdb/testsuite/gdb.cp/expand-sals.exp
@@ -48,7 +48,7 @@ gdb_continue_to_breakpoint "caller" ".*caller-line.*"
 
 # Test GDB caught this return call and not the next one through B::B()
 gdb_test "bt" \
-	 "#0 \[^\r\n\]* A \[^\r\n\]*\r\n#1 \[^\r\n\]* main \[^\r\n\]*" \
+	 "#0 \[^\r\n\]* (A::)?A \[^\r\n\]*\r\n#1 \[^\r\n\]* main \[^\r\n\]*" \
 	 "bt from A"
 
 gdb_continue_to_breakpoint "next caller func" ".*func-line.*"
diff --git a/gdb/testsuite/gdb.cp/gdb9593.cc b/gdb/testsuite/gdb.cp/gdb9593.cc
new file mode 100644
index 0000000..783c962
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/gdb9593.cc
@@ -0,0 +1,180 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   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/>.
+   */
+#include <iostream>
+
+using namespace std;
+
+class NextOverThrowDerivates
+{
+
+public:
+
+
+  // Single throw an exception in this function.
+  void function1() 
+  {
+    throw 20;
+  }
+
+  // Throw an exception in another function.
+  void function2() 
+  {
+    function1();
+  }
+
+  // Throw an exception in another function, but handle it
+  // locally.
+  void function3 () 
+  {
+    {
+      try
+	{
+	  function1 ();
+	}
+      catch (...) 
+	{
+	  cout << "Caught and handled function1 exception" << endl;
+	}
+    }
+  }
+
+  void rethrow ()
+  {
+    try
+      {
+	function1 ();
+      }
+    catch (...)
+      {
+	throw;
+      }
+  }
+
+  void finish ()
+  {
+    // We use this to test that a "finish" here does not end up in
+    // this frame, but in the one above.
+    try
+      {
+	function1 ();
+      }
+    catch (int x)
+      {
+      }
+    function1 ();		// marker for until
+  }
+
+  void until ()
+  {
+    function1 ();
+    function1 ();		// until here
+  }
+
+};
+NextOverThrowDerivates next_cases;
+
+
+int main () 
+{ 
+  try
+    {
+      next_cases.function1 ();
+    }
+  catch (...)
+    {
+      // Discard
+    }
+
+  try
+    {
+      next_cases.function2 ();
+    }
+  catch (...)
+    {
+      // Discard
+    }
+
+  try
+    {
+      // This is duplicated so we can next over one but step into
+      // another.
+      next_cases.function2 ();
+    }
+  catch (...)
+    {
+      // Discard
+    }
+
+  next_cases.function3 ();
+
+  try
+    {
+      next_cases.rethrow ();
+    }
+  catch (...)
+    {
+      // Discard
+    }
+
+  try
+    {
+      // Another duplicate so we can test "finish".
+      next_cases.function2 ();
+    }
+  catch (...)
+    {
+      // Discard
+    }
+
+  // Another test for "finish".
+  try
+    {
+      next_cases.finish ();
+    }
+  catch (...)
+    {
+    }
+
+  // Test of "until".
+  try
+    {
+      next_cases.finish ();
+    }
+  catch (...)
+    {
+    }
+
+  // Test of "until" with an argument.
+  try
+    {
+      next_cases.until ();
+    }
+  catch (...)
+    {
+    }
+
+  // Test of "advance".
+  try
+    {
+      next_cases.until ();
+    }
+  catch (...)
+    {
+    }
+}
+
diff --git a/gdb/testsuite/gdb.cp/gdb9593.exp b/gdb/testsuite/gdb.cp/gdb9593.exp
new file mode 100644
index 0000000..ee9aeff
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/gdb9593.exp
@@ -0,0 +1,185 @@
+# 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/>.
+
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+if { [skip_cplus_tests] } { continue }
+
+set prms_id 9593
+set bug_id 0
+
+set testfile "gdb9593"
+set srcfile ${testfile}.cc
+set binfile $objdir/$subdir/$testfile
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile} "c++"] {
+    untested gdb9593.exp
+    return -1
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+    untested gdb9593.exp
+    return -1
+}
+
+# Some targets can't do function calls, so don't even bother with this
+# test.
+if [target_info exists gdb,cannot_call_functions] {
+    setup_xfail "*-*-*" 9593
+    fail "This target can not call functions"
+    continue
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    perror "couldn't run to main"
+    continue
+} 
+
+# See whether we have the needed unwinder hooks.
+set ok 1
+gdb_test_multiple "print _Unwind_DebugHook" "check for unwinder hook" {
+    -re "= .*_Unwind_DebugHook.*\r\n$gdb_prompt $" {
+	pass "check for unwinder hook"
+    }
+    -re "No symbol .* in current context.\r\n$gdb_prompt $" {
+	# Pass the test so we don't get bogus fails in the results.
+	pass "check for unwinder hook"
+	set ok 0
+    }
+}
+if {!$ok} {
+    untested gdb9593.exp
+    return -1
+}
+
+# See http://sourceware.org/bugzilla/show_bug.cgi?id=9593
+
+gdb_test "next" \
+    ".*catch (...).*" \
+    "next over a throw 1"
+
+gdb_test "next" \
+  ".*next_cases.function2.*" \
+  "next past catch 1"
+
+gdb_test "next" \
+    ".*catch (...).*" \
+    "next over a throw 2"
+
+gdb_test "next" \
+  ".*next_cases.function2.*" \
+  "next past catch 2"
+
+gdb_test "step" \
+  ".*function1().*" \
+  "step into function2 1"
+
+gdb_test "next" \
+    ".*catch (...).*" \
+    "next over a throw 3"
+
+gdb_test "next" \
+  ".*next_cases.function3.*" \
+  "next past catch 3"
+
+gdb_test "next" \
+  ".*next_cases.rethrow.*" \
+    "next over a throw 4"
+
+gdb_test "next" \
+  ".*catch (...).*" \
+  "next over a rethrow"
+
+gdb_test "next" \
+  ".*next_cases.function2.*" \
+  "next after a rethrow"
+
+gdb_test "step" \
+  ".*function1().*" \
+  "step into function2 2"
+
+gdb_test "finish" \
+  ".*catch (...).*" \
+  "finish 1"
+
+gdb_test "next" \
+  ".*next_cases.finish ().*" \
+  "next past catch 4"
+
+gdb_test "step" \
+  ".*function1 ().*" \
+  "step into finish method"
+
+gdb_test "finish" \
+  ".*catch (...).*" \
+  "finish 2"
+
+gdb_test "next" \
+  ".*next_cases.finish ().*" \
+  "next past catch 5"
+
+gdb_test "step" \
+  ".*function1 ().*" \
+  "step into finish, for until"
+
+gdb_test "until" \
+  ".*catch .int x.*" \
+  "until with no argument 1"
+
+set line [gdb_get_line_number "marker for until" $testfile.cc]
+
+gdb_test "until $line" \
+  ".*function1 ().*" \
+  "next past catch 6"
+
+gdb_test "until" \
+  ".*catch (...).*" \
+  "until with no argument 2"
+
+set line [gdb_get_line_number "until here" $testfile.cc]
+
+gdb_test "next" \
+  ".*next_cases.until ().*" \
+  "next past catch 6"
+
+gdb_test "step" \
+  ".*function1 ().*" \
+  "step into until"
+
+gdb_test "until $line" \
+  ".*catch (...).*" \
+  "until-over-throw"
+
+gdb_test "next" \
+  ".*next_cases.until ().*" \
+  "next past catch 7"
+
+gdb_test "step" \
+  ".*function1 ().*" \
+  "step into until, for advance"
+
+gdb_test "advance $line" \
+  ".*catch (...).*" \
+  "advance-over-throw"
diff --git a/gdb/testsuite/gdb.cp/member-ptr.cc b/gdb/testsuite/gdb.cp/member-ptr.cc
index 1dff70a..648b2af 100644
--- a/gdb/testsuite/gdb.cp/member-ptr.cc
+++ b/gdb/testsuite/gdb.cp/member-ptr.cc
@@ -138,6 +138,7 @@ class Diamond : public Padding, public Left, public Right
 {
 public:
   virtual int vget_base ();
+  int (*func_ptr) (int);
 };
 
 int Diamond::vget_base ()
@@ -145,6 +146,12 @@ int Diamond::vget_base ()
   return this->Left::x + 2000;
 }
 
+int
+func (int x)
+{
+  return 19 + x;
+}
+
 int main ()
 {
   A a;
@@ -162,6 +169,7 @@ int main ()
   int (Diamond::*right_vpmf) ();
   int (Base::*base_vpmf) ();
   int Diamond::*diamond_pmi;
+  int (* Diamond::*diamond_pfunc_ptr) (int);
 
   PMI null_pmi;
   PMF null_pmf;
@@ -179,6 +187,7 @@ int main ()
 
   diamond.Left::x = 77;
   diamond.Right::x = 88;
+  diamond.func_ptr = func;
 
   /* Some valid pointer to members from a base class.  */
   left_pmf = (int (Diamond::*) ()) (int (Left::*) ()) (&Base::get_x);
@@ -193,11 +202,19 @@ int main ()
   /* A pointer to data member from a base class.  */
   diamond_pmi = (int Diamond::*) (int Left::*) &Base::x;
 
+  /* A pointer to data member, where the member is itself a pointer to
+     a function.  */
+  diamond_pfunc_ptr = (int (* Diamond::*) (int)) &Diamond::func_ptr;
+
   null_pmi = NULL;
   null_pmf = NULL;
 
   pmi = NULL; /* Breakpoint 1 here.  */
 
+  // Invalid (uses diamond_pfunc_ptr as a function):
+  // diamond.*diamond_pfunc_ptr (20);
+  (diamond.*diamond_pfunc_ptr) (20);
+
   k = (a.*pmf)(3);
 
   pmi = &A::jj;
diff --git a/gdb/testsuite/gdb.cp/member-ptr.exp b/gdb/testsuite/gdb.cp/member-ptr.exp
index b69d4ad..83dd0d5 100644
--- a/gdb/testsuite/gdb.cp/member-ptr.exp
+++ b/gdb/testsuite/gdb.cp/member-ptr.exp
@@ -390,6 +390,33 @@ gdb_test_multiple "print ((int) pmi) == ((char *) &a.j - (char *) & a)" $name {
     }
 }
 
+# Check pointers to data members, which are themselves pointers to
+# functions.  These behave like data members, not like pointers to
+# member functions.
+
+gdb_test "ptype diamond_pfunc_ptr" \
+    "type = int \\(\\*Diamond::\\*\\)\\(int\\)"
+
+gdb_test "ptype diamond.*diamond_pfunc_ptr" \
+    "type = int \\(\\*\\)\\(int\\)"
+
+# This one is invalid; () binds more tightly than .*, so it tries to
+# call the member pointer as a normal pointer-to-function.
+
+gdb_test "print diamond.*diamond_pfunc_ptr (20)" \
+    "Invalid data type for function to be called."
+
+# With parentheses, it is valid.
+
+gdb_test "print (diamond.*diamond_pfunc_ptr) (20)" \
+    "$vhn = 39"
+
+# Make sure that we do not interpret this as either a member pointer
+# call or a member function call.
+
+gdb_test "print diamond.func_ptr (20)" \
+    "$vhn = 39"
+
 # ==========================
 # pointer to member function
 # ==========================
@@ -420,7 +447,7 @@ gdb_test_multiple "ptype pmf" $name {
 
 set name "print pmf"
 gdb_test_multiple "print pmf" $name {
-    -re "$vhn = $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
+    -re "$vhn = \\(int \\(A::\\*\\)\\(A \\*, int\\)\\) $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
 	pass $name
     }
     -re "$vhn = .*not supported with HP aCC.*\r\n$gdb_prompt $" {
@@ -608,6 +635,9 @@ gdb_test_multiple "print (a.*pmf)(3)" $name {
     }
 }
 
+gdb_test "ptype a.*pmf" "type = int \\(A \\*, int\\)"
+gdb_test "ptype (a.*pmf)(3)" "type = int"
+
 # Print out a pointer to data member which requires looking into
 # a base class.
 gdb_test "print diamond_pmi" "$vhn = &Base::x"
@@ -658,5 +688,5 @@ gdb_test "print null_pmi = &A::j" "$vhn = &A::j"
 gdb_test "print null_pmi = 0" "$vhn = NULL"
 
 gdb_test "print null_pmf" "$vhn = NULL"
-gdb_test "print null_pmf = &A::foo" "$vhn = $hex <A::foo ?\\(int\\)>"
+gdb_test "print null_pmf = &A::foo" "$vhn = \\(int \\(A::\\*\\)\\(A \\*, int\\)\\) $hex <A::foo ?\\(int\\)>"
 gdb_test "print null_pmf = 0" "$vhn = NULL"
diff --git a/gdb/testsuite/gdb.cp/namespace-multiple-imports.cc b/gdb/testsuite/gdb.cp/namespace-multiple-imports.cc
new file mode 100644
index 0000000..6b180d6
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-multiple-imports.cc
@@ -0,0 +1,20 @@
+namespace A {
+  int x = 11;
+  namespace{
+    int xx = 22;
+  }
+}
+
+using namespace A;
+
+namespace{
+  int xxx = 33;
+};
+
+int main()
+{
+  x;
+  xx;
+  xxx;
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.cp/namespace-multiple-imports.exp b/gdb/testsuite/gdb.cp/namespace-multiple-imports.exp
new file mode 100644
index 0000000..e4bb9f8
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-multiple-imports.exp
@@ -0,0 +1,49 @@
+# 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 $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile namespace-multiple-imports
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+############################################
+# test printing of namespace imported within
+# the function.
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
+gdb_test "print x" "\\$\[0-9\].* = 11"
+gdb_test "print xx" "\\$\[0-9\].* = 22"
+gdb_test "print xxx" "\\$\[0-9\].* = 33"
diff --git a/gdb/testsuite/gdb.cp/namespace-nested-imports.cc b/gdb/testsuite/gdb.cp/namespace-nested-imports.cc
new file mode 100644
index 0000000..9723f87
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-nested-imports.cc
@@ -0,0 +1,36 @@
+namespace A
+{
+  namespace B
+  {
+    int ab = 11;
+  }
+}
+
+namespace C
+{
+  namespace D
+  {
+    using namespace A::B;
+
+    int
+    second()
+    {
+      ab;
+      return 0;
+    }
+  }
+
+  int
+  first()
+  {
+    //ab;
+    return D::second();
+  }
+}
+
+int
+main()
+{
+  //ab;
+  return C::first();
+}
diff --git a/gdb/testsuite/gdb.cp/namespace-nested-imports.exp b/gdb/testsuite/gdb.cp/namespace-nested-imports.exp
new file mode 100644
index 0000000..d279fb5
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-nested-imports.exp
@@ -0,0 +1,57 @@
+# 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 $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile namespace-nested-imports
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+############################################
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
+gdb_test "print ab" "No symbol .* in current context."
+
+############################################
+gdb_breakpoint C::first
+gdb_continue_to_breakpoint "C::first"
+
+gdb_test "print ab" "No symbol .* in current context."
+gdb_test "print C::D::ab" "= 11"
+
+############################################
+gdb_breakpoint C::D::second
+gdb_continue_to_breakpoint "C::D::second"
+
+gdb_test "print ab" "= 11"
diff --git a/gdb/testsuite/gdb.cp/namespace-no-imports.cc b/gdb/testsuite/gdb.cp/namespace-no-imports.cc
new file mode 100644
index 0000000..d1c68ab
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-no-imports.cc
@@ -0,0 +1,37 @@
+
+namespace A
+{
+  int _a = 11;
+
+  namespace B{
+
+    int ab = 22;
+
+    namespace C{
+
+      int abc = 33;
+
+      int second(){
+        return 0;
+      }
+
+    }
+
+    int first(){
+      _a;
+      ab;
+      C::abc;
+      return C::second();
+    }
+  }
+}
+
+
+int
+main()
+{
+  A::_a;
+  A::B::ab;
+  A::B::C::abc;
+  return A::B::first();
+}
diff --git a/gdb/testsuite/gdb.cp/namespace-no-imports.exp b/gdb/testsuite/gdb.cp/namespace-no-imports.exp
new file mode 100644
index 0000000..e508103
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-no-imports.exp
@@ -0,0 +1,76 @@
+# 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 $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile namespace-no-imports
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+############################################
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
+gdb_test "print A::_a" "= 11"
+gdb_test "print A::B::ab" "= 22"
+gdb_test "print A::B::C::abc" "= 33"
+
+gdb_test "print _a" "No symbol .* in current context."
+gdb_test "print ab" "No symbol .* in current context."
+gdb_test "print abc" "No symbol .* in current context."
+
+############################################
+gdb_breakpoint A::B::first
+gdb_continue_to_breakpoint "A::B::first"
+
+gdb_test "print A::_a" "= 11"
+gdb_test "print A::B::ab" "= 22"
+gdb_test "print A::B::C::abc" "= 33"
+
+gdb_test "print _a" "= 11"
+gdb_test "print ab" "= 22"
+gdb_test "print C::abc" "= 33"
+
+gdb_test "print abc" "No symbol .* in current context."
+
+############################################
+gdb_breakpoint A::B::C::second
+gdb_continue_to_breakpoint "A::B::C::second"
+
+gdb_test "print A::_a" "= 11"
+gdb_test "print A::B::ab" "= 22"
+gdb_test "print A::B::C::abc" "= 33"
+
+gdb_test "print _a" "= 11"
+gdb_test "print ab" "= 22"
+gdb_test "print abc" "= 33"
diff --git a/gdb/testsuite/gdb.cp/namespace-recursive.cc b/gdb/testsuite/gdb.cp/namespace-recursive.cc
new file mode 100644
index 0000000..46d4c18
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-recursive.cc
@@ -0,0 +1,47 @@
+namespace A{
+  int ax = 9;
+}
+
+namespace B{
+  using namespace A;
+}
+
+namespace C{
+  using namespace B;
+}
+
+using namespace C;
+
+//---------------
+namespace D{
+  using namespace D;
+  int dx = 99;
+}
+using namespace D;
+
+//---------------
+namespace{
+  namespace{
+    int xx = 999;
+  }
+}
+
+//---------------
+namespace E{
+  int ex = 9999;
+}
+
+namespace F{
+  namespace FE = E;
+}
+
+namespace G{
+  namespace GF = F;
+}
+
+//----------------
+int main(){
+  using namespace D;
+  namespace GX = G;
+  return ax + dx + xx + G::GF::FE::ex;
+}
diff --git a/gdb/testsuite/gdb.cp/namespace-recursive.exp b/gdb/testsuite/gdb.cp/namespace-recursive.exp
new file mode 100644
index 0000000..5543757
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-recursive.exp
@@ -0,0 +1,75 @@
+# 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 $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile namespace-recursive
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+if [get_compiler_info ${binfile}] {
+    return -1;
+}
+
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
+############################################
+# test printing from namespace imported into
+# imported namespace
+
+gdb_test "print ax" "= 9"
+
+############################################
+# test that gdb can print without falling 
+# into search loop
+
+gdb_test "print dx" "= 99"
+
+############################################
+# test printing from namespace imported into
+# imported namespace where imports are implicit
+# anonymous namespace imports.
+
+gdb_test "print xx" "= 999"
+
+############################################
+# Test printing using recursive namespace
+# aliases.
+
+setup_kfail "gdb/10541" "*-*-*"
+gdb_test "ptype G::GF" "= namespace F"
+
+setup_kfail "gdb/10541" "*-*-*"
+gdb_test "print G::GF::FE::ex" "= 9999"
diff --git a/gdb/testsuite/gdb.cp/namespace-stress.cc b/gdb/testsuite/gdb.cp/namespace-stress.cc
new file mode 100644
index 0000000..f34083e
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-stress.cc
@@ -0,0 +1,60 @@
+
+namespace A{ int x; }
+namespace B{ int x; }
+namespace C{ int x; }
+namespace D{ int x; }
+namespace E{ int x; }
+namespace F{ int x; }
+namespace G{ int x; }
+namespace H{ int x; }
+namespace I{ int x; }
+namespace J{ int x; }
+namespace K{ int x; }
+namespace L{ int x; }
+namespace M{ int x; }
+namespace N{ int x; }
+namespace O{ int x; }
+namespace P{ int x; }
+namespace Q{ int x; }
+namespace R{ int x; }
+namespace S{ int x; }
+namespace T{ int x; }
+namespace U{ int x; }
+namespace V{ int x; }
+namespace W{ int x; }
+namespace X{ int x; }
+namespace Y{ int x; }
+namespace Z{ int x; }
+
+
+int main(){
+
+  using namespace A;
+  using namespace B;
+  using namespace C;
+  using namespace D;
+  using namespace E;
+  using namespace F;
+  using namespace G;
+  using namespace H;
+  using namespace I;
+  using namespace J;
+  using namespace K;
+  using namespace L;
+  using namespace M;
+  using namespace N;
+  using namespace O;
+  using namespace P;
+  using namespace Q;
+  using namespace R;
+  using namespace S;
+  using namespace T;
+  using namespace U;
+  using namespace V;
+  using namespace W;
+  using namespace X;
+  using namespace Y;
+  using namespace Z;
+
+  return 0;
+}
\ No newline at end of file
diff --git a/gdb/testsuite/gdb.cp/namespace-stress.exp b/gdb/testsuite/gdb.cp/namespace-stress.exp
new file mode 100644
index 0000000..1806523
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-stress.exp
@@ -0,0 +1,50 @@
+# 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 $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile namespace-stress
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+if [get_compiler_info ${binfile}] {
+    return -1;
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
+############################################
+# Test that the search can fail efficiently 
+
+gdb_test "print y" "No symbol \"y\" in current context."
diff --git a/gdb/testsuite/gdb.cp/namespace-using.cc b/gdb/testsuite/gdb.cp/namespace-using.cc
index 4786fd5..8ff5622 100644
--- a/gdb/testsuite/gdb.cp/namespace-using.cc
+++ b/gdb/testsuite/gdb.cp/namespace-using.cc
@@ -1,26 +1,129 @@
+namespace M
+{
+  int x = 911;
+}
+
+namespace N
+{
+  int x = 912;
+}
+
+int marker10 ()
+{
+  using namespace M;
+  int y = x + 1;       // marker10 stop
+  using namespace N;
+  return y;
+}
+
+namespace J
+{
+  int jx = 44;
+}
+
+namespace K
+{
+  int
+  marker9 ()
+  {
+    //x;
+    return marker10 ();
+  }
+}
+
+namespace L
+{
+  using namespace J;
+  int
+  marker8 ()
+  {
+    jx;
+    return K::marker9 ();
+  }
+}
+
+namespace G
+{
+  namespace H
+  {
+    int ghx = 6;
+  }
+}
+
+namespace I
+{  
+  int
+  marker7 ()
+  {
+    using namespace G::H;
+    ghx;
+    return L::marker8 ();
+  }
+}
+
+namespace E
+{
+  namespace F
+  {
+    int efx = 5;
+  }
+}
+
+using namespace E::F;
+int
+marker6 ()
+{
+  efx;
+  return I::marker7 ();
+}
+
 namespace A
 {
   int _a = 1;
   int x = 2;
 }
 
-int marker4(){
-	using A::x;
-	return 0;
+namespace C
+{
+  int cc = 3;
+}
+
+namespace D
+{
+  int dx = 4;
+}
+
+using namespace C;
+int
+marker5 ()
+{
+  cc;
+  return marker6 ();
+}
+
+int
+marker4 ()
+{
+  using D::dx;
+  return marker5 ();
 }
 
-int marker3(){
-	return marker4();
+int
+marker3 ()
+{
+  return marker4 ();
 }
 
-int marker2()
+int
+marker2 ()
 {
   namespace B = A;
   B::_a;
-  return marker3();
+  return marker3 ();
 }
 
-int marker1()
+int
+marker1 ()
 {
   int total = 0;
   {
@@ -29,17 +132,18 @@ int marker1()
       using namespace A;
       int c = 2;
       {
-        int d = 3;
-        total = _a + b + c + d + marker2(); // marker1 stop
+	int d = 3;
+	total = _a + b + c + d + marker2 (); // marker1 stop
       }
     }
   }
   return total;
 }
 
-int main()
+int
+main ()
 {
   using namespace A;
   _a;
-  return marker1();
+  return marker1 ();
 }
diff --git a/gdb/testsuite/gdb.cp/namespace-using.exp b/gdb/testsuite/gdb.cp/namespace-using.exp
index f24973f..fc23115 100644
--- a/gdb/testsuite/gdb.cp/namespace-using.exp
+++ b/gdb/testsuite/gdb.cp/namespace-using.exp
@@ -28,6 +28,11 @@ if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
     return -1
 }
 
+if [get_compiler_info ${binfile}] {
+    return -1;
+}
+
+
 # Get things started.
 
 gdb_exit
@@ -46,42 +51,155 @@ if ![runto_main] then {
 
 gdb_test "print _a" "= 1"
 
+# Test that names are not printed when they 
+# are not imported
+
+gdb_breakpoint marker3
+gdb_continue_to_breakpoint "marker3"
+
+#send_gdb "break marker3\n"
+#send_gdb "continue\n"
+
+gdb_test "print _a" "No symbol \"_a\" in current context." "Print _a without import"
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
 ############################################
 # test printing of namespace imported into 
 # a scope containing the pc.
 
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
 gdb_breakpoint [gdb_get_line_number "marker1 stop"]
 gdb_continue_to_breakpoint "marker1 stop"
 
 gdb_test "print _a" "= 1" "print _a in a nested scope"
 
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+############################################
+# test printing of namespace imported into 
+# file scope.
+
+
+if ![runto marker5] then {
+    perror "couldn't run to breakpoint marker5"
+    continue
+}
+
+gdb_test "print cc" "= 3"
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
 ############################################
 # Test printing of namespace aliases
 
-setup_kfail "gdb/7935" "*-*-*"
 if ![runto marker2] then {
     perror "couldn't run to breakpoint marker2"
     continue
 }
 
-gdb_test "print B::a" "= 1"
+gdb_test "print B::_a" "= 1"
+
+gdb_test "print _a" "No symbol \"_a\" in current context." "print _a in namespace alias scope"
+gdb_test "print x" "No symbol \"x\" in current context." "print x in namespace alias scope"
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
 
 ############################################
 # Test that names are not printed when they 
 # are not imported
 
-gdb_breakpoint "marker3"
-gdb_continue_to_breakpoint "marker3"
+if {![runto marker3]} {
+    perror "couldn't run to breakpoint marker3"
+}
 
-gdb_test "print _a" "No symbol \"_a\" in current context." "Print a without import"
+# gcc-4-3 puts import statements for aliases in
+# the global scope instead of the corresponding
+# function scope. These wrong import statements throw
+# this test off. This is fixed in gcc-4-4.
+if [test_compiler_info gcc-4-3-*] then { setup_xfail *-*-* }
+
+gdb_test "print _a" "No symbol \"_a\" in current context." "Print _a without import"
 
 ############################################
 # Test printing of individually imported elements
 
-setup_kfail "gdb/7936" "*-*-*"
 if ![runto marker4] then {
     perror "couldn't run to breakpoint marker4"
     continue
 }
 
-gdb_test "print x" "= 2"
+gdb_test "print dx" "= 4"
+
+############################################
+# Test printing of namespace aliases
+
+if ![runto marker5] then {
+    perror "couldn't run to marker5"
+    continue
+}
+
+gdb_test "print efx" "= 5"
+
+############################################
+# Test printing of variables imported from
+# nested namespaces
+
+if ![runto I::marker7] then {
+    perror "couldn't run to breakpoint I::marker7"
+    continue
+}
+
+gdb_test "print ghx" "= 6"
+
+############################################
+# Test that variables are not printed in a namespace
+# that is sibling to the namespace containing an import
+
+if ![runto L::marker8] then {
+    perror "couldn't run to breakpoint L::marker8"
+    continue
+}
+
+gdb_test "print jx" "= 44"
+
+gdb_breakpoint "K::marker9"
+gdb_continue_to_breakpoint "K::marker9"
+
+gdb_test "print jx" "No symbol \"jx\" in current context."
+
+############################################
+# Test that variables are only printed after the line
+# containing the import
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "marker10 stop"]
+gdb_continue_to_breakpoint "marker10 stop"
+
+# Assert that M::x is printed and not N::x
+gdb_test "print x" "= 911" "print x (from M::x)"
+
diff --git a/gdb/testsuite/gdb.cp/namespace.exp b/gdb/testsuite/gdb.cp/namespace.exp
index 76b1b82..2042db2 100644
--- a/gdb/testsuite/gdb.cp/namespace.exp
+++ b/gdb/testsuite/gdb.cp/namespace.exp
@@ -24,6 +24,7 @@
 # for namespaces.
 # Note: As of 2000-06-03, they passed under g++ - djb
 
+load_lib "cp-support.exp"
 
 if $tracelevel then {
         strace $tracelevel
@@ -259,11 +260,16 @@ gdb_test "ptype E" "type = namespace C::D::E"
 gdb_test "ptype CClass" "type = (class C::CClass \{\r\n  public:|struct C::CClass \{)\r\n    int x;\r\n\}"
 gdb_test "ptype CClass::NestedClass" "type = (class C::CClass::NestedClass \{\r\n  public:|struct C::CClass::NestedClass \{)\r\n    int y;\r\n\}"
 gdb_test "ptype NestedClass" "No symbol \"NestedClass\" in current context."
-setup_kfail "gdb/1448" "*-*-*"
-gdb_test "ptype ::C::CClass" "type = class C::CClass \{\r\n  public:\r\n    int x;\r\n\}"
-setup_kfail "gdb/1448" "*-*-*"
-gdb_test "ptype ::C::CClass::NestedClass" "type = class C::CClass::NestedClass \{\r\n  public:\r\n    int y;\r\n\}"
-setup_kfail "gdb/1448" "*-*-*"
+cp_test_ptype_class \
+	"ptype ::C::CClass" "" "class" "C::CClass" \
+	{
+	    { field public "int x;" }
+	}
+cp_test_ptype_class \
+	"ptype ::C::CClass::NestedClass" "" "class" "C::CClass::NestedClass" \
+	{
+	    { field public "int y;" }
+	}
 gdb_test "ptype ::C::NestedClass" "No symbol \"NestedClass\" in namespace \"C\"."
 gdb_test "ptype C::CClass" "No symbol \"CClass\" in namespace \"C::C\"."
 gdb_test "ptype C::CClass::NestedClass" "No type \"CClass\" within class or namespace \"C::C\"."
@@ -273,8 +279,11 @@ gdb_test "ptype C::NestedClass" "No symbol \"NestedClass\" in namespace \"C::C\"
 
 gdb_test "print cOtherFile" "\\$\[0-9\].* = 316"
 gdb_test "ptype OtherFileClass" "type = (class C::OtherFileClass \{\r\n  public:|struct C::OtherFileClass \{)\r\n    int z;\r\n\}"
-setup_kfail "gdb/1448" "*-*-*"
-gdb_test "ptype ::C::OtherFileClass" "type = class C::OtherFileClass \{\r\n  public:\r\n    int z;\r\n\}"
+cp_test_ptype_class \
+	"ptype ::C::OtherFileClass" "" "class" "C::OtherFileClass" \
+	{
+	    { field public "int z;" }
+	}
 gdb_test "ptype C::OtherFileClass" "No symbol \"OtherFileClass\" in namespace \"C::C\"."
 
 # Some anonymous namespace tests.
diff --git a/gdb/testsuite/gdb.cp/overload.exp b/gdb/testsuite/gdb.cp/overload.exp
index 24025a2..a72932e 100644
--- a/gdb/testsuite/gdb.cp/overload.exp
+++ b/gdb/testsuite/gdb.cp/overload.exp
@@ -74,12 +74,12 @@ set re_methods	"${re_methods}${ws}int overload1arg\\((void|)\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(char\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(signed char\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(unsigned char\\);"
-set re_methods	"${re_methods}${ws}int overload1arg\\(short\\);"
-set re_methods	"${re_methods}${ws}int overload1arg\\(unsigned short\\);"
+set re_methods	"${re_methods}${ws}int overload1arg\\(short( int)?\\);"
+set re_methods	"${re_methods}${ws}int overload1arg\\((unsigned short|short unsigned)( int)?\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(int\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(unsigned int\\);"
-set re_methods	"${re_methods}${ws}int overload1arg\\(long\\);"
-set re_methods	"${re_methods}${ws}int overload1arg\\(unsigned long\\);"
+set re_methods	"${re_methods}${ws}int overload1arg\\(long( int)?\\);"
+set re_methods	"${re_methods}${ws}int overload1arg\\((unsigned long|long unsigned)( int)?\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(float\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(double\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\((void|)\\);"
diff --git a/gdb/testsuite/gdb.cp/ovldbreak.exp b/gdb/testsuite/gdb.cp/ovldbreak.exp
index 8a6b795..9997a45 100644
--- a/gdb/testsuite/gdb.cp/ovldbreak.exp
+++ b/gdb/testsuite/gdb.cp/ovldbreak.exp
@@ -127,10 +127,24 @@ proc set_bp_overloaded {name expectedmenu mychoice bpnumber linenumber} {
 }
 
 # This is the expected menu for overload1arg.
-# Note the arg type variations on lines 6 and 13.
+# Note the arg type variations for void and integer types.
 # This accommodates different versions of g++.
 
-set menu_overload1arg "\\\[0\\\] cancel\r\n\\\[1\\\] all\r\n\\\[2\\\] foo::overload1arg\\(double\\) at.*$srcfile:121\r\n\\\[3\\\] foo::overload1arg\\(float\\) at.*$srcfile:120\r\n\\\[4\\\] foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r\n\\\[5\\\] foo::overload1arg\\(long\\) at.*$srcfile:118\r\n\\\[6\\\] foo::overload1arg\\((unsigned int|unsigned)\\) at.*$srcfile:117\r\n\\\[7\\\] foo::overload1arg\\(int\\) at.*$srcfile:116\r\n\\\[8\\\] foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r\n\\\[9\\\] foo::overload1arg\\(short\\) at.*$srcfile:114\r\n\\\[10\\\] foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r\n\\\[11\\\] foo::overload1arg\\(signed char\\) at.*$srcfile:112\r\n\\\[12\\\] foo::overload1arg\\(char\\) at.*$srcfile:111\r\n\\\[13\\\] foo::overload1arg\\((void|)\\) at.*$srcfile:110\r\n> $"
+set    menu_overload1arg "\\\[0\\\] cancel\r\n"
+append menu_overload1arg "\\\[1\\\] all\r\n"
+append menu_overload1arg "\\\[2\\\] foo::overload1arg\\(double\\) at.*$srcfile:121\r\n"
+append menu_overload1arg "\\\[3\\\] foo::overload1arg\\(float\\) at.*$srcfile:120\r\n"
+append menu_overload1arg "\\\[4\\\] foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r\n"
+append menu_overload1arg "\\\[5\\\] foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r\n"
+append menu_overload1arg "\\\[6\\\] foo::overload1arg\\((unsigned int|unsigned)\\) at.*$srcfile:117\r\n"
+append menu_overload1arg "\\\[7\\\] foo::overload1arg\\(int\\) at.*$srcfile:116\r\n"
+append menu_overload1arg "\\\[8\\\] foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r\n"
+append menu_overload1arg "\\\[9\\\] foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r\n"
+append menu_overload1arg "\\\[10\\\] foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r\n"
+append menu_overload1arg "\\\[11\\\] foo::overload1arg\\(signed char\\) at.*$srcfile:112\r\n"
+append menu_overload1arg "\\\[12\\\] foo::overload1arg\\(char\\) at.*$srcfile:111\r\n"
+append menu_overload1arg "\\\[13\\\] foo::overload1arg\\((void|)\\) at.*$srcfile:110\r\n"
+append menu_overload1arg "> $"
 
 # Set multiple-symbols to "ask", to allow us to test the use
 # of the multiple-choice menu when breaking on an overloaded method.
@@ -157,17 +171,17 @@ set_bp_overloaded "foo::overload1arg" "$menu_overload1arg" 13   13 110
 
 gdb_test "info break" \
     "Num     Type\[\t \]+Disp Enb Address\[\t \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main(\\((|void)\\))? at.*$srcfile:49\r
 \[\t \]+breakpoint already hit 1 time\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \
@@ -215,17 +229,17 @@ gdb_expect {
 
 gdb_test "info break" \
     "Num     Type\[\t \]+Disp Enb Address\[\t \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main(\\((|void)\\))? at.*$srcfile:49\r
 \[\t \]+breakpoint already hit 1 time\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \
@@ -296,12 +310,12 @@ gdb_test "info break" \
     "Num     Type\[\t \]+Disp Enb Address\[\t \]+What.*
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
diff --git a/gdb/testsuite/gdb.cp/shadowing.cc b/gdb/testsuite/gdb.cp/shadowing.cc
new file mode 100644
index 0000000..6d9c2f1
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/shadowing.cc
@@ -0,0 +1,48 @@
+namespace A
+{
+  int x = 11;
+}
+
+int x = 22;
+int y = 0;
+
+class B
+{
+public:
+  int x;
+
+  int
+  func()
+  {
+    x = 33;
+    y+=x; // marker1
+
+      {
+        int x = 44;
+        y+=x; // marker2
+
+          {
+            int x = 55;
+            y+=x; // marker3
+
+              {
+                int z = x; //prevent gcc from optimizing away this scope
+                using namespace A;
+                y+=x; // marker4
+
+                using A::x;
+                y+=x; // marker5
+                
+                return this->x;
+              }
+          }
+      }
+  }
+};
+
+int
+main()
+{
+  B theB;
+  return theB.func();
+}
diff --git a/gdb/testsuite/gdb.cp/shadowing.exp b/gdb/testsuite/gdb.cp/shadowing.exp
new file mode 100644
index 0000000..6922eed
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/shadowing.exp
@@ -0,0 +1,91 @@
+# 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 $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile shadowing
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+if [get_compiler_info ${binfile}] {
+    return -1;
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
+############################################
+# Test printing of class variable is not shadowed
+# by global variable
+
+gdb_breakpoint [gdb_get_line_number "marker1"]
+gdb_continue_to_breakpoint "marker1"
+
+gdb_test "print x" "= 33" "Print class x shadowing global x"
+
+
+############################################
+# Test printing local variable is not shadowed
+# by class variable
+
+gdb_breakpoint [gdb_get_line_number "marker2"]
+gdb_continue_to_breakpoint "marker2"
+
+gdb_test "print x" "= 44" "Print local x shadowing class x"
+
+############################################
+# Test inner scope x is printed not outer scope
+
+gdb_breakpoint [gdb_get_line_number "marker3"]
+gdb_continue_to_breakpoint "marker3"
+
+gdb_test "print x" "= 55" "Print inner scope x"
+
+############################################
+# Test printing local variable is not shadowed
+# by namespace variable
+
+gdb_breakpoint [gdb_get_line_number "marker4"]
+gdb_continue_to_breakpoint "marker4"
+
+gdb_test "print x" "= 55" "Print local x not namespace x"
+
+############################################
+# Test imported namespace element is printed
+
+gdb_breakpoint [gdb_get_line_number "marker5"]
+gdb_continue_to_breakpoint "marker5"
+
+if [test_compiler_info gcc-4-3-*] then { setup_xfail *-*-* }
+
+gdb_test "print x" "= 11" "Print imported namespace x"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-aranges.S b/gdb/testsuite/gdb.dwarf2/dw2-aranges.S
new file mode 100644
index 0000000..d5b9ca5
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-aranges.S
@@ -0,0 +1,140 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004, 2007, 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/>.  */
+
+/* Test .debug_aranges containing zero address_size.  */
+
+/* Dummy function to provide debug information for.  */
+
+	.text
+.Lbegin_text1:
+	.globl main
+	.type main, %function
+main:
+.Lbegin_main:
+	.int 0
+.Lend_main:
+	.size main, .-main
+.Lend_text1:
+
+/* 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 */
+	.4byte	.Lend_text1			/* DW_AT_high_pc */
+	.4byte	.Lbegin_text1			/* DW_AT_low_pc */
+	.ascii	"file1.txt\0"			/* DW_AT_name */
+	.ascii	"GNU C 3.3.3\0"			/* DW_AT_producer */
+	.byte	1				/* DW_AT_language (C) */
+
+	/* main */
+	.uleb128	2			/* Abbrev: DW_TAG_subprogram */
+	.byte		1			/* DW_AT_external */
+	.byte		1			/* DW_AT_decl_file */
+	.byte		2			/* DW_AT_decl_line */
+	.ascii		"main\0"		/* DW_AT_name */
+	.4byte		.Ltype_int-.Lcu1_begin	/* DW_AT_type */
+	.4byte		.Lbegin_main	/* DW_AT_low_pc */
+	.4byte		.Lend_main		/* DW_AT_high_pc */
+	.byte		1			/* DW_AT_frame_base: length */
+	.byte		0x55			/* DW_AT_frame_base: DW_OP_reg5 */
+
+.Ltype_int:
+	.uleb128	3			/* Abbrev: DW_TAG_base_type */
+	.ascii		"int\0"			/* DW_AT_name */
+	.byte		4			/* DW_AT_byte_size */
+	.byte		5			/* DW_AT_encoding */
+
+	.byte		0			/* End of children of CU */
+
+.Lcu1_end:
+
+/* Abbrev table */
+	.section .debug_abbrev
+.Labbrev1_begin:
+	.uleb128	1			/* Abbrev code */
+	.uleb128	0x11			/* DW_TAG_compile_unit */
+	.byte		1			/* has_children */
+	.uleb128	0x12			/* DW_AT_high_pc */
+	.uleb128	0x1			/* DW_FORM_addr */
+	.uleb128	0x11			/* DW_AT_low_pc */
+	.uleb128	0x1			/* DW_FORM_addr */
+	.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	0x2e			/* DW_TAG_subprogram */
+	.byte		0			/* has_children */
+	.uleb128	0x3f			/* DW_AT_external */
+	.uleb128	0xc			/* DW_FORM_flag */
+	.uleb128	0x3a			/* DW_AT_decl_file */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.uleb128	0x3b			/* DW_AT_decl_line */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.uleb128	0x3			/* DW_AT_name */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0x49			/* DW_AT_type */
+	.uleb128	0x13			/* DW_FORM_ref4 */
+	.uleb128	0x11			/* DW_AT_low_pc */
+	.uleb128	0x1			/* DW_FORM_addr */
+	.uleb128	0x12			/* DW_AT_high_pc */
+	.uleb128	0x1			/* DW_FORM_addr */
+	.uleb128	0x40			/* DW_AT_frame_base */
+	.uleb128	0xa			/* DW_FORM_block1 */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.uleb128	3			/* Abbrev code */
+	.uleb128	0x24			/* DW_TAG_base_type */
+	.byte		0			/* has_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 */
+
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+/* aranges table */
+	.section .debug_aranges
+	.long	.Laranges_end - 1f
+1:
+	.2byte	2				/* aranges Version */
+	.4byte	.Lcu1_begin - .debug_info	/* Offset into .debug_info section */
+	/* The GDB crasher is this zero value.  */
+	.byte		0			/* aranges address_size */
+	.byte		0			/* aranges segment_size */
+
+.Laranges_end:
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp b/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp
new file mode 100644
index 0000000..39632d5
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp
@@ -0,0 +1,40 @@
+# Copyright 2004, 2005, 2007, 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/>.
+
+# Test .debug_aranges containing zero address_size.
+
+# 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 "dw2-aranges"
+set srcfile ${testfile}.S
+set binfile ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {nodebug}] != "" } {
+    return -1
+}
+
+clean_restart $testfile
+
+# Failed gdb_load would abort the testcase execution earlier.
+pass "file loaded"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.c b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c
new file mode 100644
index 0000000..1f02d90
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c
@@ -0,0 +1,42 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   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 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.  */
+
+
+/* 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)
+{
+}
+
+/* `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.dwarf2/dw2-stripped.exp b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp
new file mode 100644
index 0000000..1c6e84a
--- /dev/null
+++ 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 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.
+
+# 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
+}
+
+# This test can only be run on gcc as we use additional_flags=FIXME
+if {$gcc_compiled == 0} {
+    return 0
+}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-ggdb3}] != "" } {
+    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)"
+}
+
+set test "stripping test file functionality"
+if [ regexp ".debug_loc " $strip_output]  {
+    fail "$test (.debug_loc still present)"
+} else {
+    pass "$test (.debug_loc stripped)"
+}
+
+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..5fcdd84
--- /dev/null
+++ 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 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/>.  */
+
+/* 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:
+
+/* 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..c41151c
--- /dev/null
+++ 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
+# (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 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 "dw2-struct-member-data-location"
+set srcfile ${testfile}.S
+set binfile ${testfile}.x
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${binfile}" object {nodebug}] != "" } {
+    return -1
+}
+
+clean_restart $binfile
+
+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/common-block.exp b/gdb/testsuite/gdb.fortran/common-block.exp
new file mode 100644
index 0000000..888f6c3
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/common-block.exp
@@ -0,0 +1,101 @@
+# Copyright 2008 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
+
+set testfile "common-block"
+set srcfile ${testfile}.f90
+set binfile ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto MAIN__] then {
+    perror "couldn't run to breakpoint MAIN__"
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "stop-here-out"]
+gdb_continue_to_breakpoint "stop-here-out"
+
+# Common block naming with source name /foo/:
+#                .symtab  DW_TAG_common_block's DW_AT_name
+# Intel Fortran  foo_     foo_
+# GNU Fortran    foo_     foo
+#set suffix "_"
+set suffix ""
+
+set int4 {(integer\(kind=4\)|INTEGER\(4\))}
+set real4 {(real\(kind=4\)|REAL\(4\))}
+set real8 {(real\(kind=8\)|REAL\(8\))}
+
+gdb_test "whatis foo$suffix" "No symbol \"foo$suffix\" in current context."
+gdb_test "ptype foo$suffix" "No symbol \"foo$suffix\" in current context."
+gdb_test "p foo$suffix" "No symbol \"foo$suffix\" in current context."
+gdb_test "whatis fo_o$suffix" "No symbol \"fo_o$suffix\" in current context."
+gdb_test "ptype fo_o$suffix" "No symbol \"fo_o$suffix\" in current context."
+gdb_test "p fo_o$suffix" "No symbol \"fo_o$suffix\" in current context."
+
+gdb_test "info locals" "ix_x = 11\r\niy_y = 22\r\niz_z = 33\r\nix = 1\r\niy = 2\r\niz = 3" "info locals out"
+gdb_test "info common" "Contents of F77 COMMON block 'fo_o':\r\nix_x = 11\r\niy_y = 22\r\niz_z = 33\r\n\r\nContents of F77 COMMON block 'foo':\r\nix = 1\r\niy = 2\r\niz = 3" "info common out"
+
+gdb_test "ptype ix" "type = $int4" "ptype ix out"
+gdb_test "ptype iy" "type = $real4" "ptype iy out"
+gdb_test "ptype iz" "type = $real8" "ptype iz out"
+gdb_test "ptype ix_x" "type = $int4" "ptype ix_x out"
+gdb_test "ptype iy_y" "type = $real4" "ptype iy_y out"
+gdb_test "ptype iz_z" "type = $real8" "ptype iz_z out"
+
+gdb_test "p ix" " = 1 *" "p ix out"
+gdb_test "p iy" " = 2 *" "p iy out"
+gdb_test "p iz" " = 3 *" "p iz out"
+gdb_test "p ix_x" " = 11 *" "p ix_x out"
+gdb_test "p iy_y" " = 22 *" "p iy_y out"
+gdb_test "p iz_z" " = 33 *" "p iz_z out"
+
+gdb_breakpoint [gdb_get_line_number "stop-here-in"]
+gdb_continue_to_breakpoint "stop-here-in"
+
+gdb_test "whatis foo$suffix" "No symbol \"foo$suffix\" in current context." "whatis foo$suffix in"
+gdb_test "ptype foo$suffix" "No symbol \"foo$suffix\" in current context." "ptype foo$suffix in"
+gdb_test "p foo$suffix" "No symbol \"foo$suffix\" in current context." "p foo$suffix in"
+gdb_test "whatis fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." "whatis fo_o$suffix in"
+gdb_test "ptype fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." "ptype fo_o$suffix in"
+gdb_test "p fo_o$suffix" "No symbol \"fo_o$suffix\" in current context." "p fo_o$suffix in"
+
+gdb_test "info locals" "ix = 11\r\niy2 = 22\r\niz = 33\r\nix_x = 1\r\niy_y = 2\r\niz_z2 = 3\r\niy = 5\r\niz_z = 55" "info locals in"
+gdb_test "info common" "Contents of F77 COMMON block 'fo_o':\r\nix = 11\r\niy2 = 22\r\niz = 33\r\n\r\nContents of F77 COMMON block 'foo':\r\nix_x = 1\r\niy_y = 2\r\niz_z2 = 3" "info common in"
+
+gdb_test "ptype ix" "type = $int4" "ptype ix in"
+gdb_test "ptype iy2" "type = $real4" "ptype iy2 in"
+gdb_test "ptype iz" "type = $real8" "ptype iz in"
+gdb_test "ptype ix_x" "type = $int4" "ptype ix_x in"
+gdb_test "ptype iy_y" "type = $real4" "ptype iy_y in"
+gdb_test "ptype iz_z2" "type = $real8" "ptype iz_z2 in"
+
+gdb_test "p ix" " = 11 *" "p ix in"
+gdb_test "p iy2" " = 22 *" "p iy2 in"
+gdb_test "p iz" " = 33 *" "p iz in"
+gdb_test "p ix_x" " = 1 *" "p ix_x in"
+gdb_test "p iy_y" " = 2 *" "p iy_y in"
+gdb_test "p iz_z2" " = 3 *" "p iz_z2 in"
diff --git a/gdb/testsuite/gdb.fortran/common-block.f90 b/gdb/testsuite/gdb.fortran/common-block.f90
new file mode 100644
index 0000000..b614e8a
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/common-block.f90
@@ -0,0 +1,67 @@
+! Copyright 2008 Free Software Foundation, Inc.
+!
+! This program is free software; you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or
+! (at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with this program; if not, write to the Free Software
+! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+!
+! Ihis file is the Fortran source file for dynamic.exp.
+! Original file written by Jakub Jelinek <jakub@redhat.com>.
+! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>.
+
+subroutine in
+
+   INTEGER*4            ix
+   REAL*4               iy2
+   REAL*8               iz
+
+   INTEGER*4            ix_x
+   REAL*4               iy_y
+   REAL*8               iz_z2
+
+   common /fo_o/ix,iy2,iz
+   common /foo/ix_x,iy_y,iz_z2
+
+   iy = 5
+   iz_z = 55
+
+   if (ix .ne. 11 .or. iy2 .ne. 22.0 .or. iz .ne. 33.0) call abort
+   if (ix_x .ne. 1 .or. iy_y .ne. 2.0 .or. iz_z2 .ne. 3.0) call abort
+
+   ix = 0					! stop-here-in
+
+end subroutine in
+
+program common_test
+
+   INTEGER*4            ix
+   REAL*4               iy
+   REAL*8               iz
+
+   INTEGER*4            ix_x
+   REAL*4               iy_y
+   REAL*8               iz_z
+
+   common /foo/ix,iy,iz
+   common /fo_o/ix_x,iy_y,iz_z
+
+   ix = 1
+   iy = 2.0
+   iz = 3.0
+
+   ix_x = 11
+   iy_y = 22.0
+   iz_z = 33.0
+
+   call in					! stop-here-out
+
+end program common_test
diff --git a/gdb/testsuite/gdb.fortran/dwarf-stride.exp b/gdb/testsuite/gdb.fortran/dwarf-stride.exp
new file mode 100644
index 0000000..cd3486b
--- /dev/null
+++ 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 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
+
+# This file is part of the gdb testsuite.  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
+
+set testfile dwarf-stride
+set srcfile ${testfile}.f90
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f77}] } {
+    return -1
+}
+
+if ![runto MAIN__] then {
+    perror "couldn't run to breakpoint MAIN__"
+    continue
+}
+
+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..e492b3a
--- /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.
+
+program repro
+
+  type small_stride
+     character*40 long_string
+     integer      small_pad
+  end type small_stride
+
+  type(small_stride), dimension (20), target :: unpleasant
+  character*40, pointer, dimension(:):: c40pt
+
+  integer i
+
+  do i = 0,19
+     unpleasant(i+1)%small_pad = i+1
+     unpleasant(i+1)%long_string = char (ichar('0') + i) // '-hello'
+  end do
+
+  c40pt => unpleasant%long_string
+
+  print *, c40pt  ! break-here
+
+end program repro
diff --git a/gdb/testsuite/gdb.fortran/dynamic.exp b/gdb/testsuite/gdb.fortran/dynamic.exp
new file mode 100644
index 0000000..0ccebe0
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/dynamic.exp
@@ -0,0 +1,145 @@
+# Copyright 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
+
+# This file is part of the gdb testsuite.  It contains tests for dynamically
+# allocated Fortran arrays.
+# It depends on the GCC dynamic Fortran arrays DWARF support:
+# 	http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22244
+
+set testfile "dynamic"
+set srcfile ${testfile}.f90
+set binfile ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto MAIN__] then {
+    perror "couldn't run to breakpoint MAIN__"
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "varx-init"]
+gdb_continue_to_breakpoint "varx-init"
+gdb_test "p varx" "\\$\[0-9\]* = <(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"
+
+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"
+
+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"
+
+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"
+
+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"
+
+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\\."
+
+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"
+
+gdb_breakpoint [gdb_get_line_number "vary-passed"]
+gdb_continue_to_breakpoint "vary-passed"
+# $1 = (( ( 1, 1, 1, 1, 1, 1) ( 1, 1, 1, 1, 1, 1) --- , 1) ) ( ( 1, 1, ...) ...) ...)
+gdb_test "p vary" "\\$\[0-9\]* = \\(\[()1, .\]*\\)"
+
+gdb_breakpoint [gdb_get_line_number "vary-filled"]
+gdb_continue_to_breakpoint "vary-filled"
+gdb_test "ptype vary" "type = real(\\(kind=4\\)|\\*4) \\(10,10\\)"
+gdb_test "p vary(1, 1)" "\\$\[0-9\]* = 8"
+gdb_test "p vary(2, 2)" "\\$\[0-9\]* = 9"
+gdb_test "p vary(1, 3)" "\\$\[0-9\]* = 10"
+# $1 = (( ( 3, 3, 3, 3, 3, 3) ( 3, 3, 3, 3, 3, 3) --- , 3) ) ( ( 3, 3, ...) ...) ...)
+gdb_test "p varw" "\\$\[0-9\]* = \\(\[()3, .\]*\\)"
+
+gdb_breakpoint [gdb_get_line_number "varw-almostfilled"]
+gdb_continue_to_breakpoint "varw-almostfilled"
+gdb_test "ptype varw" "type = real(\\(kind=4\\)|\\*4) \\(5,4,3\\)"
+gdb_test "p varw(3,1,1)=1" "\\$\[0-9\]* = 1"
+# $1 = (( ( 6, 5, 1, 5, 5, 5) ( 5, 5, 5, 5, 5, 5) --- , 5) ) ( ( 5, 5, ...) ...) ...)
+gdb_test "p varw" "\\$\[0-9\]* = \\( *\\( *\\( *6, *5, *1,\[()5, .\]*\\)" "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"
+
+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>.
+
+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/library-module-lib.f90 b/gdb/testsuite/gdb.fortran/library-module-lib.f90
new file mode 100644
index 0000000..6369d34
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/library-module-lib.f90
@@ -0,0 +1,28 @@
+! 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/>.
+
+module lib
+        integer :: var_i = 1
+contains
+        subroutine lib_func
+        if (var_i .ne. 1) call abort
+        var_i = 2
+        end subroutine lib_func
+end module lib
+
+module libmany
+        integer :: var_j = 3
+        integer :: var_k = 4
+end module libmany
diff --git a/gdb/testsuite/gdb.fortran/library-module-main.f90 b/gdb/testsuite/gdb.fortran/library-module-main.f90
new file mode 100644
index 0000000..de63a65
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/library-module-main.f90
@@ -0,0 +1,23 @@
+! 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/>.
+
+        use lib
+	use libmany, only: var_j
+        if (var_i .ne. 1) call abort
+	call lib_func
+        if (var_i .ne. 2) call abort
+        if (var_j .ne. 3) call abort
+        var_i = var_i                 ! i-is-2
+end
diff --git a/gdb/testsuite/gdb.fortran/library-module.exp b/gdb/testsuite/gdb.fortran/library-module.exp
new file mode 100644
index 0000000..4b4ea4c
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/library-module.exp
@@ -0,0 +1,53 @@
+# 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 testfile "library-module"
+set srcfile ${testfile}-main.f90
+set srclibfile ${testfile}-lib.f90
+set libfile ${testfile}-lib.so
+set binfile ${testfile}
+
+# Required for -fPIC by gdb_compile_shlib.
+if [get_compiler_info not-used] {
+   warning "Could not get compiler info"
+   return -1
+}
+
+if  { [gdb_compile_shlib "${srcdir}/${subdir}/${srclibfile}" $objdir/$subdir/$libfile {debug f77}] != "" } {
+    untested "Couldn't compile ${srclibfile}"
+    return -1
+}
+
+# prepare_for_testing cannot be used as linking with $libfile cannot be passed
+# just for the linking phase (and not the source compilation phase).  And any
+# warnings on ignored $libfile abort the process.
+
+if  { [gdb_compile [list $srcdir/$subdir/$srcfile $objdir/$subdir/$libfile] $objdir/$subdir/$binfile executable {debug f77}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+clean_restart $binfile
+
+if ![runto MAIN__] then {
+    perror "couldn't run to breakpoint MAIN__"
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "i-is-2"]
+gdb_continue_to_breakpoint "i-is-2" ".*i-is-2.*"
+gdb_test "print var_i" " = 2"
+gdb_test "print var_j" " = 3"
+gdb_test "print var_k" "No symbol \"var_k\" in current context\\."
diff --git a/gdb/testsuite/gdb.fortran/logical.exp b/gdb/testsuite/gdb.fortran/logical.exp
new file mode 100644
index 0000000..ef76f43
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/logical.exp
@@ -0,0 +1,44 @@
+# Copyright 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
+
+set testfile "logical"
+set srcfile ${testfile}.f90
+set binfile ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto MAIN__] then {
+    perror "couldn't run to breakpoint MAIN__"
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "stop-here"]
+gdb_continue_to_breakpoint "stop-here"
+gdb_test "p l" " = \\.TRUE\\."
+gdb_test "p l1" " = \\.TRUE\\."
+gdb_test "p l2" " = \\.TRUE\\."
+gdb_test "p l4" " = \\.TRUE\\."
+gdb_test "p l8" " = \\.TRUE\\."
diff --git a/gdb/testsuite/gdb.fortran/logical.f90 b/gdb/testsuite/gdb.fortran/logical.f90
new file mode 100644
index 0000000..4229304
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/logical.f90
@@ -0,0 +1,33 @@
+! 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>.
+
+program test
+  logical :: l
+  logical (kind=1) :: l1
+  logical (kind=2) :: l2
+  logical (kind=4) :: l4
+  logical (kind=8) :: l8
+  l = .TRUE.
+  l1 = .TRUE.
+  l2 = .TRUE.
+  l4 = .TRUE.
+  l8 = .TRUE.
+  l = .FALSE.					! stop-here
+end
diff --git a/gdb/testsuite/gdb.fortran/module.exp b/gdb/testsuite/gdb.fortran/module.exp
index 342ccee..c836c3c 100644
--- a/gdb/testsuite/gdb.fortran/module.exp
+++ b/gdb/testsuite/gdb.fortran/module.exp
@@ -15,21 +15,31 @@
 
 set testfile "module"
 set srcfile ${testfile}.f90
-set binfile ${objdir}/${subdir}/${testfile}
 
-if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } {
-    untested "Couldn't compile ${srcfile}"
+if { [prepare_for_testing $testfile.exp $testfile $srcfile {debug f77}] } {
     return -1
 }
 
-gdb_exit
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
-gdb_load ${binfile}
-
 if ![runto MAIN__] then {
     perror "couldn't run to breakpoint MAIN__"
     continue
 }
 
-gdb_test "print i" " = 42"
+# Do not use simple single-letter names as GDB would pick up for expectedly
+# nonexisting symbols some static variables from system libraries debuginfos.
+
+gdb_breakpoint [gdb_get_line_number "i-is-1"]
+gdb_continue_to_breakpoint "i-is-1" ".*i-is-1.*"
+gdb_test "print var_i" " = 1" "print var_i value 1"
+
+gdb_breakpoint [gdb_get_line_number "i-is-2"]
+gdb_continue_to_breakpoint "i-is-2" ".*i-is-2.*"
+gdb_test "print var_i" " = 2" "print var_i value 2"
+
+gdb_breakpoint [gdb_get_line_number "a-b-c-d"]
+gdb_continue_to_breakpoint "a-b-c-d" ".*a-b-c-d.*"
+gdb_test "print var_a" "No symbol \"var_a\" in current context\\."
+gdb_test "print var_b" " = 11"
+gdb_test "print var_c" "No symbol \"var_c\" in current context\\."
+gdb_test "print var_d" " = 12"
+gdb_test "print var_i" " = 14" "print var_i value 14"
diff --git a/gdb/testsuite/gdb.fortran/module.f90 b/gdb/testsuite/gdb.fortran/module.f90
index 501ccc8..118931d 100644
--- a/gdb/testsuite/gdb.fortran/module.f90
+++ b/gdb/testsuite/gdb.fortran/module.f90
@@ -13,10 +13,37 @@
 ! You should have received a copy of the GNU General Public License
 ! along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-module mod
-        integer :: i = 42
-end module mod
+module mod1
+        integer :: var_i = 1
+end module mod1
 
-        use mod
-        print *, i
+module mod2
+        integer :: var_i = 2
+end module mod2
+
+module modmany
+        integer :: var_a = 10, var_b = 11, var_c = 12, var_i = 14
+end module modmany
+
+        subroutine sub1
+        use mod1
+        if (var_i .ne. 1) call abort
+        var_i = var_i                         ! i-is-1
+        end
+
+        subroutine sub2
+        use mod2
+        if (var_i .ne. 2) call abort
+        var_i = var_i                         ! i-is-2
+        end
+
+        use modmany, only: var_b, var_d => var_c, var_i
+
+        call sub1
+        call sub2
+
+        if (var_b .ne. 11) call abort
+        if (var_d .ne. 12) call abort
+        if (var_i .ne. 14) call abort
+        var_b = var_b                         ! a-b-c-d
 end
diff --git a/gdb/testsuite/gdb.fortran/string.exp b/gdb/testsuite/gdb.fortran/string.exp
new file mode 100644
index 0000000..b1120c3
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/string.exp
@@ -0,0 +1,59 @@
+# Copyright 2008 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# This file was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
+
+# This file is part of the gdb testsuite.  It contains tests for Fortran
+# strings with dynamic length.
+
+set testfile "string"
+set srcfile ${testfile}.f90
+set binfile ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto MAIN__] then {
+    perror "couldn't run to breakpoint MAIN__"
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "var-init"]
+gdb_continue_to_breakpoint "var-init"
+gdb_test "ptype c" "type = character(\\(kind=1\\)|\\*1)"
+gdb_test "ptype d" "type = character(\\(kind=8\\)|\\*8)"
+gdb_test "ptype e" "type = 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."
+
+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>.
+
+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.gdb/selftest.exp b/gdb/testsuite/gdb.gdb/selftest.exp
index 495ae45..d08d7a4 100644
--- a/gdb/testsuite/gdb.gdb/selftest.exp
+++ b/gdb/testsuite/gdb.gdb/selftest.exp
@@ -95,6 +95,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 ".*time_at_startup = get_run_time.*$gdb_prompt $" {
 		set description "next over get_run_time and everything it calls"
 		set command "next"
diff --git a/gdb/testsuite/gdb.java/jnpe.exp b/gdb/testsuite/gdb.java/jnpe.exp
new file mode 100644
index 0000000..74d4d58
--- /dev/null
+++ b/gdb/testsuite/gdb.java/jnpe.exp
@@ -0,0 +1,72 @@
+# 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 $tracelevel then {
+  strace $tracelevel
+}
+
+load_lib "java.exp"
+
+set testfile "jnpe"
+set srcfile ${srcdir}/$subdir/${testfile}.java
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [compile_java_from_source ${srcfile} ${binfile} "-g"] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set line [gdb_get_line_number "break here" $testfile.java]
+gdb_test "break $testfile.java:$line" ""
+
+gdb_test "run" \
+  "Current language.*java" \
+  "run java next-over-throw"
+
+# See whether we have the needed unwinder hooks.
+set ok 1
+gdb_test_multiple "print _Unwind_DebugHook" "check for unwinder hook in java" {
+    -re "= .*_Unwind_DebugHook.*\r\n$gdb_prompt $" {
+	pass "check for unwinder hook in java"
+    }
+    -re "No symbol .* in current context.\r\n$gdb_prompt $" {
+	# Pass the test so we don't get bogus fails in the results.
+	pass "check for unwinder hook in java"
+	set ok 0
+    }
+}
+if {!$ok} {
+    untested jnpe.exp
+    return -1
+}
+
+gdb_test "handle SIGSEGV nostop noprint" \
+  "SIGSEGV.*fault" \
+  "disable SIGSEGV for next-over-NPE"
+
+# We sometimes stop at line 37, not line 35.  This seems to be a gcj
+# oddity -- another next will solve it.
+gdb_test "next" \
+  "3\[57\].*" \
+  "next over NPE"
diff --git a/gdb/testsuite/gdb.java/jnpe.java b/gdb/testsuite/gdb.java/jnpe.java
new file mode 100644
index 0000000..ffca3ab
--- /dev/null
+++ b/gdb/testsuite/gdb.java/jnpe.java
@@ -0,0 +1,38 @@
+// Test next-over-NPE.
+/* 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/>.
+   */
+
+public class jnpe
+{
+  public static String npe ()
+  {
+    return ((Object) null).toString();
+  }
+
+  public static void main (String[] args)
+  {
+    try
+      {
+	System.out.println (npe ()); // break here
+      }
+    catch (NullPointerException n)
+      {
+	System.out.println ("success");
+      }
+  }
+}
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..729f457
--- /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.
+
+   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/>.  */
+
+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.
+
+   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/>.  */
+
+extern int func (int *arr);
+
+int
+main (void)
+{
+  int arr[] = { 42 };
+
+  func (arr);
+
+  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.
+
+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
+}
+
+if ![runto func] then {
+    return -1
+}
+
+gdb_test "p arr" "\\$\[0-9\]+ = \\(int \\*\\) *0x\[0-9a-f\]+"
+
+# 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.opt/fortran-string.exp b/gdb/testsuite/gdb.opt/fortran-string.exp
new file mode 100644
index 0000000..f997eec
--- /dev/null
+++ b/gdb/testsuite/gdb.opt/fortran-string.exp
@@ -0,0 +1,41 @@
+# 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 was written by Jan Kratochvil <jan.kratochvil@redhat.com>.
+
+# Test GDB can cope with Fortran strings having their length present in a CPU
+# register.  With -O0 the string length is passed on the stack.  To make this
+# test meaningful the follow assertion should pass.  It is not being checked
+# here as the "_s" symbol is compiler dependent:
+#   (gdb) info address _s
+#   Symbol "_s" is a variable in register XX.
+
+set test fortran-string
+set srcfile ${test}.f90
+if { [prepare_for_testing ${test}.exp ${test} ${srcfile} {debug f77 additional_flags=-O2}] } {
+    return -1
+}
+
+if ![runto MAIN__] then {
+    perror "couldn't run to breakpoint MAIN__"
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "s = s"]
+gdb_continue_to_breakpoint "s = s"
+gdb_test "frame" ".*s='foo'.*"
+gdb_test "ptype s" "type = character\\*3"
+gdb_test "p s" "\\$\[0-9\]* = 'foo'"
diff --git a/gdb/testsuite/gdb.opt/fortran-string.f90 b/gdb/testsuite/gdb.opt/fortran-string.f90
new file mode 100644
index 0000000..e48d520
--- /dev/null
+++ b/gdb/testsuite/gdb.opt/fortran-string.f90
@@ -0,0 +1,28 @@
+! 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.
+!
+! 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 f(s)
+  character*(*) s
+  s = s
+  end
+
+  program main
+  call f ('foo')
+  end
diff --git a/gdb/testsuite/gdb.python/py-cmd.exp b/gdb/testsuite/gdb.python/py-cmd.exp
index f6ef938..1032a2d 100644
--- a/gdb/testsuite/gdb.python/py-cmd.exp
+++ b/gdb/testsuite/gdb.python/py-cmd.exp
@@ -20,36 +20,15 @@ if $tracelevel then {
     strace $tracelevel
 }
 
-# Usage: gdb_py_test_multiple NAME INPUT RESULT {INPUT RESULT}...
-# Run a test named NAME, consisting of multiple lines of input.
-# After each input line INPUT, search for result line RESULT.
-# Succeed if all results are seen; fail otherwise.
-proc gdb_py_test_multiple {name args} {
-    global gdb_prompt
-    foreach {input result} $args {
-	if {[gdb_test_multiple $input "$name - $input" {
-	    -re "\[\r\n\]*($result)\[\r\n\]+($gdb_prompt | *>)$" {
-		pass "$name - $input"
-	    }
-	}]} {
-	    return 1
-	}
-    }
-    return 0
-}
-
 # Start with a fresh gdb.
 
 gdb_exit
 gdb_start
 gdb_reinitialize_dir $srcdir/$subdir
 
-gdb_test_multiple "python print 'hello, world!'" "verify python support" {
-    -re "not supported.*$gdb_prompt $"	{
-      unsupported "python support is disabled"
-      return -1
-    }
-    -re "$gdb_prompt $"	{}
+if ![python_supported] then {
+  unsupported "python support is disabled"
+  return -1
 }
 
 # Test a simple command.
diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp
index a67eaa3..5380c0f 100644
--- a/gdb/testsuite/gdb.python/py-frame.exp
+++ b/gdb/testsuite/gdb.python/py-frame.exp
@@ -20,40 +20,28 @@ if $tracelevel then {
     strace $tracelevel
 }
 
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+if ![python_supported] then {
+  unsupported "python support is disabled"
+  return -1
+}
+
 set testfile "py-frame"
 set srcfile ${testfile}.c
 set binfile ${objdir}/${subdir}/${testfile}
+
 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
     untested "Couldn't compile ${srcfile}"
     return -1
 }
 
-# Run a command in GDB, and report a failure if a Python exception is thrown.
-# If report_pass is true, report a pass if no exception is thrown.
-proc gdb_py_test_silent_cmd {cmd name report_pass} {
-  global gdb_prompt
-
-  gdb_test_multiple $cmd $name {
-      -re "Traceback.*$gdb_prompt $"  { fail $name }
-      -re "$gdb_prompt $"	      { if $report_pass { pass $name } }
-  }
-}
-
-# Start with a fresh gdb.
-
-gdb_exit
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
 gdb_load ${binfile}
 
-gdb_test_multiple "python print 'hello, world!'" "verify python support" {
-    -re "not supported.*$gdb_prompt $"	{
-      unsupported "python support is disabled"
-      return -1
-    }
-    -re "$gdb_prompt $"	{}
-}
-
 # The following tests require execution.
 
 if ![runto_main] then {
@@ -65,19 +53,20 @@ gdb_breakpoint "f2"
 gdb_continue_to_breakpoint "breakpoint at f2"
 gdb_test "up" "" ""
 
-gdb_py_test_silent_cmd "python f1 = gdb.selected_frame ()" "get second frame" 0
-gdb_py_test_silent_cmd "python f0 = f1.newer ()" "get first frame" 0
+gdb_py_test_silent_cmd "python frames = gdb.selected_thread ().frames ()" "get frames list" 1
+gdb_test "python print frames" "\\(<gdb.Frame object at 0x\[\[:xdigit:\]\]+>, <gdb.Frame object at 0x\[\[:xdigit:\]\]+>, <gdb.Frame object at 0x\[\[:xdigit:\]\]+>\\)" "verify frames list"
+gdb_py_test_silent_cmd "python f0 = frames\[0\]" "get first frame" 0
+gdb_py_test_silent_cmd "python f1 = frames\[1\]" "get second frame" 0
 
 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"
 gdb_test "python print 'result =', f0.unwind_stop_reason () == gdb.FRAME_UNWIND_NO_REASON" " = True" "test Frame.type"
 gdb_test "python print 'result =', gdb.frame_stop_reason_string (gdb.FRAME_UNWIND_INNER_ID)" " = previous frame inner to this frame \\(corrupt stack\\?\\)" "test gdb.frame_stop_reason_string"
 gdb_test "python print 'result =', f0.pc ()" " = \[0-9\]+" "test Frame.pc"
+gdb_test "python print 'result =', f0.function ()" " = symbol for f2" "test Frame.function"
 gdb_test "python print 'result =', f0.older () == f1" " = True" "test Frame.older"
 gdb_test "python print 'result =', f1.newer () == f0" " = True" "test Frame.newer"
 gdb_test "python print 'result =', f0.read_var ('variable_which_surely_doesnt_exist')" \
@@ -85,4 +74,7 @@ gdb_test "python print 'result =', f0.read_var ('variable_which_surely_doesnt_ex
   "test Frame.read_var - error"
 gdb_test "python print 'result =', f0.read_var ('a')" " = 1" "test Frame.read_var - success"
 
+gdb_test "python print 'result =', gdb.selected_thread ().newest_frame () == f0" " = True" "test gdb.newest_frame"
 gdb_test "python print 'result =', gdb.selected_frame () == f1" " = True" "test gdb.selected_frame"
+
+gdb_test "python print 'result =', f0.block ()" "<gdb.Block object at 0x\[\[:xdigit:\]\]+>" "test Frame.block"
diff --git a/gdb/testsuite/gdb.python/py-function.exp b/gdb/testsuite/gdb.python/py-function.exp
index 7feca2b..4ae519f 100644
--- a/gdb/testsuite/gdb.python/py-function.exp
+++ b/gdb/testsuite/gdb.python/py-function.exp
@@ -20,36 +20,15 @@ if $tracelevel then {
     strace $tracelevel
 }
 
-# Usage: gdb_py_test_multiple NAME INPUT RESULT {INPUT RESULT}...
-# Run a test named NAME, consisting of multiple lines of input.
-# After each input line INPUT, search for result line RESULT.
-# Succeed if all results are seen; fail otherwise.
-proc gdb_py_test_multiple {name args} {
-    global gdb_prompt
-    foreach {input result} $args {
-	if {[gdb_test_multiple $input "$name - $input" {
-	    -re "\[\r\n\]*($result)\[\r\n\]+($gdb_prompt | *>)$" {
-		pass "$name - $input"
-	    }
-	}]} {
-	    return 1
-	}
-    }
-    return 0
-}
-
 # Start with a fresh gdb.
 
 gdb_exit
 gdb_start
 gdb_reinitialize_dir $srcdir/$subdir
 
-gdb_test_multiple "python print 'hello, world!'" "verify python support" {
-    -re "not supported.*$gdb_prompt $"	{
-      unsupported "python support is disabled"
-      return -1
-    }
-    -re "$gdb_prompt $"	{}
+if ![python_supported] then {
+  unsupported "python support is disabled"
+  return -1
 }
 
 gdb_py_test_multiple "input convenience function" \
diff --git a/gdb/testsuite/gdb.python/py-inferior.c b/gdb/testsuite/gdb.python/py-inferior.c
new file mode 100644
index 0000000..0b48299
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-inferior.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#define CHUNK_SIZE 16000 /* same as findcmd.c's */
+#define BUF_SIZE (2 * CHUNK_SIZE) /* at least two chunks */
+
+static int8_t int8_search_buf[100];
+static int16_t int16_search_buf[100];
+static int32_t int32_search_buf[100];
+static int64_t int64_search_buf[100];
+
+static char *search_buf;
+static int search_buf_size;
+
+static int x;
+
+
+int f2 (int a)
+{
+  char *str = "hello, testsuite";
+
+  puts (str);	/* Break here.  */
+
+  return ++a;
+}
+
+int f1 (int a, int b)
+{
+  return f2(a) + b;
+}
+
+static void
+init_bufs ()
+{
+  search_buf_size = BUF_SIZE;
+  search_buf = malloc (search_buf_size);
+  if (search_buf == NULL)
+    exit (1);
+  memset (search_buf, 'x', search_buf_size);
+}
+
+int main (int argc, char *argv[])
+{
+  init_bufs ();
+
+  return f1 (1, 2);
+}
diff --git a/gdb/testsuite/gdb.python/py-inferior.exp b/gdb/testsuite/gdb.python/py-inferior.exp
new file mode 100644
index 0000000..719b178
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-inferior.exp
@@ -0,0 +1,201 @@
+# Copyright (C) 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/>.
+
+# This file is part of the GDB testsuite.  It tests the mechanism
+# exposing inferiors to Python.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+if ![python_supported] then {
+  unsupported "python support is disabled"
+  return -1
+}
+
+set testfile "py-inferior"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+gdb_load ${binfile}
+
+# The following tests require execution.
+
+if ![runto_main] then {
+    fail "Can't run to main"
+    return 0
+}
+
+runto [gdb_get_line_number "Break here."]
+
+# Test basic gdb.Inferior attributes and methods.
+
+gdb_py_test_silent_cmd "python inferiors = gdb.inferiors ()" "get inferiors list" 1
+gdb_test "python print inferiors" "\\(<gdb.Inferior object at 0x\[\[:xdigit:\]\]+>,\\)" "verify inferiors list"
+gdb_py_test_silent_cmd "python i0 = inferiors\[0\]" "get first inferior" 0
+
+gdb_test "python print 'result =', i0 == inferiors\[0\]" " = True" "test equality comparison (true)"
+gdb_test "python print 'result =', i0.num" " = \[0-9\]+" "test Inferior.num"
+gdb_test "python print 'result =', i0.pid" " = \[0-9\]+" "test Inferior.pid"
+gdb_test "python print 'result =', i0.was_attached" " = False" "test Inferior.was_attached"
+gdb_test "python print i0.threads ()" "\\(<gdb.InferiorThread object at 0x\[\[:xdigit:\]\]+>,\\)" "test Inferior.threads"
+
+# Test memory read and write operations.
+
+gdb_py_test_silent_cmd "python addr = gdb.selected_frame ().read_var ('str')" \
+  "read str address" 0
+gdb_py_test_silent_cmd "python str = gdb.inferiors()\[0\].read_memory (addr, 5)" \
+  "read str contents" 1
+gdb_py_test_silent_cmd "python str\[1\] = 'a'" "change str" 0
+gdb_py_test_silent_cmd "python gdb.inferiors()\[0\].write_memory (addr, str)" \
+  "write str" 1
+gdb_test "print str" " = 0x\[\[:xdigit:\]\]+ \"hallo, testsuite\"" \
+  "ensure str was changed in the inferior"
+
+# Test memory search.
+
+set hex_number {0x[0-9a-fA-F][0-9a-fA-F]*}
+set dec_number {[0-9]+}
+set history_prefix {[$][0-9]* = }
+set newline {[\r\n]+}
+set pattern_not_found "${newline}.]"
+set one_pattern_found "${newline}.${dec_number}L]"
+set two_patterns_found "${newline}.${dec_number}L, ${dec_number}L]"
+
+# Test string pattern.
+
+gdb_test "set *(int32_t*) &int8_search_buf\[10\] = 0x61616161" "" ""
+gdb_test "py search_buf = gdb.selected_frame ().read_var ('int8_search_buf')" "" ""
+gdb_test "py start_addr = search_buf.address" "" ""
+gdb_test "py length = search_buf.type.sizeof" "" ""
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, 'aaa')" \
+  "${two_patterns_found}" "find string pattern"
+
+# Test not finding pattern because search range too small, with
+# potential find at the edge of the range.
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, 10+3, 'aaaa')" \
+  "${pattern_not_found}" "pattern not found at end of range"
+
+# Increase the search range by 1 and we should find the pattern.
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, 10+3+1, \['a', 'a', 'a', 'a'\])" \
+  "${one_pattern_found}" "pattern found at end of range"
+
+# Test max-count with size, with different parameter position
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, \[0x61, 0x61\], 1, 1)" \
+  "${one_pattern_found}" "size = 1, max_count = 1"
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, \[0x61, 0x61\], 1, 2)" \
+  "${two_patterns_found}" "size = 1, max_count = 2, normal ordering"
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, \[0x61, 0x61\], size = 1, max_count = 2)" \
+  "${two_patterns_found}" "size = 1, max_count = 2, normal ordering, with keywords"
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, \[0x61, 0x61\], max_count = 2, size = 1)" \
+  "${two_patterns_found}" "size = 1, max_count = 2, inverted ordering"
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, \['a', 'a'\], max_count = 2)" \
+  "${two_patterns_found}" "max_count = 2, with keyword"
+
+# Test 16-bit pattern.
+
+gdb_test "set int16_search_buf\[10\] = 0x1234" "" ""
+gdb_test "py search_buf = gdb.selected_frame ().read_var ('int16_search_buf')" "" ""
+gdb_test "py start_addr = search_buf.address" "" ""
+gdb_test "py length = search_buf.type.sizeof" "" ""
+gdb_test "py pattern = gdb.parse_and_eval ('(int16_t) 0x1234')" "" ""
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, 0x1234, 2)" \
+  "${one_pattern_found}" "find 16-bit pattern, with python pattern"
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, pattern)" \
+  "${one_pattern_found}" "find 16-bit pattern, with value pattern"
+
+# Test 32-bit pattern.
+
+gdb_test "set int32_search_buf\[10\] = 0x12345678" "" ""
+gdb_test "py search_buf = gdb.selected_frame ().read_var ('int32_search_buf')" "" ""
+gdb_test "py start_addr = search_buf.address" "" ""
+gdb_test "py length = search_buf.type.sizeof" "" ""
+gdb_test "py pattern = gdb.parse_and_eval ('(int32_t) 0x12345678')" "" ""
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, 0x12345678, 4)" \
+  "${one_pattern_found}" "find 32-bit pattern, with python pattern"
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, pattern)" \
+  "${one_pattern_found}" "find 32-bit pattern, with value pattern"
+
+# Test 64-bit pattern.
+
+gdb_test "set int64_search_buf\[10\] = 0xfedcba9876543210LL" "" ""
+gdb_test "py search_buf = gdb.selected_frame ().read_var ('int64_search_buf')" "" ""
+gdb_test "py start_addr = search_buf.address" "" ""
+gdb_test "py length = search_buf.type.sizeof" "" ""
+gdb_test "py pattern = gdb.parse_and_eval ('(int64_t) 0xfedcba9876543210LL')" "" ""
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, 0xfedcba9876543210, 8)" \
+  "${one_pattern_found}" "find 64-bit pattern, with python pattern"
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, pattern)" \
+  "${one_pattern_found}" "find 64-bit pattern, with value pattern"
+
+# Test mixed-sized patterns.
+
+gdb_test "set *(int8_t*) &search_buf\[10\] = 0x62" "" ""
+gdb_test "set *(int16_t*) &search_buf\[11\] = 0x6363" "" ""
+gdb_test "set *(int32_t*) &search_buf\[13\] = 0x64646464" "" ""
+gdb_test "py search_buf = gdb.selected_frame ().read_var ('search_buf')" "" ""
+gdb_test "py start_addr = search_buf\[0\].address" "" ""
+gdb_test "py pattern1 = gdb.parse_and_eval ('(int8_t) 0x62')" "" ""
+gdb_test "py pattern2 = gdb.parse_and_eval ('(int16_t) 0x6363')" "" ""
+gdb_test "py pattern3 = gdb.parse_and_eval ('(int32_t) 0x64646464')" "" ""
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, 100, \[pattern1, pattern2, pattern3\])" \
+    "${one_pattern_found}" "find mixed-sized pattern"
+
+# Test search spanning a large range, in the particular case of native
+# targets, test the search spanning multiple chunks.
+# Remote targets may implement the search differently.
+
+set CHUNK_SIZE 16000 ;
+
+gdb_test "set *(int32_t*) &search_buf\[0*${CHUNK_SIZE}+100\] = 0x12345678" "" ""
+gdb_test "set *(int32_t*) &search_buf\[1*${CHUNK_SIZE}+100\] = 0x12345678" "" ""
+gdb_test "py start_addr = gdb.selected_frame ().read_var ('search_buf')" "" ""
+gdb_test "py length = gdb.selected_frame ().read_var ('search_buf_size')" "" ""
+
+gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, 0x12345678, 4)" \
+  "${two_patterns_found}" "search spanning large range"
+
+# For native targets, test a pattern straddling a chunk boundary.
+
+if [isnative] {
+    gdb_test "set *(int32_t*) &search_buf\[${CHUNK_SIZE}-1\] = 0xfdb97531" "" ""
+
+    gdb_test "py print gdb.inferiors()\[0\].search_memory (start_addr, length, 0xfdb97531, 4)" \
+      "${one_pattern_found}" "find pattern straddling chunk boundary"
+}
diff --git a/gdb/testsuite/gdb.python/py-infthread.c b/gdb/testsuite/gdb.python/py-infthread.c
new file mode 100644
index 0000000..22eb9f2
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-infthread.c
@@ -0,0 +1,14 @@
+int f2 (int a)
+{
+  return ++a;
+}
+
+int f1 (int a, int b)
+{
+  return f2(a) + b;
+}
+
+int main (int argc, char *argv[])
+{
+  return f1 (1, 2);
+}
diff --git a/gdb/testsuite/gdb.python/py-infthread.exp b/gdb/testsuite/gdb.python/py-infthread.exp
new file mode 100644
index 0000000..e9d18b7
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-infthread.exp
@@ -0,0 +1,58 @@
+# Copyright (C) 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/>.
+
+# This file is part of the GDB testsuite.  It tests the mechanism
+# exposing inferior threads to Python.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+if ![python_supported] then {
+  unsupported "python support is disabled"
+  return -1
+}
+
+set testfile "py-infthread"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+gdb_load ${binfile}
+
+# The following tests require execution.
+
+if ![runto_main] then {
+    fail "Can't run to main"
+    return 0
+}
+
+runto [gdb_get_line_number "Break here."]
+
+# Test basic gdb.Inferior attributes and methods.
+
+gdb_py_test_silent_cmd "python t0 = gdb.selected_thread ()" "test gdb.selected_thread" 1
+gdb_test "python print t0" "\\<gdb.InferiorThread object at 0x\[\[:xdigit:\]\]+>" "verify InferiorThread object"
+gdb_test "python print 'result =', t0.num" " = \[0-9\]+" "test Inferior.num"
diff --git a/gdb/testsuite/gdb.python/py-prettyprint.exp b/gdb/testsuite/gdb.python/py-prettyprint.exp
index d2db5bc..4de1620 100644
--- a/gdb/testsuite/gdb.python/py-prettyprint.exp
+++ b/gdb/testsuite/gdb.python/py-prettyprint.exp
@@ -27,12 +27,20 @@ set binfile ${objdir}/${subdir}/${testfile}
 # Start with a fresh gdb.
 gdb_exit
 gdb_start
-gdb_test_multiple "python print 'hello, world!'" "verify python support" {
-    -re "not supported.*$gdb_prompt $"	{
-      unsupported "python support is disabled"
-      return -1
-    }
-    -re "$gdb_prompt $"	{}
+if ![python_supported] then {
+  unsupported "python support is disabled"
+  return -1
+}
+
+# Run a command in GDB, and report a failure if a Python exception is thrown.
+# If report_pass is true, report a pass if no exception is thrown.
+proc gdb_py_test_silent_cmd {cmd name report_pass} {
+  global gdb_prompt
+
+  gdb_test_multiple $cmd $name {
+      -re "Traceback.*$gdb_prompt $"  { fail $name }
+      -re "$gdb_prompt $"	      { if $report_pass { pass $name } }
+  }
 }
 
 proc run_lang_tests {lang} {
@@ -79,6 +87,11 @@ proc run_lang_tests {lang} {
 	gdb_test "print derived" \
 	    " = \{.*<Vbase1> = pp class name: Vbase1.*<Vbase2> = \{.*<VirtualTest> = pp value variable is: 1,.*members of Vbase2:.*_vptr.Vbase2 = $hex.*<Vbase3> = \{.*members of Vbase3.*members of Derived:.*value = 2.*"
 	gdb_test "print ns " "\"embedded\\\\000null\\\\000string\""
+	gdb_py_test_silent_cmd "set print elements 3" "" 1
+	gdb_test "print ns" "emb\.\.\.."
+	gdb_py_test_silent_cmd "set print elements 10" "" 1
+	gdb_test "print ns" "embedded\\\\000n\.\.\.."
+	gdb_py_test_silent_cmd "set print elements 200" "" 1
     }
 
     gdb_test "print x" " = $hex \"this is x\""
@@ -86,6 +99,8 @@ proc run_lang_tests {lang} {
 
     gdb_test "print c" " = container $hex \"container\" with 2 elements = {$nl *.0. = 23,$nl *.1. = 72$nl}"
 
+    gdb_test "print nullstr" "RuntimeError: Error reading string from inferior.*"
+
     gdb_test "continue" "Program exited normally\."
 }
 
diff --git a/gdb/testsuite/gdb.python/py-template.exp b/gdb/testsuite/gdb.python/py-template.exp
index cea6ae0..c9a63d4 100644
--- a/gdb/testsuite/gdb.python/py-template.exp
+++ b/gdb/testsuite/gdb.python/py-template.exp
@@ -20,6 +20,17 @@ if $tracelevel then {
     strace $tracelevel
 }
 
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+if ![python_supported] then {
+  unsupported "python support is disabled"
+  return -1
+}
+
 set testfile "py-template"
 set srcfile ${testfile}.cc
 set binfile ${objdir}/${subdir}/${testfile}
@@ -29,20 +40,6 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
     return -1
 }
 
-# Start with a fresh gdb.
-
-gdb_exit
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
-
-gdb_test_multiple "python print 23" "verify python support" {
-    -re "not supported.*$gdb_prompt $"	{
-      unsupported "python support is disabled"
-      return -1
-    }
-    -re "$gdb_prompt $"	{}
-}
-
 proc test_template_arg {type} {
     global testfile srcdir subdir srcfile binfile
     if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
diff --git a/gdb/testsuite/gdb.python/py-value.c b/gdb/testsuite/gdb.python/py-value.c
index f3d6284..023d830 100644
--- a/gdb/testsuite/gdb.python/py-value.c
+++ b/gdb/testsuite/gdb.python/py-value.c
@@ -37,6 +37,13 @@ typedef struct s *PTR;
 
 enum e evalue = TWO;
 
+#ifdef __cplusplus
+void ptr_ref(int*& rptr_int)
+{
+  return; /* break to inspect pointer by reference. */
+}
+#endif
+
 int
 main (int argc, char *argv[])
 {
@@ -46,10 +53,18 @@ main (int argc, char *argv[])
   PTR x = &s;
   char st[17] = "divide et impera";
   char nullst[17] = "divide\0et\0impera";
+  int a[3] = {1,2,3};
+  int *p = a;
+  int i = 2;
+  int *ptr_i = &i;
 
   s.a = 3;
   s.b = 5;
   u.a = 7;
 
+#ifdef __cplusplus
+  ptr_ref(ptr_i);
+#endif
+
   return 0;      /* break to inspect struct and union */
 }
diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp
index 9b4190d..b9f2c3c 100644
--- a/gdb/testsuite/gdb.python/py-value.exp
+++ b/gdb/testsuite/gdb.python/py-value.exp
@@ -292,21 +292,106 @@ 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"
+}
+
+# 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.
+
+proc test_subscript_regression {lang} {
+
+ global srcdir subdir srcfile binfile testfile hex
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "debug $lang"] != "" } {
+     untested "Couldn't compile ${srcfile} in $lang mode"
+     return -1
+ }
+
+ # Start with a fresh gdb.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+
+ if ![runto_main ] then {
+     perror "couldn't run to breakpoint"
+     return
+ }
+
+ if {$lang == "c++"} {
+     gdb_breakpoint [gdb_get_line_number "break to inspect pointer by reference"]
+     gdb_continue_to_breakpoint "break to inspect pointer by reference"
+
+     gdb_py_test_silent_cmd "print rptr_int" \
+	 "Obtain address" 1
+     gdb_py_test_silent_cmd "python rptr = gdb.history(0)" \
+	 "Obtains value from GDB" 1
+     gdb_test "python print rptr\[0\]" "2" "Check pointer passed as reference"
+ }
+
+ gdb_breakpoint [gdb_get_line_number "break to inspect struct and union"]
+ gdb_continue_to_breakpoint "break to inspect struct and union"
+
+ gdb_py_test_silent_cmd "python intv = gdb.Value(1)" \
+     "Create a value for subscript test" 1
+ gdb_py_test_silent_cmd "python stringv = gdb.Value(\"foo\")" \
+     "Create a value for subscript test" 1
+
+ # Try to access an int with a subscript.  This should fail.
+ gdb_test "python print intv" "1" "Baseline print of a Python value"
+ gdb_test "python print intv\[0\]" "RuntimeError: Cannot subscript requested type.*" \
+     "Attempt to access an integer with a subscript"
+
+ # Try to access a string with a subscript.  This should pass.
+ gdb_test "python print stringv" "foo." "Baseline print of a Python value"
+ gdb_test "python print stringv\[0\]" "f." "Attempt to access a string with a subscript"
+
+ # Try to access an int array via a pointer with a subscript.  This should pass.
+ gdb_py_test_silent_cmd "print p" "Build pointer to array" 1
+ gdb_py_test_silent_cmd "python pointer = gdb.history(0)" "" 1
+ gdb_test "python print pointer\[0\]" "1" "Access array via pointer with int subscript"
+ gdb_test "python print pointer\[intv\]" "2" "Access array via pointer with value subscript"
+
+ # Try to access a single dimension array with a subscript to the
+ # result.  This should fail.
+ gdb_test "python print pointer\[intv\]\[0\]" "RuntimeError: Cannot subscript requested type.*" \
+     "Attempt to access an integer with a subscript"   
+
+ # Lastly, test subscript access to an array with multiple
+ # dimensions.  This should pass.
+ gdb_py_test_silent_cmd "print {\"fu \",\"foo\",\"bar\"}" "Build array" 1
+ gdb_py_test_silent_cmd "python marray = gdb.history(0)" "" 1
+ gdb_test "python print marray\[1\]\[2\]" "o." "Test multiple subscript"
+}   
+
 # Start with a fresh gdb.
 
 gdb_exit
 gdb_start
 gdb_reinitialize_dir $srcdir/$subdir
-gdb_load ${binfile}
 
-gdb_test_multiple "python print 'hello, world!'" "verify python support" {
-    -re "not supported.*$gdb_prompt $"	{
-      unsupported "python support is disabled"
-      return -1
-    }
-    -re "$gdb_prompt $"	{}
+if ![python_supported] then {
+  unsupported "python support is disabled"
+  return -1
+}
+
+set testfile "py-value"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
 }
 
+gdb_load ${binfile}
+
 test_value_creation
 test_value_numeric_ops
 test_value_boolean
@@ -322,3 +407,10 @@ if ![runto_main] then {
 
 test_value_in_inferior
 test_value_after_death
+test_cast_regression
+
+# The following test recompiles the binary to test either C or C++
+# values.
+
+test_subscript_regression "c++"
+test_subscript_regression "c"
diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp
index 5223fc8..03e1eab 100644
--- a/gdb/testsuite/gdb.python/python.exp
+++ b/gdb/testsuite/gdb.python/python.exp
@@ -26,30 +26,9 @@ gdb_exit
 gdb_start
 gdb_reinitialize_dir $srcdir/$subdir
 
-gdb_test_multiple "python print 23" "verify python support" {
-    -re "not supported.*$gdb_prompt $"	{
-      unsupported "python support is disabled"
-      return -1
-    }
-    -re "$gdb_prompt $"	{}
-}
-
-# Usage: gdb_py_test_multiple NAME INPUT RESULT {INPUT RESULT}...
-# Run a test named NAME, consisting of multiple lines of input.
-# After each input line INPUT, search for result line RESULT.
-# Succeed if all results are seen; fail otherwise.
-proc gdb_py_test_multiple {name args} {
-    global gdb_prompt
-    foreach {input result} $args {
-	if {[gdb_test_multiple $input "$name - $input" {
-	    -re "\[\r\n\]*($result)\[\r\n\]+($gdb_prompt | *>)$" {
-		pass "$name - $input"
-	    }
-	}]} {
-	    return 1
-	}
-    }
-    return 0
+if ![python_supported] then {
+  unsupported "python support is disabled"
+  return -1
 }
 
 gdb_py_test_multiple "multi-line python command" \
diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork-forkoff.c b/gdb/testsuite/gdb.threads/watchpoint-fork-forkoff.c
new file mode 100644
index 0000000..4dc308b
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/watchpoint-fork-forkoff.c
@@ -0,0 +1,175 @@
+/* Test case for forgotten hw-watchpoints after fork()-off of a process.
+
+   Copyright 2008, 2009 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>
+
+static void
+delay (void)
+{
+  int i = usleep (1000000 / 100);
+  assert (i == 0 || errno == EINTR);
+}
+
+#if defined FOLLOW_PARENT
+
+static void
+forkoff (int nr)
+{
+  pid_t child, pid_got;
+  int exit_code = 42 + nr;
+  int status, i;
+
+  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, breakpoint () 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++;
+      breakpoint ();
+
+      _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).  */
+      breakpoint ();
+    }
+}
+
+#elif defined FOLLOW_CHILD
+
+static volatile int usr1_got;
+
+static void
+handler_usr1 (int signo)
+{
+  usr1_got++;
+}
+
+static void
+forkoff (int nr)
+{
+  pid_t child;
+  int i, loop;
+  struct sigaction act, oldact;
+#ifdef THREAD
+  void *thread_result;
+#endif
+
+  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);
+
+  child = fork ();
+  switch (child)
+    {
+    case -1:
+      assert (0);
+    default:
+      printf ("parent%d: %d\n", nr, (int) child);
+
+      /* 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.  */
+
+      i = sleep (2);
+      assert (i == 0);
+
+      /* We must not get caught here (against a forgotten breakpoint).  */
+
+      var++;
+      breakpoint ();
+
+#ifdef THREAD
+      /* And neither got caught our thread.  */
+
+      step = 99;
+      i = pthread_join (thread, &thread_result);
+      assert (i == 0);
+      assert (thread_result == (void *) 99UL);
+#endif
+
+      /* Be sure our child knows we did not get caught above.  */
+
+      i = kill (child, SIGUSR1);
+      assert (i == 0);
+
+      /* Sleep for a while to check GDB's `info threads' no longer tracks us in
+	 the child fork.  */
+
+      i = sleep (2);
+      assert (i == 0);
+
+      _exit (0);
+    case 0:
+      printf ("child%d: %d\n", nr, (int) getpid ());
+
+      /* Let the parent signal us about its success.  Be careful of races.  */
+
+      for (loop = 0; loop < 1000; loop++)
+	{
+	  /* Parent either died (and USR1_GOT is zero) or it succeeded.  */
+	  if (kill (getppid (), 0) != 0)
+	    break;
+	  /* Parent succeeded?  */
+	  if (usr1_got)
+	    break;
+
+	  delay ();
+	}
+      assert (usr1_got);
+
+      /* We must get caught here (against a false watchpoint removal).  */
+
+      breakpoint ();
+    }
+
+  i = sigaction (SIGUSR1, &oldact, NULL);
+  assert (i == 0);
+}
+
+#else
+# error "!FOLLOW_PARENT && !FOLLOW_CHILD"
+#endif
diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c b/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c
new file mode 100644
index 0000000..edacfc0
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c
@@ -0,0 +1,157 @@
+/* Test case for forgotten hw-watchpoints after fork()-off of a process.
+
+   Copyright 2008, 2009 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 <assert.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#include <asm/unistd.h>
+#include <unistd.h>
+#define gettid() syscall (__NR_gettid)
+
+/* 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.  */
+
+static volatile int var;
+
+static void
+dummy (void)
+{
+}
+
+static void
+breakpoint (void)
+{
+}
+
+/* Include here the functions:
+   static void forkoff (int nr);
+   static void delay (void);  */
+
+static pthread_t thread;
+static volatile int step;
+#define THREAD
+
+#include "watchpoint-fork-forkoff.c"
+
+static void *
+start (void *arg)
+{
+  if (step >= 3)
+    goto step_3;
+
+  while (step != 1)
+    delay ();
+
+  var++;	/* validity-thread-B */
+  dummy ();	/* validity-thread-B */
+  step = 2;
+  while (step != 3)
+    {
+      if (step == 99)
+	goto step_99;
+      delay ();
+    }
+
+step_3:
+  if (step >= 5)
+    goto step_5;
+
+  var++;	/* after-fork1-B */
+  dummy ();	/* after-fork1-B */
+  step = 4;
+  while (step != 5)
+    {
+      if (step == 99)
+	goto step_99;
+      delay ();
+    }
+
+step_5:
+  var++;	/* after-fork2-B */
+  dummy ();	/* after-fork2-B */
+  return (void *) 5UL;
+
+step_99:
+  /* We must not get caught here (against a forgotten breakpoint).  */
+  var++;
+  breakpoint ();
+  return (void *) 99UL;
+}
+
+int
+main (void)
+{
+  int i;
+  void *thread_result;
+
+  setbuf (stdout, NULL);
+  printf ("main: %d\n", (int) gettid ());
+
+  /* General watchpoints validity.  */
+  var++;	/* validity-first */
+  dummy ();	/* validity-first */
+
+  i = pthread_create (&thread, NULL, start, NULL);
+  assert (i == 0);
+
+  var++;	/* validity-thread-A */
+  dummy ();	/* validity-thread-A */
+  step = 1;
+  while (step != 2)
+    delay ();
+
+  /* Hardware watchpoints got disarmed here.  */
+  forkoff (1);
+
+  var++;	/* after-fork1-A */
+  dummy ();	/* 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)
+    delay ();
+
+  /* A sanity check for double hardware watchpoints removal.  */
+  forkoff (2);
+
+  var++;	/* after-fork2-A */
+  dummy ();	/* 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
+
+  i = pthread_join (thread, &thread_result);
+  assert (i == 0);
+  assert (thread_result == (void *) 5UL);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork.c b/gdb/testsuite/gdb.threads/watchpoint-fork.c
new file mode 100644
index 0000000..5f62e7f
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/watchpoint-fork.c
@@ -0,0 +1,57 @@
+/* Test case for forgotten hw-watchpoints after fork()-off of a process.
+
+   Copyright 2008, 2009 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 <assert.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static volatile int var;
+
+static void
+breakpoint (void)
+{
+}
+
+/* Include here the function:
+   static void forkoff (int nr);  */
+
+#include "watchpoint-fork-forkoff.c"
+
+int
+main (void)
+{
+  setbuf (stdout, NULL);
+  printf ("main: %d\n", (int) getpid ());
+
+  /* General watchpoints validity.  */
+  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++;
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork.exp b/gdb/testsuite/gdb.threads/watchpoint-fork.exp
new file mode 100644
index 0000000..1dc93ab
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/watchpoint-fork.exp
@@ -0,0 +1,130 @@
+# 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/>.
+
+# Test case for forgotten hw-watchpoints after fork()-off of a process.
+
+proc test {type symbol} {
+    global objdir subdir srcdir
+
+    set test watchpoint-fork
+
+    global pf_prefix
+    set prefix_test $pf_prefix
+    lappend pf_prefix "$type:"
+    set prefix_mt $pf_prefix
+
+    # no threads
+
+    set pf_prefix $prefix_mt
+    lappend pf_prefix "singlethreaded:"
+
+    set executable ${test}-${type}
+    if { [gdb_compile ${srcdir}/${subdir}/${test}.c ${objdir}/${subdir}/${executable} executable [list debug additional_flags=-D$symbol]] != "" } {
+	untested ${test}.exp
+	return -1
+    }
+    clean_restart $executable
+
+    gdb_test "show detach-on-fork" "Whether gdb will detach the child of a fork is on."
+    gdb_test "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"
+
+    if { ![runto_main] } then {
+	gdb_suppress_tests
+	return
+    }
+
+    # Install the watchpoint only after getting into MAIN - workaround some PPC
+    # problem.
+    gdb_test "watch var" "atchpoint 2: var" "Set the watchpoint"
+
+    # It is never hit but it should not be left over in the fork()ed-off child.
+    gdb_breakpoint "breakpoint"
+
+    gdb_test "continue" \
+	     "atchpoint 2: var.*Old value = 0.*New value = 1.*forkoff *\\(1\\).*" "watchpoints work"
+    gdb_test "continue" \
+	     "reakpoint 3, breakpoint.*" "breakpoint after the first fork"
+    gdb_test "continue" \
+	     "atchpoint 2: var.*Old value = 1.*New value = 2.*forkoff *\\(2\\).*" "watchpoint after the first fork"
+    gdb_test "continue" \
+	     "reakpoint 3, breakpoint.*" "breakpoint after the second fork"
+    gdb_test "continue" \
+	     "atchpoint 2: var.*Old value = 2.*New value = 3.*return *0;" "watchpoint after the second fork"
+    gdb_test "continue" "Continuing..*Program exited normally." "finish"
+
+
+    # threads
+
+    set pf_prefix $prefix_mt
+    lappend pf_prefix "multithreaded:"
+
+    set executable ${test}-mt-${type}
+    if { [gdb_compile_pthreads ${srcdir}/${subdir}/${test}-mt.c ${objdir}/${subdir}/${executable} executable [list debug additional_flags=-D$symbol]] != "" } {
+	untested ${test}.exp
+	return -1
+    }
+    clean_restart $executable
+
+    gdb_test "set follow-fork-mode $type"
+    # Testcase uses it for the `follow-fork-mode child' type.
+    gdb_test "handle SIGUSR1 nostop noprint pass"
+
+    if { ![runto_main] } then {
+	gdb_suppress_tests
+	return
+    }
+
+    # Install the watchpoint only after getting into MAIN - workaround some PPC
+    # problem.
+    gdb_test "watch var" "atchpoint 2: var" "Set the watchpoint"
+
+    # It is never hit but it should not be left over in the fork()ed-off child.
+    gdb_breakpoint "breakpoint"
+
+    gdb_test "continue" \
+	     "atchpoint 2: var.*Old value = 0.*New value = 1.*validity-first.*" "singlethread watchpoints work"
+    gdb_test "continue" \
+	     "atchpoint 2: var.*Old value = 1.*New value = 2.*validity-thread-A.*" "multithreaded watchpoints work at A"
+    gdb_test "continue" \
+	     "atchpoint 2: var.*Old value = 2.*New value = 3.*validity-thread-B.*" "multithreaded watchpoints work at B"
+    gdb_test "continue" \
+	     "reakpoint 3, breakpoint.*" "breakpoint (A) after the first fork"
+    gdb_test "continue" \
+	     "atchpoint 2: var.*Old value = 3.*New value = 4.*after-fork1-A.*" "watchpoint A after the first fork"
+    gdb_test "continue" \
+	     "atchpoint 2: var.*Old value = 4.*New value = 5.*after-fork1-B.*" "watchpoint B after the first fork"
+    gdb_test "continue" \
+	     "reakpoint 3, breakpoint.*" "breakpoint (A) after the second fork"
+    gdb_test "continue" \
+	     "atchpoint 2: var.*Old value = 5.*New value = 6.*after-fork2-A.*" "watchpoint A after the second fork"
+    gdb_test "continue" \
+	     "atchpoint 2: var.*Old value = 6.*New value = 7.*after-fork2-B.*" "watchpoint B after the second fork"
+    gdb_test "continue" "Continuing..*Program exited normally." "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*"]} {
+    test child FOLLOW_CHILD
+}
diff --git a/gdb/testsuite/gdb.threads/watchthreads-reorder.c b/gdb/testsuite/gdb.threads/watchthreads-reorder.c
new file mode 100644
index 0000000..14f42d6
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/watchthreads-reorder.c
@@ -0,0 +1,366 @@
+/* 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/>.  */
+
+#define _GNU_SOURCE
+#include <pthread.h>
+#include <stdio.h>
+#include <limits.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <unistd.h>
+#include <asm/unistd.h>
+
+#define gettid() syscall (__NR_gettid)
+
+/* Terminate always in the main task, it can lock up with SIGSTOPped GDB
+   otherwise.  */
+#define TIMEOUT (gettid () == getpid() ? 10 : 15)
+
+static pthread_mutex_t gdbstop_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+
+static pid_t thread1_tid;
+static pthread_cond_t thread1_tid_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t thread1_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+
+static pid_t thread2_tid;
+static pthread_cond_t thread2_tid_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t thread2_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+
+static pthread_mutex_t terminate_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+
+static volatile int thread1_rwatch;
+static volatile int thread2_rwatch;
+
+static int unused1_rwatch;
+static int unused2_rwatch;
+
+/* Do not use alarm as it would create a ptrace event which would hang up us if
+ * we are being traced by GDB which we stopped ourselves.  */
+
+static void timed_mutex_lock (pthread_mutex_t *mutex)
+{
+  int i;
+  struct timespec start, now;
+
+  i = clock_gettime (CLOCK_MONOTONIC, &start);
+  assert (i == 0);
+
+  do
+    {
+      i = pthread_mutex_trylock (mutex);
+      if (i == 0)
+	return;
+      assert (i == EBUSY);
+
+      i = clock_gettime (CLOCK_MONOTONIC, &now);
+      assert (i == 0);
+      assert (now.tv_sec >= start.tv_sec);
+    }
+  while (now.tv_sec - start.tv_sec < TIMEOUT);
+
+  fprintf (stderr, "Timed out waiting for internal lock!\n");
+  exit (EXIT_FAILURE);
+}
+
+static void *
+thread1_func (void *unused)
+{
+  int i;
+  volatile int rwatch_store;
+
+  thread1_tid = gettid ();
+  i = pthread_cond_signal (&thread1_tid_cond);
+  assert (i == 0);
+
+  /* Be sure GDB is already stopped before continuing.  */
+  timed_mutex_lock (&gdbstop_mutex);
+  i = pthread_mutex_unlock (&gdbstop_mutex);
+  assert (i == 0);
+
+  rwatch_store = thread1_rwatch;
+
+  /* Be sure the "T (tracing stop)" test can proceed for both threads.  */
+  timed_mutex_lock (&terminate_mutex);
+  i = pthread_mutex_unlock (&terminate_mutex);
+  assert (i == 0);
+
+  return NULL;
+}
+
+static void *
+thread2_func (void *unused)
+{
+  int i;
+  volatile int rwatch_store;
+
+  thread2_tid = gettid ();
+  i = pthread_cond_signal (&thread2_tid_cond);
+  assert (i == 0);
+
+  /* Be sure GDB is already stopped before continuing.  */
+  timed_mutex_lock (&gdbstop_mutex);
+  i = pthread_mutex_unlock (&gdbstop_mutex);
+  assert (i == 0);
+
+  rwatch_store = thread2_rwatch;
+
+  /* Be sure the "T (tracing stop)" test can proceed for both threads.  */
+  timed_mutex_lock (&terminate_mutex);
+  i = pthread_mutex_unlock (&terminate_mutex);
+  assert (i == 0);
+
+  return NULL;
+}
+
+static const char *
+proc_string (const char *filename, const char *line)
+{
+  FILE *f;
+  static char buf[LINE_MAX];
+  size_t line_len = strlen (line);
+
+  f = fopen (filename, "r");
+  if (f == NULL)
+    {
+      fprintf (stderr, "fopen (\"%s\") for \"%s\": %s\n", filename, line,
+	       strerror (errno));
+      exit (EXIT_FAILURE);
+    }
+  while (errno = 0, fgets (buf, sizeof (buf), f))
+    {
+      char *s;
+
+      s = strchr (buf, '\n');
+      assert (s != NULL);
+      *s = 0;
+
+      if (strncmp (buf, line, line_len) != 0)
+	continue;
+
+      if (fclose (f))
+	{
+	  fprintf (stderr, "fclose (\"%s\") for \"%s\": %s\n", filename, line,
+		   strerror (errno));
+	  exit (EXIT_FAILURE);
+	}
+
+      return &buf[line_len];
+    }
+  if (errno != 0)
+    {
+      fprintf (stderr, "fgets (\"%s\": %s\n", filename, strerror (errno));
+      exit (EXIT_FAILURE);
+    }
+  fprintf (stderr, "\"%s\": No line \"%s\" found.\n", filename, line);
+  exit (EXIT_FAILURE);
+}
+
+static unsigned long
+proc_ulong (const char *filename, const char *line)
+{
+  const char *s = proc_string (filename, line);
+  long retval;
+  char *end;
+
+  errno = 0;
+  retval = strtol (s, &end, 10);
+  if (retval < 0 || retval >= LONG_MAX || (end && *end))
+    {
+      fprintf (stderr, "\"%s\":\"%s\": %ld, %s\n", filename, line, retval,
+	       strerror (errno));
+      exit (EXIT_FAILURE);
+    }
+  return retval;
+}
+
+static void
+state_wait (pid_t process, const char *wanted)
+{
+  char *filename;
+  int i;
+  struct timespec start, now;
+  const char *state;
+
+  i = asprintf (&filename, "/proc/%lu/status", (unsigned long) process);
+  assert (i > 0);
+
+  i = clock_gettime (CLOCK_MONOTONIC, &start);
+  assert (i == 0);
+
+  do
+    {
+      state = proc_string (filename, "State:\t");
+      if (strcmp (state, wanted) == 0)
+	{
+	  free (filename);
+	  return;
+	}
+
+      if (sched_yield ())
+	{
+	  perror ("sched_yield()");
+	  exit (EXIT_FAILURE);
+	}
+
+      i = clock_gettime (CLOCK_MONOTONIC, &now);
+      assert (i == 0);
+      assert (now.tv_sec >= start.tv_sec);
+    }
+  while (now.tv_sec - start.tv_sec < TIMEOUT);
+
+  fprintf (stderr, "Timed out waiting for PID %lu \"%s\" (now it is \"%s\")!\n",
+	   (unsigned long) process, wanted, state);
+  exit (EXIT_FAILURE);
+}
+
+static volatile pid_t tracer = 0;
+static pthread_t thread1, thread2;
+
+static void
+cleanup (void)
+{
+  printf ("Resuming GDB PID %lu.\n", (unsigned long) tracer);
+
+  if (tracer)
+    {
+      int i;
+      int tracer_save = tracer;
+
+      tracer = 0;
+
+      i = kill (tracer_save, SIGCONT);
+      assert (i == 0);
+    }
+}
+
+int
+main (int argc, char **argv)
+{
+  int i;
+  int standalone = 0;
+
+  if (argc == 2 && strcmp (argv[1], "-s") == 0)
+    standalone = 1;
+  else
+    assert (argc == 1);
+
+  setbuf (stdout, NULL);
+
+  timed_mutex_lock (&gdbstop_mutex);
+
+  timed_mutex_lock (&terminate_mutex);
+
+  i = pthread_create (&thread1, NULL, thread1_func, NULL);
+  assert (i == 0);
+
+  i = pthread_create (&thread2, NULL, thread2_func, NULL);
+  assert (i == 0);
+
+  if (!standalone)
+    {
+      tracer = proc_ulong ("/proc/self/status", "TracerPid:\t");
+      if (tracer == 0)
+	{
+	  fprintf (stderr, "The testcase must be run by GDB!\n");
+	  exit (EXIT_FAILURE);
+	}
+      if (tracer != getppid ())
+	{
+	  fprintf (stderr, "The testcase parent must be our GDB tracer!\n");
+	  exit (EXIT_FAILURE);
+	}
+    }
+
+  /* SIGCONT our debugger in the case of our crash as we would deadlock
+     otherwise.  */
+
+  atexit (cleanup);
+
+  printf ("Stopping GDB PID %lu.\n", (unsigned long) tracer);
+
+  if (tracer)
+    {
+      i = kill (tracer, SIGSTOP);
+      assert (i == 0);
+      state_wait (tracer, "T (stopped)");
+    }
+
+  timed_mutex_lock (&thread1_tid_mutex);
+  timed_mutex_lock (&thread2_tid_mutex);
+
+  /* Let the threads start.  */
+  i = pthread_mutex_unlock (&gdbstop_mutex);
+  assert (i == 0);
+
+  printf ("Waiting till the threads initialize their TIDs.\n");
+
+  if (thread1_tid == 0)
+    {
+      i = pthread_cond_wait (&thread1_tid_cond, &thread1_tid_mutex);
+      assert (i == 0);
+
+      assert (thread1_tid > 0);
+    }
+
+  if (thread2_tid == 0)
+    {
+      i = pthread_cond_wait (&thread2_tid_cond, &thread2_tid_mutex);
+      assert (i == 0);
+
+      assert (thread2_tid > 0);
+    }
+
+  printf ("Thread 1 TID = %lu, thread 2 TID = %lu, PID = %lu.\n",
+	  (unsigned long) thread1_tid, (unsigned long) thread2_tid,
+	  (unsigned long) getpid ());
+
+  printf ("Waiting till the threads get trapped by the watchpoints.\n");
+
+  if (tracer)
+    {
+      /* s390x-unknown-linux-gnu will fail with "R (running)".  */
+
+      state_wait (thread1_tid, "T (tracing stop)");
+
+      state_wait (thread2_tid, "T (tracing stop)");
+    }
+
+  cleanup ();
+
+  printf ("Joining the threads.\n");
+
+  i = pthread_mutex_unlock (&terminate_mutex);
+  assert (i == 0);
+
+  i = pthread_join (thread1, NULL);
+  assert (i == 0);
+
+  i = pthread_join (thread2, NULL);
+  assert (i == 0);
+
+  printf ("Exiting.\n");	/* break-at-exit */
+
+  /* Just prevent compiler `warning: ‘unusedX_rwatch’ defined but not used'.  */
+  unused1_rwatch = 1;
+  unused2_rwatch = 2;
+
+  return EXIT_SUCCESS;
+}
diff --git a/gdb/testsuite/gdb.threads/watchthreads-reorder.exp b/gdb/testsuite/gdb.threads/watchthreads-reorder.exp
new file mode 100644
index 0000000..8f65364
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/watchthreads-reorder.exp
@@ -0,0 +1,101 @@
+# 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/>.
+
+# Test GDB can cope with two watchpoints being hit by different threads at the
+# same time, GDB reports one of them and after "continue" to report the other
+# one GDB should not be confused by differently set watchpoints that time.
+# This is the goal of "reorder1".  "reorder0" tests the basic functionality of
+# two watchpoint being hit at the same time, without reordering them during the
+# stop.  The formerly broken functionality is due to the all-stop mode default
+# "show breakpoint always-inserted" being "off".  Formerly the remembered hit
+# could be assigned during continuation of a thread with pending SIGTRAP to the
+# different/new watchpoint, just based on the watchpoint/debug register number.
+
+if {[target_info exists gdb,no_hardware_watchpoints]
+    || ![istarget *-*-linux*]} {
+    return 0;
+}
+
+set testfile "watchthreads-reorder"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" ${binfile} executable [list debug additional_flags=-lrt]] != "" } {
+    return -1
+}
+
+foreach reorder {0 1} {
+
+    global pf_prefix
+    set prefix_test $pf_prefix
+    lappend pf_prefix "reorder$reorder:"
+
+    clean_restart $testfile
+
+    gdb_test "set can-use-hw-watchpoints 1"
+
+    if ![runto_main] {
+	gdb_suppress_tests
+    }
+
+    # Use "rwatch" as "watch" would report the watchpoint changed just based on its
+    # read memory value during a stop by unrelated event.  We are interested to not
+    # to lose the hardware watchpoint trigger.
+
+    gdb_test "rwatch thread1_rwatch" "Hardware read watchpoint \[0-9\]+: thread1_rwatch"
+    gdb_test {set $rwatch1=$bpnum}
+    set test "rwatch thread2_rwatch"
+    gdb_test_multiple $test $test {
+	-re "Target does not support this type of hardware watchpoint\\.\r\n$gdb_prompt $" {
+	    # ppc64 supports at most 1 hw watchpoints.
+	    unsupported $test
+	    return
+	}
+	-re "Hardware read watchpoint \[0-9\]+: thread2_rwatch\r\n$gdb_prompt $" {
+	    pass $test
+	}
+    }
+    gdb_test {set $rwatch2=$bpnum}
+    gdb_breakpoint [gdb_get_line_number "break-at-exit"]
+
+    # The watchpoints can happen in arbitrary order depending on random:
+    # SEL: Found 2 SIGTRAP events, selecting #[01]
+    # As GDB contains no srand() on the specific host/OS it will behave always the
+    # same.  Such order cannot be guaranteed for GDB in general.
+
+    gdb_test "continue" \
+	     "Hardware read watchpoint \[0-9\]+: thread\[12\]_rwatch\r\n\r\nValue = 0\r\n0x\[0-9a-f\]+ in thread\[12\]_func .*" \
+	     "continue a"
+
+    if $reorder {
+	gdb_test {delete $rwatch1}
+	gdb_test {delete $rwatch2}
+
+	gdb_test "rwatch unused1_rwatch" "Hardware read watchpoint \[0-9\]+: unused1_rwatch"
+	gdb_test "rwatch unused2_rwatch" "Hardware read watchpoint \[0-9\]+: unused2_rwatch"
+
+	gdb_test "rwatch thread1_rwatch" "Hardware read watchpoint \[0-9\]+: thread1_rwatch"
+	gdb_test "rwatch thread2_rwatch" "Hardware read watchpoint \[0-9\]+: thread2_rwatch"
+    }
+
+    gdb_test "continue" \
+	     "Hardware read watchpoint \[0-9\]+: thread\[12\]_rwatch\r\n\r\nValue = 0\r\n0x\[0-9a-f\]+ in thread\[12\]_func .*" \
+	     "continue b"
+
+    gdb_continue_to_breakpoint "break-at-exit" ".*break-at-exit.*"
+
+    set pf_prefix $prefix_test
+}
diff --git a/gdb/testsuite/lib/cp-support.exp b/gdb/testsuite/lib/cp-support.exp
index dbd2f59..44e1b51 100644
--- a/gdb/testsuite/lib/cp-support.exp
+++ b/gdb/testsuite/lib/cp-support.exp
@@ -222,7 +222,7 @@ proc cp_test_ptype_class { in_command in_testname in_key in_tag in_class_table {
 
     set parse_okay 0
     gdb_test_multiple "$in_command" "$in_testname // parse failed" {
-	-re "type = (struct|class)${wsopt}(\[A-Za-z0-9_\]*)${wsopt}((:\[^\{\]*)?)${wsopt}\{(.*)\}${wsopt}(\[^\r\n\]*)\[\r\n\]+$gdb_prompt $" {
+	-re "type = (struct|class)${wsopt}(\[A-Za-z0-9_:\]*)${wsopt}((:\[^\{\]*)?)${wsopt}\{(.*)\}${wsopt}(\[^\r\n\]*)\[\r\n\]+$gdb_prompt $" {
 	    set parse_okay          1
 	    set actual_key          $expect_out(1,string)
 	    set actual_tag          $expect_out(2,string)
@@ -231,6 +231,7 @@ proc cp_test_ptype_class { in_command in_testname in_key in_tag in_class_table {
 	    set actual_tail         $expect_out(6,string)
 	}
     }
+    
     if { ! $parse_okay } then { return }
 
     # Check the actual key.  It would be nice to require that it match
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 0c93a73..d0c3493 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -27,6 +27,7 @@ if {$tool == ""} {
 }
 
 load_lib libgloss.exp
+load_lib python-support.exp
 
 global GDB
 
diff --git a/gdb/testsuite/lib/python-support.exp b/gdb/testsuite/lib/python-support.exp
new file mode 100644
index 0000000..b8e9836
--- /dev/null
+++ b/gdb/testsuite/lib/python-support.exp
@@ -0,0 +1,53 @@
+global python_supported_saved
+
+# Return 1 if Python scripting is supported in GDB, 0 if not.
+proc python_supported { } {
+  global gdb_prompt
+  global python_supported_saved
+
+  if [info exists python_supported_saved] {
+      verbose "python_supported:  returning saved $python_supported_saved" 2
+      return $python_supported_saved
+  }
+
+  gdb_test_multiple "python print 'hello, world!'" "verify python support" {
+    -re "not supported.*$gdb_prompt $"	{
+      return [set python_supported_saved 0]
+    }
+    -re "$gdb_prompt $"	{
+      return [set python_supported_saved 1]
+    }
+  }
+
+  return [set python_supported_saved 0]
+}
+
+# Run a command in GDB, and report a failure if a Python exception is thrown.
+# If report_pass is true, report a pass if no exception is thrown.
+proc gdb_py_test_silent_cmd {cmd name report_pass} {
+  global gdb_prompt
+
+  gdb_test_multiple $cmd $name {
+      -re "Traceback.*$gdb_prompt $"  { fail $name }
+      -re "$gdb_prompt $"	      { if $report_pass { pass $name } }
+  }
+}
+
+# Usage: gdb_py_test_multiple NAME INPUT RESULT {INPUT RESULT}...
+# Run a test named NAME, consisting of multiple lines of input.
+# After each input line INPUT, search for result line RESULT.
+# Succeed if all results are seen; fail otherwise.
+proc gdb_py_test_multiple {name args} {
+    global gdb_prompt
+
+    foreach {input result} $args {
+	if {[gdb_test_multiple $input "$name - $input" {
+	    -re "\[\r\n\]*($result)\[\r\n\]+($gdb_prompt | *>)$" {
+		pass "$name - $input"
+	    }
+	}]} {
+	    return 1
+	}
+    }
+    return 0
+}
diff --git a/gdb/thread.c b/gdb/thread.c
index 55b4b96..e0ad2d3 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -61,7 +61,6 @@ static int thread_alive (struct thread_info *);
 static void info_threads_command (char *, int);
 static void thread_apply_command (char *, int);
 static void restore_current_thread (ptid_t);
-static void prune_threads (void);
 
 /* Frontend view of the thread state.  Possible extensions: stepping,
    finishing, until(ling),...  */
@@ -497,16 +496,23 @@ thread_alive (struct thread_info *tp)
   return 1;
 }
 
-static void
+void
 prune_threads (void)
 {
-  struct thread_info *tp, *next;
+  struct thread_info *tp;
+  struct thread_info **prevp = &thread_list;
 
-  for (tp = thread_list; tp; tp = next)
+  for (tp = *prevp; tp; tp = *prevp)
     {
-      next = tp->next;
+      /* If the thread has died, free it and unlink it from the list.
+	 Otherwise, advance to the next thread.  */
       if (!thread_alive (tp))
-	delete_thread (tp->ptid);
+	{
+	  *prevp = tp->next;
+	  free_thread (tp);
+	}
+      else
+	prevp = &tp->next;
     }
 }
 
diff --git a/gdb/top.c b/gdb/top.c
index 1b4aa9d..3cfe57e 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -349,6 +349,7 @@ void
 prepare_execute_command (void)
 {
   free_all_values ();
+  free_all_types ();
 
   /* With multiple threads running while the one we're examining is stopped,
      the dcache can get stale without us being able to detect it.
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index f090231..fc15ec1 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -35,6 +35,8 @@
 #include "gdb_string.h"
 #include "exceptions.h"
 #include "valprint.h"
+#include "dwarf2loc.h"
+
 #include <errno.h>
 
 extern void _initialize_typeprint (void);
@@ -76,6 +78,9 @@ void
 type_print (struct type *type, char *varstring, struct ui_file *stream,
 	    int show)
 {
+  if (show >= 0)
+    type = check_typedef (type);
+
   LA_PRINT_TYPE (type, varstring, stream, show, 0);
 }
 
@@ -114,7 +119,8 @@ whatis_exp (char *exp, int show)
 {
   struct expression *expr;
   struct value *val;
-  struct cleanup *old_chain = NULL;
+  /* Required at least for the object_address_set call.  */
+  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   struct type *real_type = NULL;
   struct type *type;
   int full = 0;
@@ -125,12 +131,13 @@ whatis_exp (char *exp, int show)
   if (exp)
     {
       expr = parse_expression (exp);
-      old_chain = make_cleanup (free_current_contents, &expr);
+      make_cleanup (free_current_contents, &expr);
       val = evaluate_type (expr);
     }
   else
     val = access_value_history (0);
 
+  object_address_set (value_raw_address (val));
   type = value_type (val);
 
   get_user_print_options (&opts);
@@ -167,8 +174,7 @@ whatis_exp (char *exp, int show)
   type_print (type, "", gdb_stdout, show);
   printf_filtered ("\n");
 
-  if (exp)
-    do_cleanups (old_chain);
+  do_cleanups (old_chain);
 }
 
 static void
diff --git a/gdb/typeprint.h b/gdb/typeprint.h
index f561310..d261c79 100644
--- a/gdb/typeprint.h
+++ b/gdb/typeprint.h
@@ -20,10 +20,13 @@
 #ifndef TYPEPRINT_H
 #define TYPEPRINT_H
 
+enum language;
 struct ui_file;
 
 void print_type_scalar (struct type * type, LONGEST, struct ui_file *);
 
 void c_type_print_varspec_suffix (struct type *, struct ui_file *, int,
 				  int, int);
+
+void c_type_print_args (struct type *, struct ui_file *, int, enum language);
 #endif
diff --git a/gdb/ui-file.c b/gdb/ui-file.c
index 527917c..07d959a 100644
--- a/gdb/ui-file.c
+++ b/gdb/ui-file.c
@@ -22,6 +22,7 @@
 
 #include "defs.h"
 #include "ui-file.h"
+#include "gdb_obstack.h"
 #include "gdb_string.h"
 
 #include <errno.h>
@@ -263,7 +264,7 @@ set_ui_file_data (struct ui_file *file, void *data,
 }
 
 /* ui_file utility function for converting a ``struct ui_file'' into
-   a memory buffer''. */
+   a memory buffer. */
 
 struct accumulated_ui_file
 {
@@ -297,6 +298,23 @@ ui_file_xstrdup (struct ui_file *file, long *length)
     *length = acc.length;
   return acc.buffer;
 }
+
+static void
+do_ui_file_obsavestring (void *context, const char *buffer, long length)
+{
+  struct obstack *obstack = (struct obstack *) context;
+  obstack_grow (obstack, buffer, length);
+}
+
+char *
+ui_file_obsavestring (struct ui_file *file, struct obstack *obstack,
+		      long *length)
+{
+  ui_file_put (file, do_ui_file_obsavestring, obstack);
+  *length = obstack_object_size (obstack);
+  obstack_1grow (obstack, '\0');
+  return obstack_finish (obstack);
+}
 
 /* A pure memory based ``struct ui_file'' that can be used an output
    buffer. The buffers accumulated contents are available via
diff --git a/gdb/ui-file.h b/gdb/ui-file.h
index bf9915c..233206c 100644
--- a/gdb/ui-file.h
+++ b/gdb/ui-file.h
@@ -19,6 +19,7 @@
 #ifndef UI_FILE_H
 #define UI_FILE_H
 
+struct obstack;
 struct ui_file;
 
 /* Create a generic ui_file object with null methods. */
@@ -77,7 +78,10 @@ extern void ui_file_put (struct ui_file *src, ui_file_put_method_ftype *write, v
    minus that appended NUL. */
 extern char *ui_file_xstrdup (struct ui_file *file, long *length);
 
-
+/* Similar to ui_file_xstrdup, but return a new string allocated on
+   OBSTACK.  */
+extern char *ui_file_obsavestring (struct ui_file *file,
+				   struct obstack *obstack, long *length);
 
 extern long ui_file_read (struct ui_file *file, char *buf, long length_buf);
 
diff --git a/gdb/utils.c b/gdb/utils.c
index 16ad084..3021a43 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -2610,7 +2610,10 @@ fprintf_symbol_filtered (struct ui_file *stream, char *name,
    As an extra hack, string1=="FOO(ARGS)" matches string2=="FOO".
    This "feature" is useful when searching for matching C++ function names
    (such as if the user types 'break FOO', where FOO is a mangled C++
-   function). */
+   function).
+
+   As an extra-special hack, we do the same with ' ', so that
+   "FOO(ARGS) const" can match "FOO", too.  */
 
 int
 strcmp_iw (const char *string1, const char *string2)
@@ -2635,7 +2638,7 @@ strcmp_iw (const char *string1, const char *string2)
 	  string2++;
 	}
     }
-  return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0');
+  return (*string1 != ' ' && *string1 != '\0' && *string1 != '(') || (*string2 != '\0' && *string2 != '(');
 }
 
 /* This is like strcmp except that it ignores whitespace and treats
diff --git a/gdb/valarith.c b/gdb/valarith.c
index a9c875d..12f6f07 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -139,7 +139,6 @@ an integer nor a pointer of the same type."));
 struct value *
 value_subscript (struct value *array, LONGEST index)
 {
-  struct value *bound;
   int c_style = current_language->c_style_arrays;
   struct type *tarray;
 
@@ -154,12 +153,26 @@ value_subscript (struct value *array, LONGEST index)
       get_discrete_bounds (range_type, &lowerbound, &upperbound);
 
       if (VALUE_LVAL (array) != lval_memory)
-	return value_subscripted_rvalue (array, index, lowerbound);
+	{
+	  if (index >= lowerbound && index <= upperbound)
+	    {
+	      CORE_ADDR element_size = TYPE_LENGTH (TYPE_TARGET_TYPE (tarray));
+	      CORE_ADDR offset = (index - lowerbound) * element_size;
+
+	      return value_subscripted_rvalue (array, offset);
+	    }
+	  error (_("array or string index out of range"));
+	}
 
       if (c_style == 0)
 	{
 	  if (index >= lowerbound && index <= upperbound)
-	    return value_subscripted_rvalue (array, index, lowerbound);
+	    {
+	      CORE_ADDR element_size = TYPE_LENGTH (TYPE_TARGET_TYPE (tarray));
+	      CORE_ADDR offset = (index - lowerbound) * element_size;
+
+	      return value_subscripted_rvalue (array, offset);
+	    }
 	  /* Emit warning unless we have an array of unknown size.
 	     An array of unknown size has lowerbound 0 and upperbound -1.  */
 	  if (upperbound > -1)
@@ -178,33 +191,37 @@ value_subscript (struct value *array, LONGEST index)
     error (_("not an array or string"));
 }
 
-/* Return the value of EXPR[IDX], expr an aggregate rvalue
-   (eg, a vector register).  This routine used to promote floats
-   to doubles, but no longer does.  */
+/* Return the value of *((void *) ARRAY + ELEMENT), ARRAY an aggregate rvalue
+   (eg, a vector register).  This routine used to promote floats to doubles,
+   but no longer does.  OFFSET is zero-based with 0 for the lowermost existing
+   element, it must be expressed in bytes (therefore multiplied by
+   check_typedef (TYPE_TARGET_TYPE (array_type)).  */
 
 struct value *
-value_subscripted_rvalue (struct value *array, LONGEST index, int lowerbound)
+value_subscripted_rvalue (struct value *array, CORE_ADDR offset)
 {
   struct type *array_type = check_typedef (value_type (array));
   struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type));
-  unsigned int elt_size = TYPE_LENGTH (elt_type);
-  unsigned int elt_offs = elt_size * longest_to_int (index - lowerbound);
   struct value *v;
 
-  if (index < lowerbound || elt_offs >= TYPE_LENGTH (array_type))
-    error (_("no such vector element"));
+  /* Do not check TYPE_LENGTH (array_type) as we may have been given the
+     innermost dimension of a multi-dimensional Fortran array where its length
+     is shorter than the possibly accessed element offset.  */
 
   v = allocate_value (elt_type);
   if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
     set_value_lazy (v, 1);
   else
-    memcpy (value_contents_writeable (v),
-	    value_contents (array) + elt_offs, elt_size);
+    {
+      unsigned int elt_size = TYPE_LENGTH (elt_type);
+      memcpy (value_contents_writeable (v),
+	      value_contents (array) + offset, elt_size);
+    }
 
   set_value_component_location (v, array);
   VALUE_REGNUM (v) = VALUE_REGNUM (array);
   VALUE_FRAME_ID (v) = VALUE_FRAME_ID (array);
-  set_value_offset (v, value_offset (array) + elt_offs);
+  set_value_offset (v, value_offset (array) + offset);
   return v;
 }
 
diff --git a/gdb/valops.c b/gdb/valops.c
index b64cb21..b7d31cc 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -38,6 +38,7 @@
 #include "cp-support.h"
 #include "dfp.h"
 #include "user-regs.h"
+#include "dwarf2loc.h"
 
 #include <errno.h>
 #include "gdb_string.h"
@@ -369,8 +370,6 @@ value_cast (struct type *type, struct value *arg2)
 	  new_length = val_length / element_length;
 	  if (val_length % element_length != 0)
 	    warning (_("array element type size does not divide object size in cast"));
-	  /* FIXME-type-allocation: need a way to free this type when
-	     we are done with it.  */
 	  range_type = create_range_type ((struct type *) NULL,
 					  TYPE_TARGET_TYPE (range_type),
 					  low_bound,
@@ -565,6 +564,64 @@ value_one (struct type *type, enum lval_type lv)
   return val;
 }
 
+/* object_address_set must be already called before this function.  */
+
+const char *
+object_address_data_not_valid (struct type *type)
+{
+  /* Attributes are present only at the target type of a typedef.  Make the
+     call conditional as it would otherwise loop through type_length_get.  */
+  if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
+    CHECK_TYPEDEF (type);
+
+  /* DW_AT_associated has a preference over DW_AT_allocated.  */
+  if (TYPE_NOT_ASSOCIATED (type)
+      || (TYPE_ASSOCIATED (type) != NULL
+	  && 0 == dwarf_locexpr_baton_eval (TYPE_ASSOCIATED (type))))
+    return N_("object is not associated");
+
+  if (TYPE_NOT_ALLOCATED (type)
+      || (TYPE_ALLOCATED (type) != NULL
+	  && 0 == dwarf_locexpr_baton_eval (TYPE_ALLOCATED (type))))
+    return N_("object is not allocated");
+
+  return NULL;
+}
+
+/* Return non-zero if the variable is valid.  If it is valid the function
+   may store the data address (DW_AT_DATA_LOCATION) of TYPE at *ADDRESS_RETURN.
+   You must set *ADDRESS_RETURN from value_raw_address (VAL) before calling this
+   function.  If no DW_AT_DATA_LOCATION is present for TYPE the address at
+   *ADDRESS_RETURN is left unchanged.  ADDRESS_RETURN must not be NULL, use
+   object_address_data_not_valid () for just the data validity check.  */
+
+int
+object_address_get_data (struct type *type, CORE_ADDR *address_return)
+{
+  gdb_assert (address_return != NULL);
+
+  object_address_set (*address_return);
+
+  /* TYPE_DATA_LOCATION_DWARF_BLOCK / TYPE_DATA_LOCATION_ADDR are present only
+     at the target type of a typedef.  */
+  CHECK_TYPEDEF (type);
+
+  if (object_address_data_not_valid (type) != NULL)
+    {
+      /* Do not try to evaluate DW_AT_data_location as it may even crash
+	 (it would just return the value zero in the gfortran case).  */
+      return 0;
+    }
+
+  if (TYPE_DATA_LOCATION_IS_ADDR (type))
+    *address_return = TYPE_DATA_LOCATION_ADDR (type);
+  else if (TYPE_DATA_LOCATION_DWARF_BLOCK (type) != NULL)
+    *address_return
+      = dwarf_locexpr_baton_eval (TYPE_DATA_LOCATION_DWARF_BLOCK (type));
+
+  return 1;
+}
+
 /* Helper function for value_at, value_at_lazy, and value_at_lazy_stack.  */
 
 static struct value *
@@ -656,15 +713,21 @@ value_fetch_lazy (struct value *val)
     }
   else if (VALUE_LVAL (val) == lval_memory)
     {
-      CORE_ADDR addr = value_address (val);
-      int length = TYPE_LENGTH (check_typedef (value_enclosing_type (val)));
+      CORE_ADDR addr = value_raw_address (val);
 
-      if (length)
+      if (object_address_get_data (value_type (val), &addr))
 	{
-	  if (value_stack (val))
-	    read_stack (addr, value_contents_all_raw (val), length);
-	  else
-	    read_memory (addr, value_contents_all_raw (val), length);
+	  struct type *type = value_enclosing_type (val);
+	  int length = TYPE_LENGTH (check_typedef (type));
+
+	  if (length)
+	    {
+	      addr += value_offset (val);
+	      if (value_stack (val))
+		read_stack (addr, value_contents_all_raw (val), length);
+	      else
+		read_memory (addr, value_contents_all_raw (val), length);
+	    }
 	}
     }
   else if (VALUE_LVAL (val) == lval_register)
@@ -1070,7 +1133,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)
     {
-      CORE_ADDR addr = value_address (val);
+      CORE_ADDR addr;
+
+      if (VALUE_LVAL (val) == lval_memory)
+	{
+	  addr = value_raw_address (val);
+	  if (!object_address_get_data (type, &addr))
+	    error (_("Can't take address of memory lvalue \"%s\"."),
+		   SYMBOL_PRINT_NAME (var));
+	  set_value_address (val, addr);
+	}
+
+      addr = value_address (val);
       return value_from_pointer (lookup_pointer_type (type), addr);
     }
 
@@ -1176,6 +1250,7 @@ struct value *
 value_coerce_array (struct value *arg1)
 {
   struct type *type = check_typedef (value_type (arg1));
+  CORE_ADDR address;
 
   /* 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
@@ -1185,8 +1260,12 @@ value_coerce_array (struct value *arg1)
   if (VALUE_LVAL (arg1) != lval_memory)
     error (_("Attempt to take address of value not located in memory."));
 
+  address = value_raw_address (arg1);
+  if (!object_address_get_data (type, &address))
+    error (_("Attempt to take address of non-valid value."));
+
   return value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
-			     value_address (arg1));
+			     address + value_offset (arg1));
 }
 
 /* Given a value which is a function, return a value which is a pointer
@@ -2069,12 +2148,25 @@ find_overload_match (struct type **arg_types, int nargs,
   if (method)
     {
       gdb_assert (obj);
+
+      /* OBJ may be a pointer value rather than the object itself.  */
+      obj = coerce_ref (obj);
+      while (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_PTR)
+	obj = coerce_ref (value_ind (obj));
       obj_type_name = TYPE_NAME (value_type (obj));
-      /* Hack: evaluate_subexp_standard often passes in a pointer
-         value rather than the object itself, so try again.  */
-      if ((!obj_type_name || !*obj_type_name) 
-	  && (TYPE_CODE (value_type (obj)) == TYPE_CODE_PTR))
-	obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (value_type (obj)));
+
+      /* First check whether this is a data member, e.g. a pointer to
+	 a function.  */
+      if (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_STRUCT)
+	{
+	  *valp = search_struct_field (name, obj, 0,
+				       check_typedef (value_type (obj)), 0);
+	  if (*valp)
+	    {
+	      *staticp = 1;
+	      return 0;
+	    }
+	}
 
       fns_ptr = value_find_oload_method_list (&temp, name, 
 					      0, &num_fns, 
@@ -2094,16 +2186,29 @@ find_overload_match (struct type **arg_types, int nargs,
     }
   else
     {
-      const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym);
+      const char *qualified_name = SYMBOL_NATURAL_NAME (fsym);
+
+      /* If we have a function with a C++ name, try to extract just
+	 the function part.  Do not try this for non-functions (e.g.
+	 function pointers).  */
+      if (qualified_name
+	  && TYPE_CODE (check_typedef (SYMBOL_TYPE (fsym))) == TYPE_CODE_FUNC)
+	{
+	  func_name = cp_func_name (qualified_name);
 
-      /* If we have a C++ name, try to extract just the function
-	 part.  */
-      if (qualified_name)
-	func_name = cp_func_name (qualified_name);
+	  /* If cp_func_name did not remove anything, the name of the
+	     symbol did not include scope or argument types - it was
+	     probably a C-style function.  */
+	  if (func_name && strcmp (func_name, qualified_name) == 0)
+	    {
+	      xfree (func_name);
+	      func_name = NULL;
+	    }
+	}
 
-      /* If there was no C++ name, this must be a C-style function.
-	 Just return the same symbol.  Do the same if cp_func_name
-	 fails for some reason.  */
+      /* If there was no C++ name, this must be a C-style function or
+	 not a function at all.  Just return the same symbol.  Do the
+	 same if cp_func_name fails for some reason.  */
       if (func_name == NULL)
         {
 	  *symp = fsym;
@@ -2534,8 +2639,8 @@ check_field (struct type *type, const char *name)
    the comment before value_struct_elt_for_reference.  */
 
 struct value *
-value_aggregate_elt (struct type *curtype,
-		     char *name, int want_address,
+value_aggregate_elt (struct type *curtype, char *name,
+		     struct type *expect_type, int want_address,
 		     enum noside noside)
 {
   switch (TYPE_CODE (curtype))
@@ -2543,7 +2648,7 @@ value_aggregate_elt (struct type *curtype,
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
       return value_struct_elt_for_reference (curtype, 0, curtype, 
-					     name, NULL,
+					     name, expect_type,
 					     want_address, noside);
     case TYPE_CODE_NAMESPACE:
       return value_namespace_elt (curtype, name, 
@@ -2554,6 +2659,56 @@ value_aggregate_elt (struct type *curtype,
     }
 }
 
+/* Compares the two method/function types T1 and T2 for "equality" 
+   with respect to the the methods' parameters. If the types of the
+   two parameter lists are the same, returns 1; 0 otherwise. This
+   comparison may ignore any artificial parameters in T1 if
+   SKIP_ARTIFICIAL is non-zero. This function will ALWAYS skip
+   the first artificial parameter in T1, assumed to be a 'this' pointer.
+
+   The type T2 is expected to have come from make_params (in eval.c). */
+static int
+compare_parameters (struct type *t1, struct type *t2, int skip_artificial)
+{
+  int start = 0;
+
+  if (TYPE_FIELD_ARTIFICIAL (t1, 0))
+    ++start;
+
+  /* If skipping artificial fields, find the first real field
+     in T1. */
+  if (skip_artificial)
+    {
+      while (start < TYPE_NFIELDS (t1)
+	     && TYPE_FIELD_ARTIFICIAL (t1, start))
+	++start;
+    }
+
+  /* Now compare parameters */
+
+  /* Special case: a method taking void. T1 will contain no
+     non-artificial fields, and T2 will contain TYPE_CODE_VOID. */
+  if ((TYPE_NFIELDS (t1) - start) == 0 && TYPE_NFIELDS (t2) == 1
+      && TYPE_CODE (TYPE_FIELD_TYPE (t2, 0)) == TYPE_CODE_VOID)
+    return 1;
+
+  if ((TYPE_NFIELDS (t1) - start) == TYPE_NFIELDS (t2))
+    {
+      int i;
+      for (i = 0; i < TYPE_NFIELDS (t2); ++i)
+	{
+	  if (rank_one_type (TYPE_FIELD_TYPE (t1, start + i),
+			      TYPE_FIELD_TYPE (t2, i))
+	      != 0)
+	    return 0;
+	}
+
+      return 1;
+    }
+
+  return 0;
+}
+
 /* C++: Given an aggregate type CURTYPE, and a member name NAME,
    return the address of this member as a "pointer to member" type.
    If INTYPE is non-null, then it will be the type of the member we
@@ -2631,23 +2786,46 @@ value_struct_elt_for_reference (struct type *domain, int offset,
 	}
       if (t_field_name && strcmp (t_field_name, name) == 0)
 	{
-	  int j = TYPE_FN_FIELDLIST_LENGTH (t, i);
+	  int j;
+	  int len = TYPE_FN_FIELDLIST_LENGTH (t, i);
 	  struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
 
 	  check_stub_method_group (t, i);
 
-	  if (intype == 0 && j > 1)
-	    error (_("non-unique member `%s' requires type instantiation"), name);
 	  if (intype)
 	    {
-	      while (j--)
-		if (TYPE_FN_FIELD_TYPE (f, j) == intype)
-		  break;
-	      if (j < 0)
-		error (_("no member function matches that type instantiation"));
-	    }
+	      for (j = 0; j < len; ++j)
+		{
+		  if (compare_parameters (TYPE_FN_FIELD_TYPE (f, j), intype, 0)
+		      || compare_parameters (TYPE_FN_FIELD_TYPE (f, j), intype, 1))
+		    break;
+		}
+
+	      if (j == len)
+		error (_("no member function matches that type instantiation"));	    }
 	  else
-	    j = 0;
+	    {
+	      int ii;
+	      /* Skip artificial methods. This is necessary if, for example,
+		 the user wants to "print subclass::subclass" with only
+		 one defined user constructor. There is no ambiguity in this
+		 case. */
+	      for (ii = 0; ii < TYPE_FN_FIELDLIST_LENGTH (t, i);
+		   ++ii)
+		{
+		  if (TYPE_FN_FIELD_ARTIFICIAL (f, ii))
+		    --len;
+		}
+
+	      /* Desired method is ambiguous if more than one method is
+		 defined. */
+	      if (len > 1)
+		error (_("non-unique member `%s' requires type instantiation"), name);
+
+	      /* This assumes, of course, that all artificial methods appear
+		 BEFORE any concrete methods. */
+	      j = TYPE_FN_FIELDLIST_LENGTH (t, i) - 1;
+	    }
 
 	  if (TYPE_FN_FIELD_STATIC_P (f, j))
 	    {
@@ -2761,7 +2939,7 @@ value_maybe_namespace_elt (const struct type *curtype,
   struct symbol *sym;
   struct value *result;
 
-  sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
+  sym = cp_lookup_symbol_namespace(namespace_name, name,
 				    get_selected_block (0), 
 				    VAR_DOMAIN);
 
@@ -2905,7 +3083,7 @@ value_of_local (const char *name, int complain)
 
   /* Calling lookup_block_symbol is necessary to get the LOC_REGISTER
      symbol instead of the LOC_ARG one (if both exist).  */
-  sym = lookup_block_symbol (b, name, NULL, VAR_DOMAIN);
+  sym = lookup_block_symbol (b, name, VAR_DOMAIN);
   if (sym == NULL)
     {
       if (complain)
@@ -2959,8 +3137,6 @@ value_slice (struct value *array, int lowbound, int length)
       || lowbound + length - 1 > upperbound)
     error (_("slice out of range"));
 
-  /* FIXME-type-allocation: need a way to free this type when we are
-     done with it.  */
   slice_range_type = create_range_type ((struct type *) NULL,
 					TYPE_TARGET_TYPE (range_type),
 					lowbound, 
diff --git a/gdb/valprint.c b/gdb/valprint.c
index cbb5d94..f9634ea 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -236,7 +236,6 @@ scalar_type_p (struct type *type)
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
     case TYPE_CODE_SET:
-    case TYPE_CODE_STRING:
     case TYPE_CODE_BITSTRING:
       return 0;
     default:
@@ -1153,6 +1152,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr,
 
   for (; i < len && things_printed < options->print_max; i++)
     {
+      size_t elt_offset = i * eltlen;
       if (i != 0)
 	{
 	  if (options->prettyprint_arrays)
@@ -1172,7 +1172,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr,
       rep1 = i + 1;
       reps = 1;
       while ((rep1 < len) &&
-	     !memcmp (valaddr + i * eltlen, valaddr + rep1 * eltlen, eltlen))
+	     !memcmp (valaddr + elt_offset, valaddr + rep1 * eltlen, eltlen))
 	{
 	  ++reps;
 	  ++rep1;
diff --git a/gdb/value.c b/gdb/value.c
index 589e03b..66013b7 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -37,8 +37,10 @@
 #include "block.h"
 #include "dfp.h"
 #include "objfiles.h"
+#include "cli/cli-decode.h"
 #include "valprint.h"
 #include "cli/cli-decode.h"
+#include "observer.h"
 
 #include "python/python.h"
 
@@ -170,6 +172,14 @@ struct value
      taken off this list.  */
   struct value *next;
 
+  /* The reference count.  A value that is still on the `all_values'
+     list will have a reference count of 0.  A call to `release_value'
+     will increment the reference count (and remove the value from the
+     list, the first time).  A call to `value_free' will decrement the
+     reference count, and will free the value when there are no more
+     references.  */
+  int refcount;
+
   /* Register number if the value is from a register.  */
   short regnum;
 
@@ -261,7 +271,9 @@ allocate_value_lazy (struct type *type)
   val->next = all_values;
   all_values = val;
   val->type = type;
+  type_incref (type);
   val->enclosing_type = type;
+  type_incref (type);
   VALUE_LVAL (val) = not_lval;
   val->location.address = 0;
   VALUE_FRAME_ID (val) = null_frame_id;
@@ -346,6 +358,8 @@ value_type (struct value *value)
 void
 deprecated_set_value_type (struct value *value, struct type *type)
 {
+  type_incref (type);
+  type_decref (value->type);
   value->type = type;
 }
 
@@ -624,6 +638,9 @@ value_free (struct value *val)
       if (val->parent != NULL)
 	value_free (val->parent);
 
+      type_decref (val->type);
+      type_decref (val->enclosing_type);
+
       if (VALUE_LVAL (val) == lval_computed)
 	{
 	  struct lval_funcs *funcs = val->location.computed.funcs;
@@ -728,6 +745,9 @@ value_copy (struct value *arg)
     val = allocate_value_lazy (encl_type);
   else
     val = allocate_value (encl_type);
+
+  type_incref (arg->type);
+  type_decref (val->type);
   val->type = arg->type;
   VALUE_LVAL (val) = VALUE_LVAL (arg);
   val->location = arg->location;
@@ -763,12 +783,15 @@ value_copy (struct value *arg)
 void
 set_value_component_location (struct value *component, struct value *whole)
 {
+  CORE_ADDR addr;
+
   if (VALUE_LVAL (whole) == lval_internalvar)
     VALUE_LVAL (component) = lval_internalvar_component;
   else
     VALUE_LVAL (component) = VALUE_LVAL (whole);
 
   component->location = whole->location;
+
   if (VALUE_LVAL (whole) == lval_computed)
     {
       struct lval_funcs *funcs = whole->location.computed.funcs;
@@ -776,6 +799,10 @@ set_value_component_location (struct value *component, struct value *whole)
       if (funcs->copy_closure)
         component->location.computed.closure = funcs->copy_closure (whole);
     }
+
+  addr = value_raw_address (component);
+  object_address_get_data (value_type (whole), &addr);
+  set_value_address (component, addr);
 }
 
 
@@ -906,6 +933,29 @@ show_values (char *num_exp, int from_tty)
       num_exp[1] = '\0';
     }
 }
+
+/* Sanity check for memory leaks and proper types reference counting.  */
+
+static void
+value_history_cleanup (void *unused)
+{
+  while (value_history_chain)
+    {
+      struct value_history_chunk *chunk = value_history_chain;
+      int i;
+
+      for (i = 0; i < ARRAY_SIZE (chunk->values); i++)
+      	value_free (chunk->values[i]);
+
+      value_history_chain = chunk->next;
+      xfree (chunk);
+    }
+  value_history_count = 0;
+
+  /* Free the unreferenced types above.  */
+  free_all_values ();
+  free_all_types ();
+}
 
 /* Internal variables.  These are variables within the debugger
    that hold values assigned by debugger commands.
@@ -1381,6 +1431,40 @@ call_internal_function (struct gdbarch *gdbarch,
   return (*ifn->handler) (gdbarch, language, ifn->cookie, argc, argv);
 }
 
+/* Call type_mark_used for any TYPEs referenced from this GDB source file.  */
+
+static void
+value_types_mark_used (void)
+{
+  struct internalvar *var;
+  struct value_history_chunk *chunk;
+
+  for (var = internalvars; var != NULL; var = var->next)
+    switch (var->kind)
+      {
+      case INTERNALVAR_VALUE:
+	type_mark_used (value_type (var->u.value));
+	break;
+
+      case INTERNALVAR_INTEGER:
+	type_mark_used (var->u.integer.type);
+	break;
+
+      case INTERNALVAR_POINTER:
+	type_mark_used (var->u.pointer.type);
+	break;
+      }
+
+  for (chunk = value_history_chain; chunk != NULL; chunk = chunk->next)
+    {
+      int i;
+
+      for (i = 0; i < ARRAY_SIZE (chunk->values); i++)
+	if (chunk->values[i])
+	  type_mark_used (value_type (chunk->values[i]));
+    }
+}
+
 /* 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
@@ -1428,11 +1512,10 @@ preserve_one_value (struct value *value, struct objfile *objfile,
 		    htab_t copied_types)
 {
   if (TYPE_OBJFILE (value->type) == objfile)
-    value->type = copy_type_recursive (objfile, value->type, copied_types);
+    value->type = copy_type_recursive (value->type, copied_types);
 
   if (TYPE_OBJFILE (value->enclosing_type) == objfile)
-    value->enclosing_type = copy_type_recursive (objfile,
-						 value->enclosing_type,
+    value->enclosing_type = copy_type_recursive (value->enclosing_type,
 						 copied_types);
 }
 
@@ -1447,13 +1530,13 @@ 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
-	  = copy_type_recursive (objfile, var->u.integer.type, copied_types);
+	  = copy_type_recursive (var->u.integer.type, copied_types);
       break;
 
     case INTERNALVAR_POINTER:
       if (TYPE_OBJFILE (var->u.pointer.type) == objfile)
 	var->u.pointer.type
-	  = copy_type_recursive (objfile, var->u.pointer.type, copied_types);
+	  = copy_type_recursive (var->u.pointer.type, copied_types);
       break;
 
     case INTERNALVAR_VALUE:
@@ -1855,6 +1938,8 @@ value_change_enclosing_type (struct value *val, struct type *new_encl_type)
     val->contents =
       (gdb_byte *) xrealloc (val->contents, TYPE_LENGTH (new_encl_type));
 
+  type_incref (new_encl_type);
+  type_decref (val->enclosing_type);
   val->enclosing_type = new_encl_type;
   return val;
 }
@@ -1919,6 +2004,8 @@ value_primitive_field (struct value *arg1, int offset,
 	  memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
 		  TYPE_LENGTH (value_enclosing_type (arg1)));
 	}
+      type_incref (type);
+      type_decref (v->type);
       v->type = type;
       v->offset = value_offset (arg1);
       v->embedded_offset = (offset + value_embedded_offset (arg1)
@@ -2177,6 +2264,42 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num)
 }
 
 
+/* Pack NUM into BUF using a target format of TYPE.  */
+
+void
+pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
+  int len;
+
+  type = check_typedef (type);
+  len = TYPE_LENGTH (type);
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_INT:
+    case TYPE_CODE_CHAR:
+    case TYPE_CODE_ENUM:
+    case TYPE_CODE_FLAGS:
+    case TYPE_CODE_BOOL:
+    case TYPE_CODE_RANGE:
+    case TYPE_CODE_MEMBERPTR:
+      store_unsigned_integer (buf, len, byte_order, num);
+      break;
+
+    case TYPE_CODE_REF:
+    case TYPE_CODE_PTR:
+      store_typed_address (buf, type, (CORE_ADDR) num);
+      break;
+
+    default:
+      error (_("\
+Unexpected type (%d) encountered for unsigned integer constant."),
+	     TYPE_CODE (type));
+    }
+}
+
+
 /* Convert C numbers into newly allocated values.  */
 
 struct value *
@@ -2190,6 +2313,19 @@ value_from_longest (struct type *type, LONGEST num)
 }
 
 
+/* Convert C unsigned numbers into newly allocated values.  */
+
+struct value *
+value_from_ulongest (struct type *type, ULONGEST num)
+{
+  struct value *val = allocate_value (type);
+
+  pack_unsigned_long (value_contents_raw (val), type, num);
+
+  return val;
+}
+
+
 /* Create a value representing a pointer of type TYPE to the address
    ADDR.  */
 struct value *
@@ -2348,4 +2484,8 @@ VARIABLE is already initialized."));
   add_prefix_cmd ("function", no_class, function_command, _("\
 Placeholder command for showing help on convenience functions."),
 		  &functionlist, "function ", 0, &cmdlist);
+
+  make_final_cleanup (value_history_cleanup, NULL);
+
+  observer_attach_mark_used (value_types_mark_used);
 }
diff --git a/gdb/value.h b/gdb/value.h
index 51e6960..48b30e4 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -342,11 +342,16 @@ extern LONGEST unpack_field_as_long (struct type *type,
 extern void pack_long (gdb_byte *buf, struct type *type, LONGEST num);
 
 extern struct value *value_from_longest (struct type *type, LONGEST num);
+extern struct value *value_from_ulongest (struct type *type, ULONGEST num);
 extern struct value *value_from_pointer (struct type *type, CORE_ADDR addr);
 extern struct value *value_from_double (struct type *type, DOUBLEST num);
 extern struct value *value_from_decfloat (struct type *type,
 					  const gdb_byte *decbytes);
 
+extern const char *object_address_data_not_valid (struct type *type);
+extern int object_address_get_data (struct type *type,
+				    CORE_ADDR *address_return);
+
 extern struct value *value_at (struct type *type, CORE_ADDR addr);
 extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr);
 
@@ -436,6 +441,7 @@ extern struct value *value_struct_elt (struct value **argp,
 
 extern struct value *value_aggregate_elt (struct type *curtype,
 					  char *name,
+					  struct type *expect_type,
 					  int want_address,
 					  enum noside noside);
 
@@ -681,7 +687,7 @@ extern struct value *value_allocate_space_in_inferior (int);
 extern struct value *value_of_local (const char *name, int complain);
 
 extern struct value *value_subscripted_rvalue (struct value *array,
-					       LONGEST index, int lowerbound);
+					       CORE_ADDR offset);
 
 /* User function handler.  */
 
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 7235635..9848de0 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -26,6 +26,8 @@
 #include "gdbcmd.h"
 #include "block.h"
 #include "valprint.h"
+#include "objfiles.h"
+#include "parser-defs.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -253,6 +255,8 @@ static void free_variable (struct varobj *var);
 
 static struct cleanup *make_cleanup_free_variable (struct varobj *var);
 
+static struct cleanup *make_cleanup_uninstall_variable (struct varobj *var);
+
 static struct type *get_type (struct varobj *var);
 
 static struct type *get_value_type (struct varobj *var);
@@ -480,6 +484,8 @@ is_root_p (struct varobj *var)
 struct cleanup *
 varobj_ensure_python_env (struct varobj *var)
 {
+  gdb_assert (var->root->is_valid);
+
   return ensure_python_env (var->root->exp->gdbarch,
 			    var->root->exp->language_defn);
 }
@@ -651,6 +657,7 @@ varobj_create (char *objname,
 	  do_cleanups (old_chain);
 	  return NULL;
 	}
+      make_cleanup_uninstall_variable (var);
     }
 
   discard_cleanups (old_chain);
@@ -821,7 +828,12 @@ varobj_get_display_hint (struct varobj *var)
   char *result = NULL;
 
 #if HAVE_PYTHON
-  struct cleanup *back_to = varobj_ensure_python_env (var);
+  struct cleanup *back_to;
+  
+  if (!var->root->is_valid)
+    return NULL;
+
+  back_to = varobj_ensure_python_env (var);
 
   if (var->pretty_printer)
     result = gdbpy_get_display_hint (var->pretty_printer);
@@ -2186,6 +2198,18 @@ make_cleanup_free_variable (struct varobj *var)
   return make_cleanup (do_free_variable_cleanup, var);
 }
 
+static void
+do_uninstall_variable_cleanup (void *var)
+{
+  uninstall_variable (var);
+}
+
+static struct cleanup *
+make_cleanup_uninstall_variable (struct varobj *var)
+{
+  return make_cleanup (do_uninstall_variable_cleanup, var);
+}
+
 /* This returns the type of the variable. It also skips past typedefs
    to return the real type of the variable.
 
@@ -3442,6 +3466,19 @@ java_value_of_variable (struct varobj *var, enum varobj_display_formats format)
   return cplus_value_of_variable (var, format);
 }
 
+/* Iterate all the existing VAROBJs and call the FUNC callback for them with an
+   arbitrary caller supplied DATA pointer.  */
+
+static void
+all_varobjs (void (*func) (struct varobj *var, void *data), void *data)
+{
+  struct vlist **vlp, *vl;
+
+  for (vlp = varobj_table; vlp < varobj_table + VAROBJ_TABLE_SIZE; vlp++)
+    for (vl = *vlp; vl != NULL; vl = vl->next)
+      (*func) (vl->var, data);
+}
+
 /* Iterate all the existing _root_ VAROBJs and call the FUNC callback for them
    with an arbitrary caller supplied DATA pointer.  */
 
@@ -3459,6 +3496,43 @@ all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data)
       (*func) (var_root->rootvar, data);
     }
 }
+
+/* Helper for varobj_types_mark_used.  Call type_mark_used for any TYPEs
+   referenced from this VAR.  */
+
+static void
+varobj_types_mark_used_iter (struct varobj *var, void *unused)
+{
+  /* Even FLOATING or IS_INVALID VARs with non-NULL TYPE references will
+     free them in free_variable.  Still EXP may also reference TYPEs
+     but these belong to SYMBOLs which should be always associated with
+     an OBJFILE (and therefore not useful to be type_mark_used).  */
+
+  type_mark_used (var->type);
+  if (var->value)
+    type_mark_used (value_type (var->value));
+
+  /* Check VAROBJROOTs only once during the varobj_types_mark_used pass.  */
+
+  if (var->root->rootvar == var)
+    {
+      if (var->root->exp)
+	exp_types_mark_used (var->root->exp);
+    }
+}
+
+/* Call type_mark_used for any TYPEs referenced from this GDB source file.  */
+
+static void
+varobj_types_mark_used (void)
+{
+  /* Check all the VAROBJs, even non-root ones.  Child VAROBJs can reference
+     types from other OBJFILEs through TYPE_IS_OPAQUE resolutions by
+     check_typedef.  Such types references will not be interconnected into the
+     same TYPE_GROUP.  */
+
+  all_varobjs (varobj_types_mark_used_iter, NULL);
+}
 
 extern void _initialize_varobj (void);
 void
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index c56ab86..dacf913 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -3038,6 +3038,7 @@ static struct sym_fns xcoff_sym_fns =
   xcoff_new_init,		/* sym_new_init: init anything gbl to entire symtab */
   xcoff_symfile_init,		/* sym_init: read initial info, setup for sym_read() */
   xcoff_initial_scan,		/* sym_read: read a symbol file into symtab */
+  NULL,				/* sym_read_psymbols */
   xcoff_symfile_finish,		/* sym_finish: finished with file, cleanup */
   xcoff_symfile_offsets,	/* sym_offsets: xlate offsets ext->int form */
   default_symfile_segments,	/* sym_segments: Get segment information from