This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project. See the GDB home page for more information.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

GDB support for m68k-linux


This patch adds host, target and native support for m68k-linux.  I hope
that this will finally be installed, more than two(!) years after i have
contributed it the first time.  All necessary assignments are already
present, since July 1996.


1998-12-01  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>

	* Makefile.in, configure.host, configure.tgt: Add support for
	m68k-linux.
	* config/m68k/linux.mh: New file.
	* config/m68k/linux.mt: New file.
	* config/m68k/nm-linux.h: New file.
	* config/m68k/tm-linux.h: New file.
	* config/m68k/xm-linux.h: New file.
	* gdb/m68klinux-nat.c: New file.
	* gdbserver/low-linux.c: Add support for m68k-linux.
	* gdb/config/m68k/tm-m68k.h (NUM_FREGS): New macro.

--- gdb-981121/gdb/Makefile.in.~1~	Mon Nov 23 23:47:55 1998
+++ gdb-981121/gdb/Makefile.in	Tue Nov 24 00:26:20 1998
@@ -1164,6 +1164,9 @@
 	$(gdbcore_h) gdb_string.h
 
 m68kly-nat.o: m68kly-nat.c $(defs_h) $(frame_h) $(inferior_h) target.h
+
+m68klinux-nat.o: m68klinux-nat.c $(defs_h) $(frame_h) $(inferior_h) \
+	$(language_h) $(gdbcore_h) $(floatformat_h) target.h
 
 m88k-nat.o: m88k-nat.c $(defs_h) $(gdbcore_h) $(inferior_h)
 
--- /dev/null	Sun Oct 25 16:43:08 1998
+++ gdb-981121/gdb/config/m68k/linux.mh	Tue Apr 30 00:25:38 1996
@@ -0,0 +1,9 @@
+# Host: Motorola m68k running Linux
+
+XM_FILE= xm-linux.h
+XDEPFILES= ser-tcp.o
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o solib.o inftarg.o fork-child.o corelow.o core-aout.o core-regset.o m68klinux-nat.o
+
+GDBSERVER_DEPFILES= low-linux.o
--- /dev/null	Sun Oct 25 16:43:08 1998
+++ gdb-981121/gdb/config/m68k/linux.mt	Mon Apr 29 23:00:57 1996
@@ -0,0 +1,3 @@
+# Target: Motorola m68k with a.out and ELF
+TDEPFILES= m68k-tdep.o
+TM_FILE= tm-linux.h
--- /dev/null	Sun Oct 25 16:43:08 1998
+++ gdb-981121/gdb/config/m68k/nm-linux.h	Sun May  3 13:09:41 1998
@@ -0,0 +1,47 @@
+/* Native support for linux, for GDB, the GNU debugger.
+   Copyright (C) 1996,1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef NM_LINUX_H
+#define NM_LINUX_H
+
+/* Return sizeof user struct to callers in less machine dependent routines */
+
+#define KERNEL_U_SIZE kernel_u_size()
+extern int kernel_u_size PARAMS ((void));
+
+/* Tell gdb that we can attach and detach other processes */
+#define ATTACH_DETACH
+
+#define U_REGS_OFFSET 0
+
+/* We define this if link.h is available, because with ELF we use SVR4 style
+   shared libraries. */
+
+#ifdef HAVE_LINK_H
+#define SVR4_SHARED_LIBS
+#include "solib.h"		/* Support for shared libraries. */
+#endif
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+	(addr) = m68k_linux_register_u_addr ((blockend),(regno));
+
+extern int
+m68k_linux_register_u_addr PARAMS ((int, int));
+
+#endif /* #ifndef NM_LINUX_H */
--- /dev/null	Sun Oct 25 16:43:08 1998
+++ gdb-981121/gdb/config/m68k/tm-linux.h	Sun May  3 13:10:15 1998
@@ -0,0 +1,109 @@
+/* Definitions to target GDB to Linux on m680x0
+   Copyright (C) 1996,1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* Number of traps that happen between exec'ing the shell to run an
+   inferior, and when we finally get to the inferior code.  This is 2
+   on most implementations.  */
+
+#define START_INFERIOR_TRAPS_EXPECTED 2
+
+/* The following definitions are appropriate when using the ELF
+   format, where floating point values are returned in fp0, pointer
+   values in a0 and other values in d0.  */
+
+/* Extract from an array REGBUF containing the (raw) register state a
+   function return value of type TYPE, and copy that, in virtual
+   format, into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+{									\
+  if (TYPE_CODE (TYPE) == TYPE_CODE_FLT)				\
+    {									\
+       REGISTER_CONVERT_TO_VIRTUAL (FP0_REGNUM, TYPE,			\
+				    ((char *) (REGBUF)			\
+				     + REGISTER_BYTE (FP0_REGNUM)),	\
+				    VALBUF);				\
+    }									\
+  else if (TYPE_CODE (TYPE) == TYPE_CODE_PTR)				\
+    memcpy (VALBUF, (char *) (REGBUF) + REGISTER_BYTE (A0_REGNUM),	\
+	    TYPE_LENGTH (TYPE));					\
+  else									\
+    memcpy (VALBUF,							\
+	    ((char *) (REGBUF)						\
+	     + (TYPE_LENGTH (TYPE) >= 4 ? 0 : 4 - TYPE_LENGTH (TYPE))),	\
+	    TYPE_LENGTH (TYPE));					\
+}
+
+/* Write into appropriate registers a function return value of type
+   TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+{									\
+  if (TYPE_CODE (TYPE) == TYPE_CODE_FLT)				\
+    {									\
+      char raw_buffer[REGISTER_RAW_SIZE (FP0_REGNUM)];			\
+      REGISTER_CONVERT_TO_RAW (TYPE, FP0_REGNUM, VALBUF, raw_buffer);	\
+      write_register_bytes (REGISTER_BYTE (FP0_REGNUM),			\
+			    raw_buffer, TYPE_LENGTH (TYPE));		\
+    }									\
+  else									\
+    {									\
+      if (TYPE_CODE (TYPE) == TYPE_CODE_PTR)				\
+	write_register_bytes (REGISTER_BYTE (A0_REGNUM), VALBUF,	\
+			      TYPE_LENGTH (TYPE));			\
+      write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE));		\
+    }									\
+}
+
+#include "tm-sysv4.h"
+#include "m68k/tm-m68k.h"
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#undef EXTRACT_STRUCT_VALUE_ADDRESS
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+  (*(CORE_ADDR *)((char *) (REGBUF) + REGISTER_BYTE (A0_REGNUM)))
+
+/* Offsets (in target ints) into jmp_buf.  */
+
+#define JB_ELEMENT_SIZE 4
+#define JB_PC 7
+
+/* Figure out where the longjmp will land.  Slurp the args out of the stack.
+   We expect the first arg to be a pointer to the jmp_buf structure from which
+   we extract the pc (JB_PC) that we will land at.  The pc is copied into ADDR.
+   This routine returns true on success */
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+
+/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>.  */
+#define SIGCONTEXT_PC_OFFSET 26
+
+#undef FRAME_SAVED_PC
+#define FRAME_SAVED_PC(FRAME) \
+  (((FRAME)->signal_handler_caller \
+    ? sigtramp_saved_pc (FRAME) \
+    : read_memory_integer ((FRAME)->frame + 4, 4)))
+
+extern CORE_ADDR sigtramp_saved_pc PARAMS ((struct frame_info *));
+
+#define IN_SIGTRAMP(pc,name) in_sigtramp (pc)
+extern int in_sigtramp PARAMS ((CORE_ADDR pc));
--- gdb-981121/gdb/config/m68k/tm-m68k.h.~1~	Wed Apr 29 18:23:33 1998
+++ gdb-981121/gdb/config/m68k/tm-m68k.h	Wed Apr 29 20:11:34 1998
@@ -110,6 +110,8 @@
 #define NUM_REGS 29
 #endif
 
+#define NUM_FREGS (NUM_REGS-24)
+
 #ifndef REGISTER_BYTES_OK
 #define REGISTER_BYTES_OK(b) \
    ((b) == REGISTER_BYTES_FP \
--- /dev/null	Sun Oct 25 16:43:08 1998
+++ gdb-981121/gdb/config/m68k/xm-linux.h	Sun May  3 13:10:38 1998
@@ -0,0 +1,40 @@
+/* Native support for linux, for GDB, the GNU debugger.
+   Copyright (C) 1996,1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef XM_LINUX_H
+#define XM_LINUX_H
+
+/* Pick up most of what we need from the generic m68k host include file. */
+
+#include "m68k/xm-m68k.h"
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+#define KERNEL_U_ADDR 0x0
+
+#define HAVE_TERMIOS
+#define NEED_POSIX_SETPGID
+
+/* Linux has sigsetjmp and siglongjmp */
+#define HAVE_SIGSETJMP
+
+/* Need R_OK etc, but USG isn't defined.  */
+#include <unistd.h>
+
+#endif	/* #ifndef XM_LINUX_H */
--- gdb-981121/gdb/configure.host.~1~	Mon Nov 23 23:48:17 1998
+++ gdb-981121/gdb/configure.host	Tue Nov 24 00:27:15 1998
@@ -86,6 +86,7 @@
 m68*-hp-bsd*)		gdb_host=hp300bsd ;;
 m68*-hp-hpux*)		gdb_host=hp300hpux ;;
 m68*-isi-*)		gdb_host=isi ;;
+m68*-*-linux*)		gdb_host=linux ;;
 m68*-*-lynxos*)		gdb_host=m68klynx ;;
 m68*-*-netbsd*)		gdb_host=nbsd ;;
 m68*-*-sysv4*)		gdb_host=m68kv4 ;;
--- gdb-981121/gdb/configure.tgt.~1~	Mon Nov 23 23:48:18 1998
+++ gdb-981121/gdb/configure.tgt	Tue Nov 24 00:28:13 1998
@@ -147,6 +147,8 @@
 m68*-*-aout*)		gdb_target=monitor ;;
 m68*-*-coff*)		gdb_target=monitor ;;
 m68*-*-elf*)		gdb_target=monitor ;;
+m68*-*-linux*)		gdb_target=linux
+		configdirs="${configdirs} gdbserver" ;;
 m68*-*-lynxos*)		gdb_target=m68klynx
 		configdirs="${configdirs} gdbserver" ;;
 m68*-*-netbsd*)		gdb_target=nbsd ;;
--- gdb-981121/gdb/gdbserver/low-linux.c.~1~	Wed Apr 29 18:25:31 1998
+++ gdb-981121/gdb/gdbserver/low-linux.c	Tue Dec  1 11:03:57 1998
@@ -45,8 +45,8 @@
 /***************End MY defs*********************/
 
 #include <sys/ptrace.h>
-#if 0
-#include <machine/reg.h>
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+#include <sys/reg.h>
 #endif
 
 extern char **environ;
@@ -165,6 +165,7 @@
     - KERNEL_U_ADDR
 #endif
 
+#ifndef TARGET_M68K
 /* this table must line up with REGISTER_NAMES in tm-i386v.h */
 /* symbols like 'EAX' come from <sys/reg.h> */
 static int regmap[] = 
@@ -198,6 +199,37 @@
     return (blockend + 4 * regmap[regnum]);
   
 }
+#else /* TARGET_M68K */
+/* This table must line up with REGISTER_NAMES in tm-m68k.h */
+static int regmap[] = 
+{
+#ifdef PT_D0
+  PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
+  PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
+  PT_SR, PT_PC,
+#else
+  14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15,
+  17, 18,
+#endif
+#ifdef PT_FP0
+  PT_FP0, PT_FP1, PT_FP2, PT_FP3, PT_FP4, PT_FP5, PT_FP6, PT_FP7,
+  PT_FPCR, PT_FPSR, PT_FPIAR
+#else
+  21, 24, 27, 30, 33, 36, 39, 42, 45, 46, 47
+#endif
+};
+
+/* BLOCKEND is the value of u.u_ar0, and points to the place where GS
+   is stored.  */
+
+int
+m68k_linux_register_u_addr (blockend, regnum)
+     int blockend;
+     int regnum;
+{
+    return (blockend + 4 * regmap[regnum]);
+}
+#endif
 
 CORE_ADDR
 register_addr (regno, blockend)
