Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH v2] gdb: bfin: new port
@ 2010-12-09  9:29 Mike Frysinger
  2010-12-09  9:31 ` [PATCH v2] gdbserver: " Mike Frysinger
                   ` (2 more replies)
  0 siblings, 3 replies; 34+ messages in thread
From: Mike Frysinger @ 2010-12-09  9:29 UTC (permalink / raw)
  To: gdb-patches; +Cc: toolchain-devel, Joel Brobecker, Jie Zhang

From: Jie Zhang <jie.zhang@analog.com>

Initial support for Blackfin processors.  This supports the standard ABI.

Signed-off-by: Jie Zhang <jie.zhang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>

2010-11-16  Jie Zhang  <jie.zhang@analog.com>

	* Makefile.in (ALLDEPFILES): Add bfin-tdep.c.
	(HFILES_NO_SRCDIR): Add bfin-tdep.h.
	* NEWS: Mention new Blackfin port.
	* bfin-tdep.c, bfin-tdep.h, config/bfin/bfin.mt: New files.
	* configure.tgt (bfin-*-*): Handle bfin targets.
---
v2
	- address feedback from Joel
	- split top level configure hunk
	- add linux syscall support

 gdb/Makefile.in             |    4 +-
 gdb/NEWS                    |    4 +
 gdb/bfin-tdep.c             | 1075 +++++++++++++++++++++++++++++++++++++++++++
 gdb/bfin-tdep.h             |  115 +++++
 gdb/config/bfin/bfin.mt     |    1 +
 gdb/configure.tgt           |    5 +
 gdb/syscalls/bfin-linux.xml |  326 +++++++++++++
 7 files changed, 1529 insertions(+), 1 deletions(-)
 create mode 100644 gdb/bfin-tdep.c
 create mode 100644 gdb/bfin-tdep.h
 create mode 100644 gdb/config/bfin/bfin.mt
 create mode 100644 gdb/syscalls/bfin-linux.xml

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index ff10039..5973c61 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -508,6 +508,7 @@ ALL_TARGET_OBS = \
 	armnbsd-tdep.o armobsd-tdep.o \
 	arm-tdep.o arm-wince-tdep.o \
 	avr-tdep.o \
+	bfin-tdep.o \
 	cris-tdep.o \
 	dicos-tdep.o \
 	frv-linux-tdep.o frv-tdep.o \
@@ -782,7 +783,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 ada-operator.inc microblaze-tdep.h \
-psymtab.h psympriv.h progspace.h
+psymtab.h psympriv.h progspace.h bfin-tdep.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -1420,6 +1421,7 @@ ALLDEPFILES = \
 	arm-linux-nat.c arm-linux-tdep.c arm-symbian-tdep.c arm-tdep.c \
 	armnbsd-nat.c armbsd-tdep.c armnbsd-tdep.c armobsd-tdep.c \
 	avr-tdep.c \
+	bfin-tdep.c \
 	bsd-uthread.c bsd-kvm.c \
 	core-regset.c corelow.c \
 	dcache.c dicos-tdep.c darwin-nat.c \
diff --git a/gdb/NEWS b/gdb/NEWS
index 9dfb249..ecc88c6 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -101,6 +101,10 @@
   ** GDBserver is now supported on PowerPC LynxOS (versions 4.x and 5.x),
      and i686 LynxOS (version 5.x).
 
+* New targets:
+
+Analog Devices, Inc. Blackfin Processor	bfin-*
+
 * Ada task switching is now supported on sparc-elf targets when
   debugging a program using the Ravenscar Profile.  For more information,
   see the "Tasking Support when using the Ravenscar Profile" section
diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
new file mode 100644
index 0000000..4725c66
--- /dev/null
+++ b/gdb/bfin-tdep.c
@@ -0,0 +1,1075 @@
+/* Target-dependent code for Analog Devices Blackfin processer, for GDB.
+
+   Copyright (C) 2005-2010 Free Software Foundation, Inc.
+   Contributed by Analog Devices.
+
+   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 "gdb_string.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "arch-utils.h"
+#include "regcache.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "frame-base.h"
+#include "trad-frame.h"
+#include "dis-asm.h"
+#include "gdb_assert.h"
+#include "dwarf2-frame.h"
+#include "symtab.h"
+#include "elf-bfd.h"
+#include "elf/bfin.h"
+#include "osabi.h"
+#include "infcall.h"
+#include "xml-syscall.h"
+#include "bfin-tdep.h"
+
+/* Macros used by prologue functions.  */
+#define P_LINKAGE			0xE800
+#define P_MINUS_SP1			0x0140
+#define P_MINUS_SP2			0x05C0
+#define P_MINUS_SP3			0x0540
+#define P_MINUS_SP4			0x04C0
+#define P_SP_PLUS			0x6C06
+#define P_P2_LOW			0xE10A
+#define P_P2_HIGH			0XE14A
+#define P_SP_EQ_SP_PLUS_P2		0X5BB2
+#define P_SP_EQ_P2_PLUS_SP		0x5B96
+#define P_MINUS_MINUS_SP_EQ_RETS	0x0167
+
+/* Macros used for program flow control.  */
+/* 16 bit instruction, max  */
+#define P_16_BIT_INSR_MAX		0xBFFF
+/* 32 bit instruction, min  */
+#define P_32_BIT_INSR_MIN		0xC000
+/* 32 bit instruction, max  */
+#define P_32_BIT_INSR_MAX		0xE801
+/* jump (preg), 16-bit, min  */
+#define P_JUMP_PREG_MIN			0x0050
+/* jump (preg), 16-bit, max  */
+#define P_JUMP_PREG_MAX			0x0057
+/* jump (pc+preg), 16-bit, min  */
+#define P_JUMP_PC_PLUS_PREG_MIN		0x0080
+/* jump (pc+preg), 16-bit, max  */
+#define P_JUMP_PC_PLUS_PREG_MAX		0x0087
+/* jump.s pcrel13m2, 16-bit, min  */
+#define P_JUMP_S_MIN			0x2000
+/* jump.s pcrel13m2, 16-bit, max  */
+#define P_JUMP_S_MAX			0x2FFF
+/* jump.l pcrel25m2, 32-bit, min  */
+#define P_JUMP_L_MIN			0xE200
+/* jump.l pcrel25m2, 32-bit, max  */
+#define P_JUMP_L_MAX			0xE2FF
+/* conditional jump pcrel11m2, 16-bit, min  */
+#define P_IF_CC_JUMP_MIN		0x1800
+/* conditional jump pcrel11m2, 16-bit, max  */
+#define P_IF_CC_JUMP_MAX		0x1BFF
+/* conditional jump(bp) pcrel11m2, 16-bit, min  */
+#define P_IF_CC_JUMP_BP_MIN		0x1C00
+/* conditional jump(bp) pcrel11m2, 16-bit, max  */
+#define P_IF_CC_JUMP_BP_MAX		0x1FFF
+/* conditional !jump pcrel11m2, 16-bit, min  */
+#define P_IF_NOT_CC_JUMP_MIN		0x1000
+/* conditional !jump pcrel11m2, 16-bit, max  */
+#define P_IF_NOT_CC_JUMP_MAX		0x13FF
+/* conditional jump(bp) pcrel11m2, 16-bit, min  */
+#define P_IF_NOT_CC_JUMP_BP_MIN		0x1400
+/* conditional jump(bp) pcrel11m2, 16-bit, max  */
+#define P_IF_NOT_CC_JUMP_BP_MAX		0x17FF
+/* call (preg), 16-bit, min  */
+#define P_CALL_PREG_MIN			0x0060
+/* call (preg), 16-bit, max  */
+#define P_CALL_PREG_MAX			0x0067
+/* call (pc+preg), 16-bit, min  */
+#define P_CALL_PC_PLUS_PREG_MIN		0x0070
+/* call (pc+preg), 16-bit, max  */
+#define P_CALL_PC_PLUS_PREG_MAX		0x0077
+/* call pcrel25m2, 32-bit, min  */
+#define P_CALL_MIN			0xE300
+/* call pcrel25m2, 32-bit, max  */
+#define P_CALL_MAX			0xE3FF
+/* RTS  */
+#define P_RTS				0x0010
+/* MNOP  */
+#define P_MNOP				0xC803
+/* EXCPT, 16-bit, min  */
+#define P_EXCPT_MIN			0x00A0
+/* EXCPT, 16-bit, max  */
+#define P_EXCPT_MAX			0x00AF
+/* multi instruction mask 1, 16-bit  */
+#define P_BIT_MULTI_INS_1		0xC000
+/* multi instruction mask 2, 16-bit  */
+#define P_BIT_MULTI_INS_2		0x0800
+
+/* Macros used for signal handling  */
+/* Instruction 1 for signal  */
+#define P_SIGNAL_INS_1			0x00ADE128
+/* Instruction 2 for signal  */
+#define P_SIGNAL_INS_2			0x000000A0
+
+/* The maximum bytes we search to skip the prologue.  */
+#define UPPER_LIMIT			40
+
+#define RETS_OFFSET			4
+
+/* Initial value: Register names used in BFIN's ISA documentation.  */
+
+static const char * const bfin_register_name_strings[] =
+{
+  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+  "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
+  "i0", "i1", "i2", "i3", "m0", "m1", "m2", "m3",
+  "b0", "b1", "b2", "b3", "l0", "l1", "l2", "l3",
+  "a0x", "a0w", "a1x", "a1w", "astat", "rets",
+  "lc0", "lt0", "lb0", "lc1", "lt1", "lb1", "cycles", "cycles2",
+  "usp", "seqstat", "syscfg", "reti", "retx", "retn", "rete",
+  "pc", "cc",
+  "text_addr", "text_end_addr", "data_addr", "fdpic_exec", "fdpic_interp",
+  "ipend"
+};
+
+#define NUM_BFIN_REGNAMES ARRAY_SIZE (bfin_register_name_strings)
+
+
+/* In this diagram successive memory locations increase downwards or the
+   stack grows upwards with negative indices.  (PUSH analogy for stack.)
+
+   The top frame is the "frame" of the current function being executed.
+
+     +--------------+ SP    -
+     |  local vars  |       ^
+     +--------------+       |
+     |  save regs   |       |
+     +--------------+ FP    |
+     |   old FP    -|--    top
+     +--------------+  |  frame
+     |    RETS      |  |    |
+     +--------------+  |    |
+     |   param 1    |  |    |
+     |   param 2    |  |    |
+     |    ...       |  |    V
+     +--------------+  |    -
+     |  local vars  |  |    ^
+     +--------------+  |    |
+     |  save regs   |  |    |
+     +--------------+<-     |
+     |   old FP    -|--   next
+     +--------------+  |  frame
+     |    RETS      |  |    |
+     +--------------+  |    |
+     |   param 1    |  |    |
+     |   param 2    |  |    |
+     |    ...       |  |    V
+     +--------------+  |    -
+     |  local vars  |  |    ^
+     +--------------+  |    |
+     |  save regs   |  |    |
+     +--------------+<-  next frame
+     |   old FP     |       |
+     +--------------+       |
+     |    RETS      |       V
+     +--------------+       -
+
+   The frame chain is formed as following:
+
+     FP has the topmost frame.
+     FP + 4 has the previous FP and so on.  */
+
+
+/* Map from DWARF2 register number to GDB register number.  */
+
+static const int map_gcc_gdb[] =
+{
+  BFIN_R0_REGNUM,
+  BFIN_R1_REGNUM,
+  BFIN_R2_REGNUM,
+  BFIN_R3_REGNUM,
+  BFIN_R4_REGNUM,
+  BFIN_R5_REGNUM,
+  BFIN_R6_REGNUM,
+  BFIN_R7_REGNUM,
+  BFIN_P0_REGNUM,
+  BFIN_P1_REGNUM,
+  BFIN_P2_REGNUM,
+  BFIN_P3_REGNUM,
+  BFIN_P4_REGNUM,
+  BFIN_P5_REGNUM,
+  BFIN_SP_REGNUM,
+  BFIN_FP_REGNUM,
+  BFIN_I0_REGNUM,
+  BFIN_I1_REGNUM,
+  BFIN_I2_REGNUM,
+  BFIN_I3_REGNUM,
+  BFIN_B0_REGNUM,
+  BFIN_B1_REGNUM,
+  BFIN_B2_REGNUM,
+  BFIN_B3_REGNUM,
+  BFIN_L0_REGNUM,
+  BFIN_L1_REGNUM,
+  BFIN_L2_REGNUM,
+  BFIN_L3_REGNUM,
+  BFIN_M0_REGNUM,
+  BFIN_M1_REGNUM,
+  BFIN_M2_REGNUM,
+  BFIN_M3_REGNUM,
+  BFIN_A0_DOT_X_REGNUM,
+  BFIN_A1_DOT_X_REGNUM,
+  BFIN_CC_REGNUM,
+  BFIN_RETS_REGNUM,
+  BFIN_RETI_REGNUM,
+  BFIN_RETX_REGNUM,
+  BFIN_RETN_REGNUM,
+  BFIN_RETE_REGNUM,
+  BFIN_ASTAT_REGNUM,
+  BFIN_SEQSTAT_REGNUM,
+  BFIN_USP_REGNUM,
+  BFIN_LT0_REGNUM,
+  BFIN_LT1_REGNUM,
+  BFIN_LC0_REGNUM,
+  BFIN_LC1_REGNUM,
+  BFIN_LB0_REGNUM,
+  BFIN_LB1_REGNUM
+};
+
+
+#define SIGCONTEXT_OFFSET	168
+
+
+/* From <asm/sigcontext.h>.  */
+
+static int bfin_linux_sigcontext_reg_offset[BFIN_NUM_REGS] =
+{
+  0 * 4,	/* %r0 */
+  1 * 4,	/* %r1 */
+  2 * 4,	/* %r2 */
+  3 * 4,	/* %r3 */
+  4 * 4,	/* %r4 */
+  5 * 4,	/* %r5 */
+  6 * 4,	/* %r6 */
+  7 * 4,	/* %r7 */
+  8 * 4,	/* %p0 */
+  9 * 4,	/* %p1 */
+  10 * 4,	/* %p2 */
+  11 * 4,	/* %p3 */
+  12 * 4,	/* %p4 */
+  13 * 4,	/* %p5 */
+  14 * 4,	/* %sp */
+  23 * 4,	/* %fp */
+  24 * 4,	/* %i0 */
+  25 * 4,	/* %i1 */
+  26 * 4,	/* %i2 */
+  27 * 4,	/* %i3 */
+  28 * 4,	/* %m0 */
+  29 * 4,	/* %m1 */
+  30 * 4,	/* %m2 */
+  31 * 4,	/* %m3 */
+  36 * 4,	/* %b0 */
+  37 * 4,	/* %b1 */
+  38 * 4,	/* %b2 */
+  39 * 4,	/* %b3 */
+  32 * 4,	/* %l0 */
+  33 * 4,	/* %l1 */
+  34 * 4,	/* %l2 */
+  35 * 4,	/* %l3 */
+  17 * 4,	/* %a0x */
+  15 * 4,	/* %a0w */
+  18 * 4,	/* %a1x */
+  16 * 4,	/* %a1w */
+  19 * 4,	/* %astat */
+  20 * 4,	/* %rets */
+  40 * 4,	/* %lc0 */
+  42 * 4,	/* %lt0 */
+  44 * 4,	/* %lb0 */
+  41 * 4,	/* %lc1 */
+  43 * 4,	/* %lt1 */
+  45 * 4,	/* %lb1 */
+  -1,		/* %cycles */
+  -1,		/* %cycles2 */
+  -1,		/* %usp */
+  46 * 4,	/* %seqstat */
+  -1,		/* syscfg */
+  21 * 4,	/* %reti */
+  22 * 4,	/* %retx */
+  -1,		/* %retn */
+  -1,		/* %rete */
+  21 * 4,	/* %pc */
+  -1,		/* %cc */
+  -1,		/* %text_addr */
+  -1,		/* %text_end_addr*/
+  -1,		/* %data_addr*/
+  -1		/* %ipend */
+};
+
+/* Get info about saved registers in sigtramp.  */
+
+struct bfin_linux_sigtramp_info
+{
+  /* Address of context.  */
+  CORE_ADDR context_addr;
+
+  /* Offset of registers in `struct sigcontext'.  */
+  int *sc_reg_offset;
+};
+
+/* Return nonzero if PC points into the signal trampoline.  For the
+   sake of bfin_linux_get_sigtramp_info.  */
+
+static int
+bfin_linux_pc_in_sigtramp (struct frame_info *this_frame, CORE_ADDR pc)
+{
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  gdb_byte buf[10];
+  gdb_byte *p;
+  unsigned long insn1, insn2;
+
+  if (pc > (CORE_ADDR) 0x7ffffffe
+      /* When the core is locked, the PC is unavailable.
+	 It makes no sense to check further.  */
+      || regcache_valid_p (get_current_regcache (), BFIN_PC_REGNUM) < 0
+      || !safe_frame_unwind_memory (this_frame, pc, buf + 4, 2))
+    return 0;
+
+  insn1 = extract_unsigned_integer (buf + 4, 2, byte_order);
+
+  if (insn1 == (P_SIGNAL_INS_1 & 0xffff))
+    {
+      if (pc > (CORE_ADDR) 0x7ffffffa
+	  || !safe_frame_unwind_memory (this_frame, pc + 2, buf + 6, 4))
+	return 0;
+      p = buf + 4;
+    }
+  else if (insn1 == P_SIGNAL_INS_2)
+    {
+      if (pc < (CORE_ADDR) 4
+	  || !safe_frame_unwind_memory (this_frame, pc - 4, buf, 4))
+	return 0;
+      p = buf;
+    }
+  else
+    return 0;
+
+  insn1 = extract_unsigned_integer (p, 4, byte_order);
+  insn2 = extract_unsigned_integer (p + 4, 2, byte_order);
+
+  if (insn1 == P_SIGNAL_INS_1 && insn2 == P_SIGNAL_INS_2)
+    return 1;
+
+  return 0;
+}
+
+static struct bfin_linux_sigtramp_info
+bfin_linux_get_sigtramp_info (struct frame_info *this_frame)
+{
+  CORE_ADDR sp;
+  int ret;
+  struct bfin_linux_sigtramp_info info;
+
+  sp = frame_unwind_register_unsigned (this_frame, BFIN_SP_REGNUM);
+  ret = bfin_linux_pc_in_sigtramp (this_frame, get_frame_pc (this_frame));
+
+  gdb_assert (ret == 1);
+
+  /* Get sigcontext address.  */
+  info.context_addr = sp + SIGCONTEXT_OFFSET;
+  info.sc_reg_offset = bfin_linux_sigcontext_reg_offset;
+
+  return info;
+}
+
+/* Signal trampolines.  */
+
+static struct trad_frame_cache *
+bfin_linux_sigtramp_frame_cache (struct frame_info *this_frame,
+				 void **this_cache)
+{
+  struct frame_id this_id;
+  struct trad_frame_cache *cache;
+  struct bfin_linux_sigtramp_info info;
+  CORE_ADDR sp;
+  int i;
+
+  if (*this_cache)
+    return *this_cache;
+
+  cache = trad_frame_cache_zalloc (this_frame);
+
+  /* The frame ID's code address should be the start-address of the
+     signal trampoline and not the current PC within that trampoline.  */
+  sp = get_frame_register_unsigned (this_frame, BFIN_SP_REGNUM);
+
+  /* This would come after the LINK instruction in the ret_from_signal
+     function, hence the frame id would be SP + 8.  */
+  this_id = frame_id_build (sp + 8, get_frame_pc (this_frame));
+  trad_frame_set_id (cache, this_id);
+
+  info = bfin_linux_get_sigtramp_info (this_frame);
+
+  for (i = 0; i < BFIN_NUM_REGS; i++)
+    if (info.sc_reg_offset[i] != -1)
+      trad_frame_set_reg_addr (cache, i,
+			       info.context_addr + info.sc_reg_offset[i]);
+
+  *this_cache = cache;
+  return cache;
+}
+
+static void
+bfin_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
+				   void **this_cache,
+				   struct frame_id *this_id)
+{
+  struct trad_frame_cache *cache;
+
+  cache = bfin_linux_sigtramp_frame_cache (this_frame, this_cache);
+  trad_frame_get_id (cache, this_id);
+}
+
+static struct value *
+bfin_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
+					 void **this_cache,
+					 int regnum)
+{
+  struct trad_frame_cache *cache;
+
+  cache = bfin_linux_sigtramp_frame_cache (this_frame, this_cache);
+  return trad_frame_get_register (cache, this_frame, regnum);
+}
+
+static int
+bfin_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
+				   struct frame_info *this_frame,
+				   void **this_cache)
+{
+  CORE_ADDR pc = get_frame_pc (this_frame);
+
+  if (bfin_linux_pc_in_sigtramp (this_frame, pc))
+    return 1;
+
+  return 0;
+}
+
+static const struct frame_unwind bfin_linux_sigtramp_frame_unwind =
+{
+  SIGTRAMP_FRAME,
+  bfin_linux_sigtramp_frame_this_id,
+  bfin_linux_sigtramp_frame_prev_register,
+  NULL,
+  bfin_linux_sigtramp_frame_sniffer
+};
+
+
+static LONGEST
+bfin_linux_get_syscall_number (struct gdbarch *gdbarch,
+                               ptid_t ptid)
+{
+  struct regcache *regcache = get_thread_regcache (ptid);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  /* The content of a register.  */
+  gdb_byte buf[4];
+  /* The result.  */
+  LONGEST ret;
+
+  /* Getting the system call number from the register.
+     When dealing with Blackfin architecture, this information
+     is stored at %p0 register.  */
+  regcache_cooked_read (regcache, BFIN_P0_REGNUM, buf);
+
+  ret = extract_signed_integer (buf, 4, byte_order);
+
+  return ret;
+}
+
+
+struct bfin_frame_cache
+{
+  /* Base address.  */
+  CORE_ADDR base;
+  CORE_ADDR sp_offset;
+  CORE_ADDR pc;
+  int frameless_pc_value;
+
+  /* Saved registers.  */
+  CORE_ADDR saved_regs[BFIN_NUM_REGS];
+  CORE_ADDR saved_sp;
+
+  /* Stack space reserved for local variables.  */
+  long locals;
+};
+
+/* Allocate and initialize a frame cache.  */
+
+static struct bfin_frame_cache *
+bfin_alloc_frame_cache (void)
+{
+  struct bfin_frame_cache *cache;
+  int i;
+
+  cache = FRAME_OBSTACK_ZALLOC (struct bfin_frame_cache);
+
+  /* Base address.  */
+  cache->base = 0;
+  cache->sp_offset = -4;
+  cache->pc = 0;
+  cache->frameless_pc_value = 0;
+
+  /* Saved registers.  We initialize these to -1 since zero is a valid
+     offset (that's where fp is supposed to be stored).  */
+  for (i = 0; i < BFIN_NUM_REGS; i++)
+    cache->saved_regs[i] = -1;
+
+  /* Frameless until proven otherwise.  */
+  cache->locals = -1;
+
+  return cache;
+}
+
+static struct bfin_frame_cache *
+bfin_frame_cache (struct frame_info *this_frame, void **this_cache)
+{
+  struct bfin_frame_cache *cache;
+  int i;
+
+  if (*this_cache)
+    return *this_cache;
+
+  cache = bfin_alloc_frame_cache ();
+  *this_cache = cache;
+
+  cache->base = get_frame_register_unsigned (this_frame, BFIN_FP_REGNUM);
+  if (cache->base == 0)
+    return cache;
+
+  /* For normal frames, PC is stored at [FP + 4].  */
+  cache->saved_regs[BFIN_PC_REGNUM] = 4;
+  cache->saved_regs[BFIN_FP_REGNUM] = 0;
+
+  /* Adjust all the saved registers such that they contain addresses
+     instead of offsets.  */
+  for (i = 0; i < BFIN_NUM_REGS; i++)
+    if (cache->saved_regs[i] != -1)
+      cache->saved_regs[i] += cache->base;
+
+  cache->pc = get_frame_func (this_frame) ;
+  if (cache->pc == 0 || cache->pc == get_frame_pc (this_frame))
+    {
+      /* Either there is no prologue (frameless function) or we are at
+	 the start of a function.  In short we do not have a frame.
+	 PC is stored in rets register.  FP points to previous frame.  */
+
+      cache->saved_regs[BFIN_PC_REGNUM] =
+	get_frame_register_unsigned (this_frame, BFIN_RETS_REGNUM);
+      cache->frameless_pc_value = 1;
+      cache->base = get_frame_register_unsigned (this_frame, BFIN_FP_REGNUM);
+#ifdef _DEBUG
+      fprintf (stderr, "frameless pc case base %x\n", cache->base);
+#endif
+      cache->saved_regs[BFIN_FP_REGNUM] = cache->base;
+      cache->saved_sp = cache->base;
+    }
+  else
+    {
+      cache->frameless_pc_value = 0;
+
+      /* Now that we have the base address for the stack frame we can
+	 calculate the value of SP in the calling frame.  */
+      cache->saved_sp = cache->base + 8;
+    }
+
+  return cache;
+}
+
+static void
+bfin_frame_this_id (struct frame_info *this_frame,
+		    void **this_cache,
+		    struct frame_id *this_id)
+{
+  struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
+
+  /* This marks the outermost frame.  */
+  if (cache->base == 0)
+    return;
+
+  /* See the end of bfin_push_dummy_call.  */
+  *this_id = frame_id_build (cache->base + 8, cache->pc);
+}
+
+static struct value *
+bfin_frame_prev_register (struct frame_info *this_frame,
+			  void **this_cache,
+			  int regnum)
+{
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
+
+  if (regnum == gdbarch_sp_regnum (gdbarch) && cache->saved_sp)
+    return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
+
+  if (regnum < BFIN_NUM_REGS && cache->saved_regs[regnum] != -1)
+    return frame_unwind_got_memory (this_frame, regnum,
+				    cache->saved_regs[regnum]);
+
+  return frame_unwind_got_register (this_frame, regnum, regnum);
+}
+
+static const struct frame_unwind bfin_frame_unwind =
+{
+  NORMAL_FRAME,
+  bfin_frame_this_id,
+  bfin_frame_prev_register,
+  NULL,
+  default_frame_sniffer
+};
+
+/* Check for "[--SP] = <reg>;" insns.  These are appear in function
+   prologues to save misc registers onto the stack.  */
+
+static int
+is_minus_minus_sp (int op)
+{
+  op &= 0xFFC0;
+
+  if ((op == P_MINUS_SP1) || (op == P_MINUS_SP2)
+      || (op == P_MINUS_SP3) || (op == P_MINUS_SP4))
+    return 1;
+
+  return 0;
+}
+
+/* Skip all the insns that appear in generated function prologues.  */
+
+static CORE_ADDR
+bfin_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  int op = read_memory_unsigned_integer (pc, 2, byte_order);
+  CORE_ADDR orig_pc = pc;
+  int done = 0;
+
+  /* The new gcc prologue generates the register saves BEFORE the link
+     or RETS saving instruction.
+     So, our job is to stop either at those instructions or some upper
+     limit saying there is no frame!  */
+
+  while (!done)
+    {
+      if (is_minus_minus_sp (op))
+	{
+	  while (is_minus_minus_sp (op))
+	    {
+	      pc += 2;
+	      op = read_memory_unsigned_integer (pc, 2, byte_order);
+	    }
+
+	  if (op == P_LINKAGE)
+	    pc += 4;
+
+	  done = 1;
+	}
+      else if (op == P_LINKAGE)
+	{
+	  pc += 4;
+	  done = 1;
+	}
+      else if (op == P_MINUS_MINUS_SP_EQ_RETS)
+	{
+	  pc += 2;
+	  done = 1;
+	}
+      else if (op == P_RTS)
+	{
+	  done = 1;
+	}
+      else if ((op >= P_JUMP_PREG_MIN && op <= P_JUMP_PREG_MAX)
+	       || (op >= P_JUMP_PC_PLUS_PREG_MIN
+		   && op <= P_JUMP_PC_PLUS_PREG_MAX)
+	       || (op == P_JUMP_S_MIN && op <= P_JUMP_S_MAX))
+	{
+	  done = 1;
+	}
+      else if (pc - orig_pc >= UPPER_LIMIT)
+	{
+	  warning (_("Function Prologue not recognised; pc will point to ENTRY_POINT of the function"));
+	  pc = orig_pc + 2;
+	  done = 1;
+	}
+      else
+	{
+	  pc += 2; /* Not a terminating instruction go on.  */
+	  op = read_memory_unsigned_integer (pc, 2, byte_order);
+	}
+    }
+
+   /* TODO:
+      Dwarf2 uses entry point value AFTER some register initializations.
+      We should perhaps skip such asssignments as well (R6 = R1, ...).  */
+
+  return pc;
+}
+
+/* Return the GDB type object for the "standard" data type of data in
+   register N.  This should be void pointer for P0-P5, SP, FP;
+   void pointer to function for PC; int otherwise.  */
+
+static struct type *
+bfin_register_type (struct gdbarch *gdbarch, int regnum)
+{
+  if ((regnum >= BFIN_P0_REGNUM && regnum <= BFIN_FP_REGNUM)
+      || regnum == BFIN_USP_REGNUM)
+    return builtin_type (gdbarch)->builtin_data_ptr;
+
+  if (regnum == BFIN_PC_REGNUM || regnum == BFIN_RETS_REGNUM)
+    return builtin_type (gdbarch)->builtin_func_ptr;
+
+  return builtin_type (gdbarch)->builtin_int32;
+}
+
+static CORE_ADDR
+bfin_push_dummy_call (struct gdbarch *gdbarch,
+		      struct value *function,
+		      struct regcache *regcache,
+		      CORE_ADDR bp_addr,
+		      int nargs,
+		      struct value **args,
+		      CORE_ADDR sp,
+		      int struct_return,
+		      CORE_ADDR struct_addr)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  char buf[4];
+  int i;
+  long reg_r0, reg_r1, reg_r2;
+  int total_len = 0;
+  enum bfin_abi abi = bfin_abi (gdbarch);
+  CORE_ADDR func_addr = find_function_addr (function, NULL);
+
+  for (i = nargs - 1; i >= 0; i--)
+    {
+      struct type *value_type = value_enclosing_type (args[i]);
+      int len = TYPE_LENGTH (value_type);
+
+      total_len += (len + 3) & ~3;
+    }
+
+  /* At least twelve bytes of stack space must be allocated for the function's
+     arguments, even for functions that have less than 12 bytes of argument
+     data.  */
+
+  if (total_len < 12)
+    sp -= 12 - total_len;
+
+  /* Push arguments in reverse order.  */
+
+  for (i = nargs - 1; i >= 0; i--)
+    {
+      struct type *value_type = value_enclosing_type (args[i]);
+      struct type *arg_type = check_typedef (value_type);
+      int len = TYPE_LENGTH (value_type);
+      int container_len = (len + 3) & ~3;
+
+      sp -= container_len;
+      write_memory (sp, value_contents_writeable (args[i]), container_len);
+    }
+
+  /* initialize R0, R1 and R2 to the first 3 words of paramters */
+
+  reg_r0 = read_memory_integer (sp, 4, byte_order);
+  regcache_cooked_write_unsigned (regcache, BFIN_R0_REGNUM, reg_r0);
+  reg_r1 = read_memory_integer (sp + 4, 4, byte_order);
+  regcache_cooked_write_unsigned (regcache, BFIN_R1_REGNUM, reg_r1);
+  reg_r2 = read_memory_integer (sp + 8, 4, byte_order);
+  regcache_cooked_write_unsigned (regcache, BFIN_R2_REGNUM, reg_r2);
+
+  /* Store struct value address.  */
+
+  if (struct_return)
+    regcache_cooked_write_unsigned (regcache, BFIN_P0_REGNUM, struct_addr);
+
+  /* Set the dummy return value to bp_addr.
+     A dummy breakpoint will be setup to execute the call.  */
+
+  regcache_cooked_write_unsigned (regcache, BFIN_RETS_REGNUM, bp_addr);
+
+  /* Finally, update the stack pointer.  */
+
+  regcache_cooked_write_unsigned (regcache, BFIN_SP_REGNUM, sp);
+
+  return sp;
+}
+
+/* Convert DWARF2 register number REG to the appropriate register number
+   used by GDB.  */
+
+static int
+bfin_reg_to_regnum (struct gdbarch *gdbarch, int reg)
+{
+  if (reg > ARRAY_SIZE (map_gcc_gdb))
+    return 0;
+
+  return map_gcc_gdb[reg];
+}
+
+/* This function implements the BREAKPOINT_FROM_PC macro.  It returns
+   a pointer to a string of bytes that encode a breakpoint instruction,
+   stores the length of the string to *lenptr, and adjusts the program
+   counter (if necessary) to point to the actual memory location where
+   the breakpoint should be inserted.  */
+
+static const unsigned char *
+bfin_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  unsigned short iw;
+  static unsigned char bfin_breakpoint[] = {0xa1, 0x00, 0x00, 0x00};
+  static unsigned char bfin_sim_breakpoint[] = {0x25, 0x00, 0x00, 0x00};
+
+  iw = read_memory_unsigned_integer (*pcptr, 2, byte_order);
+
+  if ((iw & 0xf000) >= 0xc000)
+    /* 32-bit instruction.  */
+    *lenptr = 4;
+  else
+    *lenptr = 2;
+
+  if (strcmp (target_shortname, "sim") == 0)
+    return bfin_sim_breakpoint;
+  else
+    return bfin_breakpoint;
+}
+
+static void
+bfin_extract_return_value (struct type *type,
+			   struct regcache *regs,
+			   gdb_byte *dst)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regs);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  bfd_byte *valbuf = dst;
+  int len = TYPE_LENGTH (type);
+  ULONGEST tmp;
+  int regno = BFIN_R0_REGNUM;
+
+  gdb_assert (len <= 8);
+
+  while (len > 0)
+    {
+      regcache_cooked_read_unsigned (regs, regno++, &tmp);
+      store_unsigned_integer (valbuf, (len > 4 ? 4 : len), tmp, byte_order);
+      len -= 4;
+      valbuf += 4;
+    }
+}
+
+/* Write into appropriate registers a function return value of type
+   TYPE, given in virtual format.  */
+
+static void
+bfin_store_return_value (struct type *type,
+			 struct regcache *regs,
+			 const gdb_byte *src)
+{
+  const bfd_byte *valbuf = src;
+
+  /* Integral values greater than one word are stored in consecutive
+     registers starting with R0.  This will always be a multiple of
+     the register size.  */
+
+  int len = TYPE_LENGTH (type);
+  int regno = BFIN_R0_REGNUM;
+
+  gdb_assert (len <= 8);
+
+  while (len > 0)
+    {
+      regcache_cooked_write (regs, regno++, valbuf);
+      len -= 4;
+      valbuf += 4;
+    }
+}
+
+/* Determine, for architecture GDBARCH, how a return value of TYPE
+   should be returned.  If it is supposed to be returned in registers,
+   and READBUF is nonzero, read the appropriate value from REGCACHE,
+   and copy it into READBUF.  If WRITEBUF is nonzero, write the value
+   from WRITEBUF into REGCACHE.  */
+
+static enum return_value_convention
+bfin_return_value (struct gdbarch *gdbarch,
+		   struct type *func_type,
+		   struct type *type,
+		   struct regcache *regcache,
+		   gdb_byte *readbuf,
+		   const gdb_byte *writebuf)
+{
+  if (TYPE_LENGTH (type) > 8)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+
+  if (readbuf)
+    bfin_extract_return_value (type, regcache, readbuf);
+
+  if (writebuf)
+    bfin_store_return_value (type, regcache, writebuf);
+
+  return RETURN_VALUE_REGISTER_CONVENTION;
+}
+
+/* Return the BFIN register name corresponding to register I.  */
+
+static const char *
+bfin_register_name (struct gdbarch *gdbarch, int i)
+{
+  return bfin_register_name_strings[i];
+}
+
+static CORE_ADDR
+bfin_frame_base_address (struct frame_info *this_frame, void **this_cache)
+{
+  struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
+
+  return cache->base;
+}
+
+static CORE_ADDR
+bfin_frame_local_address (struct frame_info *this_frame, void **this_cache)
+{
+  struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
+
+  return cache->base - 4;
+}
+
+static CORE_ADDR
+bfin_frame_args_address (struct frame_info *this_frame, void **this_cache)
+{
+  struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
+
+  return cache->base + 8;
+}
+
+static const struct frame_base bfin_frame_base =
+{
+  &bfin_frame_unwind,
+  bfin_frame_base_address,
+  bfin_frame_local_address,
+  bfin_frame_args_address
+};
+
+static struct frame_id
+bfin_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+  CORE_ADDR sp;
+
+  sp = get_frame_register_unsigned (this_frame, BFIN_SP_REGNUM);
+
+  return frame_id_build (sp, get_frame_pc (this_frame));
+}
+
+static CORE_ADDR
+bfin_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  return frame_unwind_register_unsigned (next_frame, BFIN_PC_REGNUM);
+}
+
+static CORE_ADDR
+bfin_frame_align (struct gdbarch *gdbarch, CORE_ADDR address)
+{
+  return (address & ~0x3);
+}
+
+/* Initialize the current architecture based on INFO.  If possible,
+   re-use an architecture from ARCHES, which is a list of
+   architectures already created during this debugging session.
+
+   Called e.g. at program startup, when reading a core file, and when
+   reading a binary file.  */
+
+static struct gdbarch *
+bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+  struct gdbarch_tdep *tdep;
+  struct gdbarch *gdbarch;
+  int elf_flags;
+  enum bfin_abi abi;
+
+  /* Extract the ELF flags, if available.  */
+  if (info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
+    elf_flags = elf_elfheader (info.abfd)->e_flags;
+  else
+    elf_flags = 0;
+
+  abi = BFIN_ABI_FLAT;
+
+  /* If there is already a candidate, use it.  */
+
+  for (arches = gdbarch_list_lookup_by_info (arches, &info);
+       arches != NULL;
+       arches = gdbarch_list_lookup_by_info (arches->next, &info))
+    {
+      if (gdbarch_tdep (arches->gdbarch)->bfin_abi != abi)
+	continue;
+      return arches->gdbarch;
+    }
+
+  tdep = XMALLOC (struct gdbarch_tdep);
+  gdbarch = gdbarch_alloc (&info, tdep);
+
+  tdep->bfin_abi = abi;
+
+  set_gdbarch_num_regs (gdbarch, BFIN_NUM_REGS);
+  set_gdbarch_num_pseudo_regs (gdbarch, 0);
+  set_gdbarch_sp_regnum (gdbarch, BFIN_SP_REGNUM);
+  set_gdbarch_pc_regnum (gdbarch, BFIN_PC_REGNUM);
+  set_gdbarch_ps_regnum (gdbarch, BFIN_ASTAT_REGNUM);
+  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, bfin_reg_to_regnum);
+  set_gdbarch_register_name (gdbarch, bfin_register_name);
+  set_gdbarch_register_type (gdbarch, bfin_register_type);
+  set_gdbarch_dummy_id (gdbarch, bfin_dummy_id);
+  set_gdbarch_push_dummy_call (gdbarch, bfin_push_dummy_call);
+  set_gdbarch_believe_pcc_promotion (gdbarch, 1);
+  set_gdbarch_return_value (gdbarch, bfin_return_value);
+  set_gdbarch_skip_prologue (gdbarch, bfin_skip_prologue);
+  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+  set_gdbarch_breakpoint_from_pc (gdbarch, bfin_breakpoint_from_pc);
+  set_gdbarch_decr_pc_after_break (gdbarch, 2);
+  set_gdbarch_frame_args_skip (gdbarch, 8);
+  set_gdbarch_unwind_pc (gdbarch, bfin_unwind_pc);
+  set_gdbarch_frame_align (gdbarch, bfin_frame_align);
+  set_gdbarch_print_insn (gdbarch, print_insn_bfin);
+
+  /* Hook in ABI-specific overrides, if they have been registered.  */
+  gdbarch_init_osabi (info, gdbarch);
+
+  dwarf2_append_unwinders (gdbarch);
+
+  frame_base_set_default (gdbarch, &bfin_frame_base);
+
+  frame_unwind_append_unwinder (gdbarch, &bfin_frame_unwind);
+
+  /* Functions for 'catch syscall'.  */
+  set_xml_syscall_file_name ("syscalls/bfin-linux.xml");
+  set_gdbarch_get_syscall_number (gdbarch,
+                                  bfin_linux_get_syscall_number);
+
+  return gdbarch;
+}
+
+void
+_initialize_bfin_tdep (void)
+{
+  register_gdbarch_init (bfd_arch_bfin, bfin_gdbarch_init);
+}
diff --git a/gdb/bfin-tdep.h b/gdb/bfin-tdep.h
new file mode 100644
index 0000000..a2f8ceb
--- /dev/null
+++ b/gdb/bfin-tdep.h
@@ -0,0 +1,115 @@
+/* Target-dependent code for Analog Devices Blackfin processer, for GDB.
+
+   Copyright (C) 2005-2010 Free Software Foundation, Inc.
+   Contributed by Analog Devices.
+
+   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/>.  */
+
+enum gdb_regnum {
+  /* Core Registers */
+  BFIN_R0_REGNUM = 0,
+  BFIN_R1_REGNUM,
+  BFIN_R2_REGNUM,
+  BFIN_R3_REGNUM,
+  BFIN_R4_REGNUM,
+  BFIN_R5_REGNUM,
+  BFIN_R6_REGNUM,
+  BFIN_R7_REGNUM,
+  BFIN_P0_REGNUM,
+  BFIN_P1_REGNUM,
+  BFIN_P2_REGNUM,
+  BFIN_P3_REGNUM,
+  BFIN_P4_REGNUM,
+  BFIN_P5_REGNUM,
+  BFIN_SP_REGNUM,
+  BFIN_FP_REGNUM,
+  BFIN_I0_REGNUM,
+  BFIN_I1_REGNUM,
+  BFIN_I2_REGNUM,
+  BFIN_I3_REGNUM,
+  BFIN_M0_REGNUM,
+  BFIN_M1_REGNUM,
+  BFIN_M2_REGNUM,
+  BFIN_M3_REGNUM,
+  BFIN_B0_REGNUM,
+  BFIN_B1_REGNUM,
+  BFIN_B2_REGNUM,
+  BFIN_B3_REGNUM,
+  BFIN_L0_REGNUM,
+  BFIN_L1_REGNUM,
+  BFIN_L2_REGNUM,
+  BFIN_L3_REGNUM,
+  BFIN_A0_DOT_X_REGNUM,
+  BFIN_AO_DOT_W_REGNUM,
+  BFIN_A1_DOT_X_REGNUM,
+  BFIN_A1_DOT_W_REGNUM,
+  BFIN_ASTAT_REGNUM,
+  BFIN_RETS_REGNUM,
+  BFIN_LC0_REGNUM,
+  BFIN_LT0_REGNUM,
+  BFIN_LB0_REGNUM,
+  BFIN_LC1_REGNUM,
+  BFIN_LT1_REGNUM,
+  BFIN_LB1_REGNUM,
+  BFIN_CYCLES_REGNUM,
+  BFIN_CYCLES2_REGNUM,
+  BFIN_USP_REGNUM,
+  BFIN_SEQSTAT_REGNUM,
+  BFIN_SYSCFG_REGNUM,
+  BFIN_RETI_REGNUM,
+  BFIN_RETX_REGNUM,
+  BFIN_RETN_REGNUM,
+  BFIN_RETE_REGNUM,
+
+  /* Pseudo Registers */
+  BFIN_PC_REGNUM,
+  BFIN_CC_REGNUM,
+  BFIN_TEXT_ADDR,		/* Address of .text section.  */
+  BFIN_TEXT_END_ADDR,		/* Address of the end of .text section.  */
+  BFIN_DATA_ADDR,		/* Address of .data section.  */
+
+  BFIN_FDPIC_EXEC_REGNUM,
+  BFIN_FDPIC_INTERP_REGNUM,
+
+  /* MMRs */
+  BFIN_IPEND_REGNUM,
+
+  /* LAST ENTRY SHOULD NOT BE CHANGED.  */
+  BFIN_NUM_REGS			/* The number of all registers.  */
+};
+
+/* The ABIs for Blackfin.  */
+enum bfin_abi
+{
+  BFIN_ABI_FLAT
+};
+
+/* Target-dependent structure in gdbarch.  */
+struct gdbarch_tdep
+{
+  /* Which ABI is in use?  */
+  enum bfin_abi bfin_abi;
+};
+
+/* in opcodes/bfin-dis.c */
+extern int print_insn_bfin (bfd_vma pc, struct disassemble_info *outf);
+
+/* Return the Blackfin ABI associated with GDBARCH.  */
+static inline enum bfin_abi
+bfin_abi (struct gdbarch *gdbarch)
+{
+  return gdbarch_tdep (gdbarch)->bfin_abi;
+}
diff --git a/gdb/config/bfin/bfin.mt b/gdb/config/bfin/bfin.mt
new file mode 100644
index 0000000..2df8fb8
--- /dev/null
+++ b/gdb/config/bfin/bfin.mt
@@ -0,0 +1 @@
+TDEPFILES= bfin-tdep.o
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index 161cbdc..4bdc81a 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -106,6 +106,11 @@ avr-*-*)
 	gdb_sim=../sim/avr/libsim.a
 	;;
 
+bfin-*-*)
+	# Target: Blackfin
+	gdb_target_obs="bfin-tdep.o"
+	;;
+
 cris*)
 	# Target: CRIS
 	gdb_target_obs="cris-tdep.o corelow.o solib.o solib-svr4.o"
diff --git a/gdb/syscalls/bfin-linux.xml b/gdb/syscalls/bfin-linux.xml
new file mode 100644
index 0000000..0fd3a96
--- /dev/null
+++ b/gdb/syscalls/bfin-linux.xml
@@ -0,0 +1,326 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-syscalls.dtd">
+
+<!-- This file was generated using the following file:
+
+     gawk '$2 ~ /^__NR_/ { gsub(/__NR_/,""); print "  <syscall name=\"" $2 "\" number=\"" $3 "\"/>" }'
+     /usr/src/linux/arch/blackfin/include/asm/unistd.h
+
+     The file mentioned above belongs to the Linux Kernel.  -->
+
+<syscalls_info>
+  <syscall name="restart_syscall" number="0"/>
+  <syscall name="exit" number="1"/>
+  <syscall name="fork" number="2"/>
+  <syscall name="read" number="3"/>
+  <syscall name="write" number="4"/>
+  <syscall name="open" number="5"/>
+  <syscall name="close" number="6"/>
+  <syscall name="creat" number="8"/>
+  <syscall name="link" number="9"/>
+  <syscall name="unlink" number="10"/>
+  <syscall name="execve" number="11"/>
+  <syscall name="chdir" number="12"/>
+  <syscall name="time" number="13"/>
+  <syscall name="mknod" number="14"/>
+  <syscall name="chmod" number="15"/>
+  <syscall name="chown" number="16"/>
+  <syscall name="lseek" number="19"/>
+  <syscall name="getpid" number="20"/>
+  <syscall name="mount" number="21"/>
+  <syscall name="setuid" number="23"/>
+  <syscall name="getuid" number="24"/>
+  <syscall name="stime" number="25"/>
+  <syscall name="ptrace" number="26"/>
+  <syscall name="alarm" number="27"/>
+  <syscall name="pause" number="29"/>
+  <syscall name="access" number="33"/>
+  <syscall name="nice" number="34"/>
+  <syscall name="sync" number="36"/>
+  <syscall name="kill" number="37"/>
+  <syscall name="rename" number="38"/>
+  <syscall name="mkdir" number="39"/>
+  <syscall name="rmdir" number="40"/>
+  <syscall name="dup" number="41"/>
+  <syscall name="pipe" number="42"/>
+  <syscall name="times" number="43"/>
+  <syscall name="brk" number="45"/>
+  <syscall name="setgid" number="46"/>
+  <syscall name="getgid" number="47"/>
+  <syscall name="geteuid" number="49"/>
+  <syscall name="getegid" number="50"/>
+  <syscall name="acct" number="51"/>
+  <syscall name="umount2" number="52"/>
+  <syscall name="ioctl" number="54"/>
+  <syscall name="fcntl" number="55"/>
+  <syscall name="setpgid" number="57"/>
+  <syscall name="umask" number="60"/>
+  <syscall name="chroot" number="61"/>
+  <syscall name="ustat" number="62"/>
+  <syscall name="dup2" number="63"/>
+  <syscall name="getppid" number="64"/>
+  <syscall name="getpgrp" number="65"/>
+  <syscall name="setsid" number="66"/>
+  <syscall name="sgetmask" number="68"/>
+  <syscall name="ssetmask" number="69"/>
+  <syscall name="setreuid" number="70"/>
+  <syscall name="setregid" number="71"/>
+  <syscall name="sethostname" number="74"/>
+  <syscall name="setrlimit" number="75"/>
+  <syscall name="getrusage" number="77"/>
+  <syscall name="gettimeofday" number="78"/>
+  <syscall name="settimeofday" number="79"/>
+  <syscall name="getgroups" number="80"/>
+  <syscall name="setgroups" number="81"/>
+  <syscall name="symlink" number="83"/>
+  <syscall name="readlink" number="85"/>
+  <syscall name="reboot" number="88"/>
+  <syscall name="munmap" number="91"/>
+  <syscall name="truncate" number="92"/>
+  <syscall name="ftruncate" number="93"/>
+  <syscall name="fchmod" number="94"/>
+  <syscall name="fchown" number="95"/>
+  <syscall name="getpriority" number="96"/>
+  <syscall name="setpriority" number="97"/>
+  <syscall name="statfs" number="99"/>
+  <syscall name="fstatfs" number="100"/>
+  <syscall name="syslog" number="103"/>
+  <syscall name="setitimer" number="104"/>
+  <syscall name="getitimer" number="105"/>
+  <syscall name="stat" number="106"/>
+  <syscall name="lstat" number="107"/>
+  <syscall name="fstat" number="108"/>
+  <syscall name="vhangup" number="111"/>
+  <syscall name="wait4" number="114"/>
+  <syscall name="sysinfo" number="116"/>
+  <syscall name="fsync" number="118"/>
+  <syscall name="clone" number="120"/>
+  <syscall name="setdomainname" number="121"/>
+  <syscall name="uname" number="122"/>
+  <syscall name="adjtimex" number="124"/>
+  <syscall name="mprotect" number="125"/>
+  <syscall name="init_module" number="128"/>
+  <syscall name="delete_module" number="129"/>
+  <syscall name="quotactl" number="131"/>
+  <syscall name="getpgid" number="132"/>
+  <syscall name="fchdir" number="133"/>
+  <syscall name="bdflush" number="134"/>
+  <syscall name="personality" number="136"/>
+  <syscall name="setfsuid" number="138"/>
+  <syscall name="setfsgid" number="139"/>
+  <syscall name="_llseek" number="140"/>
+  <syscall name="getdents" number="141"/>
+  <syscall name="flock" number="143"/>
+  <syscall name="readv" number="145"/>
+  <syscall name="writev" number="146"/>
+  <syscall name="getsid" number="147"/>
+  <syscall name="fdatasync" number="148"/>
+  <syscall name="_sysctl" number="149"/>
+  <syscall name="sched_setparam" number="154"/>
+  <syscall name="sched_getparam" number="155"/>
+  <syscall name="sched_setscheduler" number="156"/>
+  <syscall name="sched_getscheduler" number="157"/>
+  <syscall name="sched_yield" number="158"/>
+  <syscall name="sched_get_priority_max" number="159"/>
+  <syscall name="sched_get_priority_min" number="160"/>
+  <syscall name="sched_rr_get_interval" number="161"/>
+  <syscall name="nanosleep" number="162"/>
+  <syscall name="mremap" number="163"/>
+  <syscall name="setresuid" number="164"/>
+  <syscall name="getresuid" number="165"/>
+  <syscall name="nfsservctl" number="169"/>
+  <syscall name="setresgid" number="170"/>
+  <syscall name="getresgid" number="171"/>
+  <syscall name="prctl" number="172"/>
+  <syscall name="rt_sigreturn" number="173"/>
+  <syscall name="rt_sigaction" number="174"/>
+  <syscall name="rt_sigprocmask" number="175"/>
+  <syscall name="rt_sigpending" number="176"/>
+  <syscall name="rt_sigtimedwait" number="177"/>
+  <syscall name="rt_sigqueueinfo" number="178"/>
+  <syscall name="rt_sigsuspend" number="179"/>
+  <syscall name="pread" number="180"/>
+  <syscall name="pwrite" number="181"/>
+  <syscall name="lchown" number="182"/>
+  <syscall name="getcwd" number="183"/>
+  <syscall name="capget" number="184"/>
+  <syscall name="capset" number="185"/>
+  <syscall name="sigaltstack" number="186"/>
+  <syscall name="sendfile" number="187"/>
+  <syscall name="vfork" number="190"/>
+  <syscall name="getrlimit" number="191"/>
+  <syscall name="mmap2" number="192"/>
+  <syscall name="truncate64" number="193"/>
+  <syscall name="ftruncate64" number="194"/>
+  <syscall name="stat64" number="195"/>
+  <syscall name="lstat64" number="196"/>
+  <syscall name="fstat64" number="197"/>
+  <syscall name="chown32" number="198"/>
+  <syscall name="getuid32" number="199"/>
+  <syscall name="getgid32" number="200"/>
+  <syscall name="geteuid32" number="201"/>
+  <syscall name="getegid32" number="202"/>
+  <syscall name="setreuid32" number="203"/>
+  <syscall name="setregid32" number="204"/>
+  <syscall name="getgroups32" number="205"/>
+  <syscall name="setgroups32" number="206"/>
+  <syscall name="fchown32" number="207"/>
+  <syscall name="setresuid32" number="208"/>
+  <syscall name="getresuid32" number="209"/>
+  <syscall name="setresgid32" number="210"/>
+  <syscall name="getresgid32" number="211"/>
+  <syscall name="lchown32" number="212"/>
+  <syscall name="setuid32" number="213"/>
+  <syscall name="setgid32" number="214"/>
+  <syscall name="setfsuid32" number="215"/>
+  <syscall name="setfsgid32" number="216"/>
+  <syscall name="pivot_root" number="217"/>
+  <syscall name="getdents64" number="220"/>
+  <syscall name="fcntl64" number="221"/>
+  <syscall name="gettid" number="224"/>
+  <syscall name="readahead" number="225"/>
+  <syscall name="setxattr" number="226"/>
+  <syscall name="lsetxattr" number="227"/>
+  <syscall name="fsetxattr" number="228"/>
+  <syscall name="getxattr" number="229"/>
+  <syscall name="lgetxattr" number="230"/>
+  <syscall name="fgetxattr" number="231"/>
+  <syscall name="listxattr" number="232"/>
+  <syscall name="llistxattr" number="233"/>
+  <syscall name="flistxattr" number="234"/>
+  <syscall name="removexattr" number="235"/>
+  <syscall name="lremovexattr" number="236"/>
+  <syscall name="fremovexattr" number="237"/>
+  <syscall name="tkill" number="238"/>
+  <syscall name="sendfile64" number="239"/>
+  <syscall name="futex" number="240"/>
+  <syscall name="sched_setaffinity" number="241"/>
+  <syscall name="sched_getaffinity" number="242"/>
+  <syscall name="io_setup" number="245"/>
+  <syscall name="io_destroy" number="246"/>
+  <syscall name="io_getevents" number="247"/>
+  <syscall name="io_submit" number="248"/>
+  <syscall name="io_cancel" number="249"/>
+  <syscall name="exit_group" number="252"/>
+  <syscall name="lookup_dcookie" number="253"/>
+  <syscall name="bfin_spinlock" number="254"/>
+  <syscall name="epoll_create" number="255"/>
+  <syscall name="epoll_ctl" number="256"/>
+  <syscall name="epoll_wait" number="257"/>
+  <syscall name="set_tid_address" number="259"/>
+  <syscall name="timer_create" number="260"/>
+  <syscall name="timer_settime" number="261"/>
+  <syscall name="timer_gettime" number="262"/>
+  <syscall name="timer_getoverrun" number="263"/>
+  <syscall name="timer_delete" number="264"/>
+  <syscall name="clock_settime" number="265"/>
+  <syscall name="clock_gettime" number="266"/>
+  <syscall name="clock_getres" number="267"/>
+  <syscall name="clock_nanosleep" number="268"/>
+  <syscall name="statfs64" number="269"/>
+  <syscall name="fstatfs64" number="270"/>
+  <syscall name="tgkill" number="271"/>
+  <syscall name="utimes" number="272"/>
+  <syscall name="fadvise64_64" number="273"/>
+  <syscall name="mq_open" number="278"/>
+  <syscall name="mq_unlink" number="279"/>
+  <syscall name="mq_timedsend" number="280"/>
+  <syscall name="mq_timedreceive" number="281"/>
+  <syscall name="mq_notify" number="282"/>
+  <syscall name="mq_getsetattr" number="283"/>
+  <syscall name="kexec_load" number="284"/>
+  <syscall name="waitid" number="285"/>
+  <syscall name="add_key" number="286"/>
+  <syscall name="request_key" number="287"/>
+  <syscall name="keyctl" number="288"/>
+  <syscall name="ioprio_set" number="289"/>
+  <syscall name="ioprio_get" number="290"/>
+  <syscall name="inotify_init" number="291"/>
+  <syscall name="inotify_add_watch" number="292"/>
+  <syscall name="inotify_rm_watch" number="293"/>
+  <syscall name="openat" number="295"/>
+  <syscall name="mkdirat" number="296"/>
+  <syscall name="mknodat" number="297"/>
+  <syscall name="fchownat" number="298"/>
+  <syscall name="futimesat" number="299"/>
+  <syscall name="fstatat64" number="300"/>
+  <syscall name="unlinkat" number="301"/>
+  <syscall name="renameat" number="302"/>
+  <syscall name="linkat" number="303"/>
+  <syscall name="symlinkat" number="304"/>
+  <syscall name="readlinkat" number="305"/>
+  <syscall name="fchmodat" number="306"/>
+  <syscall name="faccessat" number="307"/>
+  <syscall name="pselect6" number="308"/>
+  <syscall name="ppoll" number="309"/>
+  <syscall name="unshare" number="310"/>
+  <syscall name="sram_alloc" number="311"/>
+  <syscall name="sram_free" number="312"/>
+  <syscall name="dma_memcpy" number="313"/>
+  <syscall name="accept" number="314"/>
+  <syscall name="bind" number="315"/>
+  <syscall name="connect" number="316"/>
+  <syscall name="getpeername" number="317"/>
+  <syscall name="getsockname" number="318"/>
+  <syscall name="getsockopt" number="319"/>
+  <syscall name="listen" number="320"/>
+  <syscall name="recv" number="321"/>
+  <syscall name="recvfrom" number="322"/>
+  <syscall name="recvmsg" number="323"/>
+  <syscall name="send" number="324"/>
+  <syscall name="sendmsg" number="325"/>
+  <syscall name="sendto" number="326"/>
+  <syscall name="setsockopt" number="327"/>
+  <syscall name="shutdown" number="328"/>
+  <syscall name="socket" number="329"/>
+  <syscall name="socketpair" number="330"/>
+  <syscall name="semctl" number="331"/>
+  <syscall name="semget" number="332"/>
+  <syscall name="semop" number="333"/>
+  <syscall name="msgctl" number="334"/>
+  <syscall name="msgget" number="335"/>
+  <syscall name="msgrcv" number="336"/>
+  <syscall name="msgsnd" number="337"/>
+  <syscall name="shmat" number="338"/>
+  <syscall name="shmctl" number="339"/>
+  <syscall name="shmdt" number="340"/>
+  <syscall name="shmget" number="341"/>
+  <syscall name="splice" number="342"/>
+  <syscall name="sync_file_range" number="343"/>
+  <syscall name="tee" number="344"/>
+  <syscall name="vmsplice" number="345"/>
+  <syscall name="epoll_pwait" number="346"/>
+  <syscall name="utimensat" number="347"/>
+  <syscall name="signalfd" number="348"/>
+  <syscall name="timerfd_create" number="349"/>
+  <syscall name="eventfd" number="350"/>
+  <syscall name="pread64" number="351"/>
+  <syscall name="pwrite64" number="352"/>
+  <syscall name="fadvise64" number="353"/>
+  <syscall name="set_robust_list" number="354"/>
+  <syscall name="get_robust_list" number="355"/>
+  <syscall name="fallocate" number="356"/>
+  <syscall name="semtimedop" number="357"/>
+  <syscall name="timerfd_settime" number="358"/>
+  <syscall name="timerfd_gettime" number="359"/>
+  <syscall name="signalfd4" number="360"/>
+  <syscall name="eventfd2" number="361"/>
+  <syscall name="epoll_create1" number="362"/>
+  <syscall name="dup3" number="363"/>
+  <syscall name="pipe2" number="364"/>
+  <syscall name="inotify_init1" number="365"/>
+  <syscall name="preadv" number="366"/>
+  <syscall name="pwritev" number="367"/>
+  <syscall name="rt_tgsigqueueinfo" number="368"/>
+  <syscall name="perf_event_open" number="369"/>
+  <syscall name="recvmmsg" number="370"/>
+  <syscall name="fanotify_init" number="371"/>
+  <syscall name="fanotify_mark" number="372"/>
+  <syscall name="prlimit64" number="373"/>
+</syscalls_info>
-- 
1.7.3.1


^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2] gdbserver: bfin: new port
  2010-12-09  9:29 [PATCH v2] gdb: bfin: new port Mike Frysinger
@ 2010-12-09  9:31 ` Mike Frysinger
  2010-12-13 18:44   ` Pedro Alves
  2010-12-14  6:03 ` [PATCH v2] gdb: " Joel Brobecker
  2010-12-14 20:43 ` [PATCH v3] " Mike Frysinger
  2 siblings, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2010-12-09  9:31 UTC (permalink / raw)
  To: gdb-patches; +Cc: toolchain-devel, Daniel Jacobowitz, Pedro Alves, Jie Zhang

From: Jie Zhang <jie.zhang@analog.com>

Signed-off-by: Jie Zhang <jie.zhang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>

gdb/:
2010-11-16  Jie Zhang  <jie.zhang@analog.com>

	* configure.tgt (bfin-*-*): Set build_gdbserver to yes.
	* NEWS: Mention new Blackfin support.
	* regformats/reg-bfin.dat: New file.

gdbserver/:
2010-11-16  Jie Zhang  <jie.zhang@analog.com>

	* configure.srv (bfin-*-*): Handle bfin targets.
	* linux-bfin-low.c: New file.
	* linux-low.c: Define PT_TEXT_ADDR, PT_TEXT_END_ADDR, and
	PT_DATA_ADDR for BFIN targets.
	* Makefile.in (SFILES): Add linux-bfin-low.c.
	(clean): Remove reg-bfin.c.
	(linux-bfin-low.o, reg-bfin.o, reg-bfin.c): New targets.
	* README: Mention supported Blackfin targets.
---
v2
	- address feedback from Joel

 gdb/NEWS                       |    2 +
 gdb/configure.tgt              |    1 +
 gdb/gdbserver/Makefile.in      |   10 +++-
 gdb/gdbserver/README           |    2 +
 gdb/gdbserver/configure.srv    |    5 ++
 gdb/gdbserver/linux-bfin-low.c |  106 ++++++++++++++++++++++++++++++++++++++++
 gdb/gdbserver/linux-low.c      |    4 ++
 gdb/regformats/reg-bfin.dat    |   63 ++++++++++++++++++++++++
 8 files changed, 190 insertions(+), 3 deletions(-)
 create mode 100644 gdb/gdbserver/linux-bfin-low.c
 create mode 100644 gdb/regformats/reg-bfin.dat

diff --git a/gdb/NEWS b/gdb/NEWS
index ecc88c6..7b3c08b 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -101,6 +101,8 @@
   ** GDBserver is now supported on PowerPC LynxOS (versions 4.x and 5.x),
      and i686 LynxOS (version 5.x).
 
+  ** GDBserver is now supported on Blackfin Linux.
+
 * New targets:
 
 Analog Devices, Inc. Blackfin Processor	bfin-*
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index 4bdc81a..b819e15 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -109,6 +109,7 @@ avr-*-*)
 bfin-*-*)
 	# Target: Blackfin
 	gdb_target_obs="bfin-tdep.o"
+	build_gdbserver=yes
 	;;
 
 cris*)
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 7cf68da..44187eb 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -111,8 +111,8 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/inferiors.c \
 	$(srcdir)/proc-service.list $(srcdir)/regcache.c \
 	$(srcdir)/remote-utils.c $(srcdir)/server.c $(srcdir)/target.c \
 	$(srcdir)/thread-db.c $(srcdir)/utils.c \
-	$(srcdir)/linux-arm-low.c $(srcdir)/linux-cris-low.c \
-	$(srcdir)/linux-crisv32-low.c \
+	$(srcdir)/linux-arm-low.c $(srcdir)/linux-bfin-low.c \
+	$(srcdir)/linux-cris-low.c $(srcdir)/linux-crisv32-low.c \
 	${srcdir}/i386-low.c $(srcdir)/i387-fp.c \
 	$(srcdir)/linux-ia64-low.c $(srcdir)/linux-low.c \
 	$(srcdir)/linux-m32r-low.c \
@@ -263,7 +263,7 @@ clean:
 	rm -f version.c
 	rm -f gdbserver$(EXEEXT) gdbreplay$(EXEEXT) core make.log
 	rm -f $(IPA_LIB)
-	rm -f reg-arm.c i386.c reg-ia64.c reg-m32r.c reg-m68k.c
+	rm -f reg-arm.c reg-bfin.c i386.c reg-ia64.c reg-m32r.c reg-m68k.c
 	rm -f reg-sh.c reg-sparc.c reg-spu.c amd64.c i386-linux.c
 	rm -f reg-cris.c reg-crisv32.c amd64-linux.c reg-xtensa.c
 	rm -f arm-with-iwmmxt.c
@@ -413,6 +413,7 @@ linux-low.o: linux-low.c $(linux_low_h) $(server_h)
 
 linux-arm-low.o: linux-arm-low.c $(linux_low_h) $(server_h) \
 	$(gdb_proc_service_h)
+linux-bfin-low.o: linux-bfin-low.c $(linux_low_h) $(server_h)
 linux-cris-low.o: linux-cris-low.c $(linux_low_h) $(server_h)
 linux-crisv32-low.o: linux-crisv32-low.c $(linux_low_h) $(server_h)
 linux-ia64-low.o: linux-ia64-low.c $(linux_low_h) $(server_h)
@@ -455,6 +456,9 @@ arm-with-vfpv3.c : $(srcdir)/../regformats/arm-with-vfpv3.dat $(regdat_sh)
 arm-with-neon.o : arm-with-neon.c $(regdef_h)
 arm-with-neon.c : $(srcdir)/../regformats/arm-with-neon.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/arm-with-neon.dat arm-with-neon.c
+reg-bfin.o : reg-bfin.c $(regdef_h)
+reg-bfin.c : $(srcdir)/../regformats/reg-bfin.dat $(regdat_sh)
+	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-bfin.dat reg-bfin.c
 reg-cris.o : reg-cris.c $(regdef_h)
 reg-cris.c : $(srcdir)/../regformats/reg-cris.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-cris.dat reg-cris.c
diff --git a/gdb/gdbserver/README b/gdb/gdbserver/README
index 6debbd8..3eaeb61 100644
--- a/gdb/gdbserver/README
+++ b/gdb/gdbserver/README
@@ -81,6 +81,8 @@ Building GDBserver:
 
 The supported targets as of November 2006 are:
 	arm-*-linux*
+	bfin-*-uclinux
+	bfin-*-linux-uclibc
 	crisv32-*-linux*
 	cris-*-linux*
 	i[34567]86-*-cygwin*
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 1e8fa30..ccf8381 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -67,6 +67,11 @@ case "${target}" in
 			srv_mingw=yes
 			srv_mingwce=yes
 			;;
+  bfin-*-*)		srv_regobj=reg-bfin.o
+			srv_tgtobj="linux-low.o linux-bfin-low.o"
+			srv_linux_usrregs=yes
+			srv_linux_thread_db=yes
+			;;
   crisv32-*-linux*)	srv_regobj=reg-crisv32.o
 			srv_tgtobj="linux-low.o linux-crisv32-low.o"
 			srv_linux_regsets=yes
diff --git a/gdb/gdbserver/linux-bfin-low.c b/gdb/gdbserver/linux-bfin-low.c
new file mode 100644
index 0000000..d64f22e
--- /dev/null
+++ b/gdb/gdbserver/linux-bfin-low.c
@@ -0,0 +1,106 @@
+/* GNU/Linux/BFIN specific low level interface, for the remote server for GDB.
+
+   Copyright (C) 2005-2010 Free Software Foundation, Inc.
+   Contributed by Analog Devices.
+
+   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>
+
+/* Defined in auto-generated file reg-bfin.c.  */
+void init_registers_bfin (void);
+
+static int bfin_regmap[] =
+{
+  PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7,
+  PT_P0, PT_P1, PT_P2, PT_P3, PT_P4, PT_P5, PT_USP, PT_FP,
+  PT_I0, PT_I1, PT_I2, PT_I3, PT_M0, PT_M1, PT_M2, PT_M3,
+  PT_B0, PT_B1, PT_B2, PT_B3, PT_L0, PT_L1, PT_L2, PT_L3,
+  PT_A0X, PT_A0W, PT_A1X, PT_A1W, PT_ASTAT, PT_RETS,
+  PT_LC0, PT_LT0, PT_LB0, PT_LC1, PT_LT1, PT_LB1,
+  -1 /* PT_CYCLES */, -1 /* PT_CYCLES2 */,
+  -1 /* PT_USP */, PT_SEQSTAT, PT_SYSCFG, PT_PC, PT_RETX, PT_RETN, PT_RETE,
+  PT_PC, -1 /* PT_CC */, PT_TEXT_ADDR, PT_TEXT_END_ADDR, PT_DATA_ADDR,
+  PT_FDPIC_EXEC, PT_FDPIC_INTERP,
+  PT_IPEND
+};
+
+#define bfin_num_regs ARRAY_SIZE (bfin_regmap)
+
+static int
+bfin_cannot_store_register (int regno)
+{
+  return (regno >= bfin_num_regs);
+}
+
+static int
+bfin_cannot_fetch_register (int regno)
+{
+  return (regno >= bfin_num_regs);
+}
+
+static CORE_ADDR
+bfin_get_pc (struct regcache *regcache)
+{
+  unsigned long pc;
+
+  collect_register_by_name (regcache, "pc", &pc);
+
+  return pc;
+}
+
+static void
+bfin_set_pc (struct regcache *regcache, CORE_ADDR pc)
+{
+  unsigned long newpc = pc;
+
+  supply_register_by_name (regcache, "pc", &newpc);
+}
+
+#define bfin_breakpoint_len 2
+static const unsigned char bfin_breakpoint[bfin_breakpoint_len] = {0xa1, 0x00};
+
+static int
+bfin_breakpoint_at (CORE_ADDR where)
+{
+  unsigned char insn[bfin_breakpoint_len];
+
+  read_inferior_memory(where, insn, bfin_breakpoint_len);
+  if (insn[0] == bfin_breakpoint[0]
+      && insn[1] == bfin_breakpoint[1])
+    return 1;
+
+  /* If necessary, recognize more trap instructions here.  GDB only uses the
+     one.  */
+  return 0;
+}
+
+struct linux_target_ops the_low_target = {
+  init_registers_bfin,
+  bfin_num_regs,
+  bfin_regmap,
+  bfin_cannot_fetch_register,
+  bfin_cannot_store_register,
+  bfin_get_pc,
+  bfin_set_pc,
+  bfin_breakpoint,
+  bfin_breakpoint_len,
+  0,
+  2,
+  bfin_breakpoint_at,
+};
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index c65ce54..75fe905 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -4373,6 +4373,10 @@ linux_stopped_data_address (void)
 #define PT_TEXT_ADDR 49*4
 #define PT_DATA_ADDR 50*4
 #define PT_TEXT_END_ADDR  51*4
+#elif defined(BFIN)
+#define PT_TEXT_ADDR 220
+#define PT_TEXT_END_ADDR 224
+#define PT_DATA_ADDR 228
 #endif
 
 /* Under uClinux, programs are loaded at non-zero offsets, which we need
diff --git a/gdb/regformats/reg-bfin.dat b/gdb/regformats/reg-bfin.dat
new file mode 100644
index 0000000..38dca22
--- /dev/null
+++ b/gdb/regformats/reg-bfin.dat
@@ -0,0 +1,63 @@
+name:bfin
+expedite:pc,sp,fp
+32:r0
+32:r1
+32:r2
+32:r3
+32:r4
+32:r5
+32:r6
+32:r7
+32:p0
+32:p1
+32:p2
+32:p3
+32:p4
+32:p5
+32:sp
+32:fp
+32:i0
+32:i1
+32:i2
+32:i3
+32:m0
+32:m1
+32:m2
+32:m3
+32:b0
+32:b1
+32:b2
+32:b3
+32:l0
+32:l1
+32:l2
+32:l3
+32:a0x
+32:a0w
+32:a1x
+32:a1w
+32:astat
+32:rets
+32:lc0
+32:lt0
+32:lb0
+32:lc1
+32:lt1
+32:lb1
+32:cycles
+32:cycles2
+32:usp
+32:seqstat
+32:syscfg
+32:reti
+32:retx
+32:retn
+32:rete
+32:pc
+32:cc
+32:text_addr
+32:text_end_addr
+32:data_addr
+32:fdpic_exec
+32:fdpic_interp
+32:ipend
-- 
1.7.3.1


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-09  9:31 ` [PATCH v2] gdbserver: " Mike Frysinger
@ 2010-12-13 18:44   ` Pedro Alves
  2010-12-13 19:24     ` Mike Frysinger
  2010-12-14  9:37     ` Andrew Stubbs
  0 siblings, 2 replies; 34+ messages in thread
From: Pedro Alves @ 2010-12-13 18:44 UTC (permalink / raw)
  To: gdb-patches, Andrew Stubbs
  Cc: Mike Frysinger, toolchain-devel, Daniel Jacobowitz, Jie Zhang

>  /* Under uClinux, programs are loaded at non-zero offsets, which we need
> diff --git a/gdb/regformats/reg-bfin.dat b/gdb/regformats/reg-bfin.dat
> new file mode 100644
> index 0000000..38dca22
> --- /dev/null
> +++ b/gdb/regformats/reg-bfin.dat
> @@ -0,0 +1,63 @@
> +name:bfin
> +expedite:pc,sp,fp
> +32:r0
> +32:r1
> +32:r2
> +32:r3
> +32:r4
> +32:r5
> +32:r6
> +32:r7
> +32:p0
> +32:p1
> +32:p2
> +32:p3
> +32:p4
> +32:p5
> +32:sp
> +32:fp
> +32:i0
> +32:i1
> +32:i2
> +32:i3
> +32:m0
> +32:m1
> +32:m2
> +32:m3
> +32:b0
> +32:b1
> +32:b2
> +32:b3
> +32:l0
> +32:l1
> +32:l2
> +32:l3
> +32:a0x
> +32:a0w
> +32:a1x
> +32:a1w
> +32:astat
> +32:rets
> +32:lc0
> +32:lt0
> +32:lb0
> +32:lc1
> +32:lt1
> +32:lb1
> +32:cycles
> +32:cycles2
> +32:usp
> +32:seqstat
> +32:syscfg
> +32:reti
> +32:retx
> +32:retn
> +32:rete
> +32:pc
> +32:cc

> +32:text_addr
> +32:text_end_addr
> +32:data_addr
> +32:fdpic_exec
> +32:fdpic_interp
> +32:ipend

Hmmm.  These last 6 look to be some kind of pseudo registers, not
part of the ISA -- I'm quite surprised to see these here, as
part of the bfin core register set.  I understand these to be
fdpic related; ISTR some discussion about making these be reported
with a new qXfer object?  That'd be better, IMO.

I haven't looked at any bfin docs, but if any of the other
registers aren't core registers (only available in some variants), you
should consider implementing xml target register descriptions.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-13 18:44   ` Pedro Alves
@ 2010-12-13 19:24     ` Mike Frysinger
  2010-12-14  9:37     ` Andrew Stubbs
  1 sibling, 0 replies; 34+ messages in thread
From: Mike Frysinger @ 2010-12-13 19:24 UTC (permalink / raw)
  To: Pedro Alves
  Cc: gdb-patches, Andrew Stubbs, toolchain-devel, Daniel Jacobowitz

[-- Attachment #1: Type: Text/Plain, Size: 1395 bytes --]

On Monday, December 13, 2010 13:43:59 Pedro Alves wrote:
> > +++ b/gdb/regformats/reg-bfin.dat
> > +32:text_addr
> > +32:text_end_addr
> > +32:data_addr
> > +32:fdpic_exec
> > +32:fdpic_interp
> > +32:ipend
> 
> Hmmm.  These last 6 look to be some kind of pseudo registers, not
> part of the ISA -- I'm quite surprised to see these here, as
> part of the bfin core register set.  I understand these to be
> fdpic related; ISTR some discussion about making these be reported
> with a new qXfer object?  That'd be better, IMO.
> 
> I haven't looked at any bfin docs, but if any of the other
> registers aren't core registers (only available in some variants), you
> should consider implementing xml target register descriptions.

correct, these last 6 are the only pseudo regs from the ISA perspective.  the 
rest are actual hardware registers (well, the PC/CC registers are a little 
special, but i dont think that's relevant to this discussion).

i vaguely recall people voicing displeasure at the FDPIC implementation 
details in the past, but i'm not sure this is something that we can "recover" 
from.  Linux declares these things are registers via the ptrace ABI and 
gdbserver is merely forwarding that along.

also, the Blackfin port isnt doing anything new here.  we copied the decisions 
made by the FRV peeps and accepted into the gdb tree already.
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdb: bfin: new port
  2010-12-09  9:29 [PATCH v2] gdb: bfin: new port Mike Frysinger
  2010-12-09  9:31 ` [PATCH v2] gdbserver: " Mike Frysinger
@ 2010-12-14  6:03 ` Joel Brobecker
  2010-12-14 16:14   ` Mike Frysinger
  2010-12-14 20:43 ` [PATCH v3] " Mike Frysinger
  2 siblings, 1 reply; 34+ messages in thread
From: Joel Brobecker @ 2010-12-14  6:03 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: gdb-patches, toolchain-devel, Jie Zhang

> 2010-11-16  Jie Zhang  <jie.zhang@analog.com>
> 
> 	* Makefile.in (ALLDEPFILES): Add bfin-tdep.c.
> 	(HFILES_NO_SRCDIR): Add bfin-tdep.h.

(ALL_TARGET_OBS): Add bfin-tdep.o

> 	* NEWS: Mention new Blackfin port.
> 	* bfin-tdep.c, bfin-tdep.h, config/bfin/bfin.mt: New files.
> 	* configure.tgt (bfin-*-*): Handle bfin targets.

The syscall file is also missing.

There are a couple of nits, highlighted below.  But the patch is
pre-approved with those nits fixed as suggested. One little issue,
though: Please make sure that Eli reviews the change in the NEWS
file before checking in that part of the patch (it can be done
separately).

> +#ifdef _DEBUG
> +      fprintf (stderr, "frameless pc case base %x\n", cache->base);
> +#endif

You forgot to remove the #ifdef DEBUG block...

> +/* Return the Blackfin ABI associated with GDBARCH.  */
> +static inline enum bfin_abi
> +bfin_abi (struct gdbarch *gdbarch)
> +{
> +  return gdbarch_tdep (gdbarch)->bfin_abi;
> +}

Please define that function in bfin-tdep.c, and put a declaration in
bfin-tdep.h instead.

-- 
Joel


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-13 18:44   ` Pedro Alves
  2010-12-13 19:24     ` Mike Frysinger
@ 2010-12-14  9:37     ` Andrew Stubbs
  2010-12-14 15:10       ` Mike Frysinger
  1 sibling, 1 reply; 34+ messages in thread
From: Andrew Stubbs @ 2010-12-14  9:37 UTC (permalink / raw)
  To: Pedro Alves
  Cc: gdb-patches, Mike Frysinger, toolchain-devel, Daniel Jacobowitz,
	Jie Zhang

On 13/12/10 18:43, Pedro Alves wrote:
> Hmmm.  These last 6 look to be some kind of pseudo registers, not
> part of the ISA -- I'm quite surprised to see these here, as
> part of the bfin core register set.  I understand these to be
> fdpic related; ISTR some discussion about making these be reported
> with a new qXfer object?  That'd be better, IMO.

Right, the SH-2A FDPIC implementation uses qXfer to deal with the FDPIC 
settings. The SG++ gdb has a (more-or-less) target independent mechanism 
for retrieving the load maps. This has not been submitted upstream 
simply because it's not complete. The SH-2A FDPIC kernel does (did) not 
support breakpoints, and single stepping is (was) rather broken, so I 
never got further than being able to relocate the main program.

For SH-2A, at least, the kernel does not expose the load maps as 
registers, but has extra ptrace queries PTRACE_GETFDPIC_EXEC and 
PTRACE_GETFDPIC_INTERP.

The gdbserver reads these via qXfer:fdpic:read:exec and 
qXfer:fdpic:read:interp.

Hope that helps

Andrew


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-14  9:37     ` Andrew Stubbs
@ 2010-12-14 15:10       ` Mike Frysinger
  2010-12-14 16:31         ` Pedro Alves
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2010-12-14 15:10 UTC (permalink / raw)
  To: gdb-patches
  Cc: Andrew Stubbs, Pedro Alves, toolchain-devel, Daniel Jacobowitz

[-- Attachment #1: Type: Text/Plain, Size: 1383 bytes --]

On Tuesday, December 14, 2010 04:37:35 Andrew Stubbs wrote:
> On 13/12/10 18:43, Pedro Alves wrote:
> > Hmmm.  These last 6 look to be some kind of pseudo registers, not
> > part of the ISA -- I'm quite surprised to see these here, as
> > part of the bfin core register set.  I understand these to be
> > fdpic related; ISTR some discussion about making these be reported
> > with a new qXfer object?  That'd be better, IMO.
> 
> Right, the SH-2A FDPIC implementation uses qXfer to deal with the FDPIC
> settings. The SG++ gdb has a (more-or-less) target independent mechanism
> for retrieving the load maps. This has not been submitted upstream
> simply because it's not complete. The SH-2A FDPIC kernel does (did) not
> support breakpoints, and single stepping is (was) rather broken, so I
> never got further than being able to relocate the main program.
> 
> For SH-2A, at least, the kernel does not expose the load maps as
> registers, but has extra ptrace queries PTRACE_GETFDPIC_EXEC and
> PTRACE_GETFDPIC_INTERP.
> 
> The gdbserver reads these via qXfer:fdpic:read:exec and
> qXfer:fdpic:read:interp.

but the SuperH/FDPIC port is still out of tree right ?  so i cant review it to 
see if i can leverage it ...

if the gdbserver code can remain backwards compatible with the Linux ABI, then 
i dont have a problem changing to a qXfer style.
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdb: bfin: new port
  2010-12-14  6:03 ` [PATCH v2] gdb: " Joel Brobecker
@ 2010-12-14 16:14   ` Mike Frysinger
  0 siblings, 0 replies; 34+ messages in thread
From: Mike Frysinger @ 2010-12-14 16:14 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches, toolchain-devel

[-- Attachment #1: Type: Text/Plain, Size: 1664 bytes --]

On Tuesday, December 14, 2010 01:02:47 Joel Brobecker wrote:
> > 2010-11-16  Jie Zhang  <jie.zhang@analog.com>
> > 
> > 	* Makefile.in (ALLDEPFILES): Add bfin-tdep.c.
> > 	(HFILES_NO_SRCDIR): Add bfin-tdep.h.
> 
> (ALL_TARGET_OBS): Add bfin-tdep.o
> 
> > 	* NEWS: Mention new Blackfin port.
> > 	* bfin-tdep.c, bfin-tdep.h, config/bfin/bfin.mt: New files.
> > 	* configure.tgt (bfin-*-*): Handle bfin targets.
> 
> The syscall file is also missing.

ugh, sorry about that.  when i was squashing changesets in git, i forgot to 
merge the changelogs too.

> There are a couple of nits, highlighted below.  But the patch is
> pre-approved with those nits fixed as suggested. One little issue,
> though: Please make sure that Eli reviews the change in the NEWS
> file before checking in that part of the patch (it can be done
> separately).

Eli approved the changes as found in the original patch, and they are 
unchanged in this version, so i think that should be sufficient.

> > +#ifdef _DEBUG
> > +      fprintf (stderr, "frameless pc case base %x\n", cache->base);
> > +#endif
> 
> You forgot to remove the #ifdef DEBUG block...

indeed.  i went through your original feedback again to make sure i didnt miss 
anything else, and this seems to be the only one.

> > +/* Return the Blackfin ABI associated with GDBARCH.  */
> > +static inline enum bfin_abi
> > +bfin_abi (struct gdbarch *gdbarch)
> > +{
> > +  return gdbarch_tdep (gdbarch)->bfin_abi;
> > +}
> 
> Please define that function in bfin-tdep.c, and put a declaration in
> bfin-tdep.h instead.

ah, i see what you mean now in your previous feedback
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-14 15:10       ` Mike Frysinger
@ 2010-12-14 16:31         ` Pedro Alves
  2010-12-14 16:58           ` Mike Frysinger
  0 siblings, 1 reply; 34+ messages in thread
From: Pedro Alves @ 2010-12-14 16:31 UTC (permalink / raw)
  To: gdb-patches
  Cc: Mike Frysinger, Andrew Stubbs, toolchain-devel, Daniel Jacobowitz

On Tuesday 14 December 2010 15:09:43, Mike Frysinger wrote:
> if the gdbserver code can remain backwards compatible with the Linux ABI, then 
> i dont have a problem changing to a qXfer style.

I don't think there'd be a problem with that.  gdbserver can continue
fetching whatever it needs from the kernel using the ptrace registers
api, but that'd remain hidden from gdb (or the remote protocol).  Getting rid
of the fdpic pseudo registers from the core register set also presumably
unifies the gdb core register set with an eventual bare metal bfin
toolchain (btw, isn't there such a thing?) or any other eventual
non-fdpic bfin toolchain.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-14 16:31         ` Pedro Alves
@ 2010-12-14 16:58           ` Mike Frysinger
  2010-12-14 17:16             ` Andrew Stubbs
  2010-12-14 17:40             ` Pedro Alves
  0 siblings, 2 replies; 34+ messages in thread
From: Mike Frysinger @ 2010-12-14 16:58 UTC (permalink / raw)
  To: Pedro Alves
  Cc: gdb-patches, Andrew Stubbs, toolchain-devel, Daniel Jacobowitz

[-- Attachment #1: Type: Text/Plain, Size: 1087 bytes --]

On Tuesday, December 14, 2010 11:31:33 Pedro Alves wrote:
> On Tuesday 14 December 2010 15:09:43, Mike Frysinger wrote:
> > if the gdbserver code can remain backwards compatible with the Linux ABI,
> > then i dont have a problem changing to a qXfer style.
> 
> I don't think there'd be a problem with that.  gdbserver can continue
> fetching whatever it needs from the kernel using the ptrace registers
> api, but that'd remain hidden from gdb (or the remote protocol).  Getting
> rid of the fdpic pseudo registers from the core register set also
> presumably unifies the gdb core register set with an eventual bare metal
> bfin toolchain (btw, isn't there such a thing?) or any other eventual
> non-fdpic bfin toolchain.

thinking about it more, the gdb port atm doesnt support FDPIC.  so if the only 
contentious point of the gdbserver code is the FDPIC handling, then i can 
simply drop that and revisit when the Blackfin/FDPIC core code is merged.

we do Blackfin bare metal every day.  from the Blackfin side of things, it's 
the same as doing Linux/FLAT.
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-14 16:58           ` Mike Frysinger
@ 2010-12-14 17:16             ` Andrew Stubbs
  2010-12-14 17:26               ` Mike Frysinger
  2010-12-14 17:40             ` Pedro Alves
  1 sibling, 1 reply; 34+ messages in thread
From: Andrew Stubbs @ 2010-12-14 17:16 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Pedro Alves, gdb-patches, toolchain-devel, Daniel Jacobowitz

On 14/12/10 16:57, Mike Frysinger wrote:
> thinking about it more, the gdb port atm doesnt support FDPIC.  so if the only
> contentious point of the gdbserver code is the FDPIC handling, then i can
> simply drop that and revisit when the Blackfin/FDPIC core code is merged.
>
> we do Blackfin bare metal every day.  from the Blackfin side of things, it's
> the same as doing Linux/FLAT.
> -mike

GDB does have target specific FDPIC support for FRV, I think.

I did start implementing something vaguely target independent (included 
in CodeSourcery SG++), but the state of the SH-2A kernel debug support 
put that project on the back burner, so it remains the bare minimum.

Andrew


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-14 17:16             ` Andrew Stubbs
@ 2010-12-14 17:26               ` Mike Frysinger
  2010-12-15 11:54                 ` Andrew Stubbs
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2010-12-14 17:26 UTC (permalink / raw)
  To: Andrew Stubbs
  Cc: Pedro Alves, gdb-patches, toolchain-devel, Daniel Jacobowitz

[-- Attachment #1: Type: Text/Plain, Size: 979 bytes --]

On Tuesday, December 14, 2010 12:16:13 Andrew Stubbs wrote:
> On 14/12/10 16:57, Mike Frysinger wrote:
> > thinking about it more, the gdb port atm doesnt support FDPIC.  so if the
> > only contentious point of the gdbserver code is the FDPIC handling, then
> > i can simply drop that and revisit when the Blackfin/FDPIC core code is
> > merged.
> > 
> > we do Blackfin bare metal every day.  from the Blackfin side of things,
> > it's the same as doing Linux/FLAT.
> 
> GDB does have target specific FDPIC support for FRV, I think.

sorry, i meant gdbserver

> I did start implementing something vaguely target independent (included
> in CodeSourcery SG++), but the state of the SH-2A kernel debug support
> put that project on the back burner, so it remains the bare minimum.

i'm not asking for a finished project.  i would like to simply review the code 
you said you have already.  so where might one find your SuperH/FDPIC 
gdb/gdbserver code ?
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-14 16:58           ` Mike Frysinger
  2010-12-14 17:16             ` Andrew Stubbs
@ 2010-12-14 17:40             ` Pedro Alves
  2010-12-14 17:48               ` Mike Frysinger
  1 sibling, 1 reply; 34+ messages in thread
From: Pedro Alves @ 2010-12-14 17:40 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: gdb-patches, Andrew Stubbs, toolchain-devel, Daniel Jacobowitz

On Tuesday 14 December 2010 16:57:48, Mike Frysinger wrote:
> thinking about it more, the gdb port atm doesnt support FDPIC.  so if the only 
> contentious point of the gdbserver code is the FDPIC handling, then i can 
> simply drop that and revisit when the Blackfin/FDPIC core code is merged.

I think that's the best approach.  Would it be easy to split
the linux bits out of gdb/bfin-tdep.c into gdb/bfin-linux-tdep.c?
You could even push the bare metal (bfin-elf?) bits first without
any linux bits as a first step.

Please also get rid of gdb/config/bfin/bfin.mt -- .mt files have
long since been eliminated from gdb, the code that would go there you
already have in configure.tgt.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-14 17:40             ` Pedro Alves
@ 2010-12-14 17:48               ` Mike Frysinger
  2010-12-14 18:06                 ` Pedro Alves
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2010-12-14 17:48 UTC (permalink / raw)
  To: Pedro Alves
  Cc: gdb-patches, Andrew Stubbs, toolchain-devel, Daniel Jacobowitz

[-- Attachment #1: Type: Text/Plain, Size: 1452 bytes --]

On Tuesday, December 14, 2010 12:39:27 Pedro Alves wrote:
> On Tuesday 14 December 2010 16:57:48, Mike Frysinger wrote:
> > thinking about it more, the gdb port atm doesnt support FDPIC.  so if the
> > only contentious point of the gdbserver code is the FDPIC handling, then
> > i can simply drop that and revisit when the Blackfin/FDPIC core code is
> > merged.
> 
> I think that's the best approach.  Would it be easy to split
> the linux bits out of gdb/bfin-tdep.c into gdb/bfin-linux-tdep.c?
> You could even push the bare metal (bfin-elf?) bits first without
> any linux bits as a first step.

i imagine for someone who is a gdb expert, this would be trivial.  but it 
would require a bit of research on my side, so i'd prefer to not do this 
initially.  the code Joel is OK with supports both Blackfin bare metal and 
Blackfin Linux/FLAT.

i'll open a tracker item to get this stuff eventually split out, but i dont 
see it being done in a time frame that is before the gdb-7.3 release which i 
really want to be a part of.

> Please also get rid of gdb/config/bfin/bfin.mt -- .mt files have
> long since been eliminated from gdb, the code that would go there you
> already have in configure.tgt.

i couldnt find documentation on this file (or mts in general) so i was 
hesitant to touch it.  the only thing we have in there is to set the TDEPFILES 
variable, but i guess that too is no longer used anywhere ?
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-14 17:48               ` Mike Frysinger
@ 2010-12-14 18:06                 ` Pedro Alves
  2010-12-14 18:21                   ` Mike Frysinger
  0 siblings, 1 reply; 34+ messages in thread
From: Pedro Alves @ 2010-12-14 18:06 UTC (permalink / raw)
  To: gdb-patches
  Cc: Mike Frysinger, Andrew Stubbs, toolchain-devel, Daniel Jacobowitz

On Tuesday 14 December 2010 17:47:11, Mike Frysinger wrote:
> > I think that's the best approach.  Would it be easy to split
> > the linux bits out of gdb/bfin-tdep.c into gdb/bfin-linux-tdep.c?
> > You could even push the bare metal (bfin-elf?) bits first without
> > any linux bits as a first step.
> 
> i imagine for someone who is a gdb expert, this would be trivial.  but it 
> would require a bit of research on my side, so i'd prefer to not do this 
> initially.  the code Joel is OK with supports both Blackfin bare metal and 
> Blackfin Linux/FLAT.

Okay.

> 
> i'll open a tracker item to get this stuff eventually split out, but i dont 
> see it being done in a time frame that is before the gdb-7.3 release which i 
> really want to be a part of.

That's months away.  I think you're over estimating.  :-)

> 
> > Please also get rid of gdb/config/bfin/bfin.mt -- .mt files have
> > long since been eliminated from gdb, the code that would go there you
> > already have in configure.tgt.
> 
> i couldnt find documentation on this file (or mts in general) so i was 
> hesitant to touch it.  the only thing we have in there is to set the TDEPFILES 
> variable, but i guess that too is no longer used anywhere ?

Correct.  Those sets of TDEPFILES in .mt files got migrated to
configure.tgt where you now set gdb_target_obs (as you already have, your
.mt file in the patch is empty).  BTW, you should also include
linux-tdep.o in gdb_target_obs, and call linux_init_abi somewhere
in your GDB_OSABI_LINUX osabi handler.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-14 18:06                 ` Pedro Alves
@ 2010-12-14 18:21                   ` Mike Frysinger
  2010-12-15 16:54                     ` Mike Frysinger
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2010-12-14 18:21 UTC (permalink / raw)
  To: Pedro Alves
  Cc: gdb-patches, Andrew Stubbs, toolchain-devel, Daniel Jacobowitz

[-- Attachment #1: Type: Text/Plain, Size: 869 bytes --]

On Tuesday, December 14, 2010 13:06:19 Pedro Alves wrote:
> On Tuesday 14 December 2010 17:47:11, Mike Frysinger wrote:
> > i'll open a tracker item to get this stuff eventually split out, but i
> > dont see it being done in a time frame that is before the gdb-7.3
> > release which i really want to be a part of.
> 
> That's months away.  I think you're over estimating.  :-)

i'm pessimistic when it comes to absorbing knowledge of projects under 
sourceware.org ... it's an ecosystem unto itself.

> BTW, you should also include
> linux-tdep.o in gdb_target_obs, and call linux_init_abi somewhere
> in your GDB_OSABI_LINUX osabi handler.

i'm guessing this would depend on the bfin-linux-tdep split though as we 
currently dont have any osabi handlers.  this linux-tdep code is "new" as it 
wasnt in the version of gdb we're upgrading from.
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v3] gdb: bfin: new port
  2010-12-09  9:29 [PATCH v2] gdb: bfin: new port Mike Frysinger
  2010-12-09  9:31 ` [PATCH v2] gdbserver: " Mike Frysinger
  2010-12-14  6:03 ` [PATCH v2] gdb: " Joel Brobecker
@ 2010-12-14 20:43 ` Mike Frysinger
  2010-12-14 21:31   ` Pedro Alves
  2010-12-14 21:48   ` [PATCH v3] gdbserver: " Mike Frysinger
  2 siblings, 2 replies; 34+ messages in thread
From: Mike Frysinger @ 2010-12-14 20:43 UTC (permalink / raw)
  To: gdb-patches; +Cc: toolchain-devel, Jie Zhang

From: Jie Zhang <jie.zhang@analog.com>

Initial support for Blackfin processors.  This supports the standard ABI.

Signed-off-by: Jie Zhang <jie.zhang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>

2010-11-16  Jie Zhang  <jie.zhang@analog.com>

	* Makefile.in (ALLDEPFILES): Add bfin-tdep.c.
	(HFILES_NO_SRCDIR): Add bfin-tdep.h.
	(ALL_TARGET_OBS): Add bfin-tdep.o.
	* NEWS: Mention new Blackfin port.
	* bfin-tdep.c, bfin-tdep.h, syscalls/bfin-linux.xml: New files.
	* configure.tgt (bfin-*-*): Handle bfin targets.
---
here's what i'll commit by this weekend if there's no more feedback

v3
	- update changelog
	- drop bfin.mt file
	- drop debug define for real

 gdb/Makefile.in             |    4 +-
 gdb/NEWS                    |    4 +
 gdb/bfin-tdep.c             | 1078 +++++++++++++++++++++++++++++++++++++++++++
 gdb/bfin-tdep.h             |  111 +++++
 gdb/configure.tgt           |    5 +
 gdb/syscalls/bfin-linux.xml |  326 +++++++++++++
 6 files changed, 1527 insertions(+), 1 deletions(-)
 create mode 100644 gdb/bfin-tdep.c
 create mode 100644 gdb/bfin-tdep.h
 create mode 100644 gdb/syscalls/bfin-linux.xml

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index ff10039..5973c61 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -508,6 +508,7 @@ ALL_TARGET_OBS = \
 	armnbsd-tdep.o armobsd-tdep.o \
 	arm-tdep.o arm-wince-tdep.o \
 	avr-tdep.o \
+	bfin-tdep.o \
 	cris-tdep.o \
 	dicos-tdep.o \
 	frv-linux-tdep.o frv-tdep.o \
@@ -782,7 +783,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 ada-operator.inc microblaze-tdep.h \
-psymtab.h psympriv.h progspace.h
+psymtab.h psympriv.h progspace.h bfin-tdep.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -1420,6 +1421,7 @@ ALLDEPFILES = \
 	arm-linux-nat.c arm-linux-tdep.c arm-symbian-tdep.c arm-tdep.c \
 	armnbsd-nat.c armbsd-tdep.c armnbsd-tdep.c armobsd-tdep.c \
 	avr-tdep.c \
+	bfin-tdep.c \
 	bsd-uthread.c bsd-kvm.c \
 	core-regset.c corelow.c \
 	dcache.c dicos-tdep.c darwin-nat.c \
diff --git a/gdb/NEWS b/gdb/NEWS
index 559609b..633338a 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -108,6 +108,10 @@
   ** GDBserver is now supported on PowerPC LynxOS (versions 4.x and 5.x),
      and i686 LynxOS (version 5.x).
 
+* New targets:
+
+Analog Devices, Inc. Blackfin Processor	bfin-*
+
 * Ada task switching is now supported on sparc-elf targets when
   debugging a program using the Ravenscar Profile.  For more information,
   see the "Tasking Support when using the Ravenscar Profile" section
diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
new file mode 100644
index 0000000..648fd19
--- /dev/null
+++ b/gdb/bfin-tdep.c
@@ -0,0 +1,1078 @@
+/* Target-dependent code for Analog Devices Blackfin processer, for GDB.
+
+   Copyright (C) 2005-2010 Free Software Foundation, Inc.
+   Contributed by Analog Devices.
+
+   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 "gdb_string.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "arch-utils.h"
+#include "regcache.h"
+#include "frame.h"
+#include "frame-unwind.h"
+#include "frame-base.h"
+#include "trad-frame.h"
+#include "dis-asm.h"
+#include "gdb_assert.h"
+#include "dwarf2-frame.h"
+#include "symtab.h"
+#include "elf-bfd.h"
+#include "elf/bfin.h"
+#include "osabi.h"
+#include "infcall.h"
+#include "xml-syscall.h"
+#include "bfin-tdep.h"
+
+/* Macros used by prologue functions.  */
+#define P_LINKAGE			0xE800
+#define P_MINUS_SP1			0x0140
+#define P_MINUS_SP2			0x05C0
+#define P_MINUS_SP3			0x0540
+#define P_MINUS_SP4			0x04C0
+#define P_SP_PLUS			0x6C06
+#define P_P2_LOW			0xE10A
+#define P_P2_HIGH			0XE14A
+#define P_SP_EQ_SP_PLUS_P2		0X5BB2
+#define P_SP_EQ_P2_PLUS_SP		0x5B96
+#define P_MINUS_MINUS_SP_EQ_RETS	0x0167
+
+/* Macros used for program flow control.  */
+/* 16 bit instruction, max  */
+#define P_16_BIT_INSR_MAX		0xBFFF
+/* 32 bit instruction, min  */
+#define P_32_BIT_INSR_MIN		0xC000
+/* 32 bit instruction, max  */
+#define P_32_BIT_INSR_MAX		0xE801
+/* jump (preg), 16-bit, min  */
+#define P_JUMP_PREG_MIN			0x0050
+/* jump (preg), 16-bit, max  */
+#define P_JUMP_PREG_MAX			0x0057
+/* jump (pc+preg), 16-bit, min  */
+#define P_JUMP_PC_PLUS_PREG_MIN		0x0080
+/* jump (pc+preg), 16-bit, max  */
+#define P_JUMP_PC_PLUS_PREG_MAX		0x0087
+/* jump.s pcrel13m2, 16-bit, min  */
+#define P_JUMP_S_MIN			0x2000
+/* jump.s pcrel13m2, 16-bit, max  */
+#define P_JUMP_S_MAX			0x2FFF
+/* jump.l pcrel25m2, 32-bit, min  */
+#define P_JUMP_L_MIN			0xE200
+/* jump.l pcrel25m2, 32-bit, max  */
+#define P_JUMP_L_MAX			0xE2FF
+/* conditional jump pcrel11m2, 16-bit, min  */
+#define P_IF_CC_JUMP_MIN		0x1800
+/* conditional jump pcrel11m2, 16-bit, max  */
+#define P_IF_CC_JUMP_MAX		0x1BFF
+/* conditional jump(bp) pcrel11m2, 16-bit, min  */
+#define P_IF_CC_JUMP_BP_MIN		0x1C00
+/* conditional jump(bp) pcrel11m2, 16-bit, max  */
+#define P_IF_CC_JUMP_BP_MAX		0x1FFF
+/* conditional !jump pcrel11m2, 16-bit, min  */
+#define P_IF_NOT_CC_JUMP_MIN		0x1000
+/* conditional !jump pcrel11m2, 16-bit, max  */
+#define P_IF_NOT_CC_JUMP_MAX		0x13FF
+/* conditional jump(bp) pcrel11m2, 16-bit, min  */
+#define P_IF_NOT_CC_JUMP_BP_MIN		0x1400
+/* conditional jump(bp) pcrel11m2, 16-bit, max  */
+#define P_IF_NOT_CC_JUMP_BP_MAX		0x17FF
+/* call (preg), 16-bit, min  */
+#define P_CALL_PREG_MIN			0x0060
+/* call (preg), 16-bit, max  */
+#define P_CALL_PREG_MAX			0x0067
+/* call (pc+preg), 16-bit, min  */
+#define P_CALL_PC_PLUS_PREG_MIN		0x0070
+/* call (pc+preg), 16-bit, max  */
+#define P_CALL_PC_PLUS_PREG_MAX		0x0077
+/* call pcrel25m2, 32-bit, min  */
+#define P_CALL_MIN			0xE300
+/* call pcrel25m2, 32-bit, max  */
+#define P_CALL_MAX			0xE3FF
+/* RTS  */
+#define P_RTS				0x0010
+/* MNOP  */
+#define P_MNOP				0xC803
+/* EXCPT, 16-bit, min  */
+#define P_EXCPT_MIN			0x00A0
+/* EXCPT, 16-bit, max  */
+#define P_EXCPT_MAX			0x00AF
+/* multi instruction mask 1, 16-bit  */
+#define P_BIT_MULTI_INS_1		0xC000
+/* multi instruction mask 2, 16-bit  */
+#define P_BIT_MULTI_INS_2		0x0800
+
+/* Macros used for signal handling  */
+/* Instruction 1 for signal  */
+#define P_SIGNAL_INS_1			0x00ADE128
+/* Instruction 2 for signal  */
+#define P_SIGNAL_INS_2			0x000000A0
+
+/* The maximum bytes we search to skip the prologue.  */
+#define UPPER_LIMIT			40
+
+#define RETS_OFFSET			4
+
+/* Initial value: Register names used in BFIN's ISA documentation.  */
+
+static const char * const bfin_register_name_strings[] =
+{
+  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+  "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
+  "i0", "i1", "i2", "i3", "m0", "m1", "m2", "m3",
+  "b0", "b1", "b2", "b3", "l0", "l1", "l2", "l3",
+  "a0x", "a0w", "a1x", "a1w", "astat", "rets",
+  "lc0", "lt0", "lb0", "lc1", "lt1", "lb1", "cycles", "cycles2",
+  "usp", "seqstat", "syscfg", "reti", "retx", "retn", "rete",
+  "pc", "cc",
+  "text_addr", "text_end_addr", "data_addr", "fdpic_exec", "fdpic_interp",
+  "ipend"
+};
+
+#define NUM_BFIN_REGNAMES ARRAY_SIZE (bfin_register_name_strings)
+
+
+/* In this diagram successive memory locations increase downwards or the
+   stack grows upwards with negative indices.  (PUSH analogy for stack.)
+
+   The top frame is the "frame" of the current function being executed.
+
+     +--------------+ SP    -
+     |  local vars  |       ^
+     +--------------+       |
+     |  save regs   |       |
+     +--------------+ FP    |
+     |   old FP    -|--    top
+     +--------------+  |  frame
+     |    RETS      |  |    |
+     +--------------+  |    |
+     |   param 1    |  |    |
+     |   param 2    |  |    |
+     |    ...       |  |    V
+     +--------------+  |    -
+     |  local vars  |  |    ^
+     +--------------+  |    |
+     |  save regs   |  |    |
+     +--------------+<-     |
+     |   old FP    -|--   next
+     +--------------+  |  frame
+     |    RETS      |  |    |
+     +--------------+  |    |
+     |   param 1    |  |    |
+     |   param 2    |  |    |
+     |    ...       |  |    V
+     +--------------+  |    -
+     |  local vars  |  |    ^
+     +--------------+  |    |
+     |  save regs   |  |    |
+     +--------------+<-  next frame
+     |   old FP     |       |
+     +--------------+       |
+     |    RETS      |       V
+     +--------------+       -
+
+   The frame chain is formed as following:
+
+     FP has the topmost frame.
+     FP + 4 has the previous FP and so on.  */
+
+
+/* Map from DWARF2 register number to GDB register number.  */
+
+static const int map_gcc_gdb[] =
+{
+  BFIN_R0_REGNUM,
+  BFIN_R1_REGNUM,
+  BFIN_R2_REGNUM,
+  BFIN_R3_REGNUM,
+  BFIN_R4_REGNUM,
+  BFIN_R5_REGNUM,
+  BFIN_R6_REGNUM,
+  BFIN_R7_REGNUM,
+  BFIN_P0_REGNUM,
+  BFIN_P1_REGNUM,
+  BFIN_P2_REGNUM,
+  BFIN_P3_REGNUM,
+  BFIN_P4_REGNUM,
+  BFIN_P5_REGNUM,
+  BFIN_SP_REGNUM,
+  BFIN_FP_REGNUM,
+  BFIN_I0_REGNUM,
+  BFIN_I1_REGNUM,
+  BFIN_I2_REGNUM,
+  BFIN_I3_REGNUM,
+  BFIN_B0_REGNUM,
+  BFIN_B1_REGNUM,
+  BFIN_B2_REGNUM,
+  BFIN_B3_REGNUM,
+  BFIN_L0_REGNUM,
+  BFIN_L1_REGNUM,
+  BFIN_L2_REGNUM,
+  BFIN_L3_REGNUM,
+  BFIN_M0_REGNUM,
+  BFIN_M1_REGNUM,
+  BFIN_M2_REGNUM,
+  BFIN_M3_REGNUM,
+  BFIN_A0_DOT_X_REGNUM,
+  BFIN_A1_DOT_X_REGNUM,
+  BFIN_CC_REGNUM,
+  BFIN_RETS_REGNUM,
+  BFIN_RETI_REGNUM,
+  BFIN_RETX_REGNUM,
+  BFIN_RETN_REGNUM,
+  BFIN_RETE_REGNUM,
+  BFIN_ASTAT_REGNUM,
+  BFIN_SEQSTAT_REGNUM,
+  BFIN_USP_REGNUM,
+  BFIN_LT0_REGNUM,
+  BFIN_LT1_REGNUM,
+  BFIN_LC0_REGNUM,
+  BFIN_LC1_REGNUM,
+  BFIN_LB0_REGNUM,
+  BFIN_LB1_REGNUM
+};
+
+
+#define SIGCONTEXT_OFFSET	168
+
+
+/* From <asm/sigcontext.h>.  */
+
+static int bfin_linux_sigcontext_reg_offset[BFIN_NUM_REGS] =
+{
+  0 * 4,	/* %r0 */
+  1 * 4,	/* %r1 */
+  2 * 4,	/* %r2 */
+  3 * 4,	/* %r3 */
+  4 * 4,	/* %r4 */
+  5 * 4,	/* %r5 */
+  6 * 4,	/* %r6 */
+  7 * 4,	/* %r7 */
+  8 * 4,	/* %p0 */
+  9 * 4,	/* %p1 */
+  10 * 4,	/* %p2 */
+  11 * 4,	/* %p3 */
+  12 * 4,	/* %p4 */
+  13 * 4,	/* %p5 */
+  14 * 4,	/* %sp */
+  23 * 4,	/* %fp */
+  24 * 4,	/* %i0 */
+  25 * 4,	/* %i1 */
+  26 * 4,	/* %i2 */
+  27 * 4,	/* %i3 */
+  28 * 4,	/* %m0 */
+  29 * 4,	/* %m1 */
+  30 * 4,	/* %m2 */
+  31 * 4,	/* %m3 */
+  36 * 4,	/* %b0 */
+  37 * 4,	/* %b1 */
+  38 * 4,	/* %b2 */
+  39 * 4,	/* %b3 */
+  32 * 4,	/* %l0 */
+  33 * 4,	/* %l1 */
+  34 * 4,	/* %l2 */
+  35 * 4,	/* %l3 */
+  17 * 4,	/* %a0x */
+  15 * 4,	/* %a0w */
+  18 * 4,	/* %a1x */
+  16 * 4,	/* %a1w */
+  19 * 4,	/* %astat */
+  20 * 4,	/* %rets */
+  40 * 4,	/* %lc0 */
+  42 * 4,	/* %lt0 */
+  44 * 4,	/* %lb0 */
+  41 * 4,	/* %lc1 */
+  43 * 4,	/* %lt1 */
+  45 * 4,	/* %lb1 */
+  -1,		/* %cycles */
+  -1,		/* %cycles2 */
+  -1,		/* %usp */
+  46 * 4,	/* %seqstat */
+  -1,		/* syscfg */
+  21 * 4,	/* %reti */
+  22 * 4,	/* %retx */
+  -1,		/* %retn */
+  -1,		/* %rete */
+  21 * 4,	/* %pc */
+  -1,		/* %cc */
+  -1,		/* %text_addr */
+  -1,		/* %text_end_addr*/
+  -1,		/* %data_addr*/
+  -1		/* %ipend */
+};
+
+/* Get info about saved registers in sigtramp.  */
+
+struct bfin_linux_sigtramp_info
+{
+  /* Address of context.  */
+  CORE_ADDR context_addr;
+
+  /* Offset of registers in `struct sigcontext'.  */
+  int *sc_reg_offset;
+};
+
+/* Return nonzero if PC points into the signal trampoline.  For the
+   sake of bfin_linux_get_sigtramp_info.  */
+
+static int
+bfin_linux_pc_in_sigtramp (struct frame_info *this_frame, CORE_ADDR pc)
+{
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  gdb_byte buf[10];
+  gdb_byte *p;
+  unsigned long insn1, insn2;
+
+  if (pc > (CORE_ADDR) 0x7ffffffe
+      /* When the core is locked, the PC is unavailable.
+	 It makes no sense to check further.  */
+      || regcache_valid_p (get_current_regcache (), BFIN_PC_REGNUM) < 0
+      || !safe_frame_unwind_memory (this_frame, pc, buf + 4, 2))
+    return 0;
+
+  insn1 = extract_unsigned_integer (buf + 4, 2, byte_order);
+
+  if (insn1 == (P_SIGNAL_INS_1 & 0xffff))
+    {
+      if (pc > (CORE_ADDR) 0x7ffffffa
+	  || !safe_frame_unwind_memory (this_frame, pc + 2, buf + 6, 4))
+	return 0;
+      p = buf + 4;
+    }
+  else if (insn1 == P_SIGNAL_INS_2)
+    {
+      if (pc < (CORE_ADDR) 4
+	  || !safe_frame_unwind_memory (this_frame, pc - 4, buf, 4))
+	return 0;
+      p = buf;
+    }
+  else
+    return 0;
+
+  insn1 = extract_unsigned_integer (p, 4, byte_order);
+  insn2 = extract_unsigned_integer (p + 4, 2, byte_order);
+
+  if (insn1 == P_SIGNAL_INS_1 && insn2 == P_SIGNAL_INS_2)
+    return 1;
+
+  return 0;
+}
+
+static struct bfin_linux_sigtramp_info
+bfin_linux_get_sigtramp_info (struct frame_info *this_frame)
+{
+  CORE_ADDR sp;
+  int ret;
+  struct bfin_linux_sigtramp_info info;
+
+  sp = frame_unwind_register_unsigned (this_frame, BFIN_SP_REGNUM);
+  ret = bfin_linux_pc_in_sigtramp (this_frame, get_frame_pc (this_frame));
+
+  gdb_assert (ret == 1);
+
+  /* Get sigcontext address.  */
+  info.context_addr = sp + SIGCONTEXT_OFFSET;
+  info.sc_reg_offset = bfin_linux_sigcontext_reg_offset;
+
+  return info;
+}
+
+/* Signal trampolines.  */
+
+static struct trad_frame_cache *
+bfin_linux_sigtramp_frame_cache (struct frame_info *this_frame,
+				 void **this_cache)
+{
+  struct frame_id this_id;
+  struct trad_frame_cache *cache;
+  struct bfin_linux_sigtramp_info info;
+  CORE_ADDR sp;
+  int i;
+
+  if (*this_cache)
+    return *this_cache;
+
+  cache = trad_frame_cache_zalloc (this_frame);
+
+  /* The frame ID's code address should be the start-address of the
+     signal trampoline and not the current PC within that trampoline.  */
+  sp = get_frame_register_unsigned (this_frame, BFIN_SP_REGNUM);
+
+  /* This would come after the LINK instruction in the ret_from_signal
+     function, hence the frame id would be SP + 8.  */
+  this_id = frame_id_build (sp + 8, get_frame_pc (this_frame));
+  trad_frame_set_id (cache, this_id);
+
+  info = bfin_linux_get_sigtramp_info (this_frame);
+
+  for (i = 0; i < BFIN_NUM_REGS; i++)
+    if (info.sc_reg_offset[i] != -1)
+      trad_frame_set_reg_addr (cache, i,
+			       info.context_addr + info.sc_reg_offset[i]);
+
+  *this_cache = cache;
+  return cache;
+}
+
+static void
+bfin_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
+				   void **this_cache,
+				   struct frame_id *this_id)
+{
+  struct trad_frame_cache *cache;
+
+  cache = bfin_linux_sigtramp_frame_cache (this_frame, this_cache);
+  trad_frame_get_id (cache, this_id);
+}
+
+static struct value *
+bfin_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
+					 void **this_cache,
+					 int regnum)
+{
+  struct trad_frame_cache *cache;
+
+  cache = bfin_linux_sigtramp_frame_cache (this_frame, this_cache);
+  return trad_frame_get_register (cache, this_frame, regnum);
+}
+
+static int
+bfin_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
+				   struct frame_info *this_frame,
+				   void **this_cache)
+{
+  CORE_ADDR pc = get_frame_pc (this_frame);
+
+  if (bfin_linux_pc_in_sigtramp (this_frame, pc))
+    return 1;
+
+  return 0;
+}
+
+static const struct frame_unwind bfin_linux_sigtramp_frame_unwind =
+{
+  SIGTRAMP_FRAME,
+  bfin_linux_sigtramp_frame_this_id,
+  bfin_linux_sigtramp_frame_prev_register,
+  NULL,
+  bfin_linux_sigtramp_frame_sniffer
+};
+
+
+static LONGEST
+bfin_linux_get_syscall_number (struct gdbarch *gdbarch,
+                               ptid_t ptid)
+{
+  struct regcache *regcache = get_thread_regcache (ptid);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  /* The content of a register.  */
+  gdb_byte buf[4];
+  /* The result.  */
+  LONGEST ret;
+
+  /* Getting the system call number from the register.
+     When dealing with Blackfin architecture, this information
+     is stored at %p0 register.  */
+  regcache_cooked_read (regcache, BFIN_P0_REGNUM, buf);
+
+  ret = extract_signed_integer (buf, 4, byte_order);
+
+  return ret;
+}
+
+
+struct bfin_frame_cache
+{
+  /* Base address.  */
+  CORE_ADDR base;
+  CORE_ADDR sp_offset;
+  CORE_ADDR pc;
+  int frameless_pc_value;
+
+  /* Saved registers.  */
+  CORE_ADDR saved_regs[BFIN_NUM_REGS];
+  CORE_ADDR saved_sp;
+
+  /* Stack space reserved for local variables.  */
+  long locals;
+};
+
+/* Allocate and initialize a frame cache.  */
+
+static struct bfin_frame_cache *
+bfin_alloc_frame_cache (void)
+{
+  struct bfin_frame_cache *cache;
+  int i;
+
+  cache = FRAME_OBSTACK_ZALLOC (struct bfin_frame_cache);
+
+  /* Base address.  */
+  cache->base = 0;
+  cache->sp_offset = -4;
+  cache->pc = 0;
+  cache->frameless_pc_value = 0;
+
+  /* Saved registers.  We initialize these to -1 since zero is a valid
+     offset (that's where fp is supposed to be stored).  */
+  for (i = 0; i < BFIN_NUM_REGS; i++)
+    cache->saved_regs[i] = -1;
+
+  /* Frameless until proven otherwise.  */
+  cache->locals = -1;
+
+  return cache;
+}
+
+static struct bfin_frame_cache *
+bfin_frame_cache (struct frame_info *this_frame, void **this_cache)
+{
+  struct bfin_frame_cache *cache;
+  int i;
+
+  if (*this_cache)
+    return *this_cache;
+
+  cache = bfin_alloc_frame_cache ();
+  *this_cache = cache;
+
+  cache->base = get_frame_register_unsigned (this_frame, BFIN_FP_REGNUM);
+  if (cache->base == 0)
+    return cache;
+
+  /* For normal frames, PC is stored at [FP + 4].  */
+  cache->saved_regs[BFIN_PC_REGNUM] = 4;
+  cache->saved_regs[BFIN_FP_REGNUM] = 0;
+
+  /* Adjust all the saved registers such that they contain addresses
+     instead of offsets.  */
+  for (i = 0; i < BFIN_NUM_REGS; i++)
+    if (cache->saved_regs[i] != -1)
+      cache->saved_regs[i] += cache->base;
+
+  cache->pc = get_frame_func (this_frame) ;
+  if (cache->pc == 0 || cache->pc == get_frame_pc (this_frame))
+    {
+      /* Either there is no prologue (frameless function) or we are at
+	 the start of a function.  In short we do not have a frame.
+	 PC is stored in rets register.  FP points to previous frame.  */
+
+      cache->saved_regs[BFIN_PC_REGNUM] =
+	get_frame_register_unsigned (this_frame, BFIN_RETS_REGNUM);
+      cache->frameless_pc_value = 1;
+      cache->base = get_frame_register_unsigned (this_frame, BFIN_FP_REGNUM);
+      cache->saved_regs[BFIN_FP_REGNUM] = cache->base;
+      cache->saved_sp = cache->base;
+    }
+  else
+    {
+      cache->frameless_pc_value = 0;
+
+      /* Now that we have the base address for the stack frame we can
+	 calculate the value of SP in the calling frame.  */
+      cache->saved_sp = cache->base + 8;
+    }
+
+  return cache;
+}
+
+static void
+bfin_frame_this_id (struct frame_info *this_frame,
+		    void **this_cache,
+		    struct frame_id *this_id)
+{
+  struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
+
+  /* This marks the outermost frame.  */
+  if (cache->base == 0)
+    return;
+
+  /* See the end of bfin_push_dummy_call.  */
+  *this_id = frame_id_build (cache->base + 8, cache->pc);
+}
+
+static struct value *
+bfin_frame_prev_register (struct frame_info *this_frame,
+			  void **this_cache,
+			  int regnum)
+{
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
+
+  if (regnum == gdbarch_sp_regnum (gdbarch) && cache->saved_sp)
+    return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
+
+  if (regnum < BFIN_NUM_REGS && cache->saved_regs[regnum] != -1)
+    return frame_unwind_got_memory (this_frame, regnum,
+				    cache->saved_regs[regnum]);
+
+  return frame_unwind_got_register (this_frame, regnum, regnum);
+}
+
+static const struct frame_unwind bfin_frame_unwind =
+{
+  NORMAL_FRAME,
+  bfin_frame_this_id,
+  bfin_frame_prev_register,
+  NULL,
+  default_frame_sniffer
+};
+
+/* Check for "[--SP] = <reg>;" insns.  These are appear in function
+   prologues to save misc registers onto the stack.  */
+
+static int
+is_minus_minus_sp (int op)
+{
+  op &= 0xFFC0;
+
+  if ((op == P_MINUS_SP1) || (op == P_MINUS_SP2)
+      || (op == P_MINUS_SP3) || (op == P_MINUS_SP4))
+    return 1;
+
+  return 0;
+}
+
+/* Skip all the insns that appear in generated function prologues.  */
+
+static CORE_ADDR
+bfin_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  int op = read_memory_unsigned_integer (pc, 2, byte_order);
+  CORE_ADDR orig_pc = pc;
+  int done = 0;
+
+  /* The new gcc prologue generates the register saves BEFORE the link
+     or RETS saving instruction.
+     So, our job is to stop either at those instructions or some upper
+     limit saying there is no frame!  */
+
+  while (!done)
+    {
+      if (is_minus_minus_sp (op))
+	{
+	  while (is_minus_minus_sp (op))
+	    {
+	      pc += 2;
+	      op = read_memory_unsigned_integer (pc, 2, byte_order);
+	    }
+
+	  if (op == P_LINKAGE)
+	    pc += 4;
+
+	  done = 1;
+	}
+      else if (op == P_LINKAGE)
+	{
+	  pc += 4;
+	  done = 1;
+	}
+      else if (op == P_MINUS_MINUS_SP_EQ_RETS)
+	{
+	  pc += 2;
+	  done = 1;
+	}
+      else if (op == P_RTS)
+	{
+	  done = 1;
+	}
+      else if ((op >= P_JUMP_PREG_MIN && op <= P_JUMP_PREG_MAX)
+	       || (op >= P_JUMP_PC_PLUS_PREG_MIN
+		   && op <= P_JUMP_PC_PLUS_PREG_MAX)
+	       || (op == P_JUMP_S_MIN && op <= P_JUMP_S_MAX))
+	{
+	  done = 1;
+	}
+      else if (pc - orig_pc >= UPPER_LIMIT)
+	{
+	  warning (_("Function Prologue not recognised; pc will point to ENTRY_POINT of the function"));
+	  pc = orig_pc + 2;
+	  done = 1;
+	}
+      else
+	{
+	  pc += 2; /* Not a terminating instruction go on.  */
+	  op = read_memory_unsigned_integer (pc, 2, byte_order);
+	}
+    }
+
+   /* TODO:
+      Dwarf2 uses entry point value AFTER some register initializations.
+      We should perhaps skip such asssignments as well (R6 = R1, ...).  */
+
+  return pc;
+}
+
+/* Return the GDB type object for the "standard" data type of data in
+   register N.  This should be void pointer for P0-P5, SP, FP;
+   void pointer to function for PC; int otherwise.  */
+
+static struct type *
+bfin_register_type (struct gdbarch *gdbarch, int regnum)
+{
+  if ((regnum >= BFIN_P0_REGNUM && regnum <= BFIN_FP_REGNUM)
+      || regnum == BFIN_USP_REGNUM)
+    return builtin_type (gdbarch)->builtin_data_ptr;
+
+  if (regnum == BFIN_PC_REGNUM || regnum == BFIN_RETS_REGNUM)
+    return builtin_type (gdbarch)->builtin_func_ptr;
+
+  return builtin_type (gdbarch)->builtin_int32;
+}
+
+static CORE_ADDR
+bfin_push_dummy_call (struct gdbarch *gdbarch,
+		      struct value *function,
+		      struct regcache *regcache,
+		      CORE_ADDR bp_addr,
+		      int nargs,
+		      struct value **args,
+		      CORE_ADDR sp,
+		      int struct_return,
+		      CORE_ADDR struct_addr)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  char buf[4];
+  int i;
+  long reg_r0, reg_r1, reg_r2;
+  int total_len = 0;
+  enum bfin_abi abi = bfin_abi (gdbarch);
+  CORE_ADDR func_addr = find_function_addr (function, NULL);
+
+  for (i = nargs - 1; i >= 0; i--)
+    {
+      struct type *value_type = value_enclosing_type (args[i]);
+      int len = TYPE_LENGTH (value_type);
+
+      total_len += (len + 3) & ~3;
+    }
+
+  /* At least twelve bytes of stack space must be allocated for the function's
+     arguments, even for functions that have less than 12 bytes of argument
+     data.  */
+
+  if (total_len < 12)
+    sp -= 12 - total_len;
+
+  /* Push arguments in reverse order.  */
+
+  for (i = nargs - 1; i >= 0; i--)
+    {
+      struct type *value_type = value_enclosing_type (args[i]);
+      struct type *arg_type = check_typedef (value_type);
+      int len = TYPE_LENGTH (value_type);
+      int container_len = (len + 3) & ~3;
+
+      sp -= container_len;
+      write_memory (sp, value_contents_writeable (args[i]), container_len);
+    }
+
+  /* initialize R0, R1 and R2 to the first 3 words of paramters */
+
+  reg_r0 = read_memory_integer (sp, 4, byte_order);
+  regcache_cooked_write_unsigned (regcache, BFIN_R0_REGNUM, reg_r0);
+  reg_r1 = read_memory_integer (sp + 4, 4, byte_order);
+  regcache_cooked_write_unsigned (regcache, BFIN_R1_REGNUM, reg_r1);
+  reg_r2 = read_memory_integer (sp + 8, 4, byte_order);
+  regcache_cooked_write_unsigned (regcache, BFIN_R2_REGNUM, reg_r2);
+
+  /* Store struct value address.  */
+
+  if (struct_return)
+    regcache_cooked_write_unsigned (regcache, BFIN_P0_REGNUM, struct_addr);
+
+  /* Set the dummy return value to bp_addr.
+     A dummy breakpoint will be setup to execute the call.  */
+
+  regcache_cooked_write_unsigned (regcache, BFIN_RETS_REGNUM, bp_addr);
+
+  /* Finally, update the stack pointer.  */
+
+  regcache_cooked_write_unsigned (regcache, BFIN_SP_REGNUM, sp);
+
+  return sp;
+}
+
+/* Convert DWARF2 register number REG to the appropriate register number
+   used by GDB.  */
+
+static int
+bfin_reg_to_regnum (struct gdbarch *gdbarch, int reg)
+{
+  if (reg > ARRAY_SIZE (map_gcc_gdb))
+    return 0;
+
+  return map_gcc_gdb[reg];
+}
+
+/* This function implements the BREAKPOINT_FROM_PC macro.  It returns
+   a pointer to a string of bytes that encode a breakpoint instruction,
+   stores the length of the string to *lenptr, and adjusts the program
+   counter (if necessary) to point to the actual memory location where
+   the breakpoint should be inserted.  */
+
+static const unsigned char *
+bfin_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  unsigned short iw;
+  static unsigned char bfin_breakpoint[] = {0xa1, 0x00, 0x00, 0x00};
+  static unsigned char bfin_sim_breakpoint[] = {0x25, 0x00, 0x00, 0x00};
+
+  iw = read_memory_unsigned_integer (*pcptr, 2, byte_order);
+
+  if ((iw & 0xf000) >= 0xc000)
+    /* 32-bit instruction.  */
+    *lenptr = 4;
+  else
+    *lenptr = 2;
+
+  if (strcmp (target_shortname, "sim") == 0)
+    return bfin_sim_breakpoint;
+  else
+    return bfin_breakpoint;
+}
+
+static void
+bfin_extract_return_value (struct type *type,
+			   struct regcache *regs,
+			   gdb_byte *dst)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regs);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  bfd_byte *valbuf = dst;
+  int len = TYPE_LENGTH (type);
+  ULONGEST tmp;
+  int regno = BFIN_R0_REGNUM;
+
+  gdb_assert (len <= 8);
+
+  while (len > 0)
+    {
+      regcache_cooked_read_unsigned (regs, regno++, &tmp);
+      store_unsigned_integer (valbuf, (len > 4 ? 4 : len), tmp, byte_order);
+      len -= 4;
+      valbuf += 4;
+    }
+}
+
+/* Write into appropriate registers a function return value of type
+   TYPE, given in virtual format.  */
+
+static void
+bfin_store_return_value (struct type *type,
+			 struct regcache *regs,
+			 const gdb_byte *src)
+{
+  const bfd_byte *valbuf = src;
+
+  /* Integral values greater than one word are stored in consecutive
+     registers starting with R0.  This will always be a multiple of
+     the register size.  */
+
+  int len = TYPE_LENGTH (type);
+  int regno = BFIN_R0_REGNUM;
+
+  gdb_assert (len <= 8);
+
+  while (len > 0)
+    {
+      regcache_cooked_write (regs, regno++, valbuf);
+      len -= 4;
+      valbuf += 4;
+    }
+}
+
+/* Determine, for architecture GDBARCH, how a return value of TYPE
+   should be returned.  If it is supposed to be returned in registers,
+   and READBUF is nonzero, read the appropriate value from REGCACHE,
+   and copy it into READBUF.  If WRITEBUF is nonzero, write the value
+   from WRITEBUF into REGCACHE.  */
+
+static enum return_value_convention
+bfin_return_value (struct gdbarch *gdbarch,
+		   struct type *func_type,
+		   struct type *type,
+		   struct regcache *regcache,
+		   gdb_byte *readbuf,
+		   const gdb_byte *writebuf)
+{
+  if (TYPE_LENGTH (type) > 8)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+
+  if (readbuf)
+    bfin_extract_return_value (type, regcache, readbuf);
+
+  if (writebuf)
+    bfin_store_return_value (type, regcache, writebuf);
+
+  return RETURN_VALUE_REGISTER_CONVENTION;
+}
+
+/* Return the BFIN register name corresponding to register I.  */
+
+static const char *
+bfin_register_name (struct gdbarch *gdbarch, int i)
+{
+  return bfin_register_name_strings[i];
+}
+
+static CORE_ADDR
+bfin_frame_base_address (struct frame_info *this_frame, void **this_cache)
+{
+  struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
+
+  return cache->base;
+}
+
+static CORE_ADDR
+bfin_frame_local_address (struct frame_info *this_frame, void **this_cache)
+{
+  struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
+
+  return cache->base - 4;
+}
+
+static CORE_ADDR
+bfin_frame_args_address (struct frame_info *this_frame, void **this_cache)
+{
+  struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
+
+  return cache->base + 8;
+}
+
+static const struct frame_base bfin_frame_base =
+{
+  &bfin_frame_unwind,
+  bfin_frame_base_address,
+  bfin_frame_local_address,
+  bfin_frame_args_address
+};
+
+static struct frame_id
+bfin_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+  CORE_ADDR sp;
+
+  sp = get_frame_register_unsigned (this_frame, BFIN_SP_REGNUM);
+
+  return frame_id_build (sp, get_frame_pc (this_frame));
+}
+
+static CORE_ADDR
+bfin_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  return frame_unwind_register_unsigned (next_frame, BFIN_PC_REGNUM);
+}
+
+static CORE_ADDR
+bfin_frame_align (struct gdbarch *gdbarch, CORE_ADDR address)
+{
+  return (address & ~0x3);
+}
+
+enum bfin_abi
+bfin_abi (struct gdbarch *gdbarch)
+{
+  return gdbarch_tdep (gdbarch)->bfin_abi;
+}
+
+/* Initialize the current architecture based on INFO.  If possible,
+   re-use an architecture from ARCHES, which is a list of
+   architectures already created during this debugging session.
+
+   Called e.g. at program startup, when reading a core file, and when
+   reading a binary file.  */
+
+static struct gdbarch *
+bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+  struct gdbarch_tdep *tdep;
+  struct gdbarch *gdbarch;
+  int elf_flags;
+  enum bfin_abi abi;
+
+  /* Extract the ELF flags, if available.  */
+  if (info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
+    elf_flags = elf_elfheader (info.abfd)->e_flags;
+  else
+    elf_flags = 0;
+
+  abi = BFIN_ABI_FLAT;
+
+  /* If there is already a candidate, use it.  */
+
+  for (arches = gdbarch_list_lookup_by_info (arches, &info);
+       arches != NULL;
+       arches = gdbarch_list_lookup_by_info (arches->next, &info))
+    {
+      if (gdbarch_tdep (arches->gdbarch)->bfin_abi != abi)
+	continue;
+      return arches->gdbarch;
+    }
+
+  tdep = XMALLOC (struct gdbarch_tdep);
+  gdbarch = gdbarch_alloc (&info, tdep);
+
+  tdep->bfin_abi = abi;
+
+  set_gdbarch_num_regs (gdbarch, BFIN_NUM_REGS);
+  set_gdbarch_num_pseudo_regs (gdbarch, 0);
+  set_gdbarch_sp_regnum (gdbarch, BFIN_SP_REGNUM);
+  set_gdbarch_pc_regnum (gdbarch, BFIN_PC_REGNUM);
+  set_gdbarch_ps_regnum (gdbarch, BFIN_ASTAT_REGNUM);
+  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, bfin_reg_to_regnum);
+  set_gdbarch_register_name (gdbarch, bfin_register_name);
+  set_gdbarch_register_type (gdbarch, bfin_register_type);
+  set_gdbarch_dummy_id (gdbarch, bfin_dummy_id);
+  set_gdbarch_push_dummy_call (gdbarch, bfin_push_dummy_call);
+  set_gdbarch_believe_pcc_promotion (gdbarch, 1);
+  set_gdbarch_return_value (gdbarch, bfin_return_value);
+  set_gdbarch_skip_prologue (gdbarch, bfin_skip_prologue);
+  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+  set_gdbarch_breakpoint_from_pc (gdbarch, bfin_breakpoint_from_pc);
+  set_gdbarch_decr_pc_after_break (gdbarch, 2);
+  set_gdbarch_frame_args_skip (gdbarch, 8);
+  set_gdbarch_unwind_pc (gdbarch, bfin_unwind_pc);
+  set_gdbarch_frame_align (gdbarch, bfin_frame_align);
+  set_gdbarch_print_insn (gdbarch, print_insn_bfin);
+
+  /* Hook in ABI-specific overrides, if they have been registered.  */
+  gdbarch_init_osabi (info, gdbarch);
+
+  dwarf2_append_unwinders (gdbarch);
+
+  frame_base_set_default (gdbarch, &bfin_frame_base);
+
+  frame_unwind_append_unwinder (gdbarch, &bfin_frame_unwind);
+
+  /* Functions for 'catch syscall'.  */
+  set_xml_syscall_file_name ("syscalls/bfin-linux.xml");
+  set_gdbarch_get_syscall_number (gdbarch,
+                                  bfin_linux_get_syscall_number);
+
+  return gdbarch;
+}
+
+void
+_initialize_bfin_tdep (void)
+{
+  register_gdbarch_init (bfd_arch_bfin, bfin_gdbarch_init);
+}
diff --git a/gdb/bfin-tdep.h b/gdb/bfin-tdep.h
new file mode 100644
index 0000000..ad288c4
--- /dev/null
+++ b/gdb/bfin-tdep.h
@@ -0,0 +1,111 @@
+/* Target-dependent code for Analog Devices Blackfin processer, for GDB.
+
+   Copyright (C) 2005-2010 Free Software Foundation, Inc.
+   Contributed by Analog Devices.
+
+   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/>.  */
+
+enum gdb_regnum {
+  /* Core Registers */
+  BFIN_R0_REGNUM = 0,
+  BFIN_R1_REGNUM,
+  BFIN_R2_REGNUM,
+  BFIN_R3_REGNUM,
+  BFIN_R4_REGNUM,
+  BFIN_R5_REGNUM,
+  BFIN_R6_REGNUM,
+  BFIN_R7_REGNUM,
+  BFIN_P0_REGNUM,
+  BFIN_P1_REGNUM,
+  BFIN_P2_REGNUM,
+  BFIN_P3_REGNUM,
+  BFIN_P4_REGNUM,
+  BFIN_P5_REGNUM,
+  BFIN_SP_REGNUM,
+  BFIN_FP_REGNUM,
+  BFIN_I0_REGNUM,
+  BFIN_I1_REGNUM,
+  BFIN_I2_REGNUM,
+  BFIN_I3_REGNUM,
+  BFIN_M0_REGNUM,
+  BFIN_M1_REGNUM,
+  BFIN_M2_REGNUM,
+  BFIN_M3_REGNUM,
+  BFIN_B0_REGNUM,
+  BFIN_B1_REGNUM,
+  BFIN_B2_REGNUM,
+  BFIN_B3_REGNUM,
+  BFIN_L0_REGNUM,
+  BFIN_L1_REGNUM,
+  BFIN_L2_REGNUM,
+  BFIN_L3_REGNUM,
+  BFIN_A0_DOT_X_REGNUM,
+  BFIN_AO_DOT_W_REGNUM,
+  BFIN_A1_DOT_X_REGNUM,
+  BFIN_A1_DOT_W_REGNUM,
+  BFIN_ASTAT_REGNUM,
+  BFIN_RETS_REGNUM,
+  BFIN_LC0_REGNUM,
+  BFIN_LT0_REGNUM,
+  BFIN_LB0_REGNUM,
+  BFIN_LC1_REGNUM,
+  BFIN_LT1_REGNUM,
+  BFIN_LB1_REGNUM,
+  BFIN_CYCLES_REGNUM,
+  BFIN_CYCLES2_REGNUM,
+  BFIN_USP_REGNUM,
+  BFIN_SEQSTAT_REGNUM,
+  BFIN_SYSCFG_REGNUM,
+  BFIN_RETI_REGNUM,
+  BFIN_RETX_REGNUM,
+  BFIN_RETN_REGNUM,
+  BFIN_RETE_REGNUM,
+
+  /* Pseudo Registers */
+  BFIN_PC_REGNUM,
+  BFIN_CC_REGNUM,
+  BFIN_TEXT_ADDR,		/* Address of .text section.  */
+  BFIN_TEXT_END_ADDR,		/* Address of the end of .text section.  */
+  BFIN_DATA_ADDR,		/* Address of .data section.  */
+
+  BFIN_FDPIC_EXEC_REGNUM,
+  BFIN_FDPIC_INTERP_REGNUM,
+
+  /* MMRs */
+  BFIN_IPEND_REGNUM,
+
+  /* LAST ENTRY SHOULD NOT BE CHANGED.  */
+  BFIN_NUM_REGS			/* The number of all registers.  */
+};
+
+/* The ABIs for Blackfin.  */
+enum bfin_abi
+{
+  BFIN_ABI_FLAT
+};
+
+/* Target-dependent structure in gdbarch.  */
+struct gdbarch_tdep
+{
+  /* Which ABI is in use?  */
+  enum bfin_abi bfin_abi;
+};
+
+/* in opcodes/bfin-dis.c */
+extern int print_insn_bfin (bfd_vma pc, struct disassemble_info *outf);
+
+/* Return the Blackfin ABI associated with GDBARCH.  */
+extern enum bfin_abi bfin_abi (struct gdbarch *gdbarch);
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index 161cbdc..4bdc81a 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -106,6 +106,11 @@ avr-*-*)
 	gdb_sim=../sim/avr/libsim.a
 	;;
 
