From 1994dc7cfca6b07c3cb5fa80a18ad36f76de95f9 Mon Sep 17 00:00:00 2001 From: Edith Epstein Date: Tue, 8 Dec 1998 20:41:19 +0000 Subject: [PATCH] Tue Dec 8 15:09:44 1998 Edith Epstein * config/m68k/tm-m68k.h (NUM_FREGS): m68k-linux patch. Added NUM_FREGS macro. * config/m68k/xm-linux.h: m68k-linux patch. New file. * config/m68k/tm-linux.h: m68k-linux patch. New file. * config/m68k/nm-linux.h: m68k-linux patch. New file. * config/m68k/linux.mt: m68k-linux patch. New file. * config/m68k/linux.mh: m68k-linux patch. New file. * gdbserver/low-linux.c: m68k-linux patch. Added an ifdef that checks the value of __GLIBC to decide whether or not to include sys/reg.h. * m68klinux-nat.c: m68k-linux patch. New file. Note both m68k-tdep.c and m68klinux-nat.c contain definitions for supply_gregset and supply_fpregset. The definitions in m68k-tdep.c are valid is USE_PROC_FS is defined. Otherwise, the definitions in m68klinux-nat.c will be used. This is a bit of a hack. The supply_* routines do not belong in *_tdep.c files. But, there are several lynx ports that currently depend on these definitions. * configure.tgt: m68k-linux patch. Added m68*-*-linux* gdb_target. * configure.host: m68k-linux patch. Added m68*-*-linux* gdb_host. * Makefile.in: m68k-linux patch. Added compile line for m68klinux-nat.o --- gdb/ChangeLog | 37 ++++++++++ gdb/Makefile.in | 14 +++- gdb/config/m68k/tm-linux.h | 109 +++++++++++++++++++++++++++ gdb/config/m68k/tm-m68k.h | 2 + gdb/config/m68k/xm-linux.h | 40 ++++++++++ gdb/configure.host | 1 + gdb/configure.tgt | 2 + gdb/gdbserver/low-linux.c | 37 +++++++++- gdb/m68klinux-nat.c | 146 +++++++++++++++++++++++++++++++++++++ 9 files changed, 384 insertions(+), 4 deletions(-) create mode 100644 gdb/config/m68k/tm-linux.h create mode 100644 gdb/config/m68k/xm-linux.h create mode 100644 gdb/m68klinux-nat.c diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2882cbaf758..995fe2e19e1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,40 @@ +Tue Dec 8 15:09:44 1998 Edith Epstein + + * config/m68k/tm-m68k.h (NUM_FREGS): m68k-linux patch. + Added NUM_FREGS macro. + + * config/m68k/xm-linux.h: m68k-linux patch. New file. + + * config/m68k/tm-linux.h: m68k-linux patch. New file. + + * config/m68k/nm-linux.h: m68k-linux patch. New file. + + * config/m68k/linux.mt: m68k-linux patch. New file. + + * config/m68k/linux.mh: m68k-linux patch. New file. + + * gdbserver/low-linux.c: m68k-linux patch. Added an ifdef + that checks the value of __GLIBC to decide whether or + not to include sys/reg.h. + + * m68klinux-nat.c: m68k-linux patch. New file. Note + both m68k-tdep.c and m68klinux-nat.c contain definitions + for supply_gregset and supply_fpregset. The definitions + in m68k-tdep.c are valid is USE_PROC_FS is defined. Otherwise, + the definitions in m68klinux-nat.c will be used. This is a + bit of a hack. The supply_* routines do not belong in + *_tdep.c files. But, there are several lynx ports that currently + depend on these definitions. + + * configure.tgt: m68k-linux patch. Added m68*-*-linux* + gdb_target. + + * configure.host: m68k-linux patch. Added m68*-*-linux* + gdb_host. + + * Makefile.in: m68k-linux patch. Added compile line for + m68klinux-nat.o + 1998-12-07 Jason Molenda (jsm@bugshack.cygnus.com) * config/i386/xm-cygwin.h: Remove REQUEST_QUIT definition. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 180db6386cf..10f3f590580 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -54,7 +54,6 @@ INSTALL_DATA = @INSTALL_DATA@ AR = @AR@ AR_FLAGS = qv RANLIB = @RANLIB@ -AWK = @AWK@ DLLTOOL = @DLLTOOL@ WINDRES = @WINDRES@ @@ -278,6 +277,11 @@ SIM_OBS = ANNOTATE_OBS = annotate.o +# start-sanitize-carp +# Multi-arch enabled gdb targets +MACHINE_OBS = @MACHINE_OBS@ + +# end-sanitize-carp # Host and target-dependent makefile fragments come in here. @host_makefile_frag@ @target_makefile_frag@ @@ -501,6 +505,9 @@ POSSLIBS = gnu-regex.c gnu-regex.h # Makefile.in DEPFILES = $(TDEPFILES) $(XDEPFILES) $(SER_HARDWIRE) $(NATDEPFILES) \ + $(start-sanitize-carp) \ + $(MACHINE_OBS) \ + $(end-sanitize-carp) \ $(REMOTE_OBS) $(SIM_OBS) @CONFIG_OBS@ SOURCES = $(SFILES) $(ALLDEPFILES) $(YYFILES) @CONFIG_SRCS@ @@ -1313,6 +1320,9 @@ m68k-tdep.o: m68k-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(value_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) m88k-tdep.o: m88k-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) @@ -1610,8 +1620,8 @@ tahoe-tdep.o: tahoe-tdep.c $(OP_INCLUDE)/tahoe.h $(defs_h) \ #start-sanitize-tic80 tic80-tdep.o: tic80-tdep.c $(defs_h) -#end-sanitize-tic80 +#end-sanitize-tic80 target.o: target.c $(bfd_h) $(defs_h) $(gdbcmd_h) $(inferior_h) \ objfiles.h symfile.h target.h gdb_string.h diff --git a/gdb/config/m68k/tm-linux.h b/gdb/config/m68k/tm-linux.h new file mode 100644 index 00000000000..6c119982ff5 --- /dev/null +++ b/gdb/config/m68k/tm-linux.h @@ -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 . */ +#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)); diff --git a/gdb/config/m68k/tm-m68k.h b/gdb/config/m68k/tm-m68k.h index a04e9e43a86..098500c4fcb 100644 --- a/gdb/config/m68k/tm-m68k.h +++ b/gdb/config/m68k/tm-m68k.h @@ -104,6 +104,8 @@ extern void m68k_find_saved_regs PARAMS ((struct frame_info *, struct frame_save #define NUM_REGS 29 #endif +#define NUM_FREGS (NUM_REGS-24) + #ifndef REGISTER_BYTES_OK #define REGISTER_BYTES_OK(b) \ ((b) == REGISTER_BYTES_FP \ diff --git a/gdb/config/m68k/xm-linux.h b/gdb/config/m68k/xm-linux.h new file mode 100644 index 00000000000..7266cffdfa2 --- /dev/null +++ b/gdb/config/m68k/xm-linux.h @@ -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 + +#endif /* #ifndef XM_LINUX_H */ diff --git a/gdb/configure.host b/gdb/configure.host index e7fc7fa536c..f6166546225 100644 --- a/gdb/configure.host +++ b/gdb/configure.host @@ -86,6 +86,7 @@ m68*-bull*-sysv*) gdb_host=dpx2 ;; 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 ;; diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 40f225e958a..d8169f95a3e 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -147,6 +147,8 @@ m68*-est-*) gdb_target=monitor ;; 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 ;; diff --git a/gdb/gdbserver/low-linux.c b/gdb/gdbserver/low-linux.c index a260575222a..106021057a3 100644 --- a/gdb/gdbserver/low-linux.c +++ b/gdb/gdbserver/low-linux.c @@ -45,8 +45,9 @@ char buf2[MAX_REGISTER_RAW_SIZE]; /***************End MY defs*********************/ #include -#if 0 -#include + +#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) +#include #endif extern char **environ; @@ -165,6 +166,7 @@ myresume (step, signal) - KERNEL_U_ADDR #endif +#ifndef TARGET_M68K /* this table must line up with REGISTER_NAMES in tm-i386v.h */ /* symbols like 'EAX' come from */ static int regmap[] = @@ -198,6 +200,37 @@ i386_register_u_addr (blockend, regnum) 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) diff --git a/gdb/m68klinux-nat.c b/gdb/m68klinux-nat.c new file mode 100644 index 00000000000..bcd40f02ebc --- /dev/null +++ b/gdb/m68klinux-nat.c @@ -0,0 +1,146 @@ +/* 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 +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#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. */ + +#ifndef USE_PROC_FS + +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]); +} + +#endif + + +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; +} -- 2.30.2