--- /dev/null	Sun Oct 25 16:43:08 1998
+++ gdb-981121/gdb/m68klinux-nat.c	Sun May  3 13:30:58 1998
@@ -0,0 +1,141 @@
+/* Motorola m68k native support for Linux
+   Copyright (C) 1996,1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "frame.h"
+#include "inferior.h"
+#include "language.h"
+#include "gdbcore.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <sys/procfs.h>
+
+#include <sys/file.h>
+#include "gdb_stat.h"
+
+#include "floatformat.h"
+
+#include "target.h"
+
+
+/* This table must line up with REGISTER_NAMES in tm-m68k.h */
+static const int regmap[] = 
+{
+  PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
+  PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
+  PT_SR, PT_PC,
+  /* PT_FP0, ..., PT_FP7 */
+  21, 24, 27, 30, 33, 36, 39, 42,
+  /* PT_FPCR, PT_FPSR, PT_FPIAR */
+  45, 46, 47
+};
+
+/* BLOCKEND is the value of u.u_ar0, and points to the place where GS
+   is stored.  */
+
+int
+m68k_linux_register_u_addr (blockend, regnum)
+     int blockend;
+     int regnum;
+{
+    return (blockend + 4 * regmap[regnum]);
+}
+
+/*  Given a pointer to a general register set in /proc format (gregset_t *),
+    unpack the register contents and supply them as gdb's idea of the current
+    register values. */
+
+void
+supply_gregset (gregsetp)
+     gregset_t *gregsetp;
+{
+  int regi;
+
+  for (regi = D0_REGNUM ; regi <= SP_REGNUM ; regi++)
+    supply_register (regi, (char *) (*gregsetp + regmap[regi]));
+  supply_register (PS_REGNUM, (char *) (*gregsetp + PT_SR));
+  supply_register (PC_REGNUM, (char *) (*gregsetp + PT_PC));
+}
+
+/*  Given a pointer to a floating point register set in /proc format
+    (fpregset_t *), unpack the register contents and supply them as gdb's
+    idea of the current floating point register values. */
+
+void 
+supply_fpregset (fpregsetp)
+     fpregset_t *fpregsetp;
+{
+  int regi;
+
+  for (regi = FP0_REGNUM ; regi < FPC_REGNUM ; regi++)
+    supply_register (regi, (char *) &fpregsetp->fpregs[(regi - FP0_REGNUM) * 3]);
+  supply_register (FPC_REGNUM, (char *) &fpregsetp->fpcntl[0]);
+  supply_register (FPS_REGNUM, (char *) &fpregsetp->fpcntl[1]);
+  supply_register (FPI_REGNUM, (char *) &fpregsetp->fpcntl[2]);
+}
+
+int
+kernel_u_size ()
+{
+  return (sizeof (struct user));
+}
+
+/* Return non-zero if PC points into the signal trampoline.  */
+
+int
+in_sigtramp (pc)
+     CORE_ADDR pc;
+{
+  CORE_ADDR sp;
+  char buf[TARGET_SHORT_BIT / TARGET_CHAR_BIT];
+  int insn;
+
+  sp = read_register (SP_REGNUM);
+  if (pc - 2 < sp)
+    return 0;
+
+  if (read_memory_nobpt (pc, buf, sizeof (buf)))
+    return 0;
+  insn = extract_unsigned_integer (buf, sizeof (buf));
+  if (insn == 0xdefc /* addaw #,sp */
+      || insn == 0x7077 /* moveq #119,d0 */
+      || insn == 0x4e40 /* trap #0 */
+      || insn == 0x203c /* movel #,d0 */)
+    return 1;
+
+  if (read_memory_nobpt (pc - 2, buf, sizeof (buf)))
+    return 0;
+  insn = extract_unsigned_integer (buf, sizeof (buf));
+  if (insn == 0xdefc /* addaw #,sp */
+      || insn == 0x7077 /* moveq #119,d0 */
+      || insn == 0x4e40 /* trap #0 */
+      || insn == 0x203c /* movel #,d0 */)
+    return 1;
+
+  return 0;
+}

-- 
Andreas Schwab                                      "And now for something
schwab@issan.cs.uni-dortmund.de                      completely different"
schwab@gnu.org