+bfin-*-*)
+	# Target: Blackfin
+	gdb_target_obs="bfin-tdep.o"
+	;;
+
 cris*)
 	# Target: CRIS
 	gdb_target_obs="cris-tdep.o corelow.o solib.o solib-svr4.o"
diff --git a/gdb/syscalls/bfin-linux.xml b/gdb/syscalls/bfin-linux.xml
new file mode 100644
index 0000000..0fd3a96
--- /dev/null
+++ b/gdb/syscalls/bfin-linux.xml
@@ -0,0 +1,326 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-syscalls.dtd">
+
+<!-- This file was generated using the following file:
+
+     gawk '$2 ~ /^__NR_/ { gsub(/__NR_/,""); print "  <syscall name=\"" $2 "\" number=\"" $3 "\"/>" }'
+     /usr/src/linux/arch/blackfin/include/asm/unistd.h
+
+     The file mentioned above belongs to the Linux Kernel.  -->
+
+<syscalls_info>
+  <syscall name="restart_syscall" number="0"/>
+  <syscall name="exit" number="1"/>
+  <syscall name="fork" number="2"/>
+  <syscall name="read" number="3"/>
+  <syscall name="write" number="4"/>
+  <syscall name="open" number="5"/>
+  <syscall name="close" number="6"/>
+  <syscall name="creat" number="8"/>
+  <syscall name="link" number="9"/>
+  <syscall name="unlink" number="10"/>
+  <syscall name="execve" number="11"/>
+  <syscall name="chdir" number="12"/>
+  <syscall name="time" number="13"/>
+  <syscall name="mknod" number="14"/>
+  <syscall name="chmod" number="15"/>
+  <syscall name="chown" number="16"/>
+  <syscall name="lseek" number="19"/>
+  <syscall name="getpid" number="20"/>
+  <syscall name="mount" number="21"/>
+  <syscall name="setuid" number="23"/>
+  <syscall name="getuid" number="24"/>
+  <syscall name="stime" number="25"/>
+  <syscall name="ptrace" number="26"/>
+  <syscall name="alarm" number="27"/>
+  <syscall name="pause" number="29"/>
+  <syscall name="access" number="33"/>
+  <syscall name="nice" number="34"/>
+  <syscall name="sync" number="36"/>
+  <syscall name="kill" number="37"/>
+  <syscall name="rename" number="38"/>
+  <syscall name="mkdir" number="39"/>
+  <syscall name="rmdir" number="40"/>
+  <syscall name="dup" number="41"/>
+  <syscall name="pipe" number="42"/>
+  <syscall name="times" number="43"/>
+  <syscall name="brk" number="45"/>
+  <syscall name="setgid" number="46"/>
+  <syscall name="getgid" number="47"/>
+  <syscall name="geteuid" number="49"/>
+  <syscall name="getegid" number="50"/>
+  <syscall name="acct" number="51"/>
+  <syscall name="umount2" number="52"/>
+  <syscall name="ioctl" number="54"/>
+  <syscall name="fcntl" number="55"/>
+  <syscall name="setpgid" number="57"/>
+  <syscall name="umask" number="60"/>
+  <syscall name="chroot" number="61"/>
+  <syscall name="ustat" number="62"/>
+  <syscall name="dup2" number="63"/>
+  <syscall name="getppid" number="64"/>
+  <syscall name="getpgrp" number="65"/>
+  <syscall name="setsid" number="66"/>
+  <syscall name="sgetmask" number="68"/>
+  <syscall name="ssetmask" number="69"/>
+  <syscall name="setreuid" number="70"/>
+  <syscall name="setregid" number="71"/>
+  <syscall name="sethostname" number="74"/>
+  <syscall name="setrlimit" number="75"/>
+  <syscall name="getrusage" number="77"/>
+  <syscall name="gettimeofday" number="78"/>
+  <syscall name="settimeofday" number="79"/>
+  <syscall name="getgroups" number="80"/>
+  <syscall name="setgroups" number="81"/>
+  <syscall name="symlink" number="83"/>
+  <syscall name="readlink" number="85"/>
+  <syscall name="reboot" number="88"/>
+  <syscall name="munmap" number="91"/>
+  <syscall name="truncate" number="92"/>
+  <syscall name="ftruncate" number="93"/>
+  <syscall name="fchmod" number="94"/>
+  <syscall name="fchown" number="95"/>
+  <syscall name="getpriority" number="96"/>
+  <syscall name="setpriority" number="97"/>
+  <syscall name="statfs" number="99"/>
+  <syscall name="fstatfs" number="100"/>
+  <syscall name="syslog" number="103"/>
+  <syscall name="setitimer" number="104"/>
+  <syscall name="getitimer" number="105"/>
+  <syscall name="stat" number="106"/>
+  <syscall name="lstat" number="107"/>
+  <syscall name="fstat" number="108"/>
+  <syscall name="vhangup" number="111"/>
+  <syscall name="wait4" number="114"/>
+  <syscall name="sysinfo" number="116"/>
+  <syscall name="fsync" number="118"/>
+  <syscall name="clone" number="120"/>
+  <syscall name="setdomainname" number="121"/>
+  <syscall name="uname" number="122"/>
+  <syscall name="adjtimex" number="124"/>
+  <syscall name="mprotect" number="125"/>
+  <syscall name="init_module" number="128"/>
+  <syscall name="delete_module" number="129"/>
+  <syscall name="quotactl" number="131"/>
+  <syscall name="getpgid" number="132"/>
+  <syscall name="fchdir" number="133"/>
+  <syscall name="bdflush" number="134"/>
+  <syscall name="personality" number="136"/>
+  <syscall name="setfsuid" number="138"/>
+  <syscall name="setfsgid" number="139"/>
+  <syscall name="_llseek" number="140"/>
+  <syscall name="getdents" number="141"/>
+  <syscall name="flock" number="143"/>
+  <syscall name="readv" number="145"/>
+  <syscall name="writev" number="146"/>
+  <syscall name="getsid" number="147"/>
+  <syscall name="fdatasync" number="148"/>
+  <syscall name="_sysctl" number="149"/>
+  <syscall name="sched_setparam" number="154"/>
+  <syscall name="sched_getparam" number="155"/>
+  <syscall name="sched_setscheduler" number="156"/>
+  <syscall name="sched_getscheduler" number="157"/>
+  <syscall name="sched_yield" number="158"/>
+  <syscall name="sched_get_priority_max" number="159"/>
+  <syscall name="sched_get_priority_min" number="160"/>
+  <syscall name="sched_rr_get_interval" number="161"/>
+  <syscall name="nanosleep" number="162"/>
+  <syscall name="mremap" number="163"/>
+  <syscall name="setresuid" number="164"/>
+  <syscall name="getresuid" number="165"/>
+  <syscall name="nfsservctl" number="169"/>
+  <syscall name="setresgid" number="170"/>
+  <syscall name="getresgid" number="171"/>
+  <syscall name="prctl" number="172"/>
+  <syscall name="rt_sigreturn" number="173"/>
+  <syscall name="rt_sigaction" number="174"/>
+  <syscall name="rt_sigprocmask" number="175"/>
+  <syscall name="rt_sigpending" number="176"/>
+  <syscall name="rt_sigtimedwait" number="177"/>
+  <syscall name="rt_sigqueueinfo" number="178"/>
+  <syscall name="rt_sigsuspend" number="179"/>
+  <syscall name="pread" number="180"/>
+  <syscall name="pwrite" number="181"/>
+  <syscall name="lchown" number="182"/>
+  <syscall name="getcwd" number="183"/>
+  <syscall name="capget" number="184"/>
+  <syscall name="capset" number="185"/>
+  <syscall name="sigaltstack" number="186"/>
+  <syscall name="sendfile" number="187"/>
+  <syscall name="vfork" number="190"/>
+  <syscall name="getrlimit" number="191"/>
+  <syscall name="mmap2" number="192"/>
+  <syscall name="truncate64" number="193"/>
+  <syscall name="ftruncate64" number="194"/>
+  <syscall name="stat64" number="195"/>
+  <syscall name="lstat64" number="196"/>
+  <syscall name="fstat64" number="197"/>
+  <syscall name="chown32" number="198"/>
+  <syscall name="getuid32" number="199"/>
+  <syscall name="getgid32" number="200"/>
+  <syscall name="geteuid32" number="201"/>
+  <syscall name="getegid32" number="202"/>
+  <syscall name="setreuid32" number="203"/>
+  <syscall name="setregid32" number="204"/>
+  <syscall name="getgroups32" number="205"/>
+  <syscall name="setgroups32" number="206"/>
+  <syscall name="fchown32" number="207"/>
+  <syscall name="setresuid32" number="208"/>
+  <syscall name="getresuid32" number="209"/>
+  <syscall name="setresgid32" number="210"/>
+  <syscall name="getresgid32" number="211"/>
+  <syscall name="lchown32" number="212"/>
+  <syscall name="setuid32" number="213"/>
+  <syscall name="setgid32" number="214"/>
+  <syscall name="setfsuid32" number="215"/>
+  <syscall name="setfsgid32" number="216"/>
+  <syscall name="pivot_root" number="217"/>
+  <syscall name="getdents64" number="220"/>
+  <syscall name="fcntl64" number="221"/>
+  <syscall name="gettid" number="224"/>
+  <syscall name="readahead" number="225"/>
+  <syscall name="setxattr" number="226"/>
+  <syscall name="lsetxattr" number="227"/>
+  <syscall name="fsetxattr" number="228"/>
+  <syscall name="getxattr" number="229"/>
+  <syscall name="lgetxattr" number="230"/>
+  <syscall name="fgetxattr" number="231"/>
+  <syscall name="listxattr" number="232"/>
+  <syscall name="llistxattr" number="233"/>
+  <syscall name="flistxattr" number="234"/>
+  <syscall name="removexattr" number="235"/>
+  <syscall name="lremovexattr" number="236"/>
+  <syscall name="fremovexattr" number="237"/>
+  <syscall name="tkill" number="238"/>
+  <syscall name="sendfile64" number="239"/>
+  <syscall name="futex" number="240"/>
+  <syscall name="sched_setaffinity" number="241"/>
+  <syscall name="sched_getaffinity" number="242"/>
+  <syscall name="io_setup" number="245"/>
+  <syscall name="io_destroy" number="246"/>
+  <syscall name="io_getevents" number="247"/>
+  <syscall name="io_submit" number="248"/>
+  <syscall name="io_cancel" number="249"/>
+  <syscall name="exit_group" number="252"/>
+  <syscall name="lookup_dcookie" number="253"/>
+  <syscall name="bfin_spinlock" number="254"/>
+  <syscall name="epoll_create" number="255"/>
+  <syscall name="epoll_ctl" number="256"/>
+  <syscall name="epoll_wait" number="257"/>
+  <syscall name="set_tid_address" number="259"/>
+  <syscall name="timer_create" number="260"/>
+  <syscall name="timer_settime" number="261"/>
+  <syscall name="timer_gettime" number="262"/>
+  <syscall name="timer_getoverrun" number="263"/>
+  <syscall name="timer_delete" number="264"/>
+  <syscall name="clock_settime" number="265"/>
+  <syscall name="clock_gettime" number="266"/>
+  <syscall name="clock_getres" number="267"/>
+  <syscall name="clock_nanosleep" number="268"/>
+  <syscall name="statfs64" number="269"/>
+  <syscall name="fstatfs64" number="270"/>
+  <syscall name="tgkill" number="271"/>
+  <syscall name="utimes" number="272"/>
+  <syscall name="fadvise64_64" number="273"/>
+  <syscall name="mq_open" number="278"/>
+  <syscall name="mq_unlink" number="279"/>
+  <syscall name="mq_timedsend" number="280"/>
+  <syscall name="mq_timedreceive" number="281"/>
+  <syscall name="mq_notify" number="282"/>
+  <syscall name="mq_getsetattr" number="283"/>
+  <syscall name="kexec_load" number="284"/>
+  <syscall name="waitid" number="285"/>
+  <syscall name="add_key" number="286"/>
+  <syscall name="request_key" number="287"/>
+  <syscall name="keyctl" number="288"/>
+  <syscall name="ioprio_set" number="289"/>
+  <syscall name="ioprio_get" number="290"/>
+  <syscall name="inotify_init" number="291"/>
+  <syscall name="inotify_add_watch" number="292"/>
+  <syscall name="inotify_rm_watch" number="293"/>
+  <syscall name="openat" number="295"/>
+  <syscall name="mkdirat" number="296"/>
+  <syscall name="mknodat" number="297"/>
+  <syscall name="fchownat" number="298"/>
+  <syscall name="futimesat" number="299"/>
+  <syscall name="fstatat64" number="300"/>
+  <syscall name="unlinkat" number="301"/>
+  <syscall name="renameat" number="302"/>
+  <syscall name="linkat" number="303"/>
+  <syscall name="symlinkat" number="304"/>
+  <syscall name="readlinkat" number="305"/>
+  <syscall name="fchmodat" number="306"/>
+  <syscall name="faccessat" number="307"/>
+  <syscall name="pselect6" number="308"/>
+  <syscall name="ppoll" number="309"/>
+  <syscall name="unshare" number="310"/>
+  <syscall name="sram_alloc" number="311"/>
+  <syscall name="sram_free" number="312"/>
+  <syscall name="dma_memcpy" number="313"/>
+  <syscall name="accept" number="314"/>
+  <syscall name="bind" number="315"/>
+  <syscall name="connect" number="316"/>
+  <syscall name="getpeername" number="317"/>
+  <syscall name="getsockname" number="318"/>
+  <syscall name="getsockopt" number="319"/>
+  <syscall name="listen" number="320"/>
+  <syscall name="recv" number="321"/>
+  <syscall name="recvfrom" number="322"/>
+  <syscall name="recvmsg" number="323"/>
+  <syscall name="send" number="324"/>
+  <syscall name="sendmsg" number="325"/>
+  <syscall name="sendto" number="326"/>
+  <syscall name="setsockopt" number="327"/>
+  <syscall name="shutdown" number="328"/>
+  <syscall name="socket" number="329"/>
+  <syscall name="socketpair" number="330"/>
+  <syscall name="semctl" number="331"/>
+  <syscall name="semget" number="332"/>
+  <syscall name="semop" number="333"/>
+  <syscall name="msgctl" number="334"/>
+  <syscall name="msgget" number="335"/>
+  <syscall name="msgrcv" number="336"/>
+  <syscall name="msgsnd" number="337"/>
+  <syscall name="shmat" number="338"/>
+  <syscall name="shmctl" number="339"/>
+  <syscall name="shmdt" number="340"/>
+  <syscall name="shmget" number="341"/>
+  <syscall name="splice" number="342"/>
+  <syscall name="sync_file_range" number="343"/>
+  <syscall name="tee" number="344"/>
+  <syscall name="vmsplice" number="345"/>
+  <syscall name="epoll_pwait" number="346"/>
+  <syscall name="utimensat" number="347"/>
+  <syscall name="signalfd" number="348"/>
+  <syscall name="timerfd_create" number="349"/>
+  <syscall name="eventfd" number="350"/>
+  <syscall name="pread64" number="351"/>
+  <syscall name="pwrite64" number="352"/>
+  <syscall name="fadvise64" number="353"/>
+  <syscall name="set_robust_list" number="354"/>
+  <syscall name="get_robust_list" number="355"/>
+  <syscall name="fallocate" number="356"/>
+  <syscall name="semtimedop" number="357"/>
+  <syscall name="timerfd_settime" number="358"/>
+  <syscall name="timerfd_gettime" number="359"/>
+  <syscall name="signalfd4" number="360"/>
+  <syscall name="eventfd2" number="361"/>
+  <syscall name="epoll_create1" number="362"/>
+  <syscall name="dup3" number="363"/>
+  <syscall name="pipe2" number="364"/>
+  <syscall name="inotify_init1" number="365"/>
+  <syscall name="preadv" number="366"/>
+  <syscall name="pwritev" number="367"/>
+  <syscall name="rt_tgsigqueueinfo" number="368"/>
+  <syscall name="perf_event_open" number="369"/>
+  <syscall name="recvmmsg" number="370"/>
+  <syscall name="fanotify_init" number="371"/>
+  <syscall name="fanotify_mark" number="372"/>
+  <syscall name="prlimit64" number="373"/>
+</syscalls_info>
-- 
1.7.3.1


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3] gdb: bfin: new port
  2010-12-14 20:43 ` [PATCH v3] " Mike Frysinger
@ 2010-12-14 21:31   ` Pedro Alves
  2010-12-14 22:01     ` Mike Frysinger
  2010-12-14 21:48   ` [PATCH v3] gdbserver: " Mike Frysinger
  1 sibling, 1 reply; 34+ messages in thread
From: Pedro Alves @ 2010-12-14 21:31 UTC (permalink / raw)
  To: gdb-patches; +Cc: Mike Frysinger, toolchain-devel, Jie Zhang

On Tuesday 14 December 2010 20:42:26, Mike Frysinger wrote:
> +  /* Pseudo Registers */
> +  BFIN_PC_REGNUM,
> +  BFIN_CC_REGNUM,
> +  BFIN_TEXT_ADDR,              /* Address of .text section.  */
> +  BFIN_TEXT_END_ADDR,          /* Address of the end of .text section.  */
> +  BFIN_DATA_ADDR,              /* Address of .data section.  */
> +
> +  BFIN_FDPIC_EXEC_REGNUM,
> +  BFIN_FDPIC_INTERP_REGNUM,
> +

I thought these (text_addr ... fdpic*) would be removed?

Can you explain why are the PC and CC registers pseudo
registers, but supported as being raw registers anyway?  Couldn't
gdb compute them itself from the other registers, with
gdb's pseudo register support (gdbarch_pseudo_register_read|write)?
googling I found you mentioning that the "CC pseudo register can
be deduced from the ASTAT register", though further googling doesn't
find any mention of what ASTAT is.  I'm sure there's a good reason,
I'm probably just missing a comment somewhere.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v3] gdbserver: bfin: new port
  2010-12-14 20:43 ` [PATCH v3] " Mike Frysinger
  2010-12-14 21:31   ` Pedro Alves
@ 2010-12-14 21:48   ` Mike Frysinger
  2010-12-14 23:03     ` Ralf Corsepius
  1 sibling, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2010-12-14 21:48 UTC (permalink / raw)
  To: gdb-patches; +Cc: toolchain-devel, Jie Zhang

From: Jie Zhang <jie.zhang@analog.com>

Signed-off-by: Jie Zhang <jie.zhang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>

gdb/:
2010-11-16  Jie Zhang  <jie.zhang@analog.com>

	* configure.tgt (bfin-*-*): Set build_gdbserver to yes.
	* NEWS: Mention new Blackfin support.
	* regformats/reg-bfin.dat: New file.

gdbserver/:
2010-11-16  Jie Zhang  <jie.zhang@analog.com>

	* configure.srv (bfin-*-*): Handle bfin targets.
	* linux-bfin-low.c: New file.
	* linux-low.c: Define PT_TEXT_ADDR, PT_TEXT_END_ADDR, and
	PT_DATA_ADDR for BFIN targets.
	* Makefile.in (SFILES): Add linux-bfin-low.c.
	(clean): Remove reg-bfin.c.
	(linux-bfin-low.o, reg-bfin.o, reg-bfin.c): New targets.
	* README: Mention supported Blackfin targets.
---
v3
	- comment out unused FLAT/FDPIC pseudo registers

 gdb/NEWS                       |    2 +
 gdb/configure.tgt              |    1 +
 gdb/gdbserver/Makefile.in      |   10 +++-
 gdb/gdbserver/README           |    2 +
 gdb/gdbserver/configure.srv    |    5 ++
 gdb/gdbserver/linux-bfin-low.c |  108 ++++++++++++++++++++++++++++++++++++++++
 gdb/gdbserver/linux-low.c      |    4 ++
 gdb/regformats/reg-bfin.dat    |   63 +++++++++++++++++++++++
 8 files changed, 192 insertions(+), 3 deletions(-)
 create mode 100644 gdb/gdbserver/linux-bfin-low.c
 create mode 100644 gdb/regformats/reg-bfin.dat

diff --git a/gdb/NEWS b/gdb/NEWS
index 633338a..ba60ae5 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -108,6 +108,8 @@
   ** GDBserver is now supported on PowerPC LynxOS (versions 4.x and 5.x),
      and i686 LynxOS (version 5.x).
 
+  ** GDBserver is now supported on Blackfin Linux.
+
 * New targets:
 
 Analog Devices, Inc. Blackfin Processor	bfin-*
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index 4bdc81a..b819e15 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -109,6 +109,7 @@ avr-*-*)
 bfin-*-*)
 	# Target: Blackfin
 	gdb_target_obs="bfin-tdep.o"
+	build_gdbserver=yes
 	;;
 
 cris*)
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 7cf68da..44187eb 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -111,8 +111,8 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/inferiors.c \
 	$(srcdir)/proc-service.list $(srcdir)/regcache.c \
 	$(srcdir)/remote-utils.c $(srcdir)/server.c $(srcdir)/target.c \
 	$(srcdir)/thread-db.c $(srcdir)/utils.c \
-	$(srcdir)/linux-arm-low.c $(srcdir)/linux-cris-low.c \
-	$(srcdir)/linux-crisv32-low.c \
+	$(srcdir)/linux-arm-low.c $(srcdir)/linux-bfin-low.c \
+	$(srcdir)/linux-cris-low.c $(srcdir)/linux-crisv32-low.c \
 	${srcdir}/i386-low.c $(srcdir)/i387-fp.c \
 	$(srcdir)/linux-ia64-low.c $(srcdir)/linux-low.c \
 	$(srcdir)/linux-m32r-low.c \
@@ -263,7 +263,7 @@ clean:
 	rm -f version.c
 	rm -f gdbserver$(EXEEXT) gdbreplay$(EXEEXT) core make.log
 	rm -f $(IPA_LIB)
-	rm -f reg-arm.c i386.c reg-ia64.c reg-m32r.c reg-m68k.c
+	rm -f reg-arm.c reg-bfin.c i386.c reg-ia64.c reg-m32r.c reg-m68k.c
 	rm -f reg-sh.c reg-sparc.c reg-spu.c amd64.c i386-linux.c
 	rm -f reg-cris.c reg-crisv32.c amd64-linux.c reg-xtensa.c
 	rm -f arm-with-iwmmxt.c
@@ -413,6 +413,7 @@ linux-low.o: linux-low.c $(linux_low_h) $(server_h)
 
 linux-arm-low.o: linux-arm-low.c $(linux_low_h) $(server_h) \
 	$(gdb_proc_service_h)
+linux-bfin-low.o: linux-bfin-low.c $(linux_low_h) $(server_h)
 linux-cris-low.o: linux-cris-low.c $(linux_low_h) $(server_h)
 linux-crisv32-low.o: linux-crisv32-low.c $(linux_low_h) $(server_h)
 linux-ia64-low.o: linux-ia64-low.c $(linux_low_h) $(server_h)
@@ -455,6 +456,9 @@ arm-with-vfpv3.c : $(srcdir)/../regformats/arm-with-vfpv3.dat $(regdat_sh)
 arm-with-neon.o : arm-with-neon.c $(regdef_h)
 arm-with-neon.c : $(srcdir)/../regformats/arm-with-neon.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/arm-with-neon.dat arm-with-neon.c
+reg-bfin.o : reg-bfin.c $(regdef_h)
+reg-bfin.c : $(srcdir)/../regformats/reg-bfin.dat $(regdat_sh)
+	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-bfin.dat reg-bfin.c
 reg-cris.o : reg-cris.c $(regdef_h)
 reg-cris.c : $(srcdir)/../regformats/reg-cris.dat $(regdat_sh)
 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-cris.dat reg-cris.c
diff --git a/gdb/gdbserver/README b/gdb/gdbserver/README
index 6debbd8..3eaeb61 100644
--- a/gdb/gdbserver/README
+++ b/gdb/gdbserver/README
@@ -81,6 +81,8 @@ Building GDBserver:
 
 The supported targets as of November 2006 are:
 	arm-*-linux*
+	bfin-*-uclinux
+	bfin-*-linux-uclibc
 	crisv32-*-linux*
 	cris-*-linux*
 	i[34567]86-*-cygwin*
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 1e8fa30..ccf8381 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -67,6 +67,11 @@ case "${target}" in
 			srv_mingw=yes
 			srv_mingwce=yes
 			;;
+  bfin-*-*)		srv_regobj=reg-bfin.o
+			srv_tgtobj="linux-low.o linux-bfin-low.o"
+			srv_linux_usrregs=yes
+			srv_linux_thread_db=yes
+			;;
   crisv32-*-linux*)	srv_regobj=reg-crisv32.o
 			srv_tgtobj="linux-low.o linux-crisv32-low.o"
 			srv_linux_regsets=yes
diff --git a/gdb/gdbserver/linux-bfin-low.c b/gdb/gdbserver/linux-bfin-low.c
new file mode 100644
index 0000000..ce40dea
--- /dev/null
+++ b/gdb/gdbserver/linux-bfin-low.c
@@ -0,0 +1,108 @@
+/* GNU/Linux/BFIN specific low level interface, for the remote server for GDB.
+
+   Copyright (C) 2005-2010 Free Software Foundation, Inc.
+   Contributed by Analog Devices.
+
+   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 "libiberty.h"
+#include <asm/ptrace.h>
+
+/* Defined in auto-generated file reg-bfin.c.  */
+void init_registers_bfin (void);
+
+static int bfin_regmap[] =
+{
+  PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7,
+  PT_P0, PT_P1, PT_P2, PT_P3, PT_P4, PT_P5, PT_USP, PT_FP,
+  PT_I0, PT_I1, PT_I2, PT_I3, PT_M0, PT_M1, PT_M2, PT_M3,
+  PT_B0, PT_B1, PT_B2, PT_B3, PT_L0, PT_L1, PT_L2, PT_L3,
+  PT_A0X, PT_A0W, PT_A1X, PT_A1W, PT_ASTAT, PT_RETS,
+  PT_LC0, PT_LT0, PT_LB0, PT_LC1, PT_LT1, PT_LB1,
+  -1 /* PT_CYCLES */, -1 /* PT_CYCLES2 */,
+  -1 /* PT_USP */, PT_SEQSTAT, PT_SYSCFG, PT_PC, PT_RETX, PT_RETN, PT_RETE,
+  PT_PC, -1 /* PT_CC */,
+  /* FLAT:  PT_TEXT_ADDR, PT_TEXT_END_ADDR, PT_DATA_ADDR, */
+  /* FDPIC: PT_FDPIC_EXEC PT_FDPIC_INTERP, */
+  /* MISC:  PT_IPEND */
+};
+
+#define bfin_num_regs ARRAY_SIZE (bfin_regmap)
+
+static int
+bfin_cannot_store_register (int regno)
+{
+  return (regno >= bfin_num_regs);
+}
+
+static int
+bfin_cannot_fetch_register (int regno)
+{
+  return (regno >= bfin_num_regs);
+}
+
+static CORE_ADDR
+bfin_get_pc (struct regcache *regcache)
+{
+  unsigned long pc;
+
+  collect_register_by_name (regcache, "pc", &pc);
+
+  return pc;
+}
+
+static void
+bfin_set_pc (struct regcache *regcache, CORE_ADDR pc)
+{
+  unsigned long newpc = pc;
+
+  supply_register_by_name (regcache, "pc", &newpc);
+}
+
+#define bfin_breakpoint_len 2
+static const unsigned char bfin_breakpoint[bfin_breakpoint_len] = {0xa1, 0x00};
+
+static int
+bfin_breakpoint_at (CORE_ADDR where)
+{
+  unsigned char insn[bfin_breakpoint_len];
+
+  read_inferior_memory(where, insn, bfin_breakpoint_len);
+  if (insn[0] == bfin_breakpoint[0]
+      && insn[1] == bfin_breakpoint[1])
+    return 1;
+
+  /* If necessary, recognize more trap instructions here.  GDB only uses the
+     one.  */
+  return 0;
+}
+
+struct linux_target_ops the_low_target = {
+  init_registers_bfin,
+  bfin_num_regs,
+  bfin_regmap,
+  bfin_cannot_fetch_register,
+  bfin_cannot_store_register,
+  bfin_get_pc,
+  bfin_set_pc,
+  bfin_breakpoint,
+  bfin_breakpoint_len,
+  0,
+  2,
+  bfin_breakpoint_at,
+};
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index c65ce54..75fe905 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -4373,6 +4373,10 @@ linux_stopped_data_address (void)
 #define PT_TEXT_ADDR 49*4
 #define PT_DATA_ADDR 50*4
 #define PT_TEXT_END_ADDR  51*4
+#elif defined(BFIN)
+#define PT_TEXT_ADDR 220
+#define PT_TEXT_END_ADDR 224
+#define PT_DATA_ADDR 228
 #endif
 
 /* Under uClinux, programs are loaded at non-zero offsets, which we need
diff --git a/gdb/regformats/reg-bfin.dat b/gdb/regformats/reg-bfin.dat
new file mode 100644
index 0000000..38dca22
--- /dev/null
+++ b/gdb/regformats/reg-bfin.dat
@@ -0,0 +1,63 @@
+name:bfin
+expedite:pc,sp,fp
+32:r0
+32:r1
+32:r2
+32:r3
+32:r4
+32:r5
+32:r6
+32:r7
+32:p0
+32:p1
+32:p2
+32:p3
+32:p4
+32:p5
+32:sp
+32:fp
+32:i0
+32:i1
+32:i2
+32:i3
+32:m0
+32:m1
+32:m2
+32:m3
+32:b0
+32:b1
+32:b2
+32:b3
+32:l0
+32:l1
+32:l2
+32:l3
+32:a0x
+32:a0w
+32:a1x
+32:a1w
+32:astat
+32:rets
+32:lc0
+32:lt0
+32:lb0
+32:lc1
+32:lt1
+32:lb1
+32:cycles
+32:cycles2
+32:usp
+32:seqstat
+32:syscfg
+32:reti
+32:retx
+32:retn
+32:rete
+32:pc
+32:cc
+32:text_addr
+32:text_end_addr
+32:data_addr
+32:fdpic_exec
+32:fdpic_interp
+32:ipend
-- 
1.7.3.1


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3] gdb: bfin: new port
  2010-12-14 21:31   ` Pedro Alves
@ 2010-12-14 22:01     ` Mike Frysinger
  2010-12-15 13:02       ` Mike Frysinger
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2010-12-14 22:01 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches, toolchain-devel

[-- Attachment #1: Type: Text/Plain, Size: 2106 bytes --]

On Tuesday, December 14, 2010 16:31:22 Pedro Alves wrote:
> On Tuesday 14 December 2010 20:42:26, Mike Frysinger wrote:
> > +  /* Pseudo Registers */
> > +  BFIN_PC_REGNUM,
> > +  BFIN_CC_REGNUM,
> > +  BFIN_TEXT_ADDR,              /* Address of .text section.  */
> > +  BFIN_TEXT_END_ADDR,          /* Address of the end of .text section. 
> > */ +  BFIN_DATA_ADDR,              /* Address of .data section.  */ +
> > +  BFIN_FDPIC_EXEC_REGNUM,
> > +  BFIN_FDPIC_INTERP_REGNUM,
> > +
> 
> I thought these (text_addr ... fdpic*) would be removed?

i was thinking of gdbserver, but i can do it here too.  pretty sure the first 
three are actually for FLAT, but the common code takes care of those.  i can 
comment out these as well.

> Can you explain why are the PC and CC registers pseudo
> registers, but supported as being raw registers anyway?  Couldn't
> gdb compute them itself from the other registers, with
> gdb's pseudo register support (gdbarch_pseudo_register_read|write)?
> googling I found you mentioning that the "CC pseudo register can
> be deduced from the ASTAT register", though further googling doesn't
> find any mention of what ASTAT is.  I'm sure there's a good reason,
> I'm probably just missing a comment somewhere.

i dont see how PC can be deduced from anything.  it's considered pseudo 
because in the ISA there is no way of doing "PC = <some reg or value>" or 
"<reg> = PC".  you can only indirectly affect it by doing something such as 
"<reg> = <some value>" followed by "JUMP (reg)".  Linux indirectly manipulates 
it via the RETI (return from interrupt) register (which is why the Blackfin 
kernel actually loads RETI into the PC slot in the register stack).  you do 
get a bit more direct access to it via JTAG, but that doesnt count.

CC is actually a single bit in the ASTAT (arithmetic status) register, but 
often is treated as an actual register in much of the ISA.  such as 
assignments or logical tests.  you can do "<reg> = CC" and "CC = <reg>", but 
you cant do this with any other ASTAT bit (like AZ, AN, etc...).
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3] gdbserver: bfin: new port
  2010-12-14 21:48   ` [PATCH v3] gdbserver: " Mike Frysinger
@ 2010-12-14 23:03     ` Ralf Corsepius
  2010-12-15  0:15       ` Mike Frysinger
  0 siblings, 1 reply; 34+ messages in thread
From: Ralf Corsepius @ 2010-12-14 23:03 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: gdb-patches, toolchain-devel, Jie Zhang

On 12/14/2010 10:47 PM, Mike Frysinger wrote:

>
> diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
> index 1e8fa30..ccf8381 100644
> --- a/gdb/gdbserver/configure.srv
> +++ b/gdb/gdbserver/configure.srv
> @@ -67,6 +67,11 @@ case "${target}" in
>   			srv_mingw=yes
>   			srv_mingwce=yes
>   			;;
> +  bfin-*-*)		srv_regobj=reg-bfin.o
> +			srv_tgtobj="linux-low.o linux-bfin-low.o"
> +			srv_linux_usrregs=yes
> +			srv_linux_thread_db=yes
> +			;;

Is this a generic bfin target or should is a bfin-*linux target.

Seeing linux-*low.o on the right hand side of the case, my feeling is 
the $target should be fbin-*-linux*

Ralf


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3] gdbserver: bfin: new port
  2010-12-14 23:03     ` Ralf Corsepius
@ 2010-12-15  0:15       ` Mike Frysinger
  0 siblings, 0 replies; 34+ messages in thread
From: Mike Frysinger @ 2010-12-15  0:15 UTC (permalink / raw)
  To: Ralf Corsepius; +Cc: gdb-patches, toolchain-devel

[-- Attachment #1: Type: Text/Plain, Size: 989 bytes --]

On Tuesday, December 14, 2010 18:03:01 Ralf Corsepius wrote:
> On 12/14/2010 10:47 PM, Mike Frysinger wrote:
> > diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
> > index 1e8fa30..ccf8381 100644
> > --- a/gdb/gdbserver/configure.srv
> > +++ b/gdb/gdbserver/configure.srv
> > @@ -67,6 +67,11 @@ case "${target}" in
> > 
> >   			srv_mingw=yes
> >   			srv_mingwce=yes
> >   			;;
> > 
> > +  bfin-*-*)		srv_regobj=reg-bfin.o
> > +			srv_tgtobj="linux-low.o linux-bfin-low.o"
> > +			srv_linux_usrregs=yes
> > +			srv_linux_thread_db=yes
> > +			;;
> 
> Is this a generic bfin target or should is a bfin-*linux target.
> 
> Seeing linux-*low.o on the right hand side of the case, my feeling is
> the $target should be fbin-*-linux*

we use gdbserver for bfin-uclinux (FLAT) and bfin-linux-uclibc (FDPIC) 
targets.  looking at the other targets in the configure file, i guess i should 
restrict it to bfin-*-*linux* rather than bfin-*.
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-14 17:26               ` Mike Frysinger
@ 2010-12-15 11:54                 ` Andrew Stubbs
  2010-12-15 12:55                   ` [toolchain-devel] " Mike Frysinger
  0 siblings, 1 reply; 34+ messages in thread
From: Andrew Stubbs @ 2010-12-15 11:54 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Pedro Alves, gdb-patches, toolchain-devel, Daniel Jacobowitz

[-- Attachment #1: Type: text/plain, Size: 741 bytes --]

On 14/12/10 17:25, Mike Frysinger wrote:
>> I did start implementing something vaguely target independent (included
>> >  in CodeSourcery SG++), but the state of the SH-2A kernel debug support
>> >  put that project on the back burner, so it remains the bare minimum.
> i'm not asking for a finished project.  i would like to simply review the code
> you said you have already.  so where might one find your SuperH/FDPIC
> gdb/gdbserver code ?

The latest CodeSourcery SH-2A toolchain binaries and source can be 
downloaded from here:
http://www.codesourcery.com/sgpp/lite/superh/portal/release1602

I've attached my original patch. I didn't do the forward port when we 
updated GDB myself, so it may be out-of-date in a few places.

Andrew

[-- Attachment #2: gdb-fdpic.patch --]
[-- Type: text/x-patch, Size: 21343 bytes --]

gdb/
	* configure.tgt: Add support for sh*-*-uclinux*.
	(gdb_target_obs): Add solib-fdpic.o for sh*-*-linux and sh*-*-uclinux.
	* remote.c (PACKET_qXfer_fdpic): New enum value.
	(remote_protocol_features): Add qXfer:fdpic:read packet.
	(remote_xfer_partial): Support TARGET_OBJECT_FDPIC.
	(_initialize_remote): Add set/show remote read-fdpic-loadmap command.
	* sh-linux-tdep.c: Include elf/sh.h, elf-bfd.h, solib.h, solist.h and
	solib-fdpic.h.
	(sh_linux_init_abi): Detect FDPIC binaries and enable solib-fdpic.
	* solib-fdpic.c: New file.
	* solib-fdpic.h: New file.
	* target.h (enum target_object): Add TARGET_OBJECT_FDPIC.

	gdb/gdbserver:
	* configure.srv: Add support for sh*-*-uclinux*.
	* linux-low.c (struct elf32_fdpic_loadseg): New type.
	(struct elf32_fdpic_loadmap): New type.
	(linux_read_fdpic_loadmap): New function.
	(linux_target_ops): Add linux_read_fdpic_loadmap.
	* server.c (handle_query): Support qXfer:fdpic:read packet.
	* target.h (struct target_ops): Add read_fdpic_loadmap.

	include/
	* elf/sh.h (EF_SH_PIC, EF_SH_FDPIC): New defines.
	(R_SH_LAST_INVALID_RELOC_5, R_SH_GOT20): New relocations.
	(R_SH_GOTOFF20, R_SH_GOTFUNCDESC, R_SH_GOTFUNCDESC20): Likewise.
	(R_SH_GOTOFFFUNCDESC, R_SH_GOTOFFFUNCDESC20): Likewise.
	(R_SH_FUNCDESC, R_SH_FUNCDESC_VALUE): Likewise.
	(R_SH_FIRST_INVALID_RELOC_6, R_SH_LAST_INVALID_RELOC_6): Likewise.

---
 src/gdb-trunk/gdb/configure.tgt           |    6 -
 src/gdb-trunk/gdb/gdbserver/configure.srv |    6 +
 src/gdb-trunk/gdb/gdbserver/linux-low.c   |   57 ++++++
 src/gdb-trunk/gdb/gdbserver/server.c      |   44 +++++
 src/gdb-trunk/gdb/gdbserver/target.h      |    4 
 src/gdb-trunk/gdb/remote.c                |    9 +
 src/gdb-trunk/gdb/sh-linux-tdep.c         |   12 +
 src/gdb-trunk/gdb/solib-fdpic.c           |  266 +++++++++++++++++++++++++++++
 src/gdb-trunk/gdb/solib-fdpic.h           |   25 +++
 src/gdb-trunk/gdb/target.h                |    2 
 src/gdb-trunk/include/elf/sh.h            |   18 ++
 11 files changed, 444 insertions(+), 5 deletions(-)
 create mode 100644 src/gdb-trunk/gdb/solib-fdpic.c
 create mode 100644 src/gdb-trunk/gdb/solib-fdpic.h

diff --git a/src/gdb-trunk/gdb/configure.tgt b/src/gdb-trunk/gdb/configure.tgt
index 876c5bd..7da3381 100644
--- a/src/gdb-trunk/gdb/configure.tgt
+++ b/src/gdb-trunk/gdb/configure.tgt
@@ -431,11 +431,11 @@ score-*-*)
 	build_gdbserver=yes
 	;;
 
-sh*-*-linux*)
+sh*-*-linux* | sh*-*-uclinux*)
 	# Target: GNU/Linux Super-H
 	gdb_target_obs="sh-tdep.o sh64-tdep.o sh-linux-tdep.o monitor.o \
-			dsrec.o solib.o solib-svr4.o symfile-mem.o \
-			glibc-tdep.o corelow.o"
+			dsrec.o solib.o solib-svr4.o solib-fdpic.o \
+			symfile-mem.o glibc-tdep.o corelow.o"
 	gdb_sim=../sim/sh/libsim.a
 	build_gdbserver=yes
 	;;
diff --git a/src/gdb-trunk/gdb/gdbserver/configure.srv b/src/gdb-trunk/gdb/gdbserver/configure.srv
index dae9bef..4e0f5a5 100644
--- a/src/gdb-trunk/gdb/gdbserver/configure.srv
+++ b/src/gdb-trunk/gdb/gdbserver/configure.srv
@@ -215,6 +215,12 @@ case "${target}" in
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
+  sh*-*-uclinux*)	srv_regobj=reg-sh.o
+			srv_tgtobj="linux-low.o linux-sh-low.o"
+			srv_linux_usrregs=yes
+			srv_linux_regsets=yes
+			srv_linux_thread_db=yes
+			;;
   sparc*-*-linux*)	srv_regobj=reg-sparc64.o
 			srv_tgtobj="linux-low.o linux-sparc-low.o"
 			srv_linux_regsets=yes
diff --git a/src/gdb-trunk/gdb/gdbserver/linux-low.c b/src/gdb-trunk/gdb/gdbserver/linux-low.c
index 6043f22..147bedc 100644
--- a/src/gdb-trunk/gdb/gdbserver/linux-low.c
+++ b/src/gdb-trunk/gdb/gdbserver/linux-low.c
@@ -3452,6 +3452,56 @@ linux_core_of_thread (ptid_t ptid)
   return core;
 }
 
+#ifdef __FDPIC__
+struct elf32_fdpic_loadseg
+{
+  /* Core address to which the segment is mapped.  */
+  Elf32_Addr addr;
+  /* VMA recorded in the program header.  */
+  Elf32_Addr p_vaddr;
+  /* Size of this segment in memory.  */
+  Elf32_Word p_memsz;
+};
+
+struct elf32_fdpic_loadmap {
+  /* Protocol version number, must be zero.  */
+  Elf32_Half version;
+  /* Number of segments in this map.  */
+  Elf32_Half nsegs;
+  /* The actual memory map.  */
+  struct elf32_fdpic_loadseg segs[/*nsegs*/];
+};
+
+static int
+linux_read_fdpic_loadmap (const char *annex, CORE_ADDR offset,
+			  unsigned char *myaddr, unsigned int len)
+{
+  int pid = lwpid_of (get_thread_lwp (current_inferior));
+  int addr = (strcmp (annex, "exec") == 0 ? PTRACE_GETFDPIC_EXEC :
+	      (strcmp (annex, "interp") == 0 ? PTRACE_GETFDPIC_INTERP :
+	       -1));
+  struct elf32_fdpic_loadmap *data = NULL;
+  unsigned int actual_length, copy_length;
+
+  if (addr == -1)
+    return -1;
+
+  ptrace (PTRACE_GETFDPIC, pid, addr, &data);
+  if (data == NULL)
+    return -1;
+
+  actual_length = sizeof (struct elf32_fdpic_loadmap)
+		  + sizeof (struct elf32_fdpic_loadseg) * data->nsegs;
+
+  if (offset < 0 || offset > actual_length)
+    return -1;
+
+  copy_length = actual_length - offset < len ? actual_length - offset : len;
+  memcpy (myaddr, ((char *)data) + offset, copy_length);
+  return copy_length;
+}
+#endif
+
 static struct target_ops linux_target_ops = {
   linux_create_inferior,
   linux_attach,
@@ -3495,7 +3545,12 @@ static struct target_ops linux_target_ops = {
 #else
   NULL,
 #endif
-  linux_core_of_thread
+  linux_core_of_thread,
+#ifdef __FDPIC__
+  linux_read_fdpic_loadmap
+#else
+  NULL
+#endif
 };
 
 static void
diff --git a/src/gdb-trunk/gdb/gdbserver/server.c b/src/gdb-trunk/gdb/gdbserver/server.c
index 9d21be4..9aec881 100644
--- a/src/gdb-trunk/gdb/gdbserver/server.c
+++ b/src/gdb-trunk/gdb/gdbserver/server.c
@@ -1268,6 +1268,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
       if (the_target->qxfer_siginfo != NULL)
 	strcat (own_buf, ";qXfer:siginfo:read+;qXfer:siginfo:write+");
 
+      if (the_target->read_fdpic_loadmap != NULL)
+	strcat (own_buf, ";qXfer:fdpic:read+");
+
       /* We always report qXfer:features:read, as targets may
 	 install XML files on a subsequent call to arch_setup.
 	 If we reported to GDB on startup that we don't support
@@ -1421,6 +1424,47 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
       return;
     }
 
+  if (the_target->read_fdpic_loadmap != NULL
+      && strncmp ("qXfer:fdpic:read:", own_buf, 17) == 0)
+    {
+      unsigned char *data;
+      int n;
+      CORE_ADDR ofs;
+      unsigned int len;
+      char *annex;
+
+      require_running (own_buf);
+
+      /* Grab the offset and length.  */
+      if (decode_xfer_read (own_buf + 17, &annex, &ofs, &len) < 0)
+	{
+	  strcpy (own_buf, "E00");
+	  return;
+	}
+
+      /* Read one extra byte, as an indicator of whether there is
+	 more.  */
+      if (len > PBUFSIZ - 2)
+	len = PBUFSIZ - 2;
+      data = malloc (len + 1);
+      if (data == NULL)
+	{
+	  write_enn (own_buf);
+	  return;
+	}
+      n = (*the_target->read_fdpic_loadmap) (annex, ofs, data, len + 1);
+      if (n < 0)
+	write_enn (own_buf);
+      else if (n > len)
+	*new_packet_len_p = write_qxfer_response (own_buf, data, len, 1);
+      else
+	*new_packet_len_p = write_qxfer_response (own_buf, data, n, 0);
+
+      free (data);
+
+      return;
+    }
+
   /* Otherwise we didn't know what packet it was.  Say we didn't
      understand it.  */
   own_buf[0] = 0;
diff --git a/src/gdb-trunk/gdb/gdbserver/target.h b/src/gdb-trunk/gdb/gdbserver/target.h
index ac68652..c47f01b 100644
--- a/src/gdb-trunk/gdb/gdbserver/target.h
+++ b/src/gdb-trunk/gdb/gdbserver/target.h
@@ -286,6 +286,10 @@ struct target_ops
 
   /* Returns the core given a thread, or -1 if not known.  */
   int (*core_of_thread) (ptid_t);
+
+  /* Read FDPIC loadmaps.  Read LEN bytes at OFFSET into a buffer at MYADDR.  */
+  int (*read_fdpic_loadmap) (const char *annex, CORE_ADDR offset,
+			     unsigned char *myaddr, unsigned int len);
 };
 
 extern struct target_ops *the_target;
diff --git a/src/gdb-trunk/gdb/remote.c b/src/gdb-trunk/gdb/remote.c
index bcb42a7..b11b63d 100644
--- a/src/gdb-trunk/gdb/remote.c
+++ b/src/gdb-trunk/gdb/remote.c
@@ -1301,6 +1301,7 @@ enum {
   PACKET_FastTracepoints,
   PACKET_bc,
   PACKET_bs,
+  PACKET_qXfer_fdpic,
   PACKET_MAX
 };
 
@@ -3641,6 +3642,8 @@ static struct protocol_feature remote_protocol_features[] = {
     PACKET_bc },
   { "ReverseStep", PACKET_DISABLE, remote_supported_packet,
     PACKET_bs },
+  { "qXfer:fdpic:read", PACKET_DISABLE, remote_supported_packet,
+    PACKET_qXfer_fdpic },
 };
 
 static void
@@ -8038,6 +8041,9 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
       return remote_read_qxfer (ops, "threads", annex, readbuf, offset, len,
 				&remote_protocol_packets[PACKET_qXfer_threads]);
 
+    case TARGET_OBJECT_FDPIC:
+      return remote_read_qxfer (ops, "fdpic", annex, readbuf, offset, len,
+				&remote_protocol_packets[PACKET_qXfer_fdpic]);
     default:
       return -1;
     }
@@ -10335,6 +10341,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_FastTracepoints],
 			 "FastTracepoints", "fast-tracepoints", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_fdpic],
+			 "qXfer:fdpic:read", "read-fdpic-loadmap", 0);
+
   /* Keep the old ``set remote Z-packet ...'' working.  Each individual
      Z sub-packet has its own set and show commands, but users may
      have sets to this variable in their .gdbinit files (or in their
diff --git a/src/gdb-trunk/gdb/sh-linux-tdep.c b/src/gdb-trunk/gdb/sh-linux-tdep.c
index 19cf1b9..2238620 100644
--- a/src/gdb-trunk/gdb/sh-linux-tdep.c
+++ b/src/gdb-trunk/gdb/sh-linux-tdep.c
@@ -28,6 +28,12 @@
 #include "regcache.h"
 #include "regset.h"
 
+#include "elf/sh.h"
+#include "elf-bfd.h"
+#include "solib.h"
+#include "solist.h"
+#include "solib-fdpic.h"
+
 #include "glibc-tdep.h"
 #include "sh-tdep.h"
 
@@ -94,6 +100,12 @@ sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
       tdep->core_gregmap = (struct sh_corefile_regmap *)gregs_table;
       tdep->core_fpregmap = (struct sh_corefile_regmap *)fpregs_table;
     }
+
+  if (info.abfd && elf_elfheader(info.abfd)->e_flags & EF_SH_FDPIC)
+    {
+      /* FDPIC detected.  Switch shared library mode.  */
+      set_solib_ops (gdbarch, &fdpic_so_ops);
+    }
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
diff --git a/src/gdb-trunk/gdb/solib-fdpic.c b/src/gdb-trunk/gdb/solib-fdpic.c
new file mode 100644
index 0000000..85ba688
--- /dev/null
+++ b/src/gdb-trunk/gdb/solib-fdpic.c
@@ -0,0 +1,266 @@
+/* Handle FDPIC shared libraries for GDB, the GNU Debugger.
+   Copyright (C) 2010 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/>.  */
+
+/* FDPIC dynamic libraries work like svr4 shared libraries in many ways,
+   but not quite.  The main differences are that even the main executable
+   can be relocated unpredictably, and the read-only and writable sections
+   of the inferior can be relocated independently (indeed, there may be an
+   arbitrary number of separate regions).
+
+   The load maps cannot be determined by reading from program memory,
+   because it's not at a fixed location.  Instead they must be obtained
+   from the Linux kernel using a special ptrace call.
+
+   The added complexity of the load maps means that we need more than a
+   single offset to do the relocation.  Each relocation requires a table
+   lookup to determine what range it falls into.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "solib-svr4.h"
+#include "solist.h"
+#include "bfd.h"
+#include "exec.h"
+#include "target.h"
+#include "elf.h"
+#include "objfiles.h"
+#include "cli/cli-decode.h"
+
+/* These data structures are taken from elf-fdpic.h in uCLibc.  */
+
+struct elf32_fdpic_loadseg
+{
+  /* Core address to which the segment is mapped.  */
+  Elf32_Addr addr;
+  /* VMA recorded in the program header.  */
+  Elf32_Addr p_vaddr;
+  /* Size of this segment in memory.  */
+  Elf32_Word p_memsz;
+};
+
+struct elf32_fdpic_loadmap {
+  /* Protocol version number, must be zero.  */
+  Elf32_Half version;
+  /* Number of segments in this map.  */
+  Elf32_Half nsegs;
+  /* The actual memory map.  */
+  struct elf32_fdpic_loadseg segs[/*nsegs*/];
+};
+
+/* Load maps for the main executable and the interpreter.
+   These are obtained from ptrace.  They are the starting point for getting
+   into the program, and are required to find the solib list with the
+   individual load maps for each module.  */
+
+static struct elf32_fdpic_loadmap *exec_loadmap = NULL, *interp_loadmap = NULL;
+
+
+/* normalize_loadmap_endian
+
+   Convert a load map from target endian to host endian.  */
+
+static void
+normalize_loadmap_endian (struct elf32_fdpic_loadmap *map)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+  int i;
+
+#define NORMAILIZE_ENDIAN(field) \
+  (field) = extract_unsigned_integer ((gdb_byte*)&(field), sizeof (field), \
+				      byte_order);
+
+  NORMAILIZE_ENDIAN (map->version);
+  NORMAILIZE_ENDIAN (map->nsegs);
+
+  for (i = 0; i < map->nsegs; i++)
+    {
+      NORMAILIZE_ENDIAN (map->segs[i].addr);
+      NORMAILIZE_ENDIAN (map->segs[i].p_vaddr);
+      NORMAILIZE_ENDIAN (map->segs[i].p_memsz);
+    }
+
+#undef NORMAILIZE_ENDIAN
+}
+
+static void
+fdpic_print_loadmap (struct elf32_fdpic_loadmap *map)
+{
+  int i;
+
+  if (map == NULL)
+    printf_filtered ("(null)\n");
+  else if (map->version != 0)
+    printf_filtered (_("Unsupported map version: %d\n"), map->version);
+  else
+    for (i = 0; i < map->nsegs; i++)
+      printf_filtered ("0x%08x:0x%08x -> 0x%08x:0x%08x\n",
+		       map->segs[i].p_vaddr,
+		       map->segs[i].p_vaddr + map->segs[i].p_memsz,
+		       map->segs[i].addr,
+		       map->segs[i].addr + map->segs[i].p_memsz);
+}
+
+/* fdpic_get_initial_loadmaps
+
+   Interrogate the Linux kernel to find out where the program was loaded.
+   There are two load maps; one for the executable and one for the
+   interpreter (only in the case of a dynamically linked executable).  */
+
+static void
+fdpic_get_initial_loadmaps (void)
+{
+  if (0 >= target_read_alloc (&current_target, TARGET_OBJECT_FDPIC,
+			      "exec", (gdb_byte**)&exec_loadmap))
+    {
+      error (_("Error reading FDPIC exec loadmap\n"));
+      exec_loadmap = NULL;
+      return;
+    }
+  else
+    normalize_loadmap_endian (exec_loadmap);
+
+  if (0 >= target_read_alloc (&current_target, TARGET_OBJECT_FDPIC,
+			      "interp", (gdb_byte**)&interp_loadmap))
+    interp_loadmap = NULL;
+  else
+    normalize_loadmap_endian (interp_loadmap);
+}
+
+/* fdpic_find_load_offset
+
+   Return the offset from the given objfile address to the actual loaded
+   address.  Note that, unlike normal svr4, different sections in the same
+   objfile might have different offsets.  */
+
+static CORE_ADDR
+fdpic_find_load_offset (CORE_ADDR addr, struct elf32_fdpic_loadmap *map)
+{
+  int seg;
+
+  for (seg = 0; seg < map->nsegs; seg++)
+    {
+      CORE_ADDR sectionoffset = addr - map->segs[seg].p_vaddr;
+      if (sectionoffset >= 0 && sectionoffset < map->segs[seg].p_memsz)
+	{
+	  return map->segs[seg].addr - map->segs[seg].p_vaddr;
+	}
+    }
+
+  /* The address did not match the load map.  */
+  return 0;
+}
+
+/* fdpic_relocate_file
+
+   Relocate all the symbols/sections in the given file.
+
+   If SYMFILE is NULL then relocate BFD instead.
+   If SYMFILE is non-NULL, then BFD is not used.  */
+
+static int
+fdpic_relocate_file (struct objfile *symfile, bfd *bfd,
+                     struct elf32_fdpic_loadmap *map)
+{
+  if (map == NULL)
+    return 0;
+
+  if (symfile)
+    {
+      struct section_offsets *new_offsets;
+      struct obj_section *osect;
+      int i = 0;
+
+      new_offsets = alloca (symfile_objfile->num_sections
+			      * sizeof (*new_offsets));
+
+      ALL_OBJFILE_OSECTIONS (symfile_objfile, osect)
+	new_offsets->offsets[i++] =
+	  fdpic_find_load_offset (bfd_get_section_vma (osect->objfile->abfd,
+	                                               osect->the_bfd_section),
+	                          map);
+
+      objfile_relocate (symfile_objfile, new_offsets);
+    }
+  else if (bfd)
+    {
+      asection *asect;
+
+      for (asect = exec_bfd->sections; asect != NULL; asect = asect->next)
+	{
+          CORE_ADDR vma = bfd_get_section_vma (exec_bfd, asect);
+	  exec_set_section_address (bfd_get_filename (exec_bfd), asect->index,
+				    vma + fdpic_find_load_offset (vma, map));
+	}
+    }
+  else
+    return 0;
+
+  return 1;
+}
+
+
+static void
+fdpic_clear_solib (void)
+{
+  /* GDB crashes if this function doesn't exist.  */
+}
+
+static void
+fdpic_solib_create_inferior_hook (int from_tty)
+{
+  if (exec_bfd == NULL)
+    return;
+
+  fdpic_get_initial_loadmaps ();
+
+  if (!fdpic_relocate_file (symfile_objfile, exec_bfd, exec_loadmap))
+    return;
+
+  /* TODO: actually place a hook.  */
+}
+
+static struct so_list *
+fdpic_current_sos (void)
+{
+  /* FDPIC shared libraries are not yet supported.  */
+  return NULL;
+}
+
+static void
+info_fdpic_command (char *args, int from_tty)
+{
+  printf_filtered (_("Main executable load map:\n"));
+  fdpic_print_loadmap (exec_loadmap);
+}
+
+
+struct target_so_ops fdpic_so_ops;
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_fdpic_solib;
+
+void
+_initialize_fdpic_solib (void)
+{
+  fdpic_so_ops.clear_solib = fdpic_clear_solib;
+  fdpic_so_ops.solib_create_inferior_hook =
+      fdpic_solib_create_inferior_hook;
+  fdpic_so_ops.current_sos = fdpic_current_sos;
+
+  add_info ("fdpic", info_fdpic_command, _("Display the FDPIC load maps.\n"));
+}
diff --git a/src/gdb-trunk/gdb/solib-fdpic.h b/src/gdb-trunk/gdb/solib-fdpic.h
new file mode 100644
index 0000000..5cb45a1
--- /dev/null
+++ b/src/gdb-trunk/gdb/solib-fdpic.h
@@ -0,0 +1,25 @@
+/* Handle FDPIC shared libraries for GDB, the GNU Debugger.
+   Copyright (C) 2010 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 SOLIB_FDPIC_H
+#define SOLIB_FDPIC_H
+
+struct target_so_ops;
+extern struct target_so_ops fdpic_so_ops;
+
+#endif
diff --git a/src/gdb-trunk/gdb/target.h b/src/gdb-trunk/gdb/target.h
index 27e250a..6d0eac6 100644
--- a/src/gdb-trunk/gdb/target.h
+++ b/src/gdb-trunk/gdb/target.h
@@ -266,6 +266,8 @@ enum target_object
   TARGET_OBJECT_SIGNAL_INFO,
   /* The list of threads that are being debugged.  */
   TARGET_OBJECT_THREADS,
+  /* Load maps for FDPIC systems.  */
+  TARGET_OBJECT_FDPIC
   /* Possible future objects: TARGET_OBJECT_FILE, ... */
 };
 
diff --git a/src/gdb-trunk/include/elf/sh.h b/src/gdb-trunk/include/elf/sh.h
index 4969116..158eb88 100644
--- a/src/gdb-trunk/include/elf/sh.h
+++ b/src/gdb-trunk/include/elf/sh.h
@@ -85,6 +85,12 @@ int sh_find_elf_flags (unsigned int arch_set);
 /* Convert bfd_mach_* into EF_SH*.  */
 int sh_elf_get_flags_from_mach (unsigned long mach);
 
+/* Other e_flags bits.  */
+
+#define EF_SH_PIC		0x100	/* Segments of an FDPIC binary may
+					   be relocated independently.  */
+#define EF_SH_FDPIC		0x8000	/* Uses the FDPIC ABI.  */
+
 /* Flags for the st_other symbol field.
    Keep away from the STV_ visibility flags (bit 0..1).  */
 
@@ -213,7 +219,17 @@ START_RELOC_NUMBERS (elf_sh_reloc_type)
   RELOC_NUMBER (R_SH_JMP_SLOT64, 195)
   RELOC_NUMBER (R_SH_RELATIVE64, 196)
   FAKE_RELOC (R_SH_FIRST_INVALID_RELOC_5, 197)
-  FAKE_RELOC (R_SH_LAST_INVALID_RELOC_5, 241)
+  FAKE_RELOC (R_SH_LAST_INVALID_RELOC_5, 200)
+  RELOC_NUMBER (R_SH_GOT20, 201)
+  RELOC_NUMBER (R_SH_GOTOFF20, 202)
+  RELOC_NUMBER (R_SH_GOTFUNCDESC, 203)
+  RELOC_NUMBER (R_SH_GOTFUNCDESC20, 204)
+  RELOC_NUMBER (R_SH_GOTOFFFUNCDESC, 205)
+  RELOC_NUMBER (R_SH_GOTOFFFUNCDESC20, 206)
+  RELOC_NUMBER (R_SH_FUNCDESC, 207)
+  RELOC_NUMBER (R_SH_FUNCDESC_VALUE, 208)
+  FAKE_RELOC (R_SH_FIRST_INVALID_RELOC_6, 209)
+  FAKE_RELOC (R_SH_LAST_INVALID_RELOC_6, 241)
   RELOC_NUMBER (R_SH_SHMEDIA_CODE, 242)
   RELOC_NUMBER (R_SH_PT_16, 243)
   RELOC_NUMBER (R_SH_IMMS16, 244)

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [toolchain-devel] [PATCH v2] gdbserver: bfin: new port
  2010-12-15 11:54                 ` Andrew Stubbs
@ 2010-12-15 12:55                   ` Mike Frysinger
  2010-12-15 13:17                     ` Andrew Stubbs
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2010-12-15 12:55 UTC (permalink / raw)
  To: Andrew Stubbs
  Cc: Daniel Jacobowitz, toolchain-devel, gdb-patches, Pedro Alves

On Wed, Dec 15, 2010 at 06:54, Andrew Stubbs wrote:
> On 14/12/10 17:25, Mike Frysinger wrote:
>>> I did start implementing something vaguely target independent (included
>>> >  in CodeSourcery SG++), but the state of the SH-2A kernel debug support
>>> >  put that project on the back burner, so it remains the bare minimum.
>>
>> i'm not asking for a finished project.  i would like to simply review the
>> code
>> you said you have already.  so where might one find your SuperH/FDPIC
>> gdb/gdbserver code ?
>
> The latest CodeSourcery SH-2A toolchain binaries and source can be
> downloaded from here:
> http://www.codesourcery.com/sgpp/lite/superh/portal/release1602
>
> I've attached my original patch. I didn't do the forward port when we
> updated GDB myself, so it may be out-of-date in a few places.

code looks good ... but there's one slight problem.  it is binding to
the format gdbserver itself is being compiled as.  in other words,
this code requires gdbserver itself to be compiled as FDPIC in order
to debug FDPIC applications.  the current Blackfin code does not have
that restriction ... a FLAT gdbserver can debug a FDPIC app just fine.

but it seems this limitation is superfluous ... how about we change
the __FDPIC__ ifdef to:
#if defined(PTRACE_GETFDPIC_EXEC) && defined(PTRACE_GETFDPIC_INTERP)
...
#endif

do you have an idea of when you'll submit just the qXfer:fdpic support
?  seems that these pieces can stand on their own just fine.
-mike


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3] gdb: bfin: new port
  2010-12-14 22:01     ` Mike Frysinger
@ 2010-12-15 13:02       ` Mike Frysinger
  2010-12-15 16:53         ` Pedro Alves
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2010-12-15 13:02 UTC (permalink / raw)
  To: gdb-patches; +Cc: Pedro Alves, toolchain-devel

[-- Attachment #1: Type: Text/Plain, Size: 1068 bytes --]

On Tuesday, December 14, 2010 17:00:13 Mike Frysinger wrote:
> On Tuesday, December 14, 2010 16:31:22 Pedro Alves wrote:
> > Can you explain why are the PC and CC registers pseudo
> > registers, but supported as being raw registers anyway?  Couldn't
> > gdb compute them itself from the other registers, with
> > gdb's pseudo register support (gdbarch_pseudo_register_read|write)?
> > googling I found you mentioning that the "CC pseudo register can
> > be deduced from the ASTAT register", though further googling doesn't
> > find any mention of what ASTAT is.  I'm sure there's a good reason,
> > I'm probably just missing a comment somewhere.
> 
> CC is actually a single bit in the ASTAT (arithmetic status) register, but
> often is treated as an actual register in much of the ISA.  such as
> assignments or logical tests.  you can do "<reg> = CC" and "CC = <reg>",
> but you cant do this with any other ASTAT bit (like AZ, AN, etc...).

another data point: gcc itself treats CC as a register.

btw, the name is short for "Control Code"
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [toolchain-devel] [PATCH v2] gdbserver: bfin: new port
  2010-12-15 12:55                   ` [toolchain-devel] " Mike Frysinger
@ 2010-12-15 13:17                     ` Andrew Stubbs
  0 siblings, 0 replies; 34+ messages in thread
From: Andrew Stubbs @ 2010-12-15 13:17 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Daniel Jacobowitz, toolchain-devel, gdb-patches, Pedro Alves

On 15/12/10 12:55, Mike Frysinger wrote:
> code looks good ... but there's one slight problem.  it is binding to
> the format gdbserver itself is being compiled as.  in other words,
> this code requires gdbserver itself to be compiled as FDPIC in order
> to debug FDPIC applications.  the current Blackfin code does not have
> that restriction ... a FLAT gdbserver can debug a FDPIC app just fine.
>
> but it seems this limitation is superfluous ... how about we change
> the __FDPIC__ ifdef to:
> #if defined(PTRACE_GETFDPIC_EXEC)&&  defined(PTRACE_GETFDPIC_INTERP)
> ...
> #endif

Seems fine to me.

> do you have an idea of when you'll submit just the qXfer:fdpic support
> ?  seems that these pieces can stand on their own just fine.

I had not planned to submit it until I had the whole thing working. 
Given that the kernel was badly broken, last time I checked, I couldn't 
do it then, and I haven't had time since. Nor am I likely to have time 
to do more work on this in the foreseeable future.

Feel free to take the patch and do what you like with it. It's just a 
matter of cutting out the non-gdbserver bits anyway.

Andrew


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3] gdb: bfin: new port
  2010-12-15 13:02       ` Mike Frysinger
@ 2010-12-15 16:53         ` Pedro Alves
  2010-12-15 17:08           ` Mike Frysinger
  0 siblings, 1 reply; 34+ messages in thread
From: Pedro Alves @ 2010-12-15 16:53 UTC (permalink / raw)
  To: gdb-patches; +Cc: Mike Frysinger, toolchain-devel

On Wednesday 15 December 2010 13:02:02, Mike Frysinger wrote:
> On Tuesday, December 14, 2010 17:00:13 Mike Frysinger wrote:
> > On Tuesday, December 14, 2010 16:31:22 Pedro Alves wrote:
> > > Can you explain why are the PC and CC registers pseudo
> > > registers, but supported as being raw registers anyway?  Couldn't
> > > gdb compute them itself from the other registers, with
> > > gdb's pseudo register support (gdbarch_pseudo_register_read|write)?
> > > googling I found you mentioning that the "CC pseudo register can
> > > be deduced from the ASTAT register", though further googling doesn't
> > > find any mention of what ASTAT is.  I'm sure there's a good reason,
> > > I'm probably just missing a comment somewhere.
> > 
> > CC is actually a single bit in the ASTAT (arithmetic status) register, but
> > often is treated as an actual register in much of the ISA.  such as
> > assignments or logical tests.  you can do "<reg> = CC" and "CC = <reg>",
> > but you cant do this with any other ASTAT bit (like AZ, AN, etc...).
> 
> another data point: gcc itself treats CC as a register.
> 
> btw, the name is short for "Control Code"

Thanks for the explanations.  This makes it so that the ASTAT.CC bit
can easily end up out of sync with the CC register in gdb's
regcache then, right?  E.g., "p $cc = 1; p $asat" will still show the
$asat.cc as 0, IIUC.  Does the kernel actually store CC on its
own slot in the register stack?  I ask because I see it commented out
in bfin_regmap in gdbserver.  If $cc was a pseudo-register _managed_ by
gdb (computed from ASAT), then this out-of-sync-ness would never happen.

Similar comments apply to the PC.  I see:

> +static int bfin_linux_sigcontext_reg_offset[BFIN_NUM_REGS]
...
> +  21 * 4,      /* %reti */
> +  22 * 4,      /* %retx */
> +  -1,          /* %retn */
> +  -1,          /* %rete */
> +  21 * 4,      /* %pc */

So, it's really the same stack slot as reti.

and in gdbserver:

> +static int bfin_regmap[] =
> +  -1 /* PT_USP */, PT_SEQSTAT, PT_SYSCFG, PT_PC, PT_RETX, PT_RETN, PT_RETE,
> +  PT_PC, -1 /* PT_CC */,

(PT_PC used to get at reti).

It all looks like you should really make the PC and the CC registers
pseudo registers handled by gdb, and not pass them on the remote
protocol wire, getting rid of all the possibility of confusing
out-of-sync iret/pc, astat/cc.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2] gdbserver: bfin: new port
  2010-12-14 18:21                   ` Mike Frysinger
@ 2010-12-15 16:54                     ` Mike Frysinger
  0 siblings, 0 replies; 34+ messages in thread
From: Mike Frysinger @ 2010-12-15 16:54 UTC (permalink / raw)
  To: gdb-patches
  Cc: Pedro Alves, Andrew Stubbs, toolchain-devel, Daniel Jacobowitz

[-- Attachment #1: Type: Text/Plain, Size: 1284 bytes --]

On Tuesday, December 14, 2010 13:20:35 Mike Frysinger wrote:
> On Tuesday, December 14, 2010 13:06:19 Pedro Alves wrote:
> > On Tuesday 14 December 2010 17:47:11, Mike Frysinger wrote:
> > > i'll open a tracker item to get this stuff eventually split out, but i
> > > dont see it being done in a time frame that is before the gdb-7.3
> > > release which i really want to be a part of.
> > 
> > That's months away.  I think you're over estimating.  :-)
> 
> i'm pessimistic when it comes to absorbing knowledge of projects under
> sourceware.org ... it's an ecosystem unto itself.
> 
> > BTW, you should also include
> > linux-tdep.o in gdb_target_obs, and call linux_init_abi somewhere
> > in your GDB_OSABI_LINUX osabi handler.
> 
> i'm guessing this would depend on the bfin-linux-tdep split though as we
> currently dont have any osabi handlers.  this linux-tdep code is "new" as
> it wasnt in the version of gdb we're upgrading from.

seems your optimism wins over my pessimism.  splitting out into bfin-linux-
tdep was fairly easy, as was dropping all of our old sigcontext parsing in 
favor of trad-frame.  i love watching code get deleted in favor of 
functionality equivalent snippets :).

hopefully my v4 patchset should make everyone happy.
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3] gdb: bfin: new port
  2010-12-15 16:53         ` Pedro Alves
@ 2010-12-15 17:08           ` Mike Frysinger
  2010-12-15 18:01             ` Pedro Alves
  2010-12-15 18:16             ` Mike Frysinger
  0 siblings, 2 replies; 34+ messages in thread
From: Mike Frysinger @ 2010-12-15 17:08 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches, toolchain-devel

[-- Attachment #1: Type: Text/Plain, Size: 3483 bytes --]

On Wednesday, December 15, 2010 11:49:32 Pedro Alves wrote:
> On Wednesday 15 December 2010 13:02:02, Mike Frysinger wrote:
> > On Tuesday, December 14, 2010 17:00:13 Mike Frysinger wrote:
> > > On Tuesday, December 14, 2010 16:31:22 Pedro Alves wrote:
> > > > Can you explain why are the PC and CC registers pseudo
> > > > registers, but supported as being raw registers anyway?  Couldn't
> > > > gdb compute them itself from the other registers, with
> > > > gdb's pseudo register support (gdbarch_pseudo_register_read|write)?
> > > > googling I found you mentioning that the "CC pseudo register can
> > > > be deduced from the ASTAT register", though further googling doesn't
> > > > find any mention of what ASTAT is.  I'm sure there's a good reason,
> > > > I'm probably just missing a comment somewhere.
> > > 
> > > CC is actually a single bit in the ASTAT (arithmetic status) register,
> > > but often is treated as an actual register in much of the ISA.  such
> > > as assignments or logical tests.  you can do "<reg> = CC" and "CC =
> > > <reg>", but you cant do this with any other ASTAT bit (like AZ, AN,
> > > etc...).
> > 
> > another data point: gcc itself treats CC as a register.
> > 
> > btw, the name is short for "Control Code"
> 
> Thanks for the explanations.  This makes it so that the ASTAT.CC bit
> can easily end up out of sync with the CC register in gdb's
> regcache then, right?  E.g., "p $cc = 1; p $asat" will still show the
> $asat.cc as 0, IIUC.  Does the kernel actually store CC on its
> own slot in the register stack?  I ask because I see it commented out
> in bfin_regmap in gdbserver.  If $cc was a pseudo-register _managed_ by
> gdb (computed from ASAT), then this out-of-sync-ness would never happen.

no, linux does not give CC dedicated space in the signal context.  it does 
look like setting $cc on the command line results in out-of-sync values with 
$astat.  i'll take a look at the pseudo helpers you referenced and see if i 
cant figure out how they work.

> Similar comments apply to the PC.  I see:
> > +static int bfin_linux_sigcontext_reg_offset[BFIN_NUM_REGS]
> ...
> > +  21 * 4,      /* %reti */
> > +  22 * 4,      /* %retx */
> > +  -1,          /* %retn */
> > +  -1,          /* %rete */
> > +  21 * 4,      /* %pc */
> 
> So, it's really the same stack slot as reti.
> 
> and in gdbserver:
> > +static int bfin_regmap[] =
> > +  -1 /* PT_USP */, PT_SEQSTAT, PT_SYSCFG, PT_PC, PT_RETX, PT_RETN,
> > PT_RETE, +  PT_PC, -1 /* PT_CC */,
> 
> (PT_PC used to get at reti).
> 
> It all looks like you should really make the PC and the CC registers
> pseudo registers handled by gdb, and not pass them on the remote
> protocol wire, getting rid of all the possibility of confusing
> out-of-sync iret/pc, astat/cc.

the trouble with PC is that it isnt always RETI.  with a Linux userspace app, 
the PC is managed indirectly via RETI (by nature of the sequencer).  but this 
all depends on the level the remote stub is operating at.  it could possibly 
be indirectly handled by RETX or RETN or RETE as well.  so i think the PC 
logic needs to be left up to the remote stub to properly manage.  i dont think 
we need to worry about people attempting to screw with any of the supervisor 
level registers (RET[IXNE]) because they arent allowed to in usermode and they 
make no sense unless you're in any of those contexts 
(interrupt/exception/nmi/emulation).
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3] gdb: bfin: new port
  2010-12-15 17:08           ` Mike Frysinger
@ 2010-12-15 18:01             ` Pedro Alves
  2010-12-15 18:38               ` Mike Frysinger
  2010-12-15 18:16             ` Mike Frysinger
  1 sibling, 1 reply; 34+ messages in thread
From: Pedro Alves @ 2010-12-15 18:01 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: gdb-patches, toolchain-devel

On Wednesday 15 December 2010 17:07:11, Mike Frysinger wrote:
> > It all looks like you should really make the PC and the CC registers
> > pseudo registers handled by gdb, and not pass them on the remote
> > protocol wire, getting rid of all the possibility of confusing
> > out-of-sync iret/pc, astat/cc.
> 
> the trouble with PC is that it isnt always RETI.  with a Linux userspace app, 
> the PC is managed indirectly via RETI (by nature of the sequencer).  but this 
> all depends on the level the remote stub is operating at.  it could possibly 
> be indirectly handled by RETX or RETN or RETE as well.  
> so i think the PC 
> logic needs to be left up to the remote stub to properly manage.  i dont think 
> we need to worry about people attempting to screw with any of the supervisor 
> level registers (RET[IXNE]) because they arent allowed to in usermode and they 
> make no sense unless you're in any of those contexts 
> (interrupt/exception/nmi/emulation).

I see.  Does the correct pc register depend on context (in exception, in
interrupt, in normal code, in whatnot), or is it always fixed per stub?  If
the latter, it sounds like something that should be handled by a xml target
description that somehow tells gdb which register is the pc (sounds more
complicated than it is, I think).  If the former, is there any way to tell
which is the correct register by reading some other register, perhaps?
Otherwise, yeah, best keep it a separate register, which is a bit of a
shame...

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3] gdb: bfin: new port
  2010-12-15 17:08           ` Mike Frysinger
  2010-12-15 18:01             ` Pedro Alves
@ 2010-12-15 18:16             ` Mike Frysinger
  2010-12-15 18:25               ` Pedro Alves
  1 sibling, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2010-12-15 18:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Pedro Alves, toolchain-devel

[-- Attachment #1: Type: Text/Plain, Size: 4240 bytes --]

On Wednesday, December 15, 2010 12:07:11 Mike Frysinger wrote:
> On Wednesday, December 15, 2010 11:49:32 Pedro Alves wrote:
> > Thanks for the explanations.  This makes it so that the ASTAT.CC bit
> > can easily end up out of sync with the CC register in gdb's
> > regcache then, right?  E.g., "p $cc = 1; p $asat" will still show the
> > $asat.cc as 0, IIUC.  Does the kernel actually store CC on its
> > own slot in the register stack?  I ask because I see it commented out
> > in bfin_regmap in gdbserver.  If $cc was a pseudo-register _managed_ by
> > gdb (computed from ASAT), then this out-of-sync-ness would never happen.
> 
> no, linux does not give CC dedicated space in the signal context.  it does
> look like setting $cc on the command line results in out-of-sync values
> with $astat.  i'll take a look at the pseudo helpers you referenced and
> see if i cant figure out how they work.

what do you think of this ?  seems to work for me:
(gdb) set $cc = 0
(gdb) printf "%x %x\n", $astat, $cc
2002002 0
(gdb) set $cc = 1
(gdb) printf "%x %x\n", $astat, $cc
2002022 1
(gdb) set $astat = 0
(gdb) printf "%x %x\n", $astat, $cc
0 0
(gdb) set $astat = 0x20
(gdb) printf "%x %x\n", $astat, $cc
20 1
-mike

--- a/gdb/bfin-linux-tdep.c
+++ b/gdb/bfin-linux-tdep.c
@@ -88,7 +88,6 @@ static const int bfin_linux_sigcontext_reg_offset[BFIN_NUM_REGS] =
   -1,		/* %retn */
   -1,		/* %rete */
   21 * 4,	/* %pc */
-  -1,		/* %cc */
 };
 
 /* Signal trampolines.  */
--- a/gdb/bfin-tdep.c
+++ b/gdb/bfin-tdep.c
@@ -116,16 +116,12 @@
 /* The maximum bytes we search to skip the prologue.  */
 #define UPPER_LIMIT			40
 
-#define RETS_OFFSET			4
+/* ASTAT bits  */
+#define ASTAT_CC_POS			5
+#define ASTAT_CC			(1 << ASTAT_CC_POS)
 
 /* Initial value: Register names used in BFIN's ISA documentation.  */
 
@@ -683,6 +683,36 @@ bfin_register_name (struct gdbarch *gdbarch, int i)
   return bfin_register_name_strings[i];
 }
 
+static void
+bfin_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+			   int regnum, gdb_byte *buffer)
+{
+  gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+
+  if (regnum != BFIN_CC_REGNUM)
+    internal_error (__FILE__, __LINE__,
+		    _("invalid register number %d"), regnum);
+
+  regcache_raw_read (regcache, BFIN_ASTAT_REGNUM, buf);
+  buffer[1] = buffer[2] = buffer[3] = 0;
+  buffer[0] = !!(buf[0] & ASTAT_CC);
+}
+
+static void
+bfin_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+			    int regnum, const gdb_byte *buffer)
+{
+  gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
+
+  if (regnum != BFIN_CC_REGNUM)
+    internal_error (__FILE__, __LINE__,
+		    _("invalid register number %d"), regnum);
+
+  regcache_raw_read (regcache, BFIN_ASTAT_REGNUM, buf);
+  buf[0] = (buf[0] & ~ASTAT_CC) | ((buffer[0] & 1) << ASTAT_CC_POS);
+  regcache_raw_write (regcache, BFIN_ASTAT_REGNUM, buf);
+}
+
 static CORE_ADDR
 bfin_frame_base_address (struct frame_info *this_frame, void **this_cache)
 {
@@ -783,7 +813,9 @@ bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->bfin_abi = abi;
 
   set_gdbarch_num_regs (gdbarch, BFIN_NUM_REGS);
-  set_gdbarch_num_pseudo_regs (gdbarch, 0);
+  set_gdbarch_pseudo_register_read (gdbarch, bfin_pseudo_register_read);
+  set_gdbarch_pseudo_register_write (gdbarch, bfin_pseudo_register_write);
+  set_gdbarch_num_pseudo_regs (gdbarch, BFIN_NUM_PSEUDO_REGS);
   set_gdbarch_sp_regnum (gdbarch, BFIN_SP_REGNUM);
   set_gdbarch_pc_regnum (gdbarch, BFIN_PC_REGNUM);
   set_gdbarch_ps_regnum (gdbarch, BFIN_ASTAT_REGNUM);
--- a/gdb/bfin-tdep.h
+++ b/gdb/bfin-tdep.h
@@ -74,13 +74,14 @@ enum gdb_regnum {
   BFIN_RETN_REGNUM,
   BFIN_RETE_REGNUM,
 
-  /* Pseudo Registers */
+  /* Pseudo Registers managed remotely.  */
   BFIN_PC_REGNUM,
-  BFIN_CC_REGNUM,
 
-  /* LAST ENTRY SHOULD NOT BE CHANGED.  */
-  BFIN_NUM_REGS			/* The number of all registers.  */
+  /* Pseudo Registers managed locally.  */
+  BFIN_CC_REGNUM
 };
+#define BFIN_NUM_REGS (BFIN_PC_REGNUM + 1)
+#define BFIN_NUM_PSEUDO_REGS (1)
 
 /* The ABIs for Blackfin.  */
 enum bfin_abi

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3] gdb: bfin: new port
  2010-12-15 18:16             ` Mike Frysinger
@ 2010-12-15 18:25               ` Pedro Alves
  0 siblings, 0 replies; 34+ messages in thread
From: Pedro Alves @ 2010-12-15 18:25 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: gdb-patches, toolchain-devel

On Wednesday 15 December 2010 18:15:25, Mike Frysinger wrote:
> what do you think of this ?  seems to work for me:

Awesome.  Looks good.

> (gdb) set $cc = 0
> (gdb) printf "%x %x\n", $astat, $cc
> 2002002 0
> (gdb) set $cc = 1
> (gdb) printf "%x %x\n", $astat, $cc
> 2002022 1
> (gdb) set $astat = 0
> (gdb) printf "%x %x\n", $astat, $cc
> 0 0
> (gdb) set $astat = 0x20
> (gdb) printf "%x %x\n", $astat, $cc
> 20 1
> -mike

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3] gdb: bfin: new port
  2010-12-15 18:01             ` Pedro Alves
@ 2010-12-15 18:38               ` Mike Frysinger
  2010-12-15 18:42                 ` Pedro Alves
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2010-12-15 18:38 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches, toolchain-devel

[-- Attachment #1: Type: Text/Plain, Size: 2602 bytes --]

On Wednesday, December 15, 2010 13:00:27 Pedro Alves wrote:
> On Wednesday 15 December 2010 17:07:11, Mike Frysinger wrote:
> > > It all looks like you should really make the PC and the CC registers
> > > pseudo registers handled by gdb, and not pass them on the remote
> > > protocol wire, getting rid of all the possibility of confusing
> > > out-of-sync iret/pc, astat/cc.
> > 
> > the trouble with PC is that it isnt always RETI.  with a Linux userspace
> > app, the PC is managed indirectly via RETI (by nature of the sequencer).
> >  but this all depends on the level the remote stub is operating at.  it
> > could possibly be indirectly handled by RETX or RETN or RETE as well.
> > so i think the PC
> > logic needs to be left up to the remote stub to properly manage.  i dont
> > think we need to worry about people attempting to screw with any of the
> > supervisor level registers (RET[IXNE]) because they arent allowed to in
> > usermode and they make no sense unless you're in any of those contexts
> > (interrupt/exception/nmi/emulation).
> 
> I see.  Does the correct pc register depend on context (in exception, in
> interrupt, in normal code, in whatnot), or is it always fixed per stub?  If
> the latter, it sounds like something that should be handled by a xml target
> description that somehow tells gdb which register is the pc (sounds more
> complicated than it is, I think).  If the former, is there any way to tell
> which is the correct register by reading some other register, perhaps?
> Otherwise, yeah, best keep it a separate register, which is a bit of a
> shame...

in practice, i think the reg would be fixed per stub, but there isnt a 
requirement for it to be.

in the Linux case, the userspace PC often shuffles between all the registers, 
and eventually shoves it into RETI (due to how the kernel resumes user mode 
from supervisor mode).  userspace doesnt actually know about this ... it 
merely asks via ptrace for the PT_PC register.  changing things in the kernel 
could break this assumption (RETI == PC), but the ABI would be preserved since 
we have the PT_PC indirection.

conceivably, a stub operating in a higher mode could pick it from the right 
register immediately rather than doing the delayed loading seen in the linux 
kernel.

the Blackfin simulator actually does have a dedicated PC register, so in that 
case the request is fulfilled from that source.

having the stub export the indirect logic on the fly might be possible, but 
i'm not sure the extra complication required is an improvement.
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v3] gdb: bfin: new port
  2010-12-15 18:38               ` Mike Frysinger
@ 2010-12-15 18:42                 ` Pedro Alves
  0 siblings, 0 replies; 34+ messages in thread
From: Pedro Alves @ 2010-12-15 18:42 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: gdb-patches, toolchain-devel

On Wednesday 15 December 2010 18:37:49, Mike Frysinger wrote:
> having the stub export the indirect logic on the fly might be possible, but 
> i'm not sure the extra complication required is an improvement.

Okay, let's stick with a pc register managed by the stub then.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2010-12-15 18:42 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-09  9:29 [PATCH v2] gdb: bfin: new port Mike Frysinger
2010-12-09  9:31 ` [PATCH v2] gdbserver: " Mike Frysinger
2010-12-13 18:44   ` Pedro Alves
2010-12-13 19:24     ` Mike Frysinger
2010-12-14  9:37     ` Andrew Stubbs
2010-12-14 15:10       ` Mike Frysinger
2010-12-14 16:31         ` Pedro Alves
2010-12-14 16:58           ` Mike Frysinger
2010-12-14 17:16             ` Andrew Stubbs
2010-12-14 17:26               ` Mike Frysinger
2010-12-15 11:54                 ` Andrew Stubbs
2010-12-15 12:55                   ` [toolchain-devel] " Mike Frysinger
2010-12-15 13:17                     ` Andrew Stubbs
2010-12-14 17:40             ` Pedro Alves
2010-12-14 17:48               ` Mike Frysinger
2010-12-14 18:06                 ` Pedro Alves
2010-12-14 18:21                   ` Mike Frysinger
2010-12-15 16:54                     ` Mike Frysinger
2010-12-14  6:03 ` [PATCH v2] gdb: " Joel Brobecker
2010-12-14 16:14   ` Mike Frysinger
2010-12-14 20:43 ` [PATCH v3] " Mike Frysinger
2010-12-14 21:31   ` Pedro Alves
2010-12-14 22:01     ` Mike Frysinger
2010-12-15 13:02       ` Mike Frysinger
2010-12-15 16:53         ` Pedro Alves
2010-12-15 17:08           ` Mike Frysinger
2010-12-15 18:01             ` Pedro Alves
2010-12-15 18:38               ` Mike Frysinger
2010-12-15 18:42                 ` Pedro Alves
2010-12-15 18:16             ` Mike Frysinger
2010-12-15 18:25               ` Pedro Alves
2010-12-14 21:48   ` [PATCH v3] gdbserver: " Mike Frysinger
2010-12-14 23:03     ` Ralf Corsepius
2010-12-15  0:15       ` Mike Frysinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox