--- gdb-7.8.2.orig/gdb/gdbserver/linux-microblaze-low.c 1970-01-01 00:00:00.000000000 +0100
+++ gdb-7.8.2/gdb/gdbserver/linux-microblaze-low.c 2016-09-21 10:34:30.025222164 +0200
@@ -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 . */
+
+#include "server.h"
+#include "linux-low.h"
+
+#include
+#include
+#include
+
+#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*)®buf_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 */
+ µblaze_usrregs_info,
+ µblaze_regsets_info
+ };
+
+static const struct regs_info *
+microblaze_regs_info (void)
+{
+ return ®s_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 *) µblaze_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 (µblaze_regsets_info);
+}
\ No newline at end of file