* [RFA/m32r] m32r-linux support
@ 2004-08-05 5:11 Kei Sakamoto
2004-08-05 9:19 ` Mark Kettenis
0 siblings, 1 reply; 4+ messages in thread
From: Kei Sakamoto @ 2004-08-05 5:11 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 971 bytes --]
Hello,
The attached patch adds m32r-linux support.
The M32R architecture is not added to the official Linux kernel yet.
But Linux on M32R is already available.
http://www.linux-m32r.org/
The attached enables both native and gdbserver debug on m32r-linux.
OK to commit?
2004-08-05 Kei Sakamoto <sakamoto.kei@renesas.com>
Add m32r-linux support.
* configure.tgt: Add m32r*-*-linux*.
* Makefile.in (ALLDEPFILES): Add m32r-tdep.c, m32r-linux-nat.c and
m32r-linux-tdep.c.
(m32r-linux-nat.o, m32r-linux-tdep.o): New dependencies.
* m32r-linux-nat.c, m32r-linux-tdep.c, config/m32r/linux.mh,
config/m32r/linux.mt, config/m32r/m32r.mh, config/m32r/nm-linux.h,
config/m32r/tm-linux.h, config/m32r/tm-m32r.h, gdbserver/linux-m32r-low.c,
regformats/reg-m32r.dat: New files.
* config/m32r/m32r.mt (TM_FILE): Add tm-m32r.h.
* gdbserver/Makefile.in: Add reg-m32r.c and reg-m32r.o.
* gdbserver/configure.srv: Add m32r*-*-linux*.
[-- Attachment #2: m32r-linux.patch --]
[-- Type: application/octet-stream, Size: 36511 bytes --]
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.604
diff -u -r1.604 Makefile.in
--- Makefile.in 4 Aug 2004 20:43:14 -0000 1.604
+++ Makefile.in 5 Aug 2004 04:48:33 -0000
@@ -1380,6 +1380,8 @@
infptrace.c inftarg.c irix4-nat.c irix5-nat.c \
libunwind-frame.c \
lynx-nat.c m3-nat.c \
+ m32r-tdep.c \
+ m32r-linux-nat.c m32r-linux-tdep.c \
m68hc11-tdep.c \
m68k-tdep.c \
m68kbsd-nat.c m68kbsd-tdep.c \
@@ -2121,6 +2123,12 @@
$(expression_h) $(value_h) $(gdbcore_h) $(target_h) $(m2_lang_h)
m2-valprint.o: m2-valprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \
$(m2_lang_h)
+m32r-linux-nat.o: m32r-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
+ $(regcache_h) $(linux_nat_h) $(gdb_assert_h) $(gdb_string_h)
+m32r-linux-tdep.o: m32r-linux-tdep.c $(defs_h) $(gdbcore_h) $(frame_h) \
+ $(value_h) $(regcache_h) $(inferior_h) $(osabi_h) $(reggroups_h) \
+ $(gdb_string_h) $(glibc_tdep_h) $(solib_svr4_h) $(trad_frame_h) \
+ $(frame_unwind_h)
m32r-rom.o: m32r-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
$(serial_h) $(symtab_h) $(command_h) $(gdbcmd_h) $(symfile_h) \
$(gdb_string_h) $(objfiles_h) $(inferior_h) $(regcache_h)
Index: configure.tgt
===================================================================
RCS file: /cvs/src/src/gdb/configure.tgt,v
retrieving revision 1.144
diff -u -r1.144 configure.tgt
--- configure.tgt 26 Jun 2004 10:06:34 -0000 1.144
+++ configure.tgt 5 Aug 2004 04:48:33 -0000
@@ -17,6 +17,7 @@
avr*) gdb_target_cpu=avr ;;
hppa*) gdb_target_cpu=pa ;;
i[34567]86*) gdb_target_cpu=i386 ;;
+m32r*) gdb_target_cpu=m32r ;;
m68hc11*|m6811*) gdb_target_cpu=m68hc11 ;;
m68*) gdb_target_cpu=m68k ;;
m88*) gdb_target_cpu=m88k ;;
@@ -102,7 +103,10 @@
;;
ia64*-*-*) gdb_target=ia64 ;;
-m32r-*-*) gdb_target=m32r ;;
+m32r*-*-elf*) gdb_target=m32r ;;
+m32r*-*-linux*) gdb_target=linux
+ build_gdbserver=yes
+ ;;
m68hc11*-*-*|m6811*-*-*) gdb_target=m68hc11 ;;
Index: m32r-linux-nat.c
===================================================================
RCS file: m32r-linux-nat.c
diff -N m32r-linux-nat.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ m32r-linux-nat.c 5 Aug 2004 04:48:33 -0000
@@ -0,0 +1,424 @@
+/* Native-dependent code for GNU/Linux m32r.
+
+ Copyright 2004 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 "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "linux-nat.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+#include <sys/ptrace.h>
+#include <sys/user.h>
+#include <sys/procfs.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+\f
+
+
+/* The register sets used in GNU/Linux ELF core-dumps are identical to
+ the register sets in `struct user' that is used for a.out
+ core-dumps, and is also used by `ptrace'. The corresponding types
+ are `elf_gregset_t' for the general-purpose registers (with
+ `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
+ for the floating-point registers.
+
+ Those types used to be available under the names `gregset_t' and
+ `fpregset_t' too, and this file used those names in the past. But
+ those names are now used for the register sets used in the
+ `mcontext_t' type, and have a different size and layout. */
+
+/* Mapping between the general-purpose registers in `struct user'
+ format and GDB's register array layout. */
+static int regmap[] = {
+ 4, 5, 6, 7, 0, 1, 2, 8,
+ 9, 10, 11, 12, 13, 24, 25, 23,
+ 19, 31, 26, 23, 20, 30, 16, 15,
+ 32
+};
+
+#define M32R_NUM_GREGS 25
+
+
+/* Doee apply to the corresponding SET requests as well. */
+#define GETREGS_SUPPLIES(regno) (0 <= (regno) && (regno) <= M32R_NUM_GREGS)
+#define GETFPREGS_SUPPLIES(regno) 0
+
+/* Does the current host support the GETREGS request? */
+int have_ptrace_getregs =
+#ifdef HAVE_PTRACE_GETREGS
+ 1
+#else
+ 0
+#endif
+ ;
+\f
+
+
+/* Support for the user struct. */
+
+/* Return the address of register REGNUM. BLOCKEND is the value of
+ u.u_ar0, which should point to the registers. */
+
+CORE_ADDR
+register_u_addr (CORE_ADDR blockend, int regnum)
+{
+ return (blockend + 4 * regmap[regnum]);
+}
+
+/* Return the size of the user struct. */
+
+int
+kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
+\f
+
+/* Transfering the general-purpose registers between GDB, inferiors
+ and core files. */
+
+/* Fill GDB's register array with the general-purpose register values
+ in *GREGSETP. */
+
+void
+supply_gregset (elf_gregset_t * gregsetp)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int i;
+
+ for (i = 0; i < M32R_NUM_GREGS; i++)
+ regcache_raw_supply (current_regcache, i, regp + regmap[i]);
+}
+
+/* Fill register REGNO (if it is a general-purpose register) in
+ *GREGSETPS with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_gregset (elf_gregset_t * gregsetp, int regno)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int i;
+
+ for (i = 0; i < M32R_NUM_GREGS; i++)
+ if (regno == -1 || regno == i)
+ regcache_raw_collect (current_regcache, i, regp + regmap[i]);
+}
+
+#ifdef HAVE_PTRACE_GETREGS
+
+/* Fetch all general-purpose registers from process/thread TID and
+ store their values in GDB's register array. */
+
+static void
+fetch_regs (int tid)
+{
+ elf_gregset_t regs;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0)
+ {
+ if (errno == EIO)
+ {
+ /* The kernel we're running on doesn't support the GETREGS
+ request. Reset `have_ptrace_getregs'. */
+ have_ptrace_getregs = 0;
+ return;
+ }
+
+ perror_with_name ("Couldn't get registers");
+ }
+
+ supply_gregset (®s);
+}
+
+/* Store all valid general-purpose registers in GDB's register array
+ into the process/thread specified by TID. */
+
+static void
+store_regs (int tid, int regno)
+{
+ elf_gregset_t regs;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0)
+ perror_with_name ("Couldn't get registers");
+
+ fill_gregset (®s, regno);
+
+ if (ptrace (PTRACE_SETREGS, tid, 0, (int) ®s) < 0)
+ perror_with_name ("Couldn't write registers");
+}
+
+#else
+
+static void
+fetch_regs (int tid)
+{
+}
+static void
+store_regs (int tid, int regno)
+{
+}
+
+#endif
+\f
+
+/* Transfering floating-point registers between GDB, inferiors and cores. */
+
+/* Fill GDB's register array with the floating-point register values in
+ *FPREGSETP. */
+
+void
+supply_fpregset (elf_fpregset_t * fpregsetp)
+{
+}
+
+/* Fill register REGNO (if it is a floating-point register) in
+ *FPREGSETP with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_fpregset (elf_fpregset_t * fpregsetp, int regno)
+{
+}
+
+#ifdef HAVE_PTRACE_GETREGS
+
+/* Fetch all floating-point registers from process/thread TID and store
+ thier values in GDB's register array. */
+
+static void
+fetch_fpregs (int tid)
+{
+ elf_fpregset_t fpregs;
+
+ if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
+ perror_with_name ("Couldn't get floating point status");
+
+ supply_fpregset (&fpregs);
+}
+
+/* Store all valid floating-point registers in GDB's register array
+ into the process/thread specified by TID. */
+
+static void
+store_fpregs (int tid, int regno)
+{
+ elf_fpregset_t fpregs;
+
+ if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
+ perror_with_name ("Couldn't get floating point status");
+
+ fill_fpregset (&fpregs, regno);
+
+ if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
+ perror_with_name ("Couldn't write floating point status");
+}
+
+#else
+
+static void
+fetch_fpregs (int tid)
+{
+}
+static void
+store_fpregs (int tid, int regno)
+{
+}
+
+#endif
+\f
+
+/* Transferring arbitrary registers between GDB and inferior. */
+
+/* Check if register REGNO in the child process is accessible.
+ If we are accessing registers directly via the U area, only the
+ general-purpose registers are available.
+ All registers should be accessible if we have GETREGS support. */
+
+int
+cannot_fetch_register (int regno)
+{
+ gdb_assert (regno >= 0 && regno < NUM_REGS);
+ return (!have_ptrace_getregs && regmap[regno] == -1);
+}
+
+int
+cannot_store_register (int regno)
+{
+ gdb_assert (regno >= 0 && regno < NUM_REGS);
+ return (!have_ptrace_getregs && regmap[regno] == -1);
+}
+
+/* Accessing registers through the U area, one at a time. */
+
+/* Fetch one register. */
+
+static void
+fetch_register (int regno)
+{
+ int tid;
+ int val;
+
+ gdb_assert (!have_ptrace_getregs);
+ if (cannot_fetch_register (regno))
+ {
+ regcache_raw_supply (current_regcache, regno, NULL);
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ tid = TIDGET (inferior_ptid);
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ errno = 0;
+ val = ptrace (PTRACE_PEEKUSER, tid, register_addr (regno, 0), 0);
+ if (errno != 0)
+ error ("Couldn't read register %s (#%d): %s.", REGISTER_NAME (regno),
+ regno, safe_strerror (errno));
+
+ regcache_raw_supply (current_regcache, regno, &val);
+}
+
+/* Store one register. */
+
+static void
+store_register (int regno)
+{
+ int tid;
+ int val;
+
+ gdb_assert (!have_ptrace_getregs);
+ if (cannot_store_register (regno))
+ return;
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ tid = TIDGET (inferior_ptid);
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ errno = 0;
+ regcache_raw_collect (current_regcache, regno, &val);
+ ptrace (PTRACE_POKEUSER, tid, register_addr (regno, 0), val);
+ if (errno != 0)
+ error ("Couldn't write register %s (#%d): %s.", REGISTER_NAME (regno),
+ regno, safe_strerror (errno));
+}
+
+/* Fetch register REGNO from the child process. If REGNO is -1, do
+ this for all registers (including the floating point and SSE
+ registers). */
+
+void
+fetch_inferior_registers (int regno)
+{
+ int tid;
+
+ /* Use the old method of peeking around in `struct user' if the
+ GETREGS request isn't available. */
+ if (!have_ptrace_getregs)
+ {
+ int i;
+
+ for (i = 0; i < NUM_REGS; i++)
+ if (regno == -1 || regno == i)
+ fetch_register (i);
+
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ tid = TIDGET (inferior_ptid);
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ /* Use the PTRACE_GETFPXREGS request whenever possible, since it
+ transfers more registers in one system call, and we'll cache the
+ results. */
+ if (regno == -1)
+ {
+ fetch_regs (tid);
+
+ /* The call above might reset `have_ptrace_getregs'. */
+ if (!have_ptrace_getregs)
+ {
+ fetch_inferior_registers (regno);
+ return;
+ }
+
+ fetch_fpregs (tid);
+ return;
+ }
+
+ if (GETREGS_SUPPLIES (regno))
+ {
+ fetch_regs (tid);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "Got request for bad register number %d.", regno);
+}
+
+/* Store register REGNO back into the child process. If REGNO is -1,
+ do this for all registers (including the floating point and SSE
+ registers). */
+void
+store_inferior_registers (int regno)
+{
+ int tid;
+
+ /* Use the old method of poking around in `struct user' if the
+ SETREGS request isn't available. */
+ if (!have_ptrace_getregs)
+ {
+ int i;
+
+ for (i = 0; i < NUM_REGS; i++)
+ if (regno == -1 || regno == i)
+ store_register (i);
+
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ if (regno == -1)
+ {
+ store_regs (tid, regno);
+ store_fpregs (tid, regno);
+ return;
+ }
+
+ if (GETREGS_SUPPLIES (regno))
+ {
+ store_regs (tid, regno);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "Got request to store bad register number %d.", regno);
+}
Index: m32r-linux-tdep.c
===================================================================
RCS file: m32r-linux-tdep.c
diff -N m32r-linux-tdep.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ m32r-linux-tdep.c 5 Aug 2004 04:48:33 -0000
@@ -0,0 +1,334 @@
+/* Target-dependent code for GNU/Linux m32r.
+
+ Copyright 2004 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 "gdbcore.h"
+#include "frame.h"
+#include "value.h"
+#include "regcache.h"
+#include "inferior.h"
+#include "osabi.h"
+#include "reggroups.h"
+
+#include "gdb_string.h"
+
+#include "glibc-tdep.h"
+#include "solib-svr4.h"
+
+#include "trad-frame.h"
+#include "frame-unwind.h"
+\f
+
+/* Recognizing signal handler frames. */
+
+/* GNU/Linux has two flavors of signals. Normal signal handlers, and
+ "realtime" (RT) signals. The RT signals can provide additional
+ information to the signal handler if the SA_SIGINFO flag is set
+ when establishing a signal handler using `sigaction'. It is not
+ unlikely that future versions of GNU/Linux will support SA_SIGINFO
+ for normal signals too. */
+
+/* When the m32r Linux kernel calls a signal handler and the
+ SA_RESTORER flag isn't set, the return address points to a bit of
+ code on the stack. This function returns whether the PC appears to
+ be within this bit of code.
+
+ The instruction sequence for normal signals is
+ ldi r7, #__NR_sigreturn
+ trap #2
+ or 0x67 0x77 0x10 0xf2.
+
+ Checking for the code sequence should be somewhat reliable, because
+ the effect is to call the system call sigreturn. This is unlikely
+ to occur anywhere other than in a signal trampoline.
+
+ It kind of sucks that we have to read memory from the process in
+ order to identify a signal trampoline, but there doesn't seem to be
+ any other way. Therefore we only do the memory reads if no
+ function name could be identified, which should be the case since
+ the code is on the stack.
+
+ Detection of signal trampolines for handlers that set the
+ SA_RESTORER flag is in general not possible. Unfortunately this is
+ what the GNU C Library has been doing for quite some time now.
+ However, as of version 2.1.2, the GNU C Library uses signal
+ trampolines (named __restore and __restore_rt) that are identical
+ to the ones used by the kernel. Therefore, these trampolines are
+ supported too. */
+
+/* If PC is in a sigtramp routine, return the address of the start of
+ the routine. Otherwise, return 0. */
+
+static CORE_ADDR
+m32r_linux_sigtramp_start (CORE_ADDR pc)
+{
+ /* We only recognize a signal trampoline if PC is at the start of
+ one of the instructions. We optimize for finding the PC at the
+ start of the instruction sequence, as will be the case when the
+ trampoline is not the first frame on the stack. We assume that
+ in the case where the PC is not at the start of the instruction
+ sequence, there will be a few trailing readable bytes on the
+ stack. */
+
+ if (pc % 2 != 0)
+ {
+ if (read_memory_unsigned_integer (pc, 2) == 0x10f2)
+ pc -= 2;
+ else
+ return 0;
+ }
+
+ if (read_memory_unsigned_integer (pc, 4) != 0x677710f2)
+ return 0;
+
+ return pc;
+}
+
+/* This function does the same for RT signals. Here the instruction
+ sequence is
+ ldi r7, #__NR_rt_sigreturn
+ trap #2
+ or 0x97 0xf0 0x00 0xad 0x10 0xf2 0xf0 0x00.
+
+ The effect is to call the system call rt_sigreturn. */
+
+/* If PC is in a RT sigtramp routine, return the address of the start
+ of the routine. Otherwise, return 0. */
+
+static CORE_ADDR
+m32r_linux_rt_sigtramp_start (CORE_ADDR pc)
+{
+ /* We only recognize a signal trampoline if PC is at the start of
+ one of the instructions. We optimize for finding the PC at the
+ start of the instruction sequence, as will be the case when the
+ trampoline is not the first frame on the stack. We assume that
+ in the case where the PC is not at the start of the instruction
+ sequence, there will be a few trailing readable bytes on the
+ stack. */
+
+ if (pc % 2 != 0)
+ return 0;
+
+ switch (read_memory_unsigned_integer (pc, 4))
+ {
+ case 0x97f000ad:
+ if (read_memory_unsigned_integer (pc + 4, 4) == 0x10f2f000)
+ return pc;
+ break;
+ case 0x10f2f000:
+ if (read_memory_unsigned_integer (pc - 4, 4) == 0x97f000ad)
+ return pc - 4;
+ break;
+ }
+
+ return 0;
+}
+
+static int
+m32r_linux_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+ /* If we have NAME, we can optimize the search. The trampolines are
+ named __restore and __restore_rt. However, they aren't dynamically
+ exported from the shared C library, so the trampoline may appear to
+ be part of the preceding function. This should always be sigaction,
+ __sigaction, or __libc_sigaction (all aliases to the same function). */
+ if (name == NULL || strstr (name, "sigaction") != NULL)
+ return (m32r_linux_sigtramp_start (pc) != 0
+ || m32r_linux_rt_sigtramp_start (pc) != 0);
+
+ return (strcmp ("__restore", name) == 0
+ || strcmp ("__restore_rt", name) == 0);
+}
+
+/* From <asm/sigcontext.h>. */
+static int m32r_linux_sc_reg_offset[] = {
+ 4 * 4, /* r0 */
+ 5 * 4, /* r1 */
+ 6 * 4, /* r2 */
+ 7 * 4, /* r3 */
+ 0 * 4, /* r4 */
+ 1 * 4, /* r5 */
+ 2 * 4, /* r6 */
+ 8 * 4, /* r7 */
+ 9 * 4, /* r8 */
+ 10 * 4, /* r9 */
+ 11 * 4, /* r10 */
+ 12 * 4, /* r11 */
+ 13 * 4, /* r12 */
+ 21 * 4, /* fp */
+ 22 * 4, /* lr */
+ -1 * 4, /* sp */
+ 16 * 4, /* psw */
+ -1 * 4, /* cbr */
+ 23 * 4, /* spi */
+ 20 * 4, /* spu */
+ 19 * 4, /* bpc */
+ 17 * 4, /* pc */
+ 15 * 4, /* accl */
+ 14 * 4 /* acch */
+};
+
+#define M32R_SP_REGNUM 15
+
+struct m32r_frame_cache
+{
+ CORE_ADDR base, pc;
+ struct trad_frame_saved_reg *saved_regs;
+};
+
+static struct m32r_frame_cache *
+m32r_linux_sigtramp_frame_cache (struct frame_info *next_frame,
+ void **this_cache)
+{
+ struct m32r_frame_cache *cache;
+ CORE_ADDR sigcontext_addr, addr;
+ int regnum;
+
+ if ((*this_cache) != NULL)
+ return (*this_cache);
+ cache = FRAME_OBSTACK_ZALLOC (struct m32r_frame_cache);
+ (*this_cache) = cache;
+ cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+
+ cache->base = frame_unwind_register_unsigned (next_frame, M32R_SP_REGNUM);
+ sigcontext_addr = cache->base + 4;
+
+ cache->pc = frame_pc_unwind (next_frame);
+ addr = m32r_linux_sigtramp_start (cache->pc);
+ if (addr == 0)
+ {
+ /* If this is a RT signal trampoline, adjust SIGCONTEXT_ADDR
+ accordingly. */
+ addr = m32r_linux_rt_sigtramp_start (cache->pc);
+ if (addr)
+ sigcontext_addr += 128;
+ else
+ addr = frame_func_unwind (next_frame);
+ }
+ cache->pc = addr;
+
+ cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+
+ for (regnum = 0; regnum < sizeof (m32r_linux_sc_reg_offset) / 4; regnum++)
+ {
+ if (m32r_linux_sc_reg_offset[regnum] >= 0)
+ cache->saved_regs[regnum].addr =
+ sigcontext_addr + m32r_linux_sc_reg_offset[regnum];
+ }
+
+ return cache;
+}
+
+static void
+m32r_linux_sigtramp_frame_this_id (struct frame_info *next_frame,
+ void **this_cache,
+ struct frame_id *this_id)
+{
+ struct m32r_frame_cache *cache =
+ m32r_linux_sigtramp_frame_cache (next_frame, this_cache);
+
+ (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static void
+m32r_linux_sigtramp_frame_prev_register (struct frame_info *next_frame,
+ void **this_cache,
+ int regnum, int *optimizedp,
+ enum lval_type *lvalp,
+ CORE_ADDR *addrp,
+ int *realnump, void *valuep)
+{
+ struct m32r_frame_cache *cache =
+ m32r_linux_sigtramp_frame_cache (next_frame, this_cache);
+
+ trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
+ optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind m32r_linux_sigtramp_frame_unwind = {
+ SIGTRAMP_FRAME,
+ m32r_linux_sigtramp_frame_this_id,
+ m32r_linux_sigtramp_frame_prev_register
+};
+
+static const struct frame_unwind *
+m32r_linux_sigtramp_frame_sniffer (struct frame_info *next_frame)
+{
+ CORE_ADDR pc = frame_pc_unwind (next_frame);
+ char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (m32r_linux_pc_in_sigtramp (pc, name))
+ return &m32r_linux_sigtramp_frame_unwind;
+
+ return NULL;
+}
+
+static struct link_map_offsets *
+m32r_linux_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ /* Everything we need is in the first 8 bytes. */
+ lmo.r_debug_size = 8;
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ /* Everything we need is in the first 20 bytes. */
+ lmo.link_map_size = 20;
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+ lmo.l_name_offset = 4;
+ lmo.l_name_size = 4;
+ lmo.l_next_offset = 12;
+ lmo.l_next_size = 4;
+ lmo.l_prev_offset = 16;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
+
+static void
+m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ frame_unwind_append_sniffer (gdbarch, m32r_linux_sigtramp_frame_sniffer);
+
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, m32r_linux_svr4_fetch_link_map_offsets);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern void _initialize_m32r_linux_tdep (void);
+
+void
+_initialize_m32r_linux_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_m32r, 0, GDB_OSABI_LINUX,
+ m32r_linux_init_abi);
+}
Index: config/m32r/linux.mh
===================================================================
RCS file: config/m32r/linux.mh
diff -N config/m32r/linux.mh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/linux.mh 5 Aug 2004 04:48:34 -0000
@@ -0,0 +1,9 @@
+# Host: M32R based machine running GNU/Linux
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
+ core-aout.o m32r-linux-nat.o linux-proc.o gcore.o \
+ proc-service.o thread-db.o lin-lwp.o linux-nat.o
+
+LOADLIBES= -ldl -rdynamic
+
Index: config/m32r/linux.mt
===================================================================
RCS file: config/m32r/linux.mt
diff -N config/m32r/linux.mt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/linux.mt 5 Aug 2004 04:48:34 -0000
@@ -0,0 +1,8 @@
+# Target: Renesas M32R running GNU/Linux
+TDEPFILES= m32r-tdep.o m32r-linux-tdep.o remote-m32r-sdi.o glibc-tdep.o solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-linux.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/m32r/libsim.a
+
+GDBSERVER_DEPFILES = linux-low.o linux-m32r-low.o reg-m32r.o
Index: config/m32r/m32r.mh
===================================================================
RCS file: config/m32r/m32r.mh
diff -N config/m32r/m32r.mh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/m32r.mh 5 Aug 2004 04:48:34 -0000
@@ -0,0 +1,8 @@
+# Host: M32R running GNU/Linux
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
+ core-regset.o linux-proc.o gcore.o \
+ proc-service.o thread-db.o lin-lwp.o
+
+LOADLIBES = -ldl -rdynamic
Index: config/m32r/m32r.mt
===================================================================
RCS file: /cvs/src/src/gdb/config/m32r/m32r.mt,v
retrieving revision 1.7
diff -u -r1.7 m32r.mt
--- config/m32r/m32r.mt 16 Oct 2003 02:36:39 -0000 1.7
+++ config/m32r/m32r.mt 5 Aug 2004 04:48:34 -0000
@@ -1,4 +1,5 @@
# Target: Renesas m32r processor
TDEPFILES= m32r-tdep.o monitor.o m32r-rom.o dsrec.o remote-m32r-sdi.o
+TM_FILE= tm-m32r.h
SIM_OBS = remote-sim.o
SIM = ../sim/m32r/libsim.a
Index: config/m32r/nm-linux.h
===================================================================
RCS file: config/m32r/nm-linux.h
diff -N config/m32r/nm-linux.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/nm-linux.h 5 Aug 2004 04:48:34 -0000
@@ -0,0 +1,46 @@
+/* Definitions to make GDB run on an M32R based machine under GNU/Linux.
+ Copyright 2004 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_M32R_LINUX_H
+#define NM_M32R_LINUX_H
+
+#include "config/nm-linux.h"
+
+/* Support for the user area. */
+
+/* Return the size of the user struct. */
+extern int kernel_u_size (void);
+#define KERNEL_U_SIZE kernel_u_size()
+
+/* 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
+
+/* Offset of the registers within the user area. */
+#define U_REGS_OFFSET 0
+
+extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regnum);
+#define REGISTER_U_ADDR(addr, blockend, regnum) \
+ (addr) = register_u_addr (blockend, regnum)
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+#define FETCH_INFERIOR_REGISTERS
+
+#endif /* NM_M32R_LINUX_H */
Index: config/m32r/tm-linux.h
===================================================================
RCS file: config/m32r/tm-linux.h
diff -N config/m32r/tm-linux.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/tm-linux.h 5 Aug 2004 04:48:34 -0000
@@ -0,0 +1,32 @@
+/* Target-specific definitions for GNU/Linux running on a Renesas
+ M32R.
+
+ Copyright 2004 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 TM_LINUX_H
+#define TM_LINUX_H
+
+/* Pull in GNU/Linux generic defs. */
+#include "config/tm-linux.h"
+
+/* Pull in m32r-target defs */
+#include "m32r/tm-m32r.h"
+
+#endif /* #ifndef TM_LINUX_H */
Index: config/m32r/tm-m32r.h
===================================================================
RCS file: config/m32r/tm-m32r.h
diff -N config/m32r/tm-m32r.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/tm-m32r.h 5 Aug 2004 04:48:34 -0000
@@ -0,0 +1,23 @@
+/* Parameters for execution on a Renesas m32r processor.
+ Copyright 2004 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 TM_M32R_H
+#define TM_M32R_H
+#endif /* TM_M32R_H */
Index: gdbserver/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/Makefile.in,v
retrieving revision 1.25
diff -u -r1.25 Makefile.in
--- gdbserver/Makefile.in 4 Mar 2004 21:58:59 -0000 1.25
+++ gdbserver/Makefile.in 5 Aug 2004 04:48:36 -0000
@@ -199,6 +199,7 @@
rm -f gdbserver gdbreplay core make.log
rm -f reg-arm.c reg-i386.c reg-ia64.c reg-m68k.c reg-mips.c
rm -f reg-ppc.c reg-sh.c reg-x86-64.c reg-i386-linux.c
+ rm -f reg-m32r.c
maintainer-clean realclean distclean: clean
rm -f nm.h tm.h xm.h config.status config.h stamp-h config.log
@@ -280,6 +281,9 @@
reg-ia64.o : reg-ia64.c $(regdef_h)
reg-ia64.c : $(srcdir)/../regformats/reg-ia64.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-ia64.dat reg-ia64.c
+reg-m32r.o : reg-m32r.c $(regdef_h)
+reg-m32r.c : $(srcdir)/../regformats/reg-m32r.dat $(regdat_sh)
+ sh $(regdat_sh) $(srcdir)/../regformats/reg-m32r.dat reg-m32r.c
reg-m68k.o : reg-m68k.c $(regdef_h)
reg-m68k.c : $(srcdir)/../regformats/reg-m68k.dat $(regdat_sh)
sh $(regdat_sh) $(srcdir)/../regformats/reg-m68k.dat reg-m68k.c
Index: gdbserver/configure.srv
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/configure.srv,v
retrieving revision 1.7
diff -u -r1.7 configure.srv
--- gdbserver/configure.srv 8 Aug 2003 00:47:28 -0000 1.7
+++ gdbserver/configure.srv 5 Aug 2004 04:48:36 -0000
@@ -33,6 +33,11 @@
srv_tgtobj="linux-low.o linux-ia64-low.o"
srv_linux_usrregs=yes
;;
+ m32r*-*-linux*) srv_regobj=reg-m32r.o
+ srv_tgtobj="linux-low.o linux-m32r-low.o"
+ srv_linux_usrregs=yes
+ srv_linux_thread_db=yes
+ ;;
m68*-*-linux*) srv_regobj=reg-m68k.o
srv_tgtobj="linux-low.o linux-m68k-low.o"
srv_linux_usrregs=yes
Index: gdbserver/linux-m32r-low.c
===================================================================
RCS file: gdbserver/linux-m32r-low.c
diff -N gdbserver/linux-m32r-low.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdbserver/linux-m32r-low.c 5 Aug 2004 04:48:36 -0000
@@ -0,0 +1,99 @@
+/* GNU/Linux/m32r specific low level interface, for the remote server for GDB.
+ Copyright 2004 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 "server.h"
+#include "linux-low.h"
+
+#ifdef HAVE_SYS_REG_H
+#include <sys/reg.h>
+#endif
+
+#define m32r_num_regs 25
+
+/* This table must line up with REGISTER_NAMES in tm-m32r.h */
+static int m32r_regmap[] = {
+#ifdef PT_R0
+ PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7,
+ PT_R8, PT_R9, PT_R10, PT_R11, PT_R12, PT_FP, PT_LR, PT_SPU,
+ PT_PSW, PT_CBR, PT_SPI, PT_SPU, PT_BPC, PT_PC, PT_ACCL, PT_ACCH, PT_EVB
+#else
+ 4 * 4, 4 * 5, 4 * 6, 4 * 7, 4 * 0, 4 * 1, 4 * 2, 4 * 8,
+ 4 * 9, 4 * 10, 4 * 11, 4 * 12, 4 * 13, 4 * 24, 4 * 25, 4 * 23,
+ 4 * 19, 4 * 31, 4 * 26, 4 * 23, 4 * 20, 4 * 30, 4 * 16, 4 * 15, 4 * 32
+#endif
+};
+
+static int
+m32r_cannot_store_register (int regno)
+{
+ return (regno >= m32r_num_regs);
+}
+
+static int
+m32r_cannot_fetch_register (int regno)
+{
+ return (regno >= m32r_num_regs);
+}
+
+static CORE_ADDR
+m32r_get_pc ()
+{
+ unsigned long pc;
+ collect_register_by_name ("pc", &pc);
+ return pc;
+}
+
+static void
+m32r_set_pc (CORE_ADDR pc)
+{
+ unsigned long newpc = pc;
+ supply_register_by_name ("pc", &newpc);
+}
+
+static const unsigned short m32r_breakpoint = 0x10f1;
+#define m32r_breakpoint_len 2
+
+static int
+m32r_breakpoint_at (CORE_ADDR where)
+{
+ unsigned short insn;
+
+ (*the_target->read_memory) (where, (char *) &insn, m32r_breakpoint_len);
+ if (insn == m32r_breakpoint)
+ return 1;
+
+ /* If necessary, recognize more trap instructions here. GDB only uses the
+ one. */
+ return 0;
+}
+
+struct linux_target_ops the_low_target = {
+ m32r_num_regs,
+ m32r_regmap,
+ m32r_cannot_fetch_register,
+ m32r_cannot_store_register,
+ m32r_get_pc,
+ m32r_set_pc,
+ (const char *) &m32r_breakpoint,
+ m32r_breakpoint_len,
+ NULL,
+ 0,
+ m32r_breakpoint_at,
+};
Index: regformats/reg-m32r.dat
===================================================================
RCS file: regformats/reg-m32r.dat
diff -N regformats/reg-m32r.dat
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ regformats/reg-m32r.dat 5 Aug 2004 04:48:36 -0000
@@ -0,0 +1,46 @@
+name:m32r
+expedite:pc,lr,sp
+32:r0
+32:r1
+32:r2
+32:r3
+32:r4
+32:r5
+32:r6
+32:r7
+32:r8
+32:r9
+32:r10
+32:r11
+32:r12
+32:fp
+32:lr
+32:sp
+32:psw
+32:cbr
+32:spi
+32:spu
+32:bpc
+32:pc
+32:accl
+32:acch
+32:evb
+
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
+32:
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFA/m32r] m32r-linux support
2004-08-05 5:11 [RFA/m32r] m32r-linux support Kei Sakamoto
@ 2004-08-05 9:19 ` Mark Kettenis
2004-08-06 1:12 ` Kei Sakamoto
0 siblings, 1 reply; 4+ messages in thread
From: Mark Kettenis @ 2004-08-05 9:19 UTC (permalink / raw)
To: sakamoto.kei; +Cc: gdb-patches
From: "Kei Sakamoto" <sakamoto.kei@renesas.com>
Date: Thu, 5 Aug 2004 14:11:07 +0900
Hello,
Hi Kei,
First can you seperate out the gdbserver support, and submit that as a
seperate patch? Daniel will have to review that part of the code.
Making it seperate will make it more likely that the code can be
checked in soon.
The attached patch adds m32r-linux support.
The M32R architecture is not added to the official Linux kernel yet.
But Linux on M32R is already available.
http://www.linux-m32r.org/
So Linux/M32R is a brand new port? Great, but in that case I have
some comments. It looks like you based your GDB port on the
Linux/i386 stuff. That's great, but you must realize that part of the
i386 code that you copied and modified is only there to support older
versions of Linux. I hope it isn't necessary for Linux/M32R and would
like you to remove it before this gets committed. I've got a few
other comments too. Here we go...
diff -u -r1.144 configure.tgt=0A=
--- configure.tgt 26 Jun 2004 10:06:34 -0000 1.144=0A=
+++ configure.tgt 5 Aug 2004 04:48:33 -0000=0A=
@@ -102,7 +103,10 @@
;;
ia64*-*-*) gdb_target=ia64 ;;
-m32r-*-*) gdb_target=m32r ;;
+m32r*-*-elf*) gdb_target=m32r ;;
+m32r*-*-linux*) gdb_target=linux
+ build_gdbserver=3Dyes
+ ;;
m68hc11*-*-*|m6811*-*-*) gdb_target=m68hc11 ;;
It might be a good idea to keep m32r-*-* as the generic M32R target.
Just put the m32r-*-* entry in front of it.
diff -N m32r-linux-nat.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ m32r-linux-nat.c 5 Aug 2004 04:48:33 -0000
+/* The register sets used in GNU/Linux ELF core-dumps are identical to
+ the register sets in `struct user' that is used for a.out
+ core-dumps, and is also used by `ptrace'. The corresponding types
+ are `elf_gregset_t' for the general-purpose registers (with
+ `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
+ for the floating-point registers.
+
+ Those types used to be available under the names `gregset_t' and
+ `fpregset_t' too, and this file used those names in the past. But
+ those names are now used for the register sets used in the
+ `mcontext_t' type, and have a different size and layout. */
+
+/* Mapping between the general-purpose registers in `struct user'
+ format and GDB's register array layout. */
+static int regmap[] = {
+ 4, 5, 6, 7, 0, 1, 2, 8,
+ 9, 10, 11, 12, 13, 24, 25, 23,
+ 19, 31, 26, 23, 20, 30, 16, 15,
+ 32
+};
Does Linux/M32R support a.out? That would really surprise me. So I
don't think you need this stuff.
+#define M32R_NUM_GREGS 25=0A=
I think that one really belongs in m32r-tdep.h.
+/* Doee apply to the corresponding SET requests as well. *
+#define GETREGS_SUPPLIES(regno) (0 <=3D (regno) && (regno) <= M32R_NUM_GREGS)
+#define GETFPREGS_SUPPLIES(regno) 0
Does the M32R support floating point registers at all? If not, you
could rip out all the FPREGS stuff.
+/* Does the current host support the GETREGS request? */
+int have_ptrace_getregs =
+#ifdef HAVE_PTRACE_GETREGS
+ 1
+#else
+ 0
+#endif
+ ;
I really hope that all released M32R kernels support the
PTRACE_GETREGS request. In that case this should not be necessary.
+/* Support for the user struct. */
+
+/* Return the address of register REGNUM. BLOCKEND is the value of
+ u.u_ar0, which should point to the registers. */
+
+CORE_ADDR
+register_u_addr (CORE_ADDR blockend, int regnum)
+{
+ return (blockend + 4 * regmap[regnum]);
+}
+
+/* Return the size of the user struct. */
+
+int
+kernel_u_size (void)
+{
+ return (sizeof (struct user));
+}
The `user struct' is a wart from ancient UNIX. There really is no
point in supporting it on modern versions of Linux. If Linux/M32R is
ELF-only and fully supports PTRACE_GETREGS, this can go too.
+#ifdef HAVE_PTRACE_GETREGS
+
+/* Fetch all general-purpose registers from process/thread TID and
+ store their values in GDB's register array. */
+
+static void
+fetch_regs (int tid)
+{
+ elf_gregset_t regs;
+
This code in #ifdef HAVE_PTRACE_GETREGS can be simplified considerably
if you assume that PTRACE_GETREGS works. Move the code to
fetch_inferior_registers() and store_inferior_registers() below.
+/* Transferring arbitrary registers between GDB and inferior. */
+
+/* Check if register REGNO in the child process is accessible.
+ If we are accessing registers directly via the U area, only the
+ general-purpose registers are available.
+ All registers should be accessible if we have GETREGS support. */
+
+int
+cannot_fetch_register (int regno)
+{
+ gdb_assert (regno >= 0 && regno < NUM_REGS);
+ return (!have_ptrace_getregs && regmap[regno] == -1);
+}
+
+int
+cannot_store_register (int regno)
+{
+ gdb_assert (regno >= 0 && regno < NUM_REGS);
+ return (!have_ptrace_getregs && regmap[regno] == -1);
+}
These functions should no longer be necessary.
+/* Accessing registers through the U area, one at a time. */
+
+/* Fetch one register. */
+
+static void
+fetch_register (int regno)
+{
+ int tid;
+ int val;
+
+ gdb_assert (!have_ptrace_getregs);
+ if (cannot_fetch_register (regno))
+ {
+ regcache_raw_supply (current_regcache, regno, NULL);
+ return;
+ }=
This can go too; no U area anymore :-).
diff -N config/m32r/linux.mh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/linux.mh 5 Aug 2004 04:48:34 -0000
@@ -0,0 +1,9 @@
+# Host: M32R based machine running GNU/Linux
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
+ core-aout.o m32r-linux-nat.o linux-proc.o gcore.o \
+ proc-service.o thread-db.o lin-lwp.o linux-nat.o
+
+LOADLIBES=3D -ldl -rdynamic
core-aout.o shouldn't be necessary.
diff -N config/m32r/m32r.mh
Please remove this file.
diff -u -r1.7 m32r.mt
--- config/m32r/m32r.mt 16 Oct 2003 02:36:39 -0000 1.7
+++ config/m32r/m32r.mt 5 Aug 2004 04:48:34 -0000
@@ -1,4 +1,5 @@
# Target: Renesas m32r processor
TDEPFILES= m32r-tdep.o monitor.o m32r-rom.o dsrec.o remote-m32r-sdi.o
+TM_FILE= tm-m32r.h
SIM_OBS = remote-sim.o
SIM = ../sim/m32r/libsim.a
This shouldn't be necessary. See below.
diff -N config/m32r/nm-linux.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/nm-linux.h 5 Aug 2004 04:48:34 -0000
[snip]
+/* Support for the user area. */
+
+/* Return the size of the user struct. */
+extern int kernel_u_size (void);
+#define KERNEL_U_SIZE kernel_u_size()
+
+/* 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
+
+/* Offset of the registers within the user area. */
+#define U_REGS_OFFSET 0
+
+extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regnum);
+#define REGISTER_U_ADDR(addr, blockend, regnum) \
+ (addr) = register_u_addr (blockend, regnum)
This user area stuff can go too.
diff -N config/m32r/tm-m32r.h
This file contains nothing useful. Please remove and adjust tm-linux.h.
I hope you can make the changes. The simplifications will make
maintaining the code much easier.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFA/m32r] m32r-linux support
2004-08-05 9:19 ` Mark Kettenis
@ 2004-08-06 1:12 ` Kei Sakamoto
2004-08-20 6:15 ` Kei Sakamoto
0 siblings, 1 reply; 4+ messages in thread
From: Kei Sakamoto @ 2004-08-06 1:12 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
Hello, Mark,
Thank you for your reply. It is very useful.
There is the summer holidays in Japan next week. So I'll modify my
patch and post it after that.
Kei Sakamoto
Mark Kettenis said:
> From: "Kei Sakamoto" <sakamoto.kei@renesas.com>
> Date: Thu, 5 Aug 2004 14:11:07 +0900
>
> Hello,
>
> Hi Kei,
>
> First can you seperate out the gdbserver support, and submit that as a
> seperate patch? Daniel will have to review that part of the code.
> Making it seperate will make it more likely that the code can be
> checked in soon.
>
> The attached patch adds m32r-linux support.
> The M32R architecture is not added to the official Linux kernel yet.
> But Linux on M32R is already available.
> http://www.linux-m32r.org/
>
> So Linux/M32R is a brand new port? Great, but in that case I have
> some comments. It looks like you based your GDB port on the
> Linux/i386 stuff. That's great, but you must realize that part of the
> i386 code that you copied and modified is only there to support older
> versions of Linux. I hope it isn't necessary for Linux/M32R and would
> like you to remove it before this gets committed. I've got a few
> other comments too. Here we go...
>
> diff -u -r1.144 configure.tgt=0A=
> --- configure.tgt 26 Jun 2004 10:06:34 -0000 1.144=0A=
> +++ configure.tgt 5 Aug 2004 04:48:33 -0000=0A=
> @@ -102,7 +103,10 @@
> ;;
> ia64*-*-*) gdb_target=ia64 ;;
>
> -m32r-*-*) gdb_target=m32r ;;
> +m32r*-*-elf*) gdb_target=m32r ;;
> +m32r*-*-linux*) gdb_target=linux
> + build_gdbserver=3Dyes
> + ;;
>
> m68hc11*-*-*|m6811*-*-*) gdb_target=m68hc11 ;;
>
> It might be a good idea to keep m32r-*-* as the generic M32R target.
> Just put the m32r-*-* entry in front of it.
>
> diff -N m32r-linux-nat.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ m32r-linux-nat.c 5 Aug 2004 04:48:33 -0000
> +/* The register sets used in GNU/Linux ELF core-dumps are identical to
> + the register sets in `struct user' that is used for a.out
> + core-dumps, and is also used by `ptrace'. The corresponding types
> + are `elf_gregset_t' for the general-purpose registers (with
> + `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
> + for the floating-point registers.
> +
> + Those types used to be available under the names `gregset_t' and
> + `fpregset_t' too, and this file used those names in the past. But
> + those names are now used for the register sets used in the
> + `mcontext_t' type, and have a different size and layout. */
> +
> +/* Mapping between the general-purpose registers in `struct user'
> + format and GDB's register array layout. */
> +static int regmap[] = {
> + 4, 5, 6, 7, 0, 1, 2, 8,
> + 9, 10, 11, 12, 13, 24, 25, 23,
> + 19, 31, 26, 23, 20, 30, 16, 15,
> + 32
> +};
>
> Does Linux/M32R support a.out? That would really surprise me. So I
> don't think you need this stuff.
>
> +#define M32R_NUM_GREGS 25=0A=
>
> I think that one really belongs in m32r-tdep.h.
>
> +/* Doee apply to the corresponding SET requests as well. *
> +#define GETREGS_SUPPLIES(regno) (0 <=3D (regno) && (regno) <=
M32R_NUM_GREGS)
> +#define GETFPREGS_SUPPLIES(regno) 0
>
> Does the M32R support floating point registers at all? If not, you
> could rip out all the FPREGS stuff.
>
> +/* Does the current host support the GETREGS request? */
> +int have_ptrace_getregs =
> +#ifdef HAVE_PTRACE_GETREGS
> + 1
> +#else
> + 0
> +#endif
> + ;
>
> I really hope that all released M32R kernels support the
> PTRACE_GETREGS request. In that case this should not be necessary.
>
>
> +/* Support for the user struct. */
> +
> +/* Return the address of register REGNUM. BLOCKEND is the value of
> + u.u_ar0, which should point to the registers. */
> +
> +CORE_ADDR
> +register_u_addr (CORE_ADDR blockend, int regnum)
> +{
> + return (blockend + 4 * regmap[regnum]);
> +}
> +
> +/* Return the size of the user struct. */
> +
> +int
> +kernel_u_size (void)
> +{
> + return (sizeof (struct user));
> +}
>
> The `user struct' is a wart from ancient UNIX. There really is no
> point in supporting it on modern versions of Linux. If Linux/M32R is
> ELF-only and fully supports PTRACE_GETREGS, this can go too.
>
> +#ifdef HAVE_PTRACE_GETREGS
> +
> +/* Fetch all general-purpose registers from process/thread TID and
> + store their values in GDB's register array. */
> +
> +static void
> +fetch_regs (int tid)
> +{
> + elf_gregset_t regs;
> +
>
> This code in #ifdef HAVE_PTRACE_GETREGS can be simplified considerably
> if you assume that PTRACE_GETREGS works. Move the code to
> fetch_inferior_registers() and store_inferior_registers() below.
>
> +/* Transferring arbitrary registers between GDB and inferior. */
> +
> +/* Check if register REGNO in the child process is accessible.
> + If we are accessing registers directly via the U area, only the
> + general-purpose registers are available.
> + All registers should be accessible if we have GETREGS support. */
> +
> +int
> +cannot_fetch_register (int regno)
> +{
> + gdb_assert (regno >= 0 && regno < NUM_REGS);
> + return (!have_ptrace_getregs && regmap[regno] == -1);
> +}
> +
> +int
> +cannot_store_register (int regno)
> +{
> + gdb_assert (regno >= 0 && regno < NUM_REGS);
> + return (!have_ptrace_getregs && regmap[regno] == -1);
> +}
>
> These functions should no longer be necessary.
>
> +/* Accessing registers through the U area, one at a time. */
> +
> +/* Fetch one register. */
> +
> +static void
> +fetch_register (int regno)
> +{
> + int tid;
> + int val;
> +
> + gdb_assert (!have_ptrace_getregs);
> + if (cannot_fetch_register (regno))
> + {
> + regcache_raw_supply (current_regcache, regno, NULL);
> + return;
> + }=
>
> This can go too; no U area anymore :-).
>
> diff -N config/m32r/linux.mh
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ config/m32r/linux.mh 5 Aug 2004 04:48:34 -0000
> @@ -0,0 +1,9 @@
> +# Host: M32R based machine running GNU/Linux
> +
> +NAT_FILE= nm-linux.h
> +NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
> + core-aout.o m32r-linux-nat.o linux-proc.o gcore.o \
> + proc-service.o thread-db.o lin-lwp.o linux-nat.o
> +
> +LOADLIBES=3D -ldl -rdynamic
>
> core-aout.o shouldn't be necessary.
>
> diff -N config/m32r/m32r.mh
>
> Please remove this file.
>
> diff -u -r1.7 m32r.mt
> --- config/m32r/m32r.mt 16 Oct 2003 02:36:39 -0000 1.7
> +++ config/m32r/m32r.mt 5 Aug 2004 04:48:34 -0000
> @@ -1,4 +1,5 @@
> # Target: Renesas m32r processor
> TDEPFILES= m32r-tdep.o monitor.o m32r-rom.o dsrec.o remote-m32r-sdi.o
> +TM_FILE= tm-m32r.h
> SIM_OBS = remote-sim.o
> SIM = ../sim/m32r/libsim.a
>
> This shouldn't be necessary. See below.
>
> diff -N config/m32r/nm-linux.h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ config/m32r/nm-linux.h 5 Aug 2004 04:48:34 -0000
>
> [snip]
>
> +/* Support for the user area. */
> +
> +/* Return the size of the user struct. */
> +extern int kernel_u_size (void);
> +#define KERNEL_U_SIZE kernel_u_size()
> +
> +/* 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
> +
> +/* Offset of the registers within the user area. */
> +#define U_REGS_OFFSET 0
> +
> +extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regnum);
> +#define REGISTER_U_ADDR(addr, blockend, regnum) \
> + (addr) = register_u_addr (blockend, regnum)
>
> This user area stuff can go too.
>
> diff -N config/m32r/tm-m32r.h
>
> This file contains nothing useful. Please remove and adjust tm-linux.h.
>
> I hope you can make the changes. The simplifications will make
> maintaining the code much easier.
>
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFA/m32r] m32r-linux support
2004-08-06 1:12 ` Kei Sakamoto
@ 2004-08-20 6:15 ` Kei Sakamoto
0 siblings, 0 replies; 4+ messages in thread
From: Kei Sakamoto @ 2004-08-20 6:15 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 9469 bytes --]
Hello,
I revised the patch of m32r-linux support.
Thanks to Mark Kettenis' advice, I removed many unnecessary codes
from it and simplified it. But it still contains some stuff
to support older versions of Linux because Linux/M32R does not
support PTRACE_GETREGS.
I also removed the gdbserver support from it. I'll post it
as another patch after this patch is accepted.
OK to commit?
2004-08-20 Kei Sakamoto <sakamoto.kei@renesas.com>
Add m32r-linux support.
* configure.tgt: Add m32r*-*-linux*.
* Makefile.in (ALLDEPFILES): Add m32r-tdep.c, m32r-linux-nat.c and
m32r-linux-tdep.c.
(m32r-linux-nat.o, m32r-linux-tdep.o): New dependencies.
* m32r-linux-nat.c, m32r-linux-tdep.c, config/m32r/linux.mh,
config/m32r/linux.mt, config/m32r/m32r.mh, config/m32r/nm-linux.h,
config/m32r/tm-linux.h: New files.
Kei Sakamoto said:
> Hello, Mark,
>
> Thank you for your reply. It is very useful.
>
> There is the summer holidays in Japan next week. So I'll modify my
> patch and post it after that.
>
> Kei Sakamoto
>
> Mark Kettenis said:
> > From: "Kei Sakamoto" <sakamoto.kei@renesas.com>
> > Date: Thu, 5 Aug 2004 14:11:07 +0900
> >
> > Hello,
> >
> > Hi Kei,
> >
> > First can you seperate out the gdbserver support, and submit that as a
> > seperate patch? Daniel will have to review that part of the code.
> > Making it seperate will make it more likely that the code can be
> > checked in soon.
> >
> > The attached patch adds m32r-linux support.
> > The M32R architecture is not added to the official Linux kernel yet.
> > But Linux on M32R is already available.
> > http://www.linux-m32r.org/
> >
> > So Linux/M32R is a brand new port? Great, but in that case I have
> > some comments. It looks like you based your GDB port on the
> > Linux/i386 stuff. That's great, but you must realize that part of the
> > i386 code that you copied and modified is only there to support older
> > versions of Linux. I hope it isn't necessary for Linux/M32R and would
> > like you to remove it before this gets committed. I've got a few
> > other comments too. Here we go...
> >
> > diff -u -r1.144 configure.tgt=0A=
> > --- configure.tgt 26 Jun 2004 10:06:34 -0000 1.144=0A=
> > +++ configure.tgt 5 Aug 2004 04:48:33 -0000=0A=
> > @@ -102,7 +103,10 @@
> > ;;
> > ia64*-*-*) gdb_target=ia64 ;;
> >
> > -m32r-*-*) gdb_target=m32r ;;
> > +m32r*-*-elf*) gdb_target=m32r ;;
> > +m32r*-*-linux*) gdb_target=linux
> > + build_gdbserver=3Dyes
> > + ;;
> >
> > m68hc11*-*-*|m6811*-*-*) gdb_target=m68hc11 ;;
> >
> > It might be a good idea to keep m32r-*-* as the generic M32R target.
> > Just put the m32r-*-* entry in front of it.
> >
> > diff -N m32r-linux-nat.c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ m32r-linux-nat.c 5 Aug 2004 04:48:33 -0000
> > +/* The register sets used in GNU/Linux ELF core-dumps are identical to
> > + the register sets in `struct user' that is used for a.out
> > + core-dumps, and is also used by `ptrace'. The corresponding types
> > + are `elf_gregset_t' for the general-purpose registers (with
> > + `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
> > + for the floating-point registers.
> > +
> > + Those types used to be available under the names `gregset_t' and
> > + `fpregset_t' too, and this file used those names in the past. But
> > + those names are now used for the register sets used in the
> > + `mcontext_t' type, and have a different size and layout. */
> > +
> > +/* Mapping between the general-purpose registers in `struct user'
> > + format and GDB's register array layout. */
> > +static int regmap[] = {
> > + 4, 5, 6, 7, 0, 1, 2, 8,
> > + 9, 10, 11, 12, 13, 24, 25, 23,
> > + 19, 31, 26, 23, 20, 30, 16, 15,
> > + 32
> > +};
> >
> > Does Linux/M32R support a.out? That would really surprise me. So I
> > don't think you need this stuff.
> >
> > +#define M32R_NUM_GREGS 25=0A=
> >
> > I think that one really belongs in m32r-tdep.h.
> >
> > +/* Doee apply to the corresponding SET requests as well. *
> > +#define GETREGS_SUPPLIES(regno) (0 <=3D (regno) && (regno) <=
> M32R_NUM_GREGS)
> > +#define GETFPREGS_SUPPLIES(regno) 0
> >
> > Does the M32R support floating point registers at all? If not, you
> > could rip out all the FPREGS stuff.
> >
> > +/* Does the current host support the GETREGS request? */
> > +int have_ptrace_getregs =
> > +#ifdef HAVE_PTRACE_GETREGS
> > + 1
> > +#else
> > + 0
> > +#endif
> > + ;
> >
> > I really hope that all released M32R kernels support the
> > PTRACE_GETREGS request. In that case this should not be necessary.
> >
> >
> > +/* Support for the user struct. */
> > +
> > +/* Return the address of register REGNUM. BLOCKEND is the value of
> > + u.u_ar0, which should point to the registers. */
> > +
> > +CORE_ADDR
> > +register_u_addr (CORE_ADDR blockend, int regnum)
> > +{
> > + return (blockend + 4 * regmap[regnum]);
> > +}
> > +
> > +/* Return the size of the user struct. */
> > +
> > +int
> > +kernel_u_size (void)
> > +{
> > + return (sizeof (struct user));
> > +}
> >
> > The `user struct' is a wart from ancient UNIX. There really is no
> > point in supporting it on modern versions of Linux. If Linux/M32R is
> > ELF-only and fully supports PTRACE_GETREGS, this can go too.
> >
> > +#ifdef HAVE_PTRACE_GETREGS
> > +
> > +/* Fetch all general-purpose registers from process/thread TID and
> > + store their values in GDB's register array. */
> > +
> > +static void
> > +fetch_regs (int tid)
> > +{
> > + elf_gregset_t regs;
> > +
> >
> > This code in #ifdef HAVE_PTRACE_GETREGS can be simplified considerably
> > if you assume that PTRACE_GETREGS works. Move the code to
> > fetch_inferior_registers() and store_inferior_registers() below.
> >
> > +/* Transferring arbitrary registers between GDB and inferior. */
> > +
> > +/* Check if register REGNO in the child process is accessible.
> > + If we are accessing registers directly via the U area, only the
> > + general-purpose registers are available.
> > + All registers should be accessible if we have GETREGS support. */
> > +
> > +int
> > +cannot_fetch_register (int regno)
> > +{
> > + gdb_assert (regno >= 0 && regno < NUM_REGS);
> > + return (!have_ptrace_getregs && regmap[regno] == -1);
> > +}
> > +
> > +int
> > +cannot_store_register (int regno)
> > +{
> > + gdb_assert (regno >= 0 && regno < NUM_REGS);
> > + return (!have_ptrace_getregs && regmap[regno] == -1);
> > +}
> >
> > These functions should no longer be necessary.
> >
> > +/* Accessing registers through the U area, one at a time. */
> > +
> > +/* Fetch one register. */
> > +
> > +static void
> > +fetch_register (int regno)
> > +{
> > + int tid;
> > + int val;
> > +
> > + gdb_assert (!have_ptrace_getregs);
> > + if (cannot_fetch_register (regno))
> > + {
> > + regcache_raw_supply (current_regcache, regno, NULL);
> > + return;
> > + }=
> >
> > This can go too; no U area anymore :-).
> >
> > diff -N config/m32r/linux.mh
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ config/m32r/linux.mh 5 Aug 2004 04:48:34 -0000
> > @@ -0,0 +1,9 @@
> > +# Host: M32R based machine running GNU/Linux
> > +
> > +NAT_FILE= nm-linux.h
> > +NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
> > + core-aout.o m32r-linux-nat.o linux-proc.o gcore.o \
> > + proc-service.o thread-db.o lin-lwp.o linux-nat.o
> > +
> > +LOADLIBES=3D -ldl -rdynamic
> >
> > core-aout.o shouldn't be necessary.
> >
> > diff -N config/m32r/m32r.mh
> >
> > Please remove this file.
> >
> > diff -u -r1.7 m32r.mt
> > --- config/m32r/m32r.mt 16 Oct 2003 02:36:39 -0000 1.7
> > +++ config/m32r/m32r.mt 5 Aug 2004 04:48:34 -0000
> > @@ -1,4 +1,5 @@
> > # Target: Renesas m32r processor
> > TDEPFILES= m32r-tdep.o monitor.o m32r-rom.o dsrec.o remote-m32r-sdi.o
> > +TM_FILE= tm-m32r.h
> > SIM_OBS = remote-sim.o
> > SIM = ../sim/m32r/libsim.a
> >
> > This shouldn't be necessary. See below.
> >
> > diff -N config/m32r/nm-linux.h
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ config/m32r/nm-linux.h 5 Aug 2004 04:48:34 -0000
> >
> > [snip]
> >
> > +/* Support for the user area. */
> > +
> > +/* Return the size of the user struct. */
> > +extern int kernel_u_size (void);
> > +#define KERNEL_U_SIZE kernel_u_size()
> > +
> > +/* 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
> > +
> > +/* Offset of the registers within the user area. */
> > +#define U_REGS_OFFSET 0
> > +
> > +extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regnum);
> > +#define REGISTER_U_ADDR(addr, blockend, regnum) \
> > + (addr) = register_u_addr (blockend, regnum)
> >
> > This user area stuff can go too.
> >
> > diff -N config/m32r/tm-m32r.h
> >
> > This file contains nothing useful. Please remove and adjust tm-linux.h.
> >
> > I hope you can make the changes. The simplifications will make
> > maintaining the code much easier.
[-- Attachment #2: m32r-linux.patch --]
[-- Type: application/octet-stream, Size: 26453 bytes --]
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.608
diff -u -r1.608 Makefile.in
--- Makefile.in 14 Aug 2004 20:40:14 -0000 1.608
+++ Makefile.in 20 Aug 2004 05:54:29 -0000
@@ -1373,6 +1373,8 @@
infptrace.c inftarg.c irix4-nat.c irix5-nat.c \
libunwind-frame.c \
lynx-nat.c m3-nat.c \
+ m32r-tdep.c \
+ m32r-linux-tdep.c m32r-linux-nat.c \
m68hc11-tdep.c \
m68k-tdep.c \
m68kbsd-nat.c m68kbsd-tdep.c \
@@ -2114,6 +2116,11 @@
$(expression_h) $(value_h) $(gdbcore_h) $(target_h) $(m2_lang_h)
m2-valprint.o: m2-valprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) \
$(m2_lang_h)
+m32r-linux-nat.o: m32r-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
+ $(regcache_h) $(linux_nat_h) $(gdb_assert_h) $(gdb_string_h)
+m32r-linux-tdep.o: m32r-linux-tdep.c $(defs_h) $(gdbcore_h) $(frame_h) \
+ $(value_h) $(regcache_h) $(inferior_h) $(osabi_h) $(reggroups_h) \
+ $(gdb_string_h) $(glibc_tdep_h) $(solib_svr4_h)
m32r-rom.o: m32r-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
$(serial_h) $(symtab_h) $(command_h) $(gdbcmd_h) $(symfile_h) \
$(gdb_string_h) $(objfiles_h) $(inferior_h) $(regcache_h)
Index: configure.tgt
===================================================================
RCS file: /cvs/src/src/gdb/configure.tgt,v
retrieving revision 1.146
diff -u -r1.146 configure.tgt
--- configure.tgt 12 Aug 2004 22:29:56 -0000 1.146
+++ configure.tgt 20 Aug 2004 05:54:29 -0000
@@ -106,7 +106,8 @@
;;
ia64*-*-*) gdb_target=ia64 ;;
-m32r-*-*) gdb_target=m32r ;;
+m32r*-*-linux*) gdb_target=linux ;;
+m32r*-*-*) gdb_target=m32r ;;
m68hc11*-*-*|m6811*-*-*) gdb_target=m68hc11 ;;
Index: m32r-linux-nat.c
===================================================================
RCS file: m32r-linux-nat.c
diff -N m32r-linux-nat.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ m32r-linux-nat.c 20 Aug 2004 05:54:29 -0000
@@ -0,0 +1,345 @@
+/* Native-dependent code for GNU/Linux m32r.
+
+ Copyright 2004 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 "inferior.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "linux-nat.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+#include <sys/ptrace.h>
+#include <sys/user.h>
+#include <sys/procfs.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+\f
+
+
+/* The register sets used in GNU/Linux ELF core-dumps are identical to
+ the register sets in `struct user' that is used by `ptrace'. The
+ corresponding types are `elf_gregset_t' for the general-purpose
+ registers (with `elf_greg_t' the type of a single GP register) and
+ `elf_fpregset_t' for the floating-point registers.
+
+ Those types used to be available under the names `gregset_t' and
+ `fpregset_t' too, and this file used those names in the past. But
+ those names are now used for the register sets used in the
+ `mcontext_t' type, and have a different size and layout. */
+
+/* Mapping between the general-purpose registers in `struct user'
+ format and GDB's register array layout. */
+static int regmap[] = {
+ 4, 5, 6, 7, 0, 1, 2, 8,
+ 9, 10, 11, 12, 13, 24, 25, 23,
+ 19, 31, 26, 23, 20, 30, 16, 15,
+ 32
+};
+
+/* Doee apply to the corresponding SET requests as well. */
+#define GETREGS_SUPPLIES(regno) (0 <= (regno) && (regno) <= NUM_REGS)
+
+/* Does the current host support the GETREGS request? */
+int have_ptrace_getregs =
+#ifdef HAVE_PTRACE_GETREGS
+ 1
+#else
+ 0
+#endif
+ ;
+\f
+
+/* Transfering the general-purpose registers between GDB, inferiors
+ and core files. */
+
+/* Fill GDB's register array with the general-purpose register values
+ in *GREGSETP. */
+
+void
+supply_gregset (elf_gregset_t * gregsetp)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int i;
+
+ for (i = 0; i < NUM_REGS; i++)
+ regcache_raw_supply (current_regcache, i, regp + regmap[i]);
+}
+
+/* Fill register REGNO (if it is a general-purpose register) in
+ *GREGSETPS with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_gregset (elf_gregset_t * gregsetp, int regno)
+{
+ elf_greg_t *regp = (elf_greg_t *) gregsetp;
+ int i;
+
+ for (i = 0; i < NUM_REGS; i++)
+ if (regno == -1 || regno == i)
+ regcache_raw_collect (current_regcache, i, regp + regmap[i]);
+}
+
+#ifdef HAVE_PTRACE_GETREGS
+
+/* Fetch all general-purpose registers from process/thread TID and
+ store their values in GDB's register array. */
+
+static void
+fetch_regs (int tid)
+{
+ elf_gregset_t regs;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0)
+ {
+ if (errno == EIO)
+ {
+ /* The kernel we're running on doesn't support the GETREGS
+ request. Reset `have_ptrace_getregs'. */
+ have_ptrace_getregs = 0;
+ return;
+ }
+
+ perror_with_name ("Couldn't get registers");
+ }
+
+ supply_gregset (®s);
+}
+
+/* Store all valid general-purpose registers in GDB's register array
+ into the process/thread specified by TID. */
+
+static void
+store_regs (int tid, int regno)
+{
+ elf_gregset_t regs;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0)
+ perror_with_name ("Couldn't get registers");
+
+ fill_gregset (®s, regno);
+
+ if (ptrace (PTRACE_SETREGS, tid, 0, (int) ®s) < 0)
+ perror_with_name ("Couldn't write registers");
+}
+
+#else
+
+static void
+fetch_regs (int tid)
+{
+}
+static void
+store_regs (int tid, int regno)
+{
+}
+
+#endif
+\f
+
+/* Transfering floating-point registers between GDB, inferiors and cores. */
+
+/* Fill GDB's register array with the floating-point register values in
+ *FPREGSETP. */
+
+void
+supply_fpregset (elf_fpregset_t * fpregsetp)
+{
+}
+
+/* Fill register REGNO (if it is a floating-point register) in
+ *FPREGSETP with the value in GDB's register array. If REGNO is -1,
+ do this for all registers. */
+
+void
+fill_fpregset (elf_fpregset_t * fpregsetp, int regno)
+{
+}
+
+\f
+
+/* Transferring arbitrary registers between GDB and inferior. */
+
+/* Check if register REGNO in the child process is accessible.
+ If we are accessing registers directly via the U area, only the
+ general-purpose registers are available.
+ All registers should be accessible if we have GETREGS support. */
+
+int
+cannot_fetch_register (int regno)
+{
+ gdb_assert (regno >= 0 && regno < NUM_REGS);
+ return (!have_ptrace_getregs && regmap[regno] == -1);
+}
+
+int
+cannot_store_register (int regno)
+{
+ gdb_assert (regno >= 0 && regno < NUM_REGS);
+ return (!have_ptrace_getregs && regmap[regno] == -1);
+}
+
+/* Accessing registers through the U area, one at a time. */
+
+/* Fetch one register. */
+
+static void
+fetch_register (int regno)
+{
+ int tid;
+ int val;
+
+ gdb_assert (!have_ptrace_getregs);
+ if (cannot_fetch_register (regno))
+ {
+ regcache_raw_supply (current_regcache, regno, NULL);
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ tid = TIDGET (inferior_ptid);
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ errno = 0;
+ val = ptrace (PTRACE_PEEKUSER, tid, 4 * regmap[regno], 0);
+ if (errno != 0)
+ error ("Couldn't read register %s (#%d): %s.", REGISTER_NAME (regno),
+ regno, safe_strerror (errno));
+
+ regcache_raw_supply (current_regcache, regno, &val);
+}
+
+/* Store one register. */
+
+static void
+store_register (int regno)
+{
+ int tid;
+ int val;
+
+ gdb_assert (!have_ptrace_getregs);
+ if (cannot_store_register (regno))
+ return;
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ tid = TIDGET (inferior_ptid);
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ errno = 0;
+ regcache_raw_collect (current_regcache, regno, &val);
+ ptrace (PTRACE_POKEUSER, tid, 4 * regmap[regno], val);
+ if (errno != 0)
+ error ("Couldn't write register %s (#%d): %s.", REGISTER_NAME (regno),
+ regno, safe_strerror (errno));
+}
+
+/* Fetch register REGNO from the child process. If REGNO is -1, do
+ this for all registers (including the floating point and SSE
+ registers). */
+
+void
+fetch_inferior_registers (int regno)
+{
+ int tid;
+
+ /* Use the old method of peeking around in `struct user' if the
+ GETREGS request isn't available. */
+ if (!have_ptrace_getregs)
+ {
+ int i;
+
+ for (i = 0; i < NUM_REGS; i++)
+ if (regno == -1 || regno == i)
+ fetch_register (i);
+
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ tid = TIDGET (inferior_ptid);
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ /* Use the PTRACE_GETFPXREGS request whenever possible, since it
+ transfers more registers in one system call, and we'll cache the
+ results. */
+ if (regno == -1)
+ {
+ fetch_regs (tid);
+
+ /* The call above might reset `have_ptrace_getregs'. */
+ if (!have_ptrace_getregs)
+ {
+ fetch_inferior_registers (regno);
+ return;
+ }
+
+ return;
+ }
+
+ if (GETREGS_SUPPLIES (regno))
+ {
+ fetch_regs (tid);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "Got request for bad register number %d.", regno);
+}
+
+/* Store register REGNO back into the child process. If REGNO is -1,
+ do this for all registers (including the floating point and SSE
+ registers). */
+void
+store_inferior_registers (int regno)
+{
+ int tid;
+
+ /* Use the old method of poking around in `struct user' if the
+ SETREGS request isn't available. */
+ if (!have_ptrace_getregs)
+ {
+ int i;
+
+ for (i = 0; i < NUM_REGS; i++)
+ if (regno == -1 || regno == i)
+ store_register (i);
+
+ return;
+ }
+
+ /* GNU/Linux LWP ID's are process ID's. */
+ if ((tid = TIDGET (inferior_ptid)) == 0)
+ tid = PIDGET (inferior_ptid); /* Not a threaded program. */
+
+ if (regno == -1 || GETREGS_SUPPLIES (regno))
+ {
+ store_regs (tid, regno);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "Got request to store bad register number %d.", regno);
+}
Index: m32r-linux-tdep.c
===================================================================
RCS file: m32r-linux-tdep.c
diff -N m32r-linux-tdep.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ m32r-linux-tdep.c 20 Aug 2004 05:54:29 -0000
@@ -0,0 +1,334 @@
+/* Target-dependent code for GNU/Linux m32r.
+
+ Copyright 2004 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 "gdbcore.h"
+#include "frame.h"
+#include "value.h"
+#include "regcache.h"
+#include "inferior.h"
+#include "osabi.h"
+#include "reggroups.h"
+
+#include "gdb_string.h"
+
+#include "glibc-tdep.h"
+#include "solib-svr4.h"
+
+#include "trad-frame.h"
+#include "frame-unwind.h"
+\f
+
+/* Recognizing signal handler frames. */
+
+/* GNU/Linux has two flavors of signals. Normal signal handlers, and
+ "realtime" (RT) signals. The RT signals can provide additional
+ information to the signal handler if the SA_SIGINFO flag is set
+ when establishing a signal handler using `sigaction'. It is not
+ unlikely that future versions of GNU/Linux will support SA_SIGINFO
+ for normal signals too. */
+
+/* When the m32r Linux kernel calls a signal handler and the
+ SA_RESTORER flag isn't set, the return address points to a bit of
+ code on the stack. This function returns whether the PC appears to
+ be within this bit of code.
+
+ The instruction sequence for normal signals is
+ ldi r7, #__NR_sigreturn
+ trap #2
+ or 0x67 0x77 0x10 0xf2.
+
+ Checking for the code sequence should be somewhat reliable, because
+ the effect is to call the system call sigreturn. This is unlikely
+ to occur anywhere other than in a signal trampoline.
+
+ It kind of sucks that we have to read memory from the process in
+ order to identify a signal trampoline, but there doesn't seem to be
+ any other way. Therefore we only do the memory reads if no
+ function name could be identified, which should be the case since
+ the code is on the stack.
+
+ Detection of signal trampolines for handlers that set the
+ SA_RESTORER flag is in general not possible. Unfortunately this is
+ what the GNU C Library has been doing for quite some time now.
+ However, as of version 2.1.2, the GNU C Library uses signal
+ trampolines (named __restore and __restore_rt) that are identical
+ to the ones used by the kernel. Therefore, these trampolines are
+ supported too. */
+
+/* If PC is in a sigtramp routine, return the address of the start of
+ the routine. Otherwise, return 0. */
+
+static CORE_ADDR
+m32r_linux_sigtramp_start (CORE_ADDR pc)
+{
+ /* We only recognize a signal trampoline if PC is at the start of
+ one of the instructions. We optimize for finding the PC at the
+ start of the instruction sequence, as will be the case when the
+ trampoline is not the first frame on the stack. We assume that
+ in the case where the PC is not at the start of the instruction
+ sequence, there will be a few trailing readable bytes on the
+ stack. */
+
+ if (pc % 2 != 0)
+ {
+ if (read_memory_unsigned_integer (pc, 2) == 0x10f2)
+ pc -= 2;
+ else
+ return 0;
+ }
+
+ if (read_memory_unsigned_integer (pc, 4) != 0x677710f2)
+ return 0;
+
+ return pc;
+}
+
+/* This function does the same for RT signals. Here the instruction
+ sequence is
+ ldi r7, #__NR_rt_sigreturn
+ trap #2
+ or 0x97 0xf0 0x00 0xad 0x10 0xf2 0xf0 0x00.
+
+ The effect is to call the system call rt_sigreturn. */
+
+/* If PC is in a RT sigtramp routine, return the address of the start
+ of the routine. Otherwise, return 0. */
+
+static CORE_ADDR
+m32r_linux_rt_sigtramp_start (CORE_ADDR pc)
+{
+ /* We only recognize a signal trampoline if PC is at the start of
+ one of the instructions. We optimize for finding the PC at the
+ start of the instruction sequence, as will be the case when the
+ trampoline is not the first frame on the stack. We assume that
+ in the case where the PC is not at the start of the instruction
+ sequence, there will be a few trailing readable bytes on the
+ stack. */
+
+ if (pc % 2 != 0)
+ return 0;
+
+ switch (read_memory_unsigned_integer (pc, 4))
+ {
+ case 0x97f000ad:
+ if (read_memory_unsigned_integer (pc + 4, 4) == 0x10f2f000)
+ return pc;
+ break;
+ case 0x10f2f000:
+ if (read_memory_unsigned_integer (pc - 4, 4) == 0x97f000ad)
+ return pc - 4;
+ break;
+ }
+
+ return 0;
+}
+
+static int
+m32r_linux_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+ /* If we have NAME, we can optimize the search. The trampolines are
+ named __restore and __restore_rt. However, they aren't dynamically
+ exported from the shared C library, so the trampoline may appear to
+ be part of the preceding function. This should always be sigaction,
+ __sigaction, or __libc_sigaction (all aliases to the same function). */
+ if (name == NULL || strstr (name, "sigaction") != NULL)
+ return (m32r_linux_sigtramp_start (pc) != 0
+ || m32r_linux_rt_sigtramp_start (pc) != 0);
+
+ return (strcmp ("__restore", name) == 0
+ || strcmp ("__restore_rt", name) == 0);
+}
+
+/* From <asm/sigcontext.h>. */
+static int m32r_linux_sc_reg_offset[] = {
+ 4 * 4, /* r0 */
+ 5 * 4, /* r1 */
+ 6 * 4, /* r2 */
+ 7 * 4, /* r3 */
+ 0 * 4, /* r4 */
+ 1 * 4, /* r5 */
+ 2 * 4, /* r6 */
+ 8 * 4, /* r7 */
+ 9 * 4, /* r8 */
+ 10 * 4, /* r9 */
+ 11 * 4, /* r10 */
+ 12 * 4, /* r11 */
+ 13 * 4, /* r12 */
+ 21 * 4, /* fp */
+ 22 * 4, /* lr */
+ -1 * 4, /* sp */
+ 16 * 4, /* psw */
+ -1 * 4, /* cbr */
+ 23 * 4, /* spi */
+ 20 * 4, /* spu */
+ 19 * 4, /* bpc */
+ 17 * 4, /* pc */
+ 15 * 4, /* accl */
+ 14 * 4 /* acch */
+};
+
+#define M32R_SP_REGNUM 15
+
+struct m32r_frame_cache
+{
+ CORE_ADDR base, pc;
+ struct trad_frame_saved_reg *saved_regs;
+};
+
+static struct m32r_frame_cache *
+m32r_linux_sigtramp_frame_cache (struct frame_info *next_frame,
+ void **this_cache)
+{
+ struct m32r_frame_cache *cache;
+ CORE_ADDR sigcontext_addr, addr;
+ int regnum;
+
+ if ((*this_cache) != NULL)
+ return (*this_cache);
+ cache = FRAME_OBSTACK_ZALLOC (struct m32r_frame_cache);
+ (*this_cache) = cache;
+ cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+
+ cache->base = frame_unwind_register_unsigned (next_frame, M32R_SP_REGNUM);
+ sigcontext_addr = cache->base + 4;
+
+ cache->pc = frame_pc_unwind (next_frame);
+ addr = m32r_linux_sigtramp_start (cache->pc);
+ if (addr == 0)
+ {
+ /* If this is a RT signal trampoline, adjust SIGCONTEXT_ADDR
+ accordingly. */
+ addr = m32r_linux_rt_sigtramp_start (cache->pc);
+ if (addr)
+ sigcontext_addr += 128;
+ else
+ addr = frame_func_unwind (next_frame);
+ }
+ cache->pc = addr;
+
+ cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+
+ for (regnum = 0; regnum < sizeof (m32r_linux_sc_reg_offset) / 4; regnum++)
+ {
+ if (m32r_linux_sc_reg_offset[regnum] >= 0)
+ cache->saved_regs[regnum].addr =
+ sigcontext_addr + m32r_linux_sc_reg_offset[regnum];
+ }
+
+ return cache;
+}
+
+static void
+m32r_linux_sigtramp_frame_this_id (struct frame_info *next_frame,
+ void **this_cache,
+ struct frame_id *this_id)
+{
+ struct m32r_frame_cache *cache =
+ m32r_linux_sigtramp_frame_cache (next_frame, this_cache);
+
+ (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static void
+m32r_linux_sigtramp_frame_prev_register (struct frame_info *next_frame,
+ void **this_cache,
+ int regnum, int *optimizedp,
+ enum lval_type *lvalp,
+ CORE_ADDR *addrp,
+ int *realnump, void *valuep)
+{
+ struct m32r_frame_cache *cache =
+ m32r_linux_sigtramp_frame_cache (next_frame, this_cache);
+
+ trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
+ optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind m32r_linux_sigtramp_frame_unwind = {
+ SIGTRAMP_FRAME,
+ m32r_linux_sigtramp_frame_this_id,
+ m32r_linux_sigtramp_frame_prev_register
+};
+
+static const struct frame_unwind *
+m32r_linux_sigtramp_frame_sniffer (struct frame_info *next_frame)
+{
+ CORE_ADDR pc = frame_pc_unwind (next_frame);
+ char *name;
+
+ find_pc_partial_function (pc, &name, NULL, NULL);
+ if (m32r_linux_pc_in_sigtramp (pc, name))
+ return &m32r_linux_sigtramp_frame_unwind;
+
+ return NULL;
+}
+
+static struct link_map_offsets *
+m32r_linux_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ /* Everything we need is in the first 8 bytes. */
+ lmo.r_debug_size = 8;
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ /* Everything we need is in the first 20 bytes. */
+ lmo.link_map_size = 20;
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+ lmo.l_name_offset = 4;
+ lmo.l_name_size = 4;
+ lmo.l_next_offset = 12;
+ lmo.l_next_size = 4;
+ lmo.l_prev_offset = 16;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
+
+static void
+m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ frame_unwind_append_sniffer (gdbarch, m32r_linux_sigtramp_frame_sniffer);
+
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, m32r_linux_svr4_fetch_link_map_offsets);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern void _initialize_m32r_linux_tdep (void);
+
+void
+_initialize_m32r_linux_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_m32r, 0, GDB_OSABI_LINUX,
+ m32r_linux_init_abi);
+}
Index: config/m32r/linux.mh
===================================================================
RCS file: config/m32r/linux.mh
diff -N config/m32r/linux.mh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/linux.mh 20 Aug 2004 05:54:29 -0000
@@ -0,0 +1,8 @@
+# Host: M32R based machine running GNU/Linux
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
+ m32r-linux-nat.o linux-proc.o gcore.o \
+ proc-service.o thread-db.o lin-lwp.o linux-nat.o
+
+LOADLIBES= -ldl -rdynamic
Index: config/m32r/linux.mt
===================================================================
RCS file: config/m32r/linux.mt
diff -N config/m32r/linux.mt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/linux.mt 20 Aug 2004 05:54:29 -0000
@@ -0,0 +1,6 @@
+# Target: Renesas M32R running GNU/Linux
+TDEPFILES= m32r-tdep.o m32r-linux-tdep.o remote-m32r-sdi.o glibc-tdep.o solib.o solib-svr4.o solib-legacy.o
+TM_FILE= tm-linux.h
+
+SIM_OBS = remote-sim.o
+SIM = ../sim/m32r/libsim.a
Index: config/m32r/m32r.mh
===================================================================
RCS file: config/m32r/m32r.mh
diff -N config/m32r/m32r.mh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/m32r.mh 20 Aug 2004 05:54:29 -0000
@@ -0,0 +1,8 @@
+# Host: M32R running GNU/Linux
+
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
+ core-regset.o linux-proc.o gcore.o \
+ proc-service.o thread-db.o lin-lwp.o
+
+LOADLIBES = -ldl -rdynamic
Index: config/m32r/nm-linux.h
===================================================================
RCS file: config/m32r/nm-linux.h
diff -N config/m32r/nm-linux.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/nm-linux.h 20 Aug 2004 05:54:29 -0000
@@ -0,0 +1,29 @@
+/* Definitions to make GDB run on an M32R based machine under GNU/Linux.
+ Copyright 2004 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_M32R_LINUX_H
+#define NM_M32R_LINUX_H
+
+#include "config/nm-linux.h"
+
+/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
+#define FETCH_INFERIOR_REGISTERS
+
+#endif /* NM_M32R_LINUX_H */
Index: config/m32r/tm-linux.h
===================================================================
RCS file: config/m32r/tm-linux.h
diff -N config/m32r/tm-linux.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config/m32r/tm-linux.h 20 Aug 2004 05:54:29 -0000
@@ -0,0 +1,29 @@
+/* Target-specific definitions for GNU/Linux running on a Renesas
+ M32R.
+
+ Copyright 2004 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 TM_LINUX_H
+#define TM_LINUX_H
+
+/* Pull in GNU/Linux generic defs. */
+#include "config/tm-linux.h"
+
+#endif /* #ifndef TM_LINUX_H */
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2004-08-20 6:15 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-08-05 5:11 [RFA/m32r] m32r-linux support Kei Sakamoto
2004-08-05 9:19 ` Mark Kettenis
2004-08-06 1:12 ` Kei Sakamoto
2004-08-20 6:15 ` Kei Sakamoto
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox