New Mach stuff:

* config/i386/i386mach.c: Explain this is for the old (probably
	non-functional and/or obsolete) Mach stuff.
	* m3-nat.c, config/nm-m3.h,
	i386m3-nat.c, mipsm3-nat.c, ns32km3-nat.c,
	config/i386/{i386m3.mh,i386m3.mt,tm-i386m3.h,xm-i386m3.h},
	config/i386/{i386mk.mh,i386mk.mt,tm-i386mk.h,xm-i386mk.h},
	config/mips/{mipsm3.mh,mipsm3.mt,tm-mipsm3.h,xm-mipsm3.h},
	config/ns32k/{ns32km3.mh,ns32km3.mt,tm-ns32km3.h,xm-ns32km3.h}:
	New files.
This commit is contained in:
Jim Kingdon 1993-10-07 20:13:08 +00:00
parent 44a19d2c5b
commit c2d751d5e5
28 changed files with 5924 additions and 0 deletions

View File

@ -129,6 +129,7 @@ i386aix-nat.c
i386b-nat.c
i386ly-tdep.c
i386lynx-nat.c
i386m3-nat.c
i386mach-nat.c
i386v-nat.c
i386v4-nat.c
@ -151,6 +152,7 @@ m2-lang.c
m2-lang.h
m2-typeprint.c
m2-valprint.c
m3-nat.c
m68k-pinsn.c
m68k-stub.c
m68k-tdep.c
@ -165,6 +167,7 @@ minsyms.c
mips-nat.c
mips-pinsn.c
mips-tdep.c
mipsm3-nat.c
mipsread.c
monitor.h
munch
@ -174,6 +177,7 @@ nindy-tdep.c
nlmread.c
ns32k-opcode.h
ns32k-pinsn.c
ns32km3-nat.c
objfiles.c
objfiles.h
osfsolib.c

View File

@ -1,5 +1,16 @@
Thu Oct 7 12:56:57 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
New Mach stuff:
* config/i386/i386mach.c: Explain this is for the old (probably
non-functional and/or obsolete) Mach stuff.
* m3-nat.c, config/nm-m3.h,
i386m3-nat.c, mipsm3-nat.c, ns32km3-nat.c,
config/i386/{i386m3.mh,i386m3.mt,tm-i386m3.h,xm-i386m3.h},
config/i386/{i386mk.mh,i386mk.mt,tm-i386mk.h,xm-i386mk.h},
config/mips/{mipsm3.mh,mipsm3.mt,tm-mipsm3.h,xm-mipsm3.h},
config/ns32k/{ns32km3.mh,ns32km3.mt,tm-ns32km3.h,xm-ns32km3.h}:
New files.
* blockframe.c (find_pc_partial_function): If we call
PSYMTAB_TO_SYMTAB, call target_terminal_ours_for_output first.
This is needed now that wait_for_inferior passes in endaddr.

View File

@ -33,6 +33,7 @@ i960
m68k
m88k
mips
nm-m3.h
nm-sysv4.h
nm-trash.h
none

View File

@ -30,6 +30,10 @@ i386bsd.mt
i386lynx.mh
i386lynx.mt
i386mach.mh
i386m3.mh
i386m3.mt
i386mk.mh
i386mk.mt
i386nw.mt
i386sco.mh
i386sco4.mh
@ -63,6 +67,8 @@ symmetry.mt
tm-i386aix.h
tm-i386bsd.h
tm-i386lynx.h
tm-i386m3.h
tm-i386mk.h
tm-i386nw.h
tm-i386v.h
tm-i386v4.h
@ -73,7 +79,9 @@ xm-go32.h
xm-i386aix.h
xm-i386bsd.h
xm-i386lynx.h
xm-i386m3.h
xm-i386mach.h
xm-i386mk.h
xm-i386sco.h
xm-i386v.h
xm-i386v32.h

View File

@ -0,0 +1,8 @@
# Host: Intel 386 running Mach3
XDEPFILES= os-mach3.o i386mach3-xdep.o i387-tdep.o coredep.o
XM_FILE= xm-i386mach3.h
# Don't use the mmalloc library in Mach 3.
MMALLOC_LIB =
MMALLOC_DISABLE = -DNO_MMALLOC

View File

@ -0,0 +1,4 @@
# Target: Intel 386 with a.out
TDEPFILES= exec.o i386-pinsn.o i386-tdep.o
TM_FILE= tm-i386mach3.h

View File

@ -1,5 +1,9 @@
# Host: Intel 386 running Mach
# This is for mach2, maybe, or is obsolete (and seems to have only
# host and native, not target). Once we get the mach3 stuff working,
# I think it can go away.
XDEPFILES=
XM_FILE= xm-i386mach.h
NAT_FILE= nm-i386mach.h

View File

@ -0,0 +1,8 @@
# Host: Intel 386 running Mach3 with OSF 1/MK
XDEPFILES= os-mach3.o i386mach3-xdep.o i387-tdep.o
XM_FILE= xm-i386osf1mk.h
# Don't use the mmalloc library in Mach 3.
MMALLOC_LIB =
MMALLOC_DISABLE = -DNO_MMALLOC

View File

@ -0,0 +1,7 @@
# Target: Intel 386 with a.out in osf 1/mk
#
TDEPFILES= exec.o i386-pinsn.o i386-tdep.o
TM_FILE= tm-i386osf1mk.h
TM_CFLAGS= -I/usr/mach3/include
TM_CLIBS= /usr/mach3/ccs/lib/libmachid.a /usr/mach3/ccs/lib/libnetname.a /usr/mach3/ccs/lib/libmach.a
OBJFORMATS= dbxread.o

View File

@ -0,0 +1,74 @@
/* Macro definitions for i386, Mach 3.0
Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Include common definitions for Mach3 systems */
#include "os-mach3.h"
/* Define offsets to access CPROC stack when it does not have
* a kernel thread.
*/
#define MACHINE_CPROC_SP_OFFSET 20
#define MACHINE_CPROC_PC_OFFSET 16
#define MACHINE_CPROC_FP_OFFSET 12
/* Thread flavors used in re-setting the T bit.
* @@ this is also bad for cross debugging.
*/
#define TRACE_FLAVOR i386_THREAD_STATE
#define TRACE_FLAVOR_SIZE i386_THREAD_STATE_COUNT
#define TRACE_SET(x,state) \
((struct i386_thread_state *)state)->efl |= 0x100
#define TRACE_CLEAR(x,state) \
((((struct i386_thread_state *)state)->efl &= ~0x100), 1)
/* we can do it */
#define ATTACH_DETACH 1
/* 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.
*
* On Mach 3.0 it is the number of exec() system calls before
* the task contains the debugged program. It is always 2 when
* using the shell to start up the program.
*/
#undef START_INFERIOR_TRAPS_EXPECTED
#define START_INFERIOR_TRAPS_EXPECTED 2
/* Define this if the C compiler puts an underscore at the front
of external names before giving them to the linker. */
#define NAMES_HAVE_UNDERSCORE
/* Sigh. There should be a file for i386 but no sysv stuff in it */
#include "tm-i386v.h"
/* I want to test this float info code. See comment in tm-i386v.h */
#undef FLOAT_INFO
#define FLOAT_INFO { i386_mach3_float_info (); }
/* We use a.out format */
#undef COFF_NO_LONG_FILE_NAMES
/* Address of end of stack space.
* for MACH, see <machine/vmparam.h>
* @@@ I don't know what is in the 5 ints...
*/
#undef STACK_END_ADDR
#define STACK_END_ADDR (0xc0000000-sizeof(int [5]))

View File

@ -0,0 +1,25 @@
/* Macro definitions for i386, Mach 3.0, OSF 1/MK
Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Until OSF switches to a newer Mach kernel that has
* a different get_emul_vector() interface.
*/
#define MK67 1
#include "tm-i386mach3.h"

View File

@ -0,0 +1,44 @@
/* Definitions to make GDB run on Mach 3 on an Intel 386
Copyright (C) 1986, 1987, 1989, 1991 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define HOST_BYTE_ORDER LITTLE_ENDIAN
/* Avoid "INT_MIN redefined" warnings -- by defining it here, exactly
the same as in the system <machine/machtypes.h> file. */
#undef INT_MIN
#define INT_MIN 0x80000000
/* Get rid of any system-imposed stack limit if possible. */
#define SET_STACK_LIMIT_HUGE
#define BROKEN_LARGE_ALLOCA
/* Do implement the attach and detach commands. */
#define ATTACH_DETACH 1
/* Not needeed */
#define KERNEL_U_ADDR 0
#ifndef EMULATOR_BASE
/* For EMULATOR_BASE and EMULATOR_END.
* OSF 1/MK has different values in some other place.
*/
#include <machine/vmparam.h>
#endif /* EMULATOR_BASE */

View File

@ -0,0 +1,25 @@
/* Definitions to make GDB run on Mach 3 OSF 1/MK on an Intel 386
Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define HAVE_TERMIO 1
#define EMULATOR_BASE 0xa0000000
#define EMULATOR_END 0xa0040000
#include "xm-i386mach3.h"

View File

@ -31,6 +31,8 @@ irix3.mt
irix4.mh
littlemips.mh
littlemips.mt
mipsm3.mh
mipsm3.mt
news-mips.mh
nm-irix3.h
nm-irix4.h
@ -41,10 +43,12 @@ riscos.mh
tm-bigmips.h
tm-irix3.h
tm-mips.h
tm-mipsm3.h
xm-irix3.h
xm-irix4.h
xm-makeva.h
xm-mips.h
xm-mipsm3.h
xm-news-mips.h
xm-riscos.h

View File

@ -0,0 +1,9 @@
# Host: Little endian MIPS machine such as pmax
# running Mach 3.0 operating system
XDEPFILES= os-mach3.o mipsmach3-xdep.o coredep.o
XM_FILE= xm-mipsmach3.h
# Don't use the mmalloc library in Mach 3.
MMALLOC_LIB =
MMALLOC_DISABLE = -DNO_MMALLOC

View File

@ -0,0 +1,4 @@
# Target: Little-endian MIPS machine such as pmax
# running Mach 3.0 operating system
TDEPFILES= mips-pinsn.o mips-tdep.o mipsread.o exec.o
TM_FILE= tm-mipsmach3.h

View File

@ -0,0 +1,79 @@
/* Definitions to make GDB run on a mips box under Mach 3.0
Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Mach specific definitions for little endian mips (e.g. pmax)
* running Mach 3.0
*
* Author: Jukka Virtanen <jtv@hut.fi>
*/
/* Include common definitions for Mach3 systems */
#include "os-mach3.h"
/* Define offsets to access CPROC stack when it does not have
* a kernel thread.
*/
/* From mk/user/threads/mips/csw.s */
#define SAVED_FP (12*4)
#define SAVED_PC (13*4)
#define SAVED_BYTES (14*4)
/* Using these, define our offsets to items strored in
* cproc_switch in csw.s
*/
#define MACHINE_CPROC_SP_OFFSET SAVED_BYTES
#define MACHINE_CPROC_PC_OFFSET SAVED_PC
#define MACHINE_CPROC_FP_OFFSET SAVED_FP
/* Thread flavors used in setting the Trace state.
*
* In <mach/machine/thread_status.h>
*/
#define TRACE_FLAVOR MIPS_EXC_STATE
#define TRACE_FLAVOR_SIZE MIPS_EXC_STATE_COUNT
#define TRACE_SET(x,state) ((struct mips_exc_state *)state)->cause = EXC_SST;
#define TRACE_CLEAR(x,state) 0
/* Mach supports attach/detach */
#define ATTACH_DETACH 1
#include "tm-mips.h"
/*
* On Mach 3.0 this is the number of exec() system calls before
* the task contains the debugged program. It is always 2 when
* using the shell to start up the program.
*/
#undef START_INFERIOR_TRAPS_EXPECTED
#define START_INFERIOR_TRAPS_EXPECTED 2
/* Address of end of user stack space.
* for MACH, see <machine/vmparam.h>
*/
#undef STACK_END_ADDR
#define STACK_END_ADDR USRSTACK
/* Don't output r?? names for registers, since they
* can't be used as reg names anyway
*/
#define NUMERIC_REG_NAMES
/* Output registers in tabular format */
#define TABULAR_REGISTER_OUTPUT

View File

@ -0,0 +1,36 @@
/* Definitions to make GDB run on a mips box under 4.3bsd.
Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin
and by Alessandro Forin(af@cs.cmu.edu) at CMU
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (HOST_BYTE_ORDER)
#define HOST_BYTE_ORDER LITTLE_ENDIAN
#endif
/* Get rid of any system-imposed stack limit if possible */
#define SET_STACK_LIMIT_HUGE
#define KERNEL_U_ADDR 0 /* Not needed. */
/* Only used for core files on DECstations. */
#define REGISTER_U_ADDR(addr, blockend, regno) \
if (regno < 38) addr = (NBPG*UPAGES) + (regno - 38)*sizeof(int);\
else addr = 0; /* ..somewhere in the pcb */

View File

@ -0,0 +1,133 @@
/* Mach 3.0 common definitions and global vars.
Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _OS_MACH3_H_
#define _OS_MACH3_H
#include <mach.h>
/* Mach3 doesn't declare errno in <errno.h>. */
extern int errno;
/* Task port of our debugged inferior. */
extern task_t inferior_task;
/* Thread port of the current thread in the inferior. */
extern thread_t current_thread;
/* If nonzero, we must suspend/abort && resume threads
* when setting or getting the state.
*/
extern int must_suspend_thread;
/* Get relevant ports when creating a new inferior */
#define CREATE_INFERIOR_HOOK(pid) mach_create_inferior_hook(pid)
/* wait for the inferior to change state */
#define INFERIOR_WAIT_HOOK(w) mach_really_wait(w)
/* After fork() call this before exec() in the inferior task */
#define PREPARE_INFERIOR prepare_inferior_task
/* Startup the inferior task and suspend it after the correct code is loaded */
#define STARTUP_INFERIOR(x) intercept_exec_calls(x)
#define PREPARE_TO_PROCEED(select_it) mach3_prepare_to_proceed(select_it)
/* Try to get the privileged host port for authentication to machid
*
* If you can get this, you may debug anything on this host.
*
* If you can't, gdb gives it's own task port as the
* authentication port
*/
#define mach_privileged_host_port() task_by_pid(-1)
/*
* This is the MIG ID number of the emulator/server bsd_execve() RPC call.
*
* It SHOULD never change, but if it does, gdb `run'
* command won't work until you fix this define.
*
*/
#define MIG_EXEC_SYSCALL_ID 101000
/* If our_message_port gets a msg with this ID,
* GDB suspends it's inferior and enters command level.
* (Useful at least if ^C does not work)
*/
#define GDB_MESSAGE_ID_STOP 0x41151
/* wait3 WNOHANG is defined in <sys/wait.h> but
* for some reason gdb does not want to include
* that file.
*
* If your system defines WNOHANG differently, this has to be changed.
*/
#define WNOHANG 1
/* Before storing, we need to read all the registers. */
#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
/* Check if the inferior exists */
#define MACH_ERROR_NO_INFERIOR \
do if (!MACH_PORT_VALID (inferior_task)) \
error ("Inferior task does not exist."); while(0)
/* Error handler for mach calls */
#define CHK(str,ret) \
do if (ret != KERN_SUCCESS) \
error ("Gdb %s [%d] %s : %s\n",__FILE__,__LINE__,str, \
mach_error_string(ret)); while(0)
/* This is from POE9 emulator/emul_stack.h
*/
/*
* Top of emulator stack holds link and reply port.
*/
struct emul_stack_top {
struct emul_stack_top *link;
mach_port_t reply_port;
};
#define EMULATOR_STACK_SIZE (4096*4)
#define THREAD_ALLOWED_TO_BREAK(mid) mach_thread_for_breakpoint (mid)
#define THREAD_PARSE_ID(arg) mach_thread_parse_id (arg)
#define THREAD_OUTPUT_ID(mid) mach_thread_output_id (mid)
#define ATTACH_TO_THREAD attach_to_thread
/* Do Mach 3 dependent operations when ^C or a STOP is requested */
#define DO_QUIT() mach3_quit ()
/* If in mach_msg() and ^C is typed set immediate_quit */
#define REQUEST_QUIT() mach3_request_quit ()
#endif /* _OS_MACH3_H_ */

View File

@ -24,11 +24,15 @@ Things-to-keep:
merlin.mh
merlin.mt
nm-umax.h
ns32km3.mh
ns32km3.mt
tm-merlin.h
tm-ns32km3.h
tm-umax.h
umax.mh
umax.mt
xm-merlin.h
xm-ns32km3.h
xm-umax.h
Things-to-lose:

View File

@ -0,0 +1,8 @@
# Host: ns32k running Mach3
XDEPFILES= os-mach3.o ns32kmach3-xdep.o
XM_FILE= xm-ns32kmach3.h
# Don't use the mmalloc library in Mach 3.
MMALLOC_LIB =
MMALLOC_DISABLE = -DNO_MMALLOC

View File

@ -0,0 +1,4 @@
# Target: ns32k with a.out on Mach 3
TDEPFILES= exec.o ns32k-pinsn.o ns32k-tdep.o
TM_FILE= tm-ns32kmach3.h

View File

@ -0,0 +1,64 @@
/* Macro definitions for ns532, Mach 3.0
Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Include common definitions for Mach3 systems */
#include "os-mach3.h"
/* Define offsets to access CPROC stack when it does not have
* a kernel thread.
*/
#define MACHINE_CPROC_SP_OFFSET 20
#define MACHINE_CPROC_PC_OFFSET 16
#define MACHINE_CPROC_FP_OFFSET 12
#include <ns532/psl.h>
#include <ns532/vmparam.h>
/* Thread flavors used in re-setting the T bit.
* @@ this is also bad for cross debugging.
*/
#define TRACE_FLAVOR NS532_THREAD_STATE
#define TRACE_FLAVOR_SIZE NS532_THREAD_STATE_COUNT
#define TRACE_SET(x,state) \
((struct ns532_thread_state *)state)->psr |= PSR_T
#define TRACE_CLEAR(x,state) \
((((struct ns532_thread_state *)state)->psr &= ~PSR_T), 1)
/* we can do it */
#define ATTACH_DETACH 1
/* 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.
*
* On Mach 3.0 it is the number of exec() system calls before
* the task contains the debugged program. It is always 2 when
* using the shell to start up the program.
*/
#undef START_INFERIOR_TRAPS_EXPECTED
#define START_INFERIOR_TRAPS_EXPECTED 2
#define INVALID_FLOAT(p, s) isa_NAN(p, s)
/* Address of end of stack space.
* for MACH, see <ns532/vmparam.h>
*/
#define STACK_END_ADDR USRSTACK
#include "tm-umax.h"

View File

@ -0,0 +1,37 @@
/* Definitions to make GDB run on Mach 3 on an National ns32k
Copyright (C) 1986, 1987, 1989, 1991 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define HOST_BYTE_ORDER LITTLE_ENDIAN
/* Avoid "INT_MIN redefined" warnings -- by defining it here, exactly
the same as in the system <machine/machtypes.h> file. */
#undef INT_MIN
#define INT_MIN 0x80000000
/* Get rid of any system-imposed stack limit if possible. */
#define SET_STACK_LIMIT_HUGE
#define BROKEN_LARGE_ALLOCA
/* Do implement the attach and detach commands. */
#define ATTACH_DETACH 1
/* signal.h has declaration for psignal() */
#define PSIGNAL_IN_SIGNAL_H

View File

@ -0,0 +1,422 @@
/* Low level interface to I386 running mach 3.0.
Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
#include "inferior.h"
#include <stdio.h>
#include <mach.h>
#include <mach/message.h>
#include <mach/exception.h>
#include <mach_error.h>
/* Hmmm... Should this not be here?
* Now for i386_float_info() target_has_execution
*/
#include <target.h>
/* This mess is duplicated in bfd/i386mach3.h
*
* This is an ugly way to hack around the incorrect
* definition of UPAGES in i386/machparam.h.
*
* The definition should specify the size reserved
* for "struct user" in core files in PAGES,
* but instead it gives it in 512-byte core-clicks
* for i386 and i860.
*/
#include <sys/param.h>
#if UPAGES == 16
#define UAREA_SIZE ctob(UPAGES)
#elif UPAGES == 2
#define UAREA_SIZE (NBPG*UPAGES)
#else
FIXME!! UPAGES is neither 2 nor 16
#endif
/* @@@ Should move print_387_status() to i387-tdep.c */
extern void print_387_control_word (); /* i387-tdep.h */
extern void print_387_status_word ();
extern struct ext_format ext_format_i387;
#define private static
/* Find offsets to thread states at compile time.
* If your compiler does not grok this, calculate offsets
* offsets yourself and use them (or get a compatible compiler :-)
*/
#define REG_OFFSET(reg) (int)(&((struct i386_thread_state *)0)->reg)
/* at reg_offset[i] is the offset to the i386_thread_state
* location where the gdb registers[i] is stored.
*/
static int reg_offset[] =
{
REG_OFFSET(eax), REG_OFFSET(ecx), REG_OFFSET(edx), REG_OFFSET(ebx),
REG_OFFSET(uesp), REG_OFFSET(ebp), REG_OFFSET(esi), REG_OFFSET(edi),
REG_OFFSET(eip), REG_OFFSET(efl), REG_OFFSET(cs), REG_OFFSET(ss),
REG_OFFSET(ds), REG_OFFSET(es), REG_OFFSET(fs), REG_OFFSET(gs)
};
#define REG_ADDRESS(state,regnum) ((char *)(state)+reg_offset[regnum])
/* Fetch COUNT contiguous registers from thread STATE starting from REGNUM
* Caller knows that the regs handled in one transaction are of same size.
*/
#define FETCH_REGS(state, regnum, count) \
bcopy (REG_ADDRESS (state, regnum), \
&registers[REGISTER_BYTE (regnum)], \
count*sizeof (REGISTER_TYPE))
/* Store COUNT contiguous registers to thread STATE starting from REGNUM */
#define STORE_REGS(state, regnum, count) \
bcopy (&registers[REGISTER_BYTE (regnum)], \
REG_ADDRESS (state, regnum), \
count*sizeof (REGISTER_TYPE))
/*
* Fetch inferiors registers for gdb.
* REGNO specifies which (as gdb views it) register, -1 for all.
*/
void
fetch_inferior_registers (regno)
int regno;
{
kern_return_t ret;
thread_state_data_t state;
unsigned int stateCnt = i386_THREAD_STATE_COUNT;
int index;
if (! MACH_PORT_VALID (current_thread))
error ("fetch inferior registers: Invalid thread");
if (must_suspend_thread)
setup_thread (current_thread, 1);
ret = thread_get_state (current_thread,
i386_THREAD_STATE,
state,
&stateCnt);
if (ret != KERN_SUCCESS)
message ("fetch_inferior_registers: %s ",
mach_error_string (ret));
#if 0
/* It may be more effective to store validate all of them,
* since we fetched them all anyway
*/
else if (regno != -1)
supply_register (regno, (char *)state+reg_offset[regno]);
#endif
else
{
for (index = 0; index < NUM_REGS; index++)
supply_register (index, (char *)state+reg_offset[index]);
}
if (must_suspend_thread)
setup_thread (current_thread, 0);
}
/* Store our register values back into the inferior.
* If REGNO is -1, do this for all registers.
* Otherwise, REGNO specifies which register
*
* On mach3 all registers are always saved in one call.
*/
void
store_inferior_registers (regno)
int regno;
{
kern_return_t ret;
thread_state_data_t state;
unsigned int stateCnt = i386_THREAD_STATE_COUNT;
register int index;
if (! MACH_PORT_VALID (current_thread))
error ("store inferior registers: Invalid thread");
if (must_suspend_thread)
setup_thread (current_thread, 1);
/* Fetch the state of the current thread */
ret = thread_get_state (current_thread,
i386_THREAD_STATE,
state,
&stateCnt);
if (ret != KERN_SUCCESS)
{
message ("store_inferior_registers (get): %s",
mach_error_string (ret));
if (must_suspend_thread)
setup_thread (current_thread, 0);
return;
}
/* move gdb's registers to thread's state
*
* Since we save all registers anyway, save the ones
* that gdb thinks are valid (e.g. ignore the regno
* parameter)
*/
#if 0
if (regno != -1)
STORE_REGS (state, regno, 1);
else
#endif
{
for (index = 0; index < NUM_REGS; index++)
STORE_REGS (state, index, 1);
}
/* Write gdb's current view of register to the thread
*/
ret = thread_set_state (current_thread,
i386_THREAD_STATE,
state,
i386_THREAD_STATE_COUNT);
if (ret != KERN_SUCCESS)
message ("store_inferior_registers (set): %s",
mach_error_string (ret));
if (must_suspend_thread)
setup_thread (current_thread, 0);
}
/* Return the address in the core dump or inferior of register REGNO.
* BLOCKEND should be the address of the end of the UPAGES area read
* in memory, but it's not?
*
* Currently our UX server dumps the whole thread state to the
* core file. If your UX does something else, adapt the routine
* below to return the offset to the given register.
*
* Called by coredep.c(fetch_core_registers)
*/
unsigned int
register_addr (regno, blockend)
int regno;
int blockend;
{
unsigned int addr;
if (regno < 0 || regno >= NUM_REGS)
error ("Invalid register number %d.", regno);
/* UAREA_SIZE == 8 kB in i386 */
addr = (unsigned int)REG_ADDRESS (UAREA_SIZE - sizeof(struct i386_thread_state), regno);
return addr;
}
/* jtv@hut.fi: I copied and modified this 387 code from
* gdb/i386-xdep.c. Modifications for Mach 3.0.
*
* i387 status dumper. See also i387-tdep.c
*/
struct env387
{
unsigned short control;
unsigned short r0;
unsigned short status;
unsigned short r1;
unsigned short tag;
unsigned short r2;
unsigned long eip;
unsigned short code_seg;
unsigned short opcode;
unsigned long operand;
unsigned short operand_seg;
unsigned short r3;
unsigned char regs[8][10];
};
/* This routine is machine independent?
* Should move it to i387-tdep.c but you need to export struct env387
*/
private
print_387_status (status, ep)
unsigned short status;
struct env387 *ep;
{
int i;
int bothstatus;
int top;
int fpreg;
unsigned char *p;
bothstatus = ((status != 0) && (ep->status != 0));
if (status != 0)
{
if (bothstatus)
printf ("u: ");
print_387_status_word (status);
}
if (ep->status != 0)
{
if (bothstatus)
printf ("e: ");
print_387_status_word (ep->status);
}
print_387_control_word (ep->control);
printf ("last exception: ");
printf ("opcode %s; ", local_hex_string(ep->opcode));
printf ("pc %s:", local_hex_string(ep->code_seg));
printf ("%s; ", local_hex_string(ep->eip));
printf ("operand %s", local_hex_string(ep->operand_seg));
printf (":%s\n", local_hex_string(ep->operand));
top = (ep->status >> 11) & 7;
printf ("regno tag msb lsb value\n");
for (fpreg = 7; fpreg >= 0; fpreg--)
{
double val;
printf ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
switch ((ep->tag >> (fpreg * 2)) & 3)
{
case 0: printf ("valid "); break;
case 1: printf ("zero "); break;
case 2: printf ("trap "); break;
case 3: printf ("empty "); break;
}
for (i = 9; i >= 0; i--)
printf ("%02x", ep->regs[fpreg][i]);
ieee_extended_to_double (&ext_format_i387, (char *)ep->regs[fpreg],
&val);
printf (" %g\n", val);
}
if (ep->r0)
printf ("warning: reserved0 is %s\n", local_hex_string(ep->r0));
if (ep->r1)
printf ("warning: reserved1 is %s\n", local_hex_string(ep->r1));
if (ep->r2)
printf ("warning: reserved2 is %s\n", local_hex_string(ep->r2));
if (ep->r3)
printf ("warning: reserved3 is %s\n", local_hex_string(ep->r3));
}
/*
* values that go into fp_kind (from <i386/fpreg.h>)
*/
#define FP_NO 0 /* no fp chip, no emulator (no fp support) */
#define FP_SW 1 /* no fp chip, using software emulator */
#define FP_HW 2 /* chip present bit */
#define FP_287 2 /* 80287 chip present */
#define FP_387 3 /* 80387 chip present */
typedef struct fpstate {
#if 1
unsigned char state[FP_STATE_BYTES]; /* "hardware" state */
#else
struct env387 state; /* Actually this */
#endif
int status; /* Duplicate status */
} *fpstate_t;
/* Mach 3 specific routines.
*/
private boolean_t
get_i387_state (fstate)
struct fpstate *fstate;
{
kern_return_t ret;
thread_state_data_t state;
unsigned int fsCnt = i386_FLOAT_STATE_COUNT;
struct i386_float_state *fsp;
ret = thread_get_state (current_thread,
i386_FLOAT_STATE,
state,
&fsCnt);
if (ret != KERN_SUCCESS)
{
message ("Can not get live floating point state: %s",
mach_error_string (ret));
return FALSE;
}
fsp = (struct i386_float_state *)state;
/* The 387 chip (also 486 counts) or a software emulator? */
if (!fsp->initialized || (fsp->fpkind != FP_387 && fsp->fpkind != FP_SW))
return FALSE;
/* Clear the target then copy thread's float state there.
Make a copy of the status word, for some reason?
*/
bzero (fstate, sizeof(struct fpstate));
fstate->status = fsp->exc_status;
bcopy ((char *)&fsp->hw_state, fstate->state, FP_STATE_BYTES);
return TRUE;
}
private boolean_t
get_i387_core_state (fstate)
struct fpstate *fstate;
{
/* Not implemented yet. Core files do not contain float state. */
return FALSE;
}
/*
* This is called by "info float" command
*/
void
i386_mach3_float_info()
{
char buf [sizeof (struct fpstate) + 2 * sizeof (int)];
boolean_t valid = FALSE;
fpstate_t fps;
if (target_has_execution)
valid = get_i387_state (buf);
#if 0
else if (WE HAVE CORE FILE) /* @@@@ Core files not supported */
valid = get_i387_core_state (buf);
#endif
if (!valid)
{
message("no floating point status saved");
return;
}
fps = (fpstate_t) buf;
print_387_status (fps->status, (struct env387 *)fps->state);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,386 @@
/* Definitions to make GDB run on a mips box under Mach 3.0
Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Mach specific routines for little endian mips (e.g. pmax)
* running Mach 3.0
*
* Author: Jukka Virtanen <jtv@hut.fi>
*/
#include "defs.h"
#include "inferior.h"
#include <stdio.h>
#include <mach.h>
#include <mach/message.h>
#include <mach/exception.h>
#include <mach_error.h>
/* Find offsets to thread states at compile time.
* If your compiler does not grok this, check the hand coded
* offsets and use them.
*/
#if 1
#define REG_OFFSET(reg) (int)(&((struct mips_thread_state *)0)->reg)
#define CREG_OFFSET(reg) (int)(&((struct mips_float_state *)0)->reg)
#define EREG_OFFSET(reg) (int)(&((struct mips_exc_state *)0)->reg)
/* at reg_offset[i] is the offset to the mips_thread_state
* location where the gdb registers[i] is stored.
*
* -1 means mach does not save it anywhere.
*/
static int reg_offset[] =
{
/* zero at v0 v1 */
-1, REG_OFFSET(r1), REG_OFFSET(r2), REG_OFFSET(r3),
/* a0 a1 a2 a3 */
REG_OFFSET(r4), REG_OFFSET(r5), REG_OFFSET(r6), REG_OFFSET(r7),
/* t0 t1 t2 t3 */
REG_OFFSET(r8), REG_OFFSET(r9), REG_OFFSET(r10), REG_OFFSET(r11),
/* t4 t5 t6 t7 */
REG_OFFSET(r12), REG_OFFSET(r13), REG_OFFSET(r14), REG_OFFSET(r15),
/* s0 s1 s2 s3 */
REG_OFFSET(r16), REG_OFFSET(r17), REG_OFFSET(r18), REG_OFFSET(r19),
/* s4 s5 s6 s7 */
REG_OFFSET(r20), REG_OFFSET(r21), REG_OFFSET(r22), REG_OFFSET(r23),
/* t8 t9 k0 k1 */
REG_OFFSET(r24), REG_OFFSET(r25), REG_OFFSET(r26), REG_OFFSET(r27),
/* gp sp s8(30) == fp(72) ra */
REG_OFFSET(r28), REG_OFFSET(r29), REG_OFFSET(r30), REG_OFFSET(r31),
/* sr(32) PS_REGNUM */
EREG_OFFSET(coproc_state),
/* lo(33) hi(34) */
REG_OFFSET(mdlo), REG_OFFSET(mdhi),
/* bad(35) cause(36) pc(37) */
EREG_OFFSET(address), EREG_OFFSET(cause), REG_OFFSET(pc),
/* f0(38) f1(39) f2(40) f3(41) */
CREG_OFFSET(r0), CREG_OFFSET(r1), CREG_OFFSET(r2), CREG_OFFSET(r3),
CREG_OFFSET(r4), CREG_OFFSET(r5), CREG_OFFSET(r6), CREG_OFFSET(r7),
CREG_OFFSET(r8), CREG_OFFSET(r9), CREG_OFFSET(r10), CREG_OFFSET(r11),
CREG_OFFSET(r12), CREG_OFFSET(r13), CREG_OFFSET(r14), CREG_OFFSET(r15),
CREG_OFFSET(r16), CREG_OFFSET(r17), CREG_OFFSET(r18), CREG_OFFSET(r19),
CREG_OFFSET(r20), CREG_OFFSET(r21), CREG_OFFSET(r22), CREG_OFFSET(r23),
CREG_OFFSET(r24), CREG_OFFSET(r25), CREG_OFFSET(r26), CREG_OFFSET(r27),
CREG_OFFSET(r28), CREG_OFFSET(r29), CREG_OFFSET(r30), CREG_OFFSET(r31),
/* fsr(70) fir(71) fp(72) == s8(30) */
CREG_OFFSET(csr), CREG_OFFSET(esr), REG_OFFSET(r30)
};
#else
/* If the compiler does not grok the above defines */
static int reg_offset[] =
{
/* mach_thread_state offsets: */
-1, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56,
60, 64, 68, 72, 76, 80, 84, 88, 92, 96,100,104, 108,112,116,120,
/*sr, lo, hi,addr,cause,pc */
8,124,128, 4, 0,132,
/* mach_float_state offsets: */
0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
64, 68, 72, 76, 80, 84, 88, 92, 96,100,104,108, 112,116,120,124,
/*fsr,fir*/
128,132,
/* FP_REGNUM pseudo maps to s8==r30 in mach_thread_state */
116
};
#endif
/* Fetch COUNT contiguous registers from thread STATE starting from REGNUM
* Caller knows that the regs handled in one transaction are of same size.
*/
#define FETCH_REGS(state, regnum, count) \
bcopy ((char *)state+reg_offset[ regnum ], \
&registers[REGISTER_BYTE (regnum)], \
count*sizeof (REGISTER_TYPE))
/* Store COUNT contiguous registers to thread STATE starting from REGNUM */
#define STORE_REGS(state, regnum, count) \
bcopy (&registers[REGISTER_BYTE (regnum)], \
(char *)state+reg_offset[ regnum ], \
count*sizeof (REGISTER_TYPE))
#define REGS_ALL -1
#define REGS_NORMAL 1
#define REGS_EXC 2
#define REGS_COP1 4
/* Hardware regs that matches FP_REGNUM */
#define MACH_FP_REGNUM 30
/* Fech thread's registers. if regno == -1, fetch all regs */
void
fetch_inferior_registers (regno)
int regno;
{
kern_return_t ret;
thread_state_data_t state;
struct mips_exc_state exc_state;
int stateCnt = MIPS_THREAD_STATE_COUNT;
int which_regs = 0; /* A bit mask */
if (! MACH_PORT_VALID (current_thread))
error ("fetch inferior registers: Invalid thread");
if (regno < -1 || regno >= NUM_REGS)
error ("invalid register %d supplied to fetch_inferior_registers", regno);
if (regno == -1)
which_regs = REGS_ALL;
else if (regno == ZERO_REGNUM)
{
int zero = 0;
supply_register (ZERO_REGNUM, &zero);
return;
}
else if ((ZERO_REGNUM < regno && regno < PS_REGNUM)
|| regno == FP_REGNUM
|| regno == LO_REGNUM
|| regno == HI_REGNUM
|| regno == PC_REGNUM)
which_regs = REGS_NORMAL;
else if (FP0_REGNUM <= regno && regno <= FCRIR_REGNUM)
which_regs = REGS_COP1 | REGS_EXC;
else
which_regs = REGS_EXC;
/* fetch regs saved to mips_thread_state */
if (which_regs & REGS_NORMAL)
{
ret = thread_get_state (current_thread,
MIPS_THREAD_STATE,
state,
&stateCnt);
CHK ("fetch inferior registers: thread_get_state", ret);
if (which_regs == REGS_NORMAL)
{
/* Fetch also FP_REGNUM if fetching MACH_FP_REGNUM and vice versa */
if (regno == MACH_FP_REGNUM || regno == FP_REGNUM)
{
supply_register (FP_REGNUM,
(char *)state+reg_offset[ MACH_FP_REGNUM ]);
supply_register (MACH_FP_REGNUM,
(char *)state+reg_offset[ MACH_FP_REGNUM ]);
}
else
supply_register (regno,
(char *)state+reg_offset[ regno ]);
return;
}
/* ZERO_REGNUM is always zero */
*(int *) registers = 0;
/* Copy thread saved regs 1..31 to gdb's reg value array
* Luckily, they are contiquous
*/
FETCH_REGS (state, 1, 31);
/* Copy mdlo and mdhi */
FETCH_REGS (state, LO_REGNUM, 2);
/* Copy PC */
FETCH_REGS (state, PC_REGNUM, 1);
/* Mach 3.0 saves FP to MACH_FP_REGNUM.
* For some reason gdb wants to assign a pseudo register for it.
*/
FETCH_REGS (state, FP_REGNUM, 1);
}
/* Read exc state. Also read if need to fetch floats */
if (which_regs & REGS_EXC)
{
stateCnt = MIPS_EXC_STATE_COUNT;
ret = thread_get_state (current_thread,
MIPS_EXC_STATE,
(thread_state_t) &exc_state,
&stateCnt);
CHK ("fetch inferior regs (exc): thread_get_state", ret);
/* We need to fetch exc_state to see if the floating
* state is valid for the thread.
*/
/* cproc_state: Which coprocessors the thread uses */
supply_register (PS_REGNUM,
(char *)&exc_state+reg_offset[ PS_REGNUM ]);
if (which_regs == REGS_EXC || which_regs == REGS_ALL)
{
supply_register (BADVADDR_REGNUM,
(char *)&exc_state+reg_offset[ BADVADDR_REGNUM ]);
supply_register (CAUSE_REGNUM,
(char *)&exc_state+reg_offset[ CAUSE_REGNUM ]);
if (which_regs == REGS_EXC)
return;
}
}
if (which_regs & REGS_COP1)
{
/* If the thread does not have saved COPROC1, set regs to zero */
if (! (exc_state.coproc_state & MIPS_STATUS_USE_COP1))
bzero (&registers[ REGISTER_BYTE (FP0_REGNUM) ],
sizeof (struct mips_float_state));
else
{
stateCnt = MIPS_FLOAT_STATE_COUNT;
ret = thread_get_state (current_thread,
MIPS_FLOAT_STATE,
state,
&stateCnt);
CHK ("fetch inferior regs (floats): thread_get_state", ret);
if (regno != -1)
{
supply_register (regno,
(char *)state+reg_offset[ regno ]);
return;
}
FETCH_REGS (state, FP0_REGNUM, 34);
}
}
/* All registers are valid, if not returned yet */
registers_fetched ();
}
/* Store gdb's view of registers to the thread.
* All registers are always valid when entering here.
* @@ ahem, maybe that is too strict, we could validate the necessary ones
* here.
*
* Hmm. It seems that gdb set $reg=value command first reads everything,
* then sets the reg and then stores everything. -> we must make sure
* that the immutable registers are not changed by reading them first.
*/
void
store_inferior_registers (regno)
register int regno;
{
thread_state_data_t state;
kern_return_t ret;
if (! MACH_PORT_VALID (current_thread))
error ("store inferior registers: Invalid thread");
/* Check for read only regs.
* @@ If some of these is can be changed, fix this
*/
if (regno == ZERO_REGNUM ||
regno == PS_REGNUM ||
regno == BADVADDR_REGNUM ||
regno == CAUSE_REGNUM ||
regno == FCRIR_REGNUM)
{
message ("You can not alter read-only register `%s'",
reg_names[ regno ]);
fetch_inferior_registers (regno);
return;
}
if (regno == -1)
{
/* Don't allow these to change */
/* ZERO_REGNUM */
*(int *)registers = 0;
fetch_inferior_registers (PS_REGNUM);
fetch_inferior_registers (BADVADDR_REGNUM);
fetch_inferior_registers (CAUSE_REGNUM);
fetch_inferior_registers (FCRIR_REGNUM);
}
if (regno == -1 || (ZERO_REGNUM < regno && regno <= PC_REGNUM))
{
#if 1
/* Mach 3.0 saves thread's FP to MACH_FP_REGNUM.
* GDB wants assigns a pseudo register FP_REGNUM for frame pointer.
*
* @@@ Here I assume (!) that gdb's FP has the value that
* should go to threads frame pointer. If not true, this
* fails badly!!!!!
*/
bcopy (&registers[REGISTER_BYTE (FP_REGNUM)],
&registers[REGISTER_BYTE (MACH_FP_REGNUM)],
REGISTER_RAW_SIZE (FP_REGNUM));
#endif
/* Save gdb's regs 1..31 to thread saved regs 1..31
* Luckily, they are contiquous
*/
STORE_REGS (state, 1, 31);
/* Save mdlo, mdhi */
STORE_REGS (state, LO_REGNUM, 2);
/* Save PC */
STORE_REGS (state, PC_REGNUM, 1);
ret = thread_set_state (current_thread,
MIPS_THREAD_STATE,
state,
MIPS_FLOAT_STATE_COUNT);
CHK ("store inferior regs : thread_set_state", ret);
}
if (regno == -1 || regno >= FP0_REGNUM)
{
/* If thread has floating state, save it */
if (read_register (PS_REGNUM) & MIPS_STATUS_USE_COP1)
{
/* Do NOT save FCRIR_REGNUM */
STORE_REGS (state, FP0_REGNUM, 33);
ret = thread_set_state (current_thread,
MIPS_FLOAT_STATE,
state,
MIPS_FLOAT_STATE_COUNT);
CHK ("store inferior registers (floats): thread_set_state", ret);
}
else if (regno != -1)
message
("Thread does not use floating point unit, floating regs not saved");
}
}

View File

@ -0,0 +1,193 @@
/* Low level interface to ns532 running mach 3.0.
Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
#include "inferior.h"
#include <stdio.h>
#include <mach.h>
#include <mach/message.h>
#include <mach/exception.h>
#include <mach_error.h>
#define private static
/* Find offsets to thread states at compile time.
* If your compiler does not grok this, calculate offsets
* offsets yourself and use them (or get a compatible compiler :-)
*/
#define REG_N_OFFSET(reg) (int)(&((struct ns532_combined_state *)0)->ts.reg)
#define REG_F_OFFSET(reg) (int)(&((struct ns532_combined_state *)0)->fs.reg)
/* at reg_offset[i] is the offset to the ns532_combined_state
* location where the gdb registers[i] is stored.
*/
static int reg_offset[] =
{
REG_N_OFFSET(r0), REG_N_OFFSET(r1), REG_N_OFFSET(r2), REG_N_OFFSET(r3),
REG_N_OFFSET(r4), REG_N_OFFSET(r5), REG_N_OFFSET(r6), REG_N_OFFSET(r7),
REG_F_OFFSET(l0a), REG_F_OFFSET(l1a),REG_F_OFFSET(l2a),REG_F_OFFSET(l3a),
REG_F_OFFSET(l4a), REG_F_OFFSET(l5a),REG_F_OFFSET(l6a),REG_F_OFFSET(l7a),
REG_N_OFFSET(sp), REG_N_OFFSET(fp), REG_N_OFFSET(pc), REG_N_OFFSET(psr),
REG_F_OFFSET(fsr),
REG_F_OFFSET(l0a), REG_F_OFFSET(l2a),REG_F_OFFSET(l4a),REG_F_OFFSET(l6a)
/* @@@ 532 has more double length floating point regs, not accessed currently */
};
/* Fetch COUNT contiguous registers from thread STATE starting from REGNUM
* Caller knows that the regs handled in one transaction are of same size.
*/
#define FETCH_REGS(state, regnum, count) \
bcopy ((char *)state+reg_offset[ regnum ], \
&registers[REGISTER_BYTE (regnum)], \
count*sizeof (REGISTER_TYPE))
/* Store COUNT contiguous registers to thread STATE starting from REGNUM */
#define STORE_REGS(state, regnum, count) \
bcopy (&registers[REGISTER_BYTE (regnum)], \
(char *)state+reg_offset[ regnum ], \
count*sizeof (REGISTER_TYPE))
/* 4.4 bfd support function */
/* jtv@hut.fi: UNIMPLEMENTED!!!!! */
void
fetch_core_registers (core_regs, core_reg_size, which)
char *core_regs;
unsigned int core_reg_size;
int which;
{
error ("Unimplemented routine fetch_core_registers called");
}
/*
* Fetch inferiors registers for gdb.
* REGNO specifies which (as gdb views it) register, -1 for all.
*/
void
fetch_inferior_registers (regno)
int regno;
{
kern_return_t ret;
thread_state_data_t state;
unsigned int stateCnt = NS532_COMBINED_STATE_COUNT;
int index;
if (! MACH_PORT_VALID (current_thread))
error ("fetch inferior registers: Invalid thread");
if (must_suspend_thread)
setup_thread (current_thread, 1);
ret = thread_get_state (current_thread,
NS532_COMBINED_STATE,
state,
&stateCnt);
if (ret != KERN_SUCCESS)
message ("fetch_inferior_registers: %s ",
mach_error_string (ret));
#if 0
/* It may be more effective to store validate all of them,
* since we fetched them all anyway
*/
else if (regno != -1)
supply_register (regno, (char *)state+reg_offset[regno]);
#endif
else
{
for (index = 0; index < NUM_REGS; index++)
supply_register (index, (char *)state+reg_offset[index]);
}
if (must_suspend_thread)
setup_thread (current_thread, 0);
}
/* Store our register values back into the inferior.
* If REGNO is -1, do this for all registers.
* Otherwise, REGNO specifies which register
*
* On mach3 all registers are always saved in one call.
*/
void
store_inferior_registers (regno)
int regno;
{
kern_return_t ret;
thread_state_data_t state;
unsigned int stateCnt = NS532_COMBINED_STATE_COUNT;
register int index;
if (! MACH_PORT_VALID (current_thread))
error ("store inferior registers: Invalid thread");
if (must_suspend_thread)
setup_thread (current_thread, 1);
/* Fetch the state of the current thread */
ret = thread_get_state (current_thread,
NS532_COMBINED_STATE,
state,
&stateCnt);
if (ret != KERN_SUCCESS)
{
message ("store_inferior_registers (get): %s",
mach_error_string (ret));
if (must_suspend_thread)
setup_thread (current_thread, 0);
return;
}
/* move gdb's registers to thread's state
*
* Since we save all registers anyway, save the ones
* that gdb thinks are valid (e.g. ignore the regno
* parameter)
*/
#if 0
if (regno != -1)
STORE_REGS (state, regno, 1);
else
#endif
{
for (index = 0; index < NUM_REGS; index++)
STORE_REGS (state, index, 1);
}
/* Write gdb's current view of register to the thread
*/
ret = thread_set_state (current_thread,
NS532_COMBINED_STATE,
state,
NS532_COMBINED_STATE_COUNT);
if (ret != KERN_SUCCESS)
message ("store_inferior_registers (set): %s",
mach_error_string (ret));
if (must_suspend_thread)
setup_thread (current_thread, 0);
}