diff -Nur gdb-7.7.orig/bfd/bfd-in2.h gdb-7.7/bfd/bfd-in2.h
--- gdb-7.7.orig/bfd/bfd-in2.h	2014-02-06 03:21:29.000000000 +0100
+++ gdb-7.7/bfd/bfd-in2.h	2014-03-26 19:43:36.000000000 +0100
@@ -5378,6 +5378,11 @@
 expressions of the form "Symbol Op Symbol"  */
   BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM,
 
+/* This is a 32 bit reloc that stores the 32 bit pc relative
+value in two words (with an imm instruction).  No relocation is 
+done here - only used for relaxing  */
+  BFD_RELOC_MICROBLAZE_32_NONE,
+
 /* This is a 64 bit reloc that stores the 32 bit pc relative
 value in two words (with an imm instruction).  No relocation is
 done here - only used for relaxing  */
diff -Nur gdb-7.7.orig/bfd/elf32-microblaze.c gdb-7.7/bfd/elf32-microblaze.c
--- gdb-7.7.orig/bfd/elf32-microblaze.c	2013-12-08 05:55:47.000000000 +0100
+++ gdb-7.7/bfd/elf32-microblaze.c	2014-03-27 08:30:48.000000000 +0100
@@ -177,6 +177,20 @@
           FALSE), 		/* PC relative offset?  */
 
    /* This reloc does nothing.  Used for relaxation.  */
+   HOWTO (R_MICROBLAZE_32_NONE,	/* Type.  */
+          0,			/* Rightshift.  */
+          2,			/* Size (0 = byte, 1 = short, 2 = long).  */
+          32,			/* Bitsize.  */
+          TRUE,			/* PC_relative.  */
+          0,			/* Bitpos.  */
+          complain_overflow_bitfield,  /* Complain on overflow.  */
+          NULL,                  /* Special Function.  */
+          "R_MICROBLAZE_32_NONE",/* Name.  */
+          FALSE,		/* Partial Inplace.  */
+          0,			/* Source Mask.  */
+          0,			/* Dest Mask.  */
+          FALSE),		/* PC relative offset?  */
+
    HOWTO (R_MICROBLAZE_64_NONE,	/* Type.  */
           0,			/* Rightshift.  */
           2,			/* Size (0 = byte, 1 = short, 2 = long).  */
@@ -532,7 +546,10 @@
     case BFD_RELOC_NONE:
       microblaze_reloc = R_MICROBLAZE_NONE;
       break;
-    case BFD_RELOC_MICROBLAZE_64_NONE:
+    case BFD_RELOC_MICROBLAZE_32_NONE:
+      microblaze_reloc = R_MICROBLAZE_32_NONE;
+      break;
+     case BFD_RELOC_MICROBLAZE_64_NONE:
       microblaze_reloc = R_MICROBLAZE_64_NONE;
       break;
     case BFD_RELOC_32:
@@ -668,6 +685,67 @@
   return _bfd_elf_is_local_label_name (abfd, name);
 }
 
+/* Support for core dump NOTE sections.  */
+static bfd_boolean
+microblaze_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+  int offset;
+  unsigned int size;
+
+  switch (note->descsz)
+    {
+      default:
+        return FALSE;
+
+      case 228:         /* Linux/MicroBlaze */
+        /* pr_cursig */
+        elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+        /* pr_pid */
+        elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
+
+        /* pr_reg */
+        offset = 72;
+        size = 50 * 4;
+
+        break;
+    }
+
+  /* Make a ".reg/999" section.  */
+  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+                                          size, note->descpos + offset);
+}
+
+static bfd_boolean
+microblaze_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+  switch (note->descsz)
+    {
+      default:
+        return FALSE;
+
+      case 128:         /* Linux/MicroBlaze elf_prpsinfo */
+        elf_tdata (abfd)->core->program
+         = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
+        elf_tdata (abfd)->core->command
+         = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
+    }
+
+  /* Note that for some reason, a spurious space is tacked
+     onto the end of the args in some (at least one anyway)
+     implementations, so strip it off if it exists.  */
+
+  {
+    char *command = elf_tdata (abfd)->core->command;
+    int n = strlen (command);
+
+    if (0 < n && command[n - 1] == ' ')
+      command[n - 1] = '\0';
+  }
+
+  return TRUE;
+}
+
 /* The microblaze linker (like many others) needs to keep track of
    the number of relocs that it decides to copy as dynamic relocs in
    check_relocs for each symbol. This is so that it can later discard
@@ -1023,7 +1101,7 @@
 	    {
 	      /* External symbol.  */
 	      bfd_boolean warned ATTRIBUTE_UNUSED;
-	      bfd_boolean ignored ATTRIBUTE_UNUSED;
+	      bfd_boolean ignored;
 
 	      RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
 				       r_symndx, symtab_hdr, sym_hashes,
@@ -1852,14 +1930,22 @@
 	        }
 	      break;
 	    case R_MICROBLAZE_NONE:
+	    case R_MICROBLAZE_32_NONE:
 	      {
 	        /* This was a PC-relative instruction that was
  		   completely resolved.  */
 	        int sfix, efix;
+		unsigned int val;
 	        bfd_vma target_address;
 	        target_address = irel->r_addend + irel->r_offset;
 	        sfix = calc_fixup (irel->r_offset, 0, sec);
 	        efix = calc_fixup (target_address, 0, sec);
+
+                /* Validate the in-band val.  */
+                val = bfd_get_32 (abfd, contents + irel->r_offset);
+                if (val != irel->r_addend && ELF32_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
+                    fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
+                }
 	        irel->r_addend -= (efix - sfix);
 	        /* Should use HOWTO.  */
 	        microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
@@ -1907,6 +1993,49 @@
           irelscanend = irelocs + o->reloc_count;
           for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
             {
+              if (1 && ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
+                {
+                  unsigned int val;
+
+                  isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
+
+                  /* hax: We only do the following fixup for debug location lists.  */
+                  if (strcmp(".debug_loc", o->name))
+                    continue;
+
+                  /* This was a PC-relative instruction that was completely resolved.  */
+                  if (ocontents == NULL)
+                    {
+		      if (elf_section_data (o)->this_hdr.contents != NULL)
+		          ocontents = elf_section_data (o)->this_hdr.contents;
+		      else
+		        {
+		          /* We always cache the section contents.
+			     Perhaps, if info->keep_memory is FALSE, we
+			     should free them, if we are permitted to.  */
+
+		          if (o->rawsize == 0)
+			      o->rawsize = o->size;
+		          ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
+		          if (ocontents == NULL)
+			      goto error_return;
+		          if (!bfd_get_section_contents (abfd, o, ocontents,
+                                                         (file_ptr) 0,
+                                                         o->rawsize))
+                              goto error_return;
+		          elf_section_data (o)->this_hdr.contents = ocontents;
+		        }
+		    }
+
+                  val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
+                  if (val != irelscan->r_addend) {
+			fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend);
+                  }
+
+                  irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
+                  microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
+                                                     irelscan->r_addend);
+              }
               if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
                 {
 	          isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
@@ -1966,7 +2095,7 @@
 			      elf_section_data (o)->this_hdr.contents = ocontents;
 			    }
 			}
-		      irelscan->r_addend -= calc_fixup (irel->r_addend
+		      irelscan->r_addend -= calc_fixup (irelscan->r_addend
 							+ isym->st_value,
 							0,
 							sec);
@@ -3506,4 +3635,7 @@
 #define elf_backend_size_dynamic_sections       microblaze_elf_size_dynamic_sections
 #define elf_backend_add_symbol_hook		microblaze_elf_add_symbol_hook
 
+#define elf_backend_grok_prstatus               microblaze_elf_grok_prstatus
+#define elf_backend_grok_psinfo                 microblaze_elf_grok_psinfo
+
 #include "elf32-target.h"
diff -Nur gdb-7.7.orig/bfd/libbfd.h gdb-7.7/bfd/libbfd.h
--- gdb-7.7.orig/bfd/libbfd.h	2014-02-06 03:21:29.000000000 +0100
+++ gdb-7.7/bfd/libbfd.h	2014-03-26 20:02:00.000000000 +0100
@@ -2615,6 +2615,7 @@
   "BFD_RELOC_MICROBLAZE_32_ROSDA",
   "BFD_RELOC_MICROBLAZE_32_RWSDA",
   "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
+  "BFD_RELOC_MICROBLAZE_32_NONE",
   "BFD_RELOC_MICROBLAZE_64_NONE",
   "BFD_RELOC_MICROBLAZE_64_GOTPC",
   "BFD_RELOC_MICROBLAZE_64_GOT",
diff -Nur gdb-7.7.orig/gdb/Makefile.in gdb-7.7/gdb/Makefile.in
--- gdb-7.7.orig/gdb/Makefile.in	2014-02-06 03:21:29.000000000 +0100
+++ gdb-7.7/gdb/Makefile.in	2014-03-26 20:33:32.000000000 +0100
@@ -849,7 +849,7 @@
 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 microblaze-tdep.h \
+gdb_usleep.h jit.h xml-syscall.h microblaze-tdep.h microblaze-linux-tdep.h \
 psymtab.h psympriv.h progspace.h bfin-tdep.h ia64-hpux-tdep.h \
 amd64-darwin-tdep.h charset-list.h \
 config/djgpp/langinfo.h config/djgpp/nl_types.h darwin-nat.h \
@@ -1547,7 +1547,7 @@
 	m68kbsd-nat.c m68kbsd-tdep.c \
 	m68klinux-nat.c m68klinux-tdep.c \
 	m88k-tdep.c m88kbsd-nat.c \
-	microblaze-tdep.c microblaze-linux-tdep.c \
+	microblaze-tdep.c microblaze-linux-nat.c microblaze-linux-tdep.c \
 	mingw-hdep.c \
 	mips-linux-nat.c mips-linux-tdep.c \
 	mips-irix-tdep.c \
diff -Nur gdb-7.7.orig/gdb/config/microblaze/linux.mh gdb-7.7/gdb/config/microblaze/linux.mh
--- gdb-7.7.orig/gdb/config/microblaze/linux.mh	1970-01-01 01:00:00.000000000 +0100
+++ gdb-7.7/gdb/config/microblaze/linux.mh	2014-03-24 15:52:56.000000000 +0100
@@ -0,0 +1,10 @@
+# Host: Microblaze, running Linux
+
+NAT_FILE= config/nm-linux.h
+NATDEPFILES= inf-ptrace.o fork-child.o \
+	microblaze-linux-nat.o proc-service.o linux-thread-db.o \
+	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o \
+	linux-waitpid.o
+NAT_CDEPS = $(srcdir)/proc-service.list
+
+LOADLIBES = -ldl $(RDYNAMIC)
diff -Nur gdb-7.7.orig/gdb/configure.host gdb-7.7/gdb/configure.host
--- gdb-7.7.orig/gdb/configure.host	2013-12-08 05:55:47.000000000 +0100
+++ gdb-7.7/gdb/configure.host	2014-03-26 20:34:44.000000000 +0100
@@ -59,6 +59,7 @@
 m68*)			gdb_host_cpu=m68k ;;
 m88*)			gdb_host_cpu=m88k ;;
 mips*)			gdb_host_cpu=mips ;;
+microblaze*)		gdb_host_cpu=microblaze ;;
 powerpc* | rs6000)	gdb_host_cpu=powerpc ;;
 sparcv9 | sparc64)	gdb_host_cpu=sparc ;;
 s390*)			gdb_host_cpu=s390 ;;
@@ -133,6 +134,8 @@
 			gdb_host=nbsd ;;
 mips64*-*-openbsd*)	gdb_host=obsd64 ;;
 
+microblaze*-*linux*)    gdb_host=linux ;;
+
 powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*)
 			gdb_host=aix ;;
 powerpc*-*-freebsd*)	gdb_host=fbsd ;;
diff -Nur gdb-7.7.orig/gdb/configure.tgt gdb-7.7/gdb/configure.tgt
--- gdb-7.7.orig/gdb/configure.tgt	2014-02-06 03:21:29.000000000 +0100
+++ gdb-7.7/gdb/configure.tgt	2014-03-26 20:36:23.000000000 +0100
@@ -340,9 +340,10 @@
 
 microblaze*-linux-*|microblaze*-*-linux*)
 	# Target: Xilinx MicroBlaze running Linux
-	gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o microblaze-rom.o \
+	gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o microblaze-rom.o glibc-tdep.o \
 			monitor.o dsrec.o solib-svr4.o symfile-mem.o linux-tdep.o"
 	gdb_sim=../sim/microblaze/libsim.a
+	build_gdbserver=yes
 	;;
 microblaze*-*-*)
 	# Target: Xilinx MicroBlaze running standalone
diff -Nur gdb-7.7.orig/gdb/gdbserver/Makefile.in gdb-7.7/gdb/gdbserver/Makefile.in
--- gdb-7.7.orig/gdb/gdbserver/Makefile.in	2014-02-06 03:21:29.000000000 +0100
+++ gdb-7.7/gdb/gdbserver/Makefile.in	2014-03-26 20:39:22.000000000 +0100
@@ -148,6 +148,7 @@
 	$(srcdir)/linux-ia64-low.c $(srcdir)/linux-low.c \
 	$(srcdir)/linux-m32r-low.c \
 	$(srcdir)/linux-m68k-low.c $(srcdir)/linux-mips-low.c \
+	$(srcdir)/linux-microblaze-low.c \
 	$(srcdir)/linux-nios2-low.c \
 	$(srcdir)/linux-ppc-low.c \
 	$(srcdir)/linux-s390-low.c \
@@ -328,6 +329,7 @@
 	rm -f arm-with-iwmmxt.c
 	rm -f arm-with-vfpv2.c arm-with-vfpv3.c arm-with-neon.c
 	rm -f mips-linux.c mips64-linux.c
+	rm -f microblaze-linux.c
 	rm -f nios2-linux.c
 	rm -f powerpc-32.c powerpc-32l.c powerpc-64l.c powerpc-e500l.c
 	rm -f powerpc-altivec32l.c powerpc-cell32l.c powerpc-vsx32l.c
@@ -600,6 +602,8 @@
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/mips64-linux.dat mips64-linux.c
 mips64-dsp-linux.c : $(srcdir)/../regformats/mips64-dsp-linux.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/mips64-dsp-linux.dat mips64-dsp-linux.c
+microblaze-linux.c : $(srcdir)/../regformats/reg-microblaze.dat $(regdat_sh)
+	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-microblaze.dat microblaze-linux.c
 nios2-linux.c :	$(srcdir)/../regformats/nios2-linux.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/nios2-linux.dat nios2-linux.c
 powerpc-32.c : $(srcdir)/../regformats/rs6000/powerpc-32.dat $(regdat_sh)
diff -Nur gdb-7.7.orig/gdb/gdbserver/configure.srv gdb-7.7/gdb/gdbserver/configure.srv
--- gdb-7.7.orig/gdb/gdbserver/configure.srv	2014-01-08 10:23:36.000000000 +0100
+++ gdb-7.7/gdb/gdbserver/configure.srv	2014-03-26 20:40:44.000000000 +0100
@@ -198,6 +198,13 @@
 			srv_linux_usrregs=yes
 			srv_linux_thread_db=yes
 			;;
+  microblaze*-*-linux*)	srv_regobj=microblaze-linux.o
+			srv_tgtobj="$srv_linux_obj linux-microblaze-low.o"
+			srv_linux_usrregs=yes
+			srv_linux_regsets=yes
+			srv_linux_thread_db=yes
+			;;
+
   nios2*-*-linux*)	srv_regobj="nios2-linux.o"
 			srv_tgtobj="$srv_linux_obj linux-nios2-low.o"
 			srv_xmlfiles="nios2-linux.xml"
diff -Nur gdb-7.7.orig/gdb/gdbserver/linux-microblaze-low.c gdb-7.7/gdb/gdbserver/linux-microblaze-low.c
--- gdb-7.7.orig/gdb/gdbserver/linux-microblaze-low.c	1970-01-01 01:00:00.000000000 +0100
+++ gdb-7.7/gdb/gdbserver/linux-microblaze-low.c	2014-03-26 20:41:13.000000000 +0100
@@ -0,0 +1,228 @@
+/* GNU/Linux/Microblaze specific low level interface, for the remote server for
+   GDB.
+   Copyright (C) 1995-2013 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 <asm/ptrace.h>
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+
+#include "gdb_proc_service.h"
+
+static int microblaze_regmap[] =
+ {PT_GPR(0),     PT_GPR(1),     PT_GPR(2),     PT_GPR(3),
+  PT_GPR(4),     PT_GPR(5),     PT_GPR(6),     PT_GPR(7),
+  PT_GPR(8),     PT_GPR(9),     PT_GPR(10),    PT_GPR(11),
+  PT_GPR(12),    PT_GPR(13),    PT_GPR(14),    PT_GPR(15),
+  PT_GPR(16),    PT_GPR(17),    PT_GPR(18),    PT_GPR(19),
+  PT_GPR(20),    PT_GPR(21),    PT_GPR(22),    PT_GPR(23),
+  PT_GPR(24),    PT_GPR(25),    PT_GPR(26),    PT_GPR(27),
+  PT_GPR(28),    PT_GPR(29),    PT_GPR(30),    PT_GPR(31),
+  PT_PC,         PT_MSR,        PT_EAR,        PT_ESR,
+  PT_FSR
+  };
+
+#define microblaze_num_regs (sizeof microblaze_regmap / sizeof microblaze_regmap[0])
+
+/* Defined in auto-generated file microblaze-linux.c.  */
+void init_registers_microblaze (void);
+extern const struct target_desc *tdesc_microblaze;
+
+static int
+microblaze_cannot_store_register (int regno)
+{
+  if (microblaze_regmap[regno] == -1 || regno == 0)
+    return 1;
+
+  return 0;
+}
+
+static int
+microblaze_cannot_fetch_register (int regno)
+{
+  return 0;
+}
+
+static CORE_ADDR
+microblaze_get_pc (struct regcache *regcache)
+{
+  unsigned long pc;
+
+  collect_register_by_name (regcache, "pc", &pc);
+  return (CORE_ADDR) pc;
+}
+
+static void
+microblaze_set_pc (struct regcache *regcache, CORE_ADDR pc)
+{
+  unsigned long newpc = pc;
+
+  supply_register_by_name (regcache, "pc", &newpc);
+}
+
+/* dbtrap insn */
+/* brki r16, 0x18; */
+static const unsigned long microblaze_breakpoint = 0xba0c0018;
+#define microblaze_breakpoint_len 4
+
+static int
+microblaze_breakpoint_at (CORE_ADDR where)
+{
+  unsigned long insn;
+
+  (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
+  if (insn == microblaze_breakpoint)
+    return 1;
+  /* If necessary, recognize more trap instructions here.  GDB only uses the
+     one.  */
+  return 0;
+}
+
+static CORE_ADDR
+microblaze_reinsert_addr (struct regcache *regcache)
+{
+  unsigned long pc;
+  collect_register_by_name (regcache, "r15", &pc);
+  return pc;
+}
+
+#ifdef HAVE_PTRACE_GETREGS
+
+static void
+microblaze_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
+{
+  int size = register_size (regcache->tdesc, regno);
+
+  memset (buf, 0, sizeof (long));
+
+  if (size < sizeof (long))
+    collect_register (regcache, regno, buf + sizeof (long) - size);
+  else
+    collect_register (regcache, regno, buf);
+}
+
+static void
+microblaze_supply_ptrace_register (struct regcache *regcache,
+			    int regno, const char *buf)
+{
+  int size = register_size (regcache->tdesc, regno);
+
+  if (regno == 0) {
+    unsigned long regbuf_0 = 0;
+    /* clobbering r0 so that it is always 0 as enforced by hardware */
+    supply_register (regcache, regno, (const char*)&regbuf_0);
+  } else {
+      if (size < sizeof (long))
+        supply_register (regcache, regno, buf + sizeof (long) - size);
+      else
+        supply_register (regcache, regno, buf);
+  }
+}
+
+/* Provide only a fill function for the general register set.  ps_lgetregs
+   will use this for NPTL support.  */
+
+static void microblaze_fill_gregset (struct regcache *regcache, void *buf)
+{
+  int i;
+
+  for (i = 0; i < 32; i++)
+    microblaze_collect_ptrace_register (regcache, i, (char *) buf + microblaze_regmap[i]);
+}
+
+static void
+microblaze_store_gregset (struct regcache *regcache, const void *buf)
+{
+  int i;
+
+  for (i = 0; i < 32; i++)
+    supply_register (regcache, i, (char *) buf + microblaze_regmap[i]);
+}
+
+#endif /* HAVE_PTRACE_GETREGS */
+
+static struct regset_info microblaze_regsets[] = {
+#ifdef HAVE_PTRACE_GETREGS
+  { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t), GENERAL_REGS, microblaze_fill_gregset, microblaze_store_gregset },
+  { 0, 0, 0, -1, -1, NULL, NULL },
+#endif /* HAVE_PTRACE_GETREGS */
+  { 0, 0, 0, -1, -1, NULL, NULL }
+};
+
+static struct regsets_info microblaze_regsets_info =
+  {
+    microblaze_regsets, /* regsets */
+    0, /* num_regsets */
+    NULL, /* disabled_regsets */
+  };
+
+static struct usrregs_info microblaze_usrregs_info =
+  {
+    microblaze_num_regs,
+    microblaze_regmap,
+  };
+
+static struct regs_info regs_info =
+  {
+    NULL, /* regset_bitmap */
+    &microblaze_usrregs_info,
+    &microblaze_regsets_info
+  };
+
+static const struct regs_info *
+microblaze_regs_info (void)
+{
+  return &regs_info;
+}
+
+static void
+microblaze_arch_setup (void)
+{
+  current_process ()->tdesc = tdesc_microblaze;
+}
+
+struct linux_target_ops the_low_target = {
+  microblaze_arch_setup,
+  microblaze_regs_info,
+  microblaze_cannot_fetch_register,
+  microblaze_cannot_store_register,
+  NULL, /* fetch_register */
+  microblaze_get_pc,
+  microblaze_set_pc,
+  (const unsigned char *) &microblaze_breakpoint,
+  microblaze_breakpoint_len,
+  microblaze_reinsert_addr,
+  0,
+  microblaze_breakpoint_at,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  microblaze_collect_ptrace_register,
+  microblaze_supply_ptrace_register,
+};
+
+void
+initialize_low_arch (void)
+{
+  init_registers_microblaze ();
+
+  initialize_regsets_info (&microblaze_regsets_info);
+}
\ No newline at end of file
diff -Nur gdb-7.7.orig/gdb/microblaze-linux-nat.c gdb-7.7/gdb/microblaze-linux-nat.c
--- gdb-7.7.orig/gdb/microblaze-linux-nat.c	1970-01-01 01:00:00.000000000 +0100
+++ gdb-7.7/gdb/microblaze-linux-nat.c	2014-03-27 09:51:56.000000000 +0100
@@ -0,0 +1,430 @@
+/* Microblaze GNU/Linux native support.
+
+   Copyright (C) 1988-1989, 1991-1992, 1994, 1996, 2000-2012 Free
+   Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 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 "arch-utils.h"
+#include "dis-asm.h"
+#include "frame.h"
+#include "trad-frame.h"
+#include "symtab.h"
+#include "value.h"
+#include "gdbcmd.h"
+#include "breakpoint.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "target.h"
+#include "frame.h"
+#include "frame-base.h"
+#include "frame-unwind.h"
+#include "dwarf2-frame.h"
+#include "osabi.h"
+
+#include "gdb_assert.h"
+#include "target-descriptions.h"
+#include "opcodes/microblaze-opcm.h"
+#include "opcodes/microblaze-dis.h"
+
+#include "linux-nat.h"
+#include "target-descriptions.h"
+
+#include <sys/user.h>
+#include <sys/utsname.h>
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+#include "microblaze-tdep.h"
+
+#include <elf/common.h>
+#include "auxv.h"
+
+/* Defines ps_err_e, struct ps_prochandle.  */
+#include "gdb_proc_service.h"
+
+/* On GNU/Linux, threads are implemented as pseudo-processes, in which
+   case we may be tracing more than one process at a time.  In that
+   case, inferior_ptid will contain the main process ID and the
+   individual thread (process) ID.  get_thread_id () is used to get
+   the thread id if it's available, and the process id otherwise.  */
+
+int
+get_thread_id (ptid_t ptid)
+{
+  int tid = ptid_get_lwp (ptid);
+  if (0 == tid)
+    tid = ptid_get_pid (ptid);
+  return tid;
+}
+
+#define GET_THREAD_ID(PTID)	get_thread_id (PTID)
+
+/* Non-zero if our kernel may support the PTRACE_GETREGS and
+   PTRACE_SETREGS requests, for reading and writing the
+   general-purpose registers.  Zero if we've tried one of
+   them and gotten an error.  */
+int have_ptrace_getsetregs = 1;
+
+static int
+microblaze_register_u_addr (struct gdbarch *gdbarch, int regno)
+{
+  int u_addr = -1;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
+     interface, and not the wordsize of the program's ABI.  */
+  int wordsize = sizeof (long);
+
+  /* General purpose registers occupy 1 slot each in the buffer.  */
+  if (regno >= MICROBLAZE_R0_REGNUM
+      && regno <= MICROBLAZE_FSR_REGNUM)
+    u_addr = (regno * wordsize);
+
+  return u_addr;
+}
+
+
+static void
+fetch_register (struct regcache *regcache, int tid, int regno)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  /* This isn't really an address.  But ptrace thinks of it as one.  */
+  CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno);
+  int bytes_transferred;
+  unsigned int offset;         /* Offset of registers within the u area.  */
+  char buf[MAX_REGISTER_SIZE];
+
+  if (regaddr == -1)
+  {
+    memset (buf, '\0', register_size (gdbarch, regno));   /* Supply zeroes */
+    regcache_raw_supply (regcache, regno, buf);
+    return;
+  }
+
+  /* Read the raw register using sizeof(long) sized chunks.  On a
+     32-bit platform, 64-bit floating-point registers will require two
+     transfers.  */
+  for (bytes_transferred = 0;
+       bytes_transferred < register_size (gdbarch, regno);
+       bytes_transferred += sizeof (long))
+  {
+    long l;
+
+    errno = 0;
+    l = ptrace (PTRACE_PEEKUSER, tid, (PTRACE_TYPE_ARG3) regaddr, 0);
+    regaddr += sizeof (long);
+    if (errno != 0)
+    {
+      char message[128];
+      sprintf (message, "reading register %s (#%d)",
+               gdbarch_register_name (gdbarch, regno), regno);
+      perror_with_name (message);
+    }
+    memcpy (&buf[bytes_transferred], &l, sizeof (l));
+  }
+
+  /* Now supply the register.  Keep in mind that the regcache's idea
+     of the register's size may not be a multiple of sizeof
+     (long).  */
+  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+  {
+    /* Little-endian values are always found at the left end of the
+       bytes transferred.  */
+    regcache_raw_supply (regcache, regno, buf);
+  }
+  else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+  {
+    /* Big-endian values are found at the right end of the bytes
+       transferred.  */
+    size_t padding = (bytes_transferred - register_size (gdbarch, regno));
+    regcache_raw_supply (regcache, regno, buf + padding);
+  }
+  else
+    internal_error (__FILE__, __LINE__,
+                    _("fetch_register: unexpected byte order: %d"),
+                    gdbarch_byte_order (gdbarch));
+}
+
+/* This function actually issues the request to ptrace, telling
+   it to get all general-purpose registers and put them into the
+   specified regset.
+
+   If the ptrace request does not exist, this function returns 0
+   and properly sets the have_ptrace_* flag.  If the request fails,
+   this function calls perror_with_name.  Otherwise, if the request
+   succeeds, then the regcache gets filled and 1 is returned.  */
+static int
+fetch_all_gp_regs (struct regcache *regcache, int tid)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  gdb_gregset_t gregset;
+
+  if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0)
+  {
+    if (errno == EIO)
+    {
+      have_ptrace_getsetregs = 0;
+      return 0;
+    }
+    perror_with_name (_("Couldn't get general-purpose registers."));
+  }
+
+  supply_gregset (regcache, (const gdb_gregset_t *) &gregset);
+
+  return 1;
+}
+
+
+/* This is a wrapper for the fetch_all_gp_regs function.  It is
+   responsible for verifying if this target has the ptrace request
+   that can be used to fetch all general-purpose registers at one
+   shot.  If it doesn't, then we should fetch them using the
+   old-fashioned way, which is to iterate over the registers and
+   request them one by one.  */
+static void
+fetch_gp_regs (struct regcache *regcache, int tid)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int i;
+
+  if (have_ptrace_getsetregs)
+    if (fetch_all_gp_regs (regcache, tid))
+      return;
+
+  /* If we've hit this point, it doesn't really matter which
+     architecture we are using.  We just need to read the
+     registers in the "old-fashioned way".  */
+  for (i = MICROBLAZE_R0_REGNUM; i <= MICROBLAZE_FSR_REGNUM; i++)
+    fetch_register (regcache, tid, i);
+}
+
+
+static void
+store_register (const struct regcache *regcache, int tid, int regno)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  /* This isn't really an address.  But ptrace thinks of it as one.  */
+  CORE_ADDR regaddr = microblaze_register_u_addr (gdbarch, regno);
+  int i;
+  size_t bytes_to_transfer;
+  char buf[MAX_REGISTER_SIZE];
+
+  if (regaddr == -1)
+    return;
+
+  /* First collect the register.  Keep in mind that the regcache's
+     idea of the register's size may not be a multiple of sizeof
+     (long).  */
+  memset (buf, 0, sizeof buf);
+  bytes_to_transfer = align_up (register_size (gdbarch, regno), sizeof (long));
+  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+  {
+    /* Little-endian values always sit at the left end of the buffer.  */
+    regcache_raw_collect (regcache, regno, buf);
+  }
+  else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+  {
+    /* Big-endian values sit at the right end of the buffer.  */
+    size_t padding = (bytes_to_transfer - register_size (gdbarch, regno));
+    regcache_raw_collect (regcache, regno, buf + padding);
+  }
+
+  for (i = 0; i < bytes_to_transfer; i += sizeof (long))
+  {
+    long l;
+
+    memcpy (&l, &buf[i], sizeof (l));
+    errno = 0;
+    ptrace (PTRACE_POKEUSER, tid, (PTRACE_TYPE_ARG3) regaddr, l);
+    regaddr += sizeof (long);
+
+    if (errno != 0)
+    {
+      char message[128];
+      sprintf (message, "writing register %s (#%d)",
+               gdbarch_register_name (gdbarch, regno), regno);
+      perror_with_name (message);
+    }
+  }
+}
+
+/* This function actually issues the request to ptrace, telling
+   it to store all general-purpose registers present in the specified
+   regset.
+
+   If the ptrace request does not exist, this function returns 0
+   and properly sets the have_ptrace_* flag.  If the request fails,
+   this function calls perror_with_name.  Otherwise, if the request
+   succeeds, then the regcache is stored and 1 is returned.  */
+static int
+store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  gdb_gregset_t gregset;
+
+  if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0)
+    {
+      if (errno == EIO)
+      {
+        have_ptrace_getsetregs = 0;
+        return 0;
+      }
+      perror_with_name (_("Couldn't get general-purpose registers."));
+    }
+
+  fill_gregset (regcache, &gregset, regno);
+
+  if (ptrace (PTRACE_SETREGS, tid, 0, (void *) &gregset) < 0)
+    {
+      if (errno == EIO)
+      {
+        have_ptrace_getsetregs = 0;
+        return 0;
+      }
+      perror_with_name (_("Couldn't set general-purpose registers."));
+    }
+
+  return 1;
+}
+
+/* This is a wrapper for the store_all_gp_regs function.  It is
+   responsible for verifying if this target has the ptrace request
+   that can be used to store all general-purpose registers at one
+   shot.  If it doesn't, then we should store them using the
+   old-fashioned way, which is to iterate over the registers and
+   store them one by one.  */
+static void
+store_gp_regs (const struct regcache *regcache, int tid, int regno)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int i;
+
+  if (have_ptrace_getsetregs)
+    if (store_all_gp_regs (regcache, tid, regno))
+      return;
+
+  /* If we hit this point, it doesn't really matter which
+     architecture we are using.  We just need to store the
+     registers in the "old-fashioned way".  */
+  for (i = MICROBLAZE_R0_REGNUM; i <= MICROBLAZE_FSR_REGNUM; i++)
+    store_register (regcache, tid, i);
+}
+
+
+/* Fetch registers from the child process.  Fetch all registers if
+   regno == -1, otherwise fetch all general registers or all floating
+   point registers depending upon the value of regno.  */
+
+static void
+microblaze_linux_fetch_inferior_registers (struct target_ops *ops,
+				    struct regcache *regcache, int regno)
+{
+  /* Get the thread id for the ptrace call.  */
+  int tid = GET_THREAD_ID (inferior_ptid);
+
+  if (regno == -1)
+    fetch_gp_regs (regcache, tid);
+  else
+    fetch_register (regcache, tid, regno);
+}
+
+/* Store registers back into the inferior.  Store all registers if
+   regno == -1, otherwise store all general registers or all floating
+   point registers depending upon the value of regno.  */
+
+static void
+microblaze_linux_store_inferior_registers (struct target_ops *ops,
+				    struct regcache *regcache, int regno)
+{
+  /* Get the thread id for the ptrace call.  */
+  int tid = GET_THREAD_ID (inferior_ptid);
+
+  if (regno >= 0)
+    store_register (regcache, tid, regno);
+  else
+    store_gp_regs (regcache, tid, -1);
+}
+
+/* Wrapper functions for the standard regset handling, used by
+   thread debugging.  */
+
+void
+fill_gregset (const struct regcache *regcache,
+	      gdb_gregset_t *gregsetp, int regno)
+{
+  microblaze_collect_gregset (NULL, regcache, regno, gregsetp);
+}
+
+void
+supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
+{
+  microblaze_supply_gregset (NULL, regcache, -1, gregsetp);
+}
+
+void
+fill_fpregset (const struct regcache *regcache,
+	      gdb_fpregset_t *fpregsetp, int regno)
+{
+  /* FIXME. */
+}
+
+void
+supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
+{
+  /* FIXME. */
+}
+
+static const struct target_desc *
+microblaze_linux_read_description (struct target_ops *ops)
+{
+  CORE_ADDR microblaze_hwcap = 0;
+
+  if (target_auxv_search (ops, AT_HWCAP, &microblaze_hwcap) != 1)
+    return NULL;
+
+  return NULL;
+}
+
+
+void _initialize_microblaze_linux_nat (void);
+
+void
+_initialize_microblaze_linux_nat (void)
+{
+  struct target_ops *t;
+
+  /* Fill in the generic GNU/Linux methods.  */
+  t = linux_target ();
+
+  /* Add our register access methods.  */
+  t->to_fetch_registers = microblaze_linux_fetch_inferior_registers;
+  t->to_store_registers = microblaze_linux_store_inferior_registers;
+
+  t->to_read_description = microblaze_linux_read_description;
+
+  /* Register the target.  */
+  linux_nat_add_target (t);
+}
diff -Nur gdb-7.7.orig/gdb/microblaze-linux-tdep.c gdb-7.7/gdb/microblaze-linux-tdep.c
--- gdb-7.7.orig/gdb/microblaze-linux-tdep.c	2014-01-08 10:23:36.000000000 +0100
+++ gdb-7.7/gdb/microblaze-linux-tdep.c	2014-03-26 10:11:41.000000000 +0100
@@ -1,6 +1,6 @@
 /* Target-dependent code for Xilinx MicroBlaze.
 
-   Copyright (C) 2009-2014 Free Software Foundation, Inc.
+   Copyright (C) 2009-2013 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -32,11 +32,28 @@
 #include "regset.h"
 #include "solib-svr4.h"
 #include "microblaze-tdep.h"
+#include "glibc-tdep.h"
 #include "trad-frame.h"
 #include "frame-unwind.h"
 #include "tramp-frame.h"
 #include "linux-tdep.h"
 
+static int microblaze_debug_flag = 0;
+
+static void
+microblaze_debug (const char *fmt, ...)
+{
+  if (microblaze_debug_flag)
+    {
+       va_list args;
+
+       va_start (args, fmt);
+       printf_unfiltered ("MICROBLAZE LINUX: ");
+       vprintf_unfiltered (fmt, args);
+       va_end (args);
+    }
+}
+
 static int
 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch, 
 					   struct bp_target_info *bp_tgt)
@@ -46,20 +63,27 @@
   int val;
   int bplen;
   gdb_byte old_contents[BREAKPOINT_MAX];
+  struct cleanup *cleanup;
 
   /* Determine appropriate breakpoint contents and size for this address.  */
   bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
   if (bp == NULL)
     error (_("Software breakpoints not implemented for this target."));
 
+  /* Make sure we see the memory breakpoints.  */
+  cleanup = make_show_memory_breakpoints_cleanup (1);
   val = target_read_memory (addr, old_contents, bplen);
 
   /* If our breakpoint is no longer at the address, this means that the
      program modified the code on us, so it is wrong to put back the
      old value.  */
   if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
-    val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
+  {
+      val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
+      microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
+  }
 
+  do_cleanups (cleanup);
   return val;
 }
 
@@ -116,6 +140,43 @@
   microblaze_linux_sighandler_cache_init
 };
 
+const struct microblaze_gregset microblaze_linux_core_gregset;
+
+static void
+microblaze_linux_supply_core_gregset (const struct regset *regset,
+                                   struct regcache *regcache,
+                                   int regnum, const void *gregs, size_t len)
+{
+  microblaze_supply_gregset (&microblaze_linux_core_gregset, regcache,
+                             regnum, gregs);
+}
+
+static void
+microblaze_linux_collect_core_gregset (const struct regset *regset,
+                                    const struct regcache *regcache,
+                                    int regnum, void *gregs, size_t len)
+{
+  microblaze_collect_gregset (&microblaze_linux_core_gregset, regcache,
+                              regnum, gregs);
+}
+
+static void
+microblaze_linux_supply_core_fpregset (const struct regset *regset,
+                                    struct regcache *regcache,
+                                    int regnum, const void *fpregs, size_t len)
+{
+  /* FIXME.  */
+  microblaze_supply_fpregset (regcache, regnum, fpregs);
+}
+
+static void
+microblaze_linux_collect_core_fpregset (const struct regset *regset,
+                                     const struct regcache *regcache,
+                                     int regnum, void *fpregs, size_t len)
+{
+  /* FIXME.  */
+  microblaze_collect_fpregset (regcache, regnum, fpregs);
+}
 
 static void
 microblaze_linux_init_abi (struct gdbarch_info info,
@@ -123,6 +184,10 @@
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
+  tdep->gregset = regset_alloc (gdbarch, microblaze_linux_supply_core_gregset,
+                                microblaze_linux_collect_core_gregset);
+  tdep->sizeof_gregset = 200;
+
   linux_init_abi (info, gdbarch);
 
   set_gdbarch_memory_remove_breakpoint (gdbarch,
@@ -135,6 +200,25 @@
   /* Trampolines.  */
   tramp_frame_prepend_unwinder (gdbarch,
 				&microblaze_linux_sighandler_tramp_frame);
+
+  /* BFD target for core files.  */
+  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+    set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblaze");
+  else
+    set_gdbarch_gcore_bfd_target (gdbarch, "elf32-microblazeel");
+
+
+  /* Shared library handling.  */
+  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+  set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
+
+  set_gdbarch_regset_from_core_section (gdbarch,
+					microblaze_regset_from_core_section);
+
+  /* Enable TLS support.  */
+  set_gdbarch_fetch_tls_load_module_address (gdbarch,
+                                             svr4_fetch_objfile_link_map);
+
 }
 
 /* -Wmissing-prototypes */
diff -Nur gdb-7.7.orig/gdb/microblaze-rom.c gdb-7.7/gdb/microblaze-rom.c
--- gdb-7.7.orig/gdb/microblaze-rom.c	2014-01-08 10:23:36.000000000 +0100
+++ gdb-7.7/gdb/microblaze-rom.c	2014-03-27 08:56:48.000000000 +0100
@@ -1,6 +1,6 @@
 /* Remote debugging interface to Xilinx MicroBlaze.
 
-   Copyright (C) 2009-2014 Free Software Foundation, Inc.
+   Copyright (C) 2009-2013 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -21,7 +21,6 @@
 #include "gdbcore.h"
 #include "target.h"
 #include "monitor.h"
-#include <string.h>
 #include "serial.h"
 #include "regcache.h"
 
diff -Nur gdb-7.7.orig/gdb/microblaze-tdep.c gdb-7.7/gdb/microblaze-tdep.c
--- gdb-7.7.orig/gdb/microblaze-tdep.c	2014-02-06 03:21:29.000000000 +0100
+++ gdb-7.7/gdb/microblaze-tdep.c	2014-03-27 08:46:21.000000000 +0100
@@ -1,6 +1,6 @@
 /* Target-dependent code for Xilinx MicroBlaze.
 
-   Copyright (C) 2009-2014 Free Software Foundation, Inc.
+   Copyright (C) 2009-2013 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -29,13 +29,13 @@
 #include "inferior.h"
 #include "regcache.h"
 #include "target.h"
+#include "frame.h"
 #include "frame-base.h"
 #include "frame-unwind.h"
 #include "dwarf2-frame.h"
 #include "osabi.h"
 
 #include "gdb_assert.h"
-#include <string.h>
 #include "target-descriptions.h"
 #include "opcodes/microblaze-opcm.h"
 #include "opcodes/microblaze-dis.h"
@@ -73,7 +73,8 @@
   "rpc",  "rmsr", "rear", "resr", "rfsr", "rbtr",
   "rpvr0", "rpvr1", "rpvr2", "rpvr3", "rpvr4", "rpvr5", "rpvr6",
   "rpvr7", "rpvr8", "rpvr9", "rpvr10", "rpvr11",
-  "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi"
+  "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi",
+  "rslr", "rshr"
 };
 
 #define MICROBLAZE_NUM_REGS ARRAY_SIZE (microblaze_register_names)
@@ -145,6 +146,14 @@
   return sp;
 }
 
+static CORE_ADDR
+microblaze_store_arguments (struct regcache *regcache, int nargs,
+			    struct value **args, CORE_ADDR sp,
+			    int struct_return, CORE_ADDR struct_addr)
+{
+  error (_("store_arguments not implemented"));
+  return sp;
+}
 
 static CORE_ADDR
 microblaze_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
@@ -156,14 +165,52 @@
   return sp;
 }
 
+static int
+microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
+				    struct bp_target_info *bp_tgt)
+{
+  CORE_ADDR addr = bp_tgt->placed_address;
+  const unsigned char *bp;
+  int val;
+  int bplen;
+  gdb_byte old_contents[BREAKPOINT_MAX];
+  struct cleanup *cleanup;
+
+  /* Determine appropriate breakpoint contents and size for this address.  */
+  bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
+  if (bp == NULL)
+    error (_("Software breakpoints not implemented for this target."));
+
+  /* Make sure we see the memory breakpoints.  */
+  cleanup = make_show_memory_breakpoints_cleanup (1);
+  val = target_read_memory (addr, old_contents, bplen);
+
+  /* If our breakpoint is no longer at the address, this means that the
+     program modified the code on us, so it is wrong to put back the
+     old value.  */
+  if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
+  {
+    val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
+    microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
+  }
+
+  do_cleanups (cleanup);
+  return val;
+}
+
 static const gdb_byte *
 microblaze_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, 
 			       int *len)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   static gdb_byte break_insn[] = MICROBLAZE_BREAKPOINT;
+  static gdb_byte break_insn_le[] = MICROBLAZE_BREAKPOINT_LE;
 
   *len = sizeof (break_insn);
-  return break_insn;
+  if (byte_order == BFD_ENDIAN_BIG)
+    return break_insn;
+  else
+    return break_insn_le;
 }
 
 /* Allocate and initialize a frame cache.  */
@@ -178,6 +225,7 @@
   /* Base address.  */
   cache->base = 0;
   cache->pc = 0;
+  cache->saved_sp = 0;
 
   /* Frameless until proven otherwise.  */
   cache->frameless_p = 1;
@@ -234,6 +282,8 @@
   int flags = 0;
   int save_hidden_pointer_found = 0;
   int non_stack_instruction_found = 0;
+  int n_insns;
+  unsigned int *insn_block;
 
   /* Find the start of this function.  */
   find_pc_partial_function (pc, &name, &func_addr, &func_end);
@@ -273,11 +323,18 @@
 		    name, paddress (gdbarch, func_addr), 
 		    paddress (gdbarch, stop));
 
+/* Do a block read to minimize the transaction with the Debug Agent */
+  n_insns = (stop == func_addr) ? 1 : ((stop - func_addr) / INST_WORD_SIZE);
+  insn_block = calloc(n_insns, sizeof(unsigned long));
+
+  target_read_memory (func_addr, (void*) insn_block, n_insns * INST_WORD_SIZE );
+
   for (addr = func_addr; addr < stop; addr += INST_WORD_SIZE)
     {
       insn = microblaze_fetch_instruction (addr);
+      //insn = insn_block[(addr - func_addr) / INST_WORD_SIZE];
       op = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);
-      microblaze_debug ("%s %08lx\n", paddress (gdbarch, pc), insn);
+      microblaze_debug ("%s %08lx op=%x r%d r%d imm=%d\n", paddress (gdbarch, addr), insn, op, rd, ra, imm);
 
       /* This code is very sensitive to what functions are present in the
 	 prologue.  It assumes that the (addi, addik, swi, sw) can be the 
@@ -291,6 +348,7 @@
 	  cache->frameless_p = 0; /* Frame found.  */
 	  save_hidden_pointer_found = 0;
 	  non_stack_instruction_found = 0;
+	  cache->register_offsets[rd] = -imm;
 	  continue;
 	}
       else if (IS_SPILL_SP(op, rd, ra))
@@ -401,8 +459,8 @@
      part of the prologue.  */
   if (save_hidden_pointer_found)
     prologue_end_addr -= INST_WORD_SIZE;
-
-  return prologue_end_addr;
+    free(insn_block);
+    return prologue_end_addr;
 }
 
 static CORE_ADDR
@@ -452,6 +510,7 @@
   return start_pc;
 }
 
+enum { REG_UNAVAIL = (CORE_ADDR) -1 };
 /* Normal frames.  */
 
 static struct microblaze_frame_cache *
@@ -459,7 +518,7 @@
 {
   struct microblaze_frame_cache *cache;
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
-  CORE_ADDR func;
+  CORE_ADDR current_pc;
   int rn;
 
   if (*this_cache)
@@ -473,9 +532,18 @@
   for (rn = 0; rn < gdbarch_num_regs (gdbarch); rn++)
     cache->register_offsets[rn] = -1;
 
-  func = get_frame_func (next_frame);
+  cache->pc = get_frame_func (next_frame);
+  current_pc = get_frame_pc (next_frame);
+
+  if (cache->pc)
+    microblaze_analyze_prologue (gdbarch, cache->pc, current_pc,
+	                         cache);
 
-  cache->pc = get_frame_address_in_block (next_frame);
+  cache->base = get_frame_register_unsigned (next_frame, gdbarch_sp_regnum (gdbarch));
+  cache->saved_sp = cache->base + cache->framesize;
+
+  cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM] = cache->base;
+  cache->register_offsets[MICROBLAZE_SP_REGNUM] = cache->saved_sp;
 
   return cache;
 }
@@ -501,6 +569,14 @@
   struct microblaze_frame_cache *cache =
     microblaze_frame_cache (this_frame, this_cache);
 
+  if ((regnum == MICROBLAZE_SP_REGNUM &&
+      cache->register_offsets[MICROBLAZE_SP_REGNUM])
+      || (regnum == MICROBLAZE_FP_REGNUM &&
+      cache->register_offsets[MICROBLAZE_SP_REGNUM]))
+
+     return frame_unwind_got_constant (this_frame, regnum,
+                                       cache->register_offsets[MICROBLAZE_SP_REGNUM]);
+
   if (cache->frameless_p)
     {
       if (regnum == MICROBLAZE_PC_REGNUM)
@@ -508,11 +584,18 @@
       if (regnum == MICROBLAZE_SP_REGNUM)
         regnum = 1;
       return trad_frame_get_prev_register (this_frame,
-					   cache->saved_regs, regnum);
+            cache->saved_regs, regnum);
     }
-  else
-    return trad_frame_get_prev_register (this_frame, cache->saved_regs,
-					 regnum);
+
+  if (regnum == MICROBLAZE_PC_REGNUM)
+    {
+      regnum = 15;
+      return frame_unwind_got_memory (this_frame, regnum,
+                                      cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM]);
+    }
+
+  return trad_frame_get_prev_register (this_frame, cache->saved_regs,
+					regnum);
 
 }
 
@@ -536,6 +619,12 @@
   return cache->base;
 }
 
+static const struct frame_unwind *
+microblaze_frame_sniffer (struct frame_info *next_frame)
+{
+  return &microblaze_frame_unwind;
+}
+
 static const struct frame_base microblaze_frame_base =
 {
   &microblaze_frame_unwind,
@@ -628,6 +717,109 @@
   return (TYPE_LENGTH (type) == 16);
 }
 
+int
+microblaze_software_single_step (struct frame_info *frame)
+{
+  struct gdbarch *arch = get_frame_arch (frame);
+  struct address_space *aspace = get_frame_address_space (frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
+  static char le_breakp[] = MICROBLAZE_BREAKPOINT_LE;
+  static char be_breakp[] = MICROBLAZE_BREAKPOINT;
+  enum bfd_endian byte_order = gdbarch_byte_order (arch);
+  char *breakp = byte_order == BFD_ENDIAN_BIG ? be_breakp : le_breakp;
+  int ret = 0;
+
+  /* Save the address and the values of the next_pc and the target */
+  static struct sstep_breaks
+  {
+    CORE_ADDR address;
+    bfd_boolean valid;
+    /* Shadow contents.  */
+    char data[INST_WORD_SIZE];
+  } stepbreaks[2];
+  int ii;
+
+  if (1)
+    {
+      CORE_ADDR pc;
+      long insn;
+      enum microblaze_instr minstr;
+      bfd_boolean isunsignednum;
+      enum microblaze_instr_type insn_type;
+      short delay_slots;
+      int imm;
+      bfd_boolean immfound = FALSE;
+
+      /* Set a breakpoint at the next instruction */
+      /* If the current instruction is an imm, set it at the inst after */
+      /* If the instruction has a delay slot, skip the delay slot */
+      pc = get_frame_pc (frame);
+      insn = microblaze_fetch_instruction (pc);
+      minstr = get_insn_microblaze (insn, &isunsignednum, &insn_type, &delay_slots);
+      if (insn_type == immediate_inst)
+	{
+	  int rd, ra, rb;
+	  immfound = TRUE;
+	  minstr = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);
+	  pc = pc + INST_WORD_SIZE;
+	  insn = microblaze_fetch_instruction (pc);
+	  minstr = get_insn_microblaze (insn, &isunsignednum, &insn_type, &delay_slots);
+	}
+      stepbreaks[0].address = pc + (delay_slots * INST_WORD_SIZE) + INST_WORD_SIZE;
+      if (insn_type != return_inst) {
+	stepbreaks[0].valid = TRUE;
+      } else {
+	stepbreaks[0].valid = FALSE;
+      }
+
+      microblaze_debug ("single-step insn_type=%x insn=%x\n", insn_type, insn);
+      /* Now check for branch or return instructions */
+      if (insn_type == branch_inst || insn_type == return_inst) {
+	int limm;
+	int lrd, lra, lrb;
+	int ra, rb;
+	bfd_boolean targetvalid;
+	bfd_boolean unconditionalbranch;
+	microblaze_decode_insn(insn, &lrd, &lra, &lrb, &limm);
+	if (lra >= 0 && lra < MICROBLAZE_NUM_REGS)
+	  ra = get_frame_register_unsigned (frame, lra);
+	else
+	  ra = 0;
+	if (lrb >= 0 && lrb < MICROBLAZE_NUM_REGS)
+	  rb = get_frame_register_unsigned (frame, lrb);
+	else
+	  rb = 0;
+
+	stepbreaks[1].address = microblaze_get_target_address (insn, immfound, imm, pc, ra, rb, &targetvalid, &unconditionalbranch);
+	microblaze_debug ("single-step uncondbr=%d targetvalid=%d target=%x\n", unconditionalbranch, targetvalid, stepbreaks[1].address);
+
+	if (unconditionalbranch)
+	  stepbreaks[0].valid = FALSE; /* This is a unconditional branch: will not come to the next address */
+	if (targetvalid && (stepbreaks[0].valid == FALSE ||
+			    (stepbreaks[0].address != stepbreaks[1].address))
+			&& (stepbreaks[1].address != pc)) {
+	  stepbreaks[1].valid = TRUE;
+	} else {
+	  stepbreaks[1].valid = FALSE;
+	}
+      } else {
+	stepbreaks[1].valid = FALSE;
+      }
+
+      /* Insert the breakpoints */
+      for (ii = 0; ii < 2; ++ii)
+        {
+
+          /* ignore invalid breakpoint. */
+          if (stepbreaks[ii].valid) {
+            insert_single_step_breakpoint (arch, aspace, stepbreaks[ii].address);
+            ret = 1;
+	  }
+	}
+    }
+    return ret;
+}
+
 static void
 microblaze_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
@@ -664,6 +856,70 @@
   return dwarf2_to_reg_map[reg];
 }
 
+
+void
+microblaze_supply_gregset (const struct microblaze_gregset *gregset,
+                        struct regcache *regcache,
+                        int regnum, const void *gregs)
+{
+  unsigned int *regs = gregs;
+  if (regnum >= 0)
+    regcache_raw_supply (regcache, regnum, regs + regnum);
+
+  if (regnum == -1) {
+    int i;
+
+    for (i = 0; i < 50; i++) {
+      regcache_raw_supply (regcache, i, regs + i);
+    }
+  }
+}
+
+
+void
+microblaze_collect_gregset (const struct microblaze_gregset *gregset,
+                         const struct regcache *regcache,
+                         int regnum, void *gregs)
+{
+   /* FIXME.  */
+}
+
+void
+microblaze_supply_fpregset (struct regcache *regcache,
+                         int regnum, const void *fpregs)
+{
+   /* FIXME.  */
+}
+
+void
+microblaze_collect_fpregset (const struct regcache *regcache,
+                          int regnum, void *fpregs)
+{
+   /* FIXME.  */
+}
+
+
+/* Return the appropriate register set for the core section identified
+   by SECT_NAME and SECT_SIZE.  */
+
+const struct regset *
+microblaze_regset_from_core_section (struct gdbarch *gdbarch,
+                                     const char *sect_name, size_t sect_size)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  microblaze_debug ("microblaze_regset_from_core_section, sect_name = %s\n", sect_name);
+
+  if (strcmp (sect_name, ".reg") == 0 && sect_size >= tdep->sizeof_gregset)
+    return tdep->gregset;
+
+  if (strcmp (sect_name, ".reg2") == 0 && sect_size >= tdep->sizeof_fpregset)
+    return tdep->fpregset;
+
+  microblaze_debug ("microblaze_regset_from_core_section returning null :-( \n");
+  return NULL;
+}
+
 static struct gdbarch *
 microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
@@ -679,6 +935,11 @@
   tdep = XMALLOC (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
 
+  tdep->gregset = NULL;
+  tdep->sizeof_gregset = 0;
+  tdep->fpregset = NULL;
+  tdep->sizeof_fpregset = 0;
+
   set_gdbarch_long_double_bit (gdbarch, 128);
 
   set_gdbarch_num_regs (gdbarch, MICROBLAZE_NUM_REGS);
@@ -706,7 +967,10 @@
   /* Stack grows downward.  */
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
 
+  set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
+
   set_gdbarch_breakpoint_from_pc (gdbarch, microblaze_breakpoint_from_pc);
+  set_gdbarch_software_single_step (gdbarch, microblaze_software_single_step);
 
   set_gdbarch_frame_args_skip (gdbarch, 8);
 
@@ -725,6 +989,13 @@
   dwarf2_append_unwinders (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &microblaze_frame_unwind);
   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
+  //frame_base_append_sniffer (gdbarch, microblaze_frame_sniffer);
+
+  /* If we have register sets, enable the generic core file support.  */
+  if (tdep->gregset) {
+      set_gdbarch_regset_from_core_section (gdbarch,
+                                          microblaze_regset_from_core_section);
+  }
 
   return gdbarch;
 }
diff -Nur gdb-7.7.orig/gdb/microblaze-tdep.h gdb-7.7/gdb/microblaze-tdep.h
--- gdb-7.7.orig/gdb/microblaze-tdep.h	2014-01-08 10:23:36.000000000 +0100
+++ gdb-7.7/gdb/microblaze-tdep.h	2014-03-26 10:11:41.000000000 +0100
@@ -1,6 +1,6 @@
 /* Target-dependent code for Xilinx MicroBlaze.
 
-   Copyright (C) 2009-2014 Free Software Foundation, Inc.
+   Copyright (C) 2009-2013 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -22,8 +22,22 @@
 
 
 /* Microblaze architecture-specific information.  */
+struct microblaze_gregset
+{
+   unsigned int gregs[32];
+   unsigned int fpregs[32];
+   unsigned int pregs[16];
+};
+
 struct gdbarch_tdep
 {
+  int dummy;		// declare something.
+
+  /* Register sets.  */
+  struct regset *gregset;
+  size_t sizeof_gregset;
+  struct regset *fpregset;
+  size_t sizeof_fpregset;
 };
 
 struct microblaze_frame_cache
@@ -42,7 +56,8 @@
   int fp_regnum;
 
   /* Offsets to saved registers.  */
-  int register_offsets[57];	/* Must match MICROBLAZE_NUM_REGS.  */
+  int register_offsets[59];	/* Must match MICROBLAZE_NUM_REGS.  */
+  CORE_ADDR saved_sp;
 
   /* Table of saved registers.  */
   struct trad_frame_saved_reg *saved_regs;
@@ -66,11 +81,11 @@
   MICROBLAZE_R12_REGNUM,
   MICROBLAZE_R13_REGNUM,
   MICROBLAZE_R14_REGNUM,
-  MICROBLAZE_R15_REGNUM,
+  MICROBLAZE_R15_REGNUM, MICROBLAZE_PREV_PC_REGNUM = MICROBLAZE_R15_REGNUM,
   MICROBLAZE_R16_REGNUM,
   MICROBLAZE_R17_REGNUM,
   MICROBLAZE_R18_REGNUM,
-  MICROBLAZE_R19_REGNUM,
+  MICROBLAZE_R19_REGNUM, MICROBLAZE_FP_REGNUM = MICROBLAZE_R19_REGNUM,
   MICROBLAZE_R20_REGNUM,
   MICROBLAZE_R21_REGNUM,
   MICROBLAZE_R22_REGNUM,
@@ -107,7 +122,9 @@
   MICROBLAZE_RTLBX_REGNUM,
   MICROBLAZE_RTLBSX_REGNUM,
   MICROBLAZE_RTLBLO_REGNUM,
-  MICROBLAZE_RTLBHI_REGNUM
+  MICROBLAZE_RTLBHI_REGNUM,
+  MICROBLAZE_SLR_REGNUM,
+  MICROBLAZE_SHR_REGNUM
 };
 
 /* All registers are 32 bits.  */
@@ -115,6 +132,21 @@
 
 /* MICROBLAZE_BREAKPOINT defines the breakpoint that should be used.
    Only used for native debugging.  */
-#define MICROBLAZE_BREAKPOINT {0xb9, 0xcc, 0x00, 0x60}
+#define MICROBLAZE_BREAKPOINT {0xba, 0x0c, 0x00, 0x18}
+#define MICROBLAZE_BREAKPOINT_LE {0x18, 0x00, 0x0c, 0xba}
+
+extern void microblaze_supply_gregset (const struct microblaze_gregset *gregset,
+                                    struct regcache *regcache,
+                                    int regnum, const void *gregs);
+extern void microblaze_collect_gregset (const struct microblaze_gregset *gregset,
+                                     const struct regcache *regcache,
+                                     int regnum, void *gregs);
+extern void microblaze_supply_fpregset (struct regcache *regcache,
+                                     int regnum, const void *fpregs);
+extern void microblaze_collect_fpregset (const struct regcache *regcache,
+                                      int regnum, void *fpregs);
+
+extern const struct regset * microblaze_regset_from_core_section (struct gdbarch *gdbarch,
+                                     const char *sect_name, size_t sect_size);
 
 #endif /* microblaze-tdep.h */
diff -Nur gdb-7.7.orig/gdb/regformats/reg-microblaze.dat gdb-7.7/gdb/regformats/reg-microblaze.dat
--- gdb-7.7.orig/gdb/regformats/reg-microblaze.dat	1970-01-01 01:00:00.000000000 +0100
+++ gdb-7.7/gdb/regformats/reg-microblaze.dat	2014-03-26 20:43:54.000000000 +0100
@@ -0,0 +1,41 @@
+name:microblaze
+expedite:r1,pc
+32:r0
+32:r1
+32:r2
+32:r3
+32:r4
+32:r5
+32:r6
+32:r7
+32:r8
+32:r9
+32:r10
+32:r11
+32:r12
+32:r13
+32:r14
+32:r15
+32:r16
+32:r17
+32:r18
+32:r19
+32:r20
+32:r21
+32:r22
+32:r23
+32:r24
+32:r25
+32:r26
+32:r27
+32:r28
+32:r29
+32:r30
+32:r31
+32:pc
+32:msr
+32:ear
+32:esr
+32:fsr
+32:slr
+32:shr
diff -Nur gdb-7.7.orig/include/elf/microblaze.h gdb-7.7/include/elf/microblaze.h
--- gdb-7.7.orig/include/elf/microblaze.h	2013-12-08 05:11:51.000000000 +0100
+++ gdb-7.7/include/elf/microblaze.h	2014-03-26 20:44:34.000000000 +0100
@@ -58,6 +58,7 @@
   RELOC_NUMBER (R_MICROBLAZE_TLSDTPREL64, 27)   /* TLS Offset Within TLS Block */
   RELOC_NUMBER (R_MICROBLAZE_TLSGOTTPREL32, 28) /* TLS Offset From Thread Pointer */
   RELOC_NUMBER (R_MICROBLAZE_TLSTPREL32, 29)    /* TLS Offset From Thread Pointer */
+  RELOC_NUMBER (R_MICROBLAZE_32_NONE, 30)
    
 END_RELOC_NUMBERS (R_MICROBLAZE_max)
 
diff -Nur gdb-7.7.orig/opcodes/microblaze-opc.h gdb-7.7/opcodes/microblaze-opc.h
--- gdb-7.7.orig/opcodes/microblaze-opc.h	2013-12-08 05:11:52.000000000 +0100
+++ gdb-7.7/opcodes/microblaze-opc.h	2014-03-26 20:45:46.000000000 +0100
@@ -91,6 +91,7 @@
 #define OPCODE_MASK_H3  0xFC000600  /* High 6 bits and bits 21, 22.  */  
 #define OPCODE_MASK_H32 0xFC00FC00  /* High 6 bits and bit 16-21.  */
 #define OPCODE_MASK_H34B 0xFC0000FF /* High 6 bits and low 8 bits.  */
+#define OPCODE_MASK_H35B 0xFC0004FF /* High 6 bits and low 9 bits.  */
 #define OPCODE_MASK_H34C 0xFC0007E0 /* High 6 bits and bits 21-26.  */
 
 /* New Mask for msrset, msrclr insns.  */
@@ -101,7 +102,7 @@
 #define DELAY_SLOT 1
 #define NO_DELAY_SLOT 0
 
-#define MAX_OPCODES 289
+#define MAX_OPCODES 291
 
 struct op_code_struct
 {
@@ -174,7 +175,9 @@
   {"wic",   INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000068, OPCODE_MASK_H34B, wic, special_inst },
   {"wdc",   INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000064, OPCODE_MASK_H34B, wdc, special_inst },
   {"wdc.clear", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000066, OPCODE_MASK_H34B, wdcclear, special_inst },
+  {"wdc.ext.clear", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000466, OPCODE_MASK_H35B, wdcextclear, special_inst },
   {"wdc.flush", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000074, OPCODE_MASK_H34B, wdcflush, special_inst },
+  {"wdc.ext.flush", INST_TYPE_R1_R2_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x90000476, OPCODE_MASK_H35B, wdcextflush, special_inst },
   {"mts",   INST_TYPE_SPECIAL_R1, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MTS, 0x9400C000, OPCODE_MASK_H13S, mts, special_inst },
   {"mfs",   INST_TYPE_RD_SPECIAL, INST_NO_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_MFS, 0x94008000, OPCODE_MASK_H23S, mfs, special_inst },
   {"br",    INST_TYPE_R2, INST_PC_OFFSET, NO_DELAY_SLOT, IMMVAL_MASK_NON_SPECIAL, 0x98000000, OPCODE_MASK_H124, br, branch_inst },
diff -Nur gdb-7.7.orig/opcodes/microblaze-opcm.h gdb-7.7/opcodes/microblaze-opcm.h
--- gdb-7.7.orig/opcodes/microblaze-opcm.h	2013-12-08 05:11:52.000000000 +0100
+++ gdb-7.7/opcodes/microblaze-opcm.h	2014-03-26 20:45:46.000000000 +0100
@@ -31,9 +31,9 @@
   idiv, idivu, bsll, bsra, bsrl, get, put, nget, nput, cget, cput,
   ncget, ncput, muli, bslli, bsrai, bsrli, mului, or, and, xor,
   andn, pcmpbf, pcmpbc, pcmpeq, pcmpne, sra, src, srl, sext8, sext16, 
-  wic, wdc, wdcclear, wdcflush, mts, mfs, mbar, br, brd,
-  brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned, blt,
-  bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni,
+  wic, wdc, wdcclear, wdcextclear, wdcflush, wdcextflush, mts, mfs, mbar,
+  br, brd, brld, bra, brad, brald, microblaze_brk, beq, beqd, bne, bned,
+  blt, bltd, ble, bled, bgt, bgtd, bge, bged, ori, andi, xori, andni,
   imm, rtsd, rtid, rtbd, rted, bri, brid, brlid, brai, braid, bralid,
   brki, beqi, beqid, bnei, bneid, blti, bltid, blei, bleid, bgti,
   bgtid, bgei, bgeid, lbu, lbur, lhu, lhur, lw, lwr, lwx, sb, sbr, sh, 
