* m3-nat.c, config/nm-m3.h: Add a target_ops struct and other

various things to try to get this to work.
This commit is contained in:
Jim Kingdon 1993-10-11 22:39:54 +00:00
parent f37449aaf3
commit 843cea0d2b
3 changed files with 276 additions and 117 deletions

View File

@ -1,5 +1,8 @@
Mon Oct 11 14:27:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
* m3-nat.c, config/nm-m3.h: Add a target_ops struct and other
various things to try to get this to work.
* symtab.h: Fix comments re headers, sharing blockvectors, etc.
Mon Oct 11 11:46:06 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)

View File

@ -39,18 +39,6 @@ extern thread_t current_thread;
*/
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)

View File

@ -54,7 +54,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "target.h"
#include "wait.h"
#include "gdbcmd.h"
#include "gdb-threads.h"
#include <servers/machid_lib.h>
@ -66,7 +65,27 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <signal.h>
#define SIG_UNKNOWN 0 /* Exception that has no matching unix signal */
#define private static
#include <cthreads.h>
/*
* Mis-use the struct cproc busy field in the copy of
* the cproc in gdb's address space.
*
* This *can* be done otherwise, but I'm too lazy.
* (Don't tell anyone :-)
*/
#define CPROC_REVERSE_MAP(x) ((x)->busy)
/* For cproc and kernel thread mapping */
typedef struct gdb_thread {
mach_port_t name;
CORE_ADDR sp;
CORE_ADDR pc;
CORE_ADDR fp;
cproc_t cproc;
boolean_t in_emulator;
int slotid;
} *gdb_thread_t;
/*
* Actions for Mach exceptions.
@ -344,7 +363,7 @@ int type;
}
/* Guard for currently_waiting_for and singlestepped_thread_port */
private void
static void
discard_single_step (thread)
thread_t thread;
{
@ -444,7 +463,7 @@ setup_single_step (thread, start_step)
}
}
private
static
request_notify (name, variant, type)
mach_port_t name;
mach_msg_id_t variant;
@ -511,7 +530,8 @@ mach_port_t original_server_port_name = MACH_PORT_NULL;
/* Called from inferior after FORK but before EXEC */
prepare_inferior_task ()
static void
m3_trace_me ()
{
kern_return_t ret;
@ -840,7 +860,7 @@ map_slot_to_mid (slot, threads, thread_count)
return mid;
}
private int
static int
parse_thread_id (arg, thread_count, slots)
char *arg;
int thread_count;
@ -1049,8 +1069,8 @@ switch_to_thread (new_thread)
/* Do this in gdb after doing FORK but before STARTUP_INFERIOR.
* Note that the registers are not yet valid in the inferior task.
*/
void
mach_create_inferior_hook (pid)
static void
m3_trace_him (pid)
int pid;
{
kern_return_t ret;
@ -1927,11 +1947,9 @@ mach3_write_inferior (addr, myaddr, length)
return length;
}
/*
* Return 0 on failure, number of bytes handled otherwise.
*/
int
child_xfer_memory (memaddr, myaddr, len, write, target)
/* Return 0 on failure, number of bytes handled otherwise. */
static int
m3_xfer_memory (memaddr, myaddr, len, write, target)
CORE_ADDR memaddr;
char *myaddr;
int len;
@ -1949,7 +1967,7 @@ child_xfer_memory (memaddr, myaddr, len, write, target)
}
private char *
static char *
translate_state(state)
int state;
{
@ -1963,7 +1981,7 @@ int state;
}
}
private char *
static char *
translate_cstate(state)
int state;
{
@ -2019,9 +2037,9 @@ map_inferior_port_name (inferior_name, type)
* of the sequential number of such cprocs.
*/
private char buf[7];
static char buf[7];
private char *
static char *
get_thread_name (one_cproc, id)
cproc_t one_cproc;
int id;
@ -2362,7 +2380,7 @@ lookup_address_of_variable (name)
return symaddr;
}
private cproc_t
static cproc_t
get_cprocs()
{
cproc_t their_cprocs, cproc_head, cproc_copy;
@ -2816,7 +2834,7 @@ flush_inferior_icache(pc, amount)
#endif FLUSH_INFERIOR_CACHE
private
static
suspend_all_threads (from_tty)
int from_tty;
{
@ -3176,7 +3194,7 @@ task_suspend_command (args, from_tty)
mid, ta_info.suspend_count);
}
private char *
static char *
get_size (bytes)
int bytes;
{
@ -3271,7 +3289,7 @@ task_info_command (args, from_tty)
* exception mid [ forward | keep ]
*/
private void
static void
exception_command (args, from_tty)
char *args;
int from_tty;
@ -3320,7 +3338,7 @@ exception_command (args, from_tty)
error ("exception action is either \"keep\" or \"forward\"");
}
private void
static void
print_exception_info (exception)
int exception;
{
@ -3532,7 +3550,7 @@ struct cmd_list_element *cmd_thread_list;
struct cmd_list_element *cmd_task_list;
/*ARGSUSED*/
private void
static void
thread_command (arg, from_tty)
char *arg;
int from_tty;
@ -3542,7 +3560,7 @@ thread_command (arg, from_tty)
}
/*ARGSUSED*/
private void
static void
task_command (arg, from_tty)
char *arg;
int from_tty;
@ -3557,11 +3575,13 @@ add_mach_specific_commands ()
/* Thread handling commands */
add_prefix_cmd ("thread", class_stack, thread_command,
"Generic command for handling threads in the debugged task.",
/* FIXME: Move our thread support into the generic thread.c stuff so we
can share that code. */
add_prefix_cmd ("mthread", class_stack, thread_command,
"Generic command for handling Mach threads in the debugged task.",
&cmd_thread_list, "thread ", 0, &cmdlist);
add_com_alias ("th", "thread", class_stack, 1);
add_com_alias ("th", "mthread", class_stack, 1);
add_cmd ("select", class_stack, thread_select_command,
"Select and print MID of the selected thread",
@ -3583,8 +3603,8 @@ add_mach_specific_commands ()
If MID/@SLOT is omitted allow all threads to break at breakpoint",
&cmd_thread_list);
/* Thread command shorthands (for backward compatibility) */
add_alias_cmd ("ts", "thread select", 0, 0, &cmdlist);
add_alias_cmd ("tl", "thread list", 0, 0, &cmdlist);
add_alias_cmd ("ts", "mthread select", 0, 0, &cmdlist);
add_alias_cmd ("tl", "mthread list", 0, 0, &cmdlist);
/* task handling commands */
@ -3626,75 +3646,6 @@ the exception to some signal (see info exception)\n\
Normally \"keep\" is used to return to GDB on exception.");
}
void
_initialize_mach_os ()
{
kern_return_t ret;
ret = mach_port_allocate(mach_task_self(),
MACH_PORT_RIGHT_PORT_SET,
&inferior_wait_port_set);
if (ret != KERN_SUCCESS)
fatal("initial port set %s",mach_error_string(ret));
/* mach_really_wait now waits for this */
currently_waiting_for = inferior_wait_port_set;
ret = netname_look_up(name_server_port, hostname, "MachID", &mid_server);
if (ret != KERN_SUCCESS)
{
mid_server = MACH_PORT_NULL;
message ("initialize machid: netname_lookup_up(MachID) : %s",
mach_error_string(ret));
message ("Some (most?) features disabled...");
}
mid_auth = mach_privileged_host_port();
if (mid_auth == MACH_PORT_NULL)
mid_auth = mach_task_self();
obstack_init (port_chain_obstack);
ret = mach_port_allocate (mach_task_self (),
MACH_PORT_RIGHT_RECEIVE,
&thread_exception_port);
CHK ("Creating thread_exception_port for single stepping", ret);
ret = mach_port_insert_right (mach_task_self (),
thread_exception_port,
thread_exception_port,
MACH_MSG_TYPE_MAKE_SEND);
CHK ("Inserting send right to thread_exception_port", ret);
/* Allocate message port */
ret = mach_port_allocate (mach_task_self (),
MACH_PORT_RIGHT_RECEIVE,
&our_message_port);
if (ret != KERN_SUCCESS)
message ("Creating message port %s", mach_error_string (ret));
else
{
char buf[ MAX_NAME_LEN ];
ret = mach_port_move_member(mach_task_self (),
our_message_port,
inferior_wait_port_set);
if (ret != KERN_SUCCESS)
message ("message move member %s", mach_error_string (ret));
/* @@@@ No way to change message port name currently */
/* Foo. This assumes gdb has a unix pid */
sprintf (buf, "gdb-%d", getpid ());
gdb_register_port (buf, our_message_port);
}
/* Heap for thread commands */
obstack_init (cproc_obstack);
add_mach_specific_commands ();
}
kern_return_t
do_mach_notify_dead_name (notify, name)
mach_port_t notify;
@ -3806,7 +3757,7 @@ do_mach_notify_send_once (notify)
}
/* Kills the inferior. It's gone when you call this */
void
static void
kill_inferior_fast ()
{
WAITTYPE w;
@ -3831,13 +3782,44 @@ kill_inferior_fast ()
setup_notify_port (0);
}
void
kill_inferior ()
static void
m3_kill_inferior ()
{
kill_inferior_fast ();
target_mourn_inferior ();
}
/* Clean up after the inferior dies. */
static void
m3_mourn_inferior ()
{
unpush_target (&m3_ops);
generic_mourn_inferior ();
}
/* Fork an inferior process, and start debugging it. */
static void
m3_create_inferior (exec_file, allargs, env)
char *exec_file;
char *allargs;
char **env;
{
fork_inferior (exec_file, allargs, env, m3_trace_m3, m3_trace_him);
/* We are at the first instruction we care about. */
/* Pedal to the metal... */
proceed ((CORE_ADDR) -1, 0, 0);
}
/* Mark our target-struct as eligible for stray "run" and "attach"
commands. */
static int
m3_can_run ()
{
return 1;
}
/* Mach 3.0 does not need ptrace for anything
* Make sure nobody uses it on mach.
@ -3853,7 +3835,8 @@ int a,b,c,d;
If SIGNAL is nonzero, give it that signal. */
void
child_resume (step, signal)
m3_resume (pid, step, signal)
int pid;
int step;
int signal;
{
@ -3971,7 +3954,8 @@ mid_attach (mid)
* like "atta 0" or "atta foo" (equal to the previous :-) and
* "atta pidself". Anyway, the latter is allowed by specifying a MID.
*/
attach (pid)
static int
m3_do_attach (pid)
int pid;
{
kern_return_t ret;
@ -4004,6 +3988,42 @@ attach (pid)
return inferior_pid;
}
/* Attach to process PID, then initialize for debugging it
and wait for the trace-trap that results from attaching. */
static void
m3_attach (args, from_tty)
char *args;
int from_tty;
{
char *exec_file;
int pid;
if (!args)
error_no_arg ("process-id to attach");
pid = atoi (args);
if (pid == getpid()) /* Trying to masturbate? */
error ("I refuse to debug myself!");
if (from_tty)
{
exec_file = (char *) get_exec_file (0);
if (exec_file)
printf ("Attaching to program `%s', %s\n", exec_file, target_pid_to_str (pid));
else
printf ("Attaching to %s\n", target_pid_to_str (pid));
fflush (stdout);
}
m3_do_attach (pid);
inferior_pid = pid;
push_target (&procfs_ops);
}
void
deallocate_inferior_ports ()
{
@ -4060,8 +4080,8 @@ deallocate_inferior_ports ()
and continue it with signal number SIGNAL.
SIGNAL = 0 means just continue it. */
void
detach (signal)
static void
m3_do_detach (signal)
int signal;
{
kern_return_t ret;
@ -4099,6 +4119,38 @@ detach (signal)
attach_flag = 0;
}
/* Take a program previously attached to and detaches it.
The program resumes execution and will no longer stop
on signals, etc. We'd better not have left any breakpoints
in the program or it'll die when it hits one. For this
to work, it may be necessary for the process to have been
previously attached. It *might* work if the program was
started via fork. */
static void
m3_detach (args, from_tty)
char *args;
int from_tty;
{
int siggnal = 0;
if (from_tty)
{
char *exec_file = get_exec_file (0);
if (exec_file == 0)
exec_file = "";
printf ("Detaching from program: %s %s\n",
exec_file, target_pid_to_str (inferior_pid));
fflush (stdout);
}
if (args)
siggnal = atoi (args);
m3_do_detach (siggnal);
inferior_pid = 0;
unpush_target (&m3_ops); /* Pop out of handling an inferior */
}
#endif /* ATTACH_DETACH */
#ifdef DUMP_SYSCALL
@ -4316,3 +4368,119 @@ char *p;
puts_filtered("\n");
}
#endif DUMP_SYSCALL
struct target_ops m3_ops = {
"mach", /* to_shortname */
"Mach child process", /* to_longname */
"Mach child process (started by the \"run\" command).", /* to_doc */
??_open, /* to_open */
0, /* to_close */
m3_attach, /* to_attach */
m3_detach, /* to_detach */
m3_resume, /* to_resume */
mach_really_wait, /* to_wait */
fetch_inferior_registers, /* to_fetch_registers */
store_inferior_registers, /* to_store_registers */
child_prepare_to_store, /* to_prepare_to_store */
m3_xfer_memory, /* to_xfer_memory */
/* FIXME: Should print MID and all that crap. */
child_files_info, /* to_files_info */
memory_insert_breakpoint, /* to_insert_breakpoint */
memory_remove_breakpoint, /* to_remove_breakpoint */
terminal_init_inferior, /* to_terminal_init */
terminal_inferior, /* to_terminal_inferior */
terminal_ours_for_output, /* to_terminal_ours_for_output */
terminal_ours, /* to_terminal_ours */
child_terminal_info, /* to_terminal_info */
m3_kill_inferior, /* to_kill */
0, /* to_load */
0, /* to_lookup_symbol */
m3_create_inferior, /* to_create_inferior */
m3_mourn_inferior, /* to_mourn_inferior */
m3_can_run, /* to_can_run */
0, /* to_notice_signals */
process_stratum, /* to_stratum */
0, /* to_next */
1, /* to_has_all_memory */
1, /* to_has_memory */
1, /* to_has_stack */
1, /* to_has_registers */
1, /* to_has_execution */
0, /* sections */
0, /* sections_end */
OPS_MAGIC /* to_magic */
};
void
_initialize_m3_nat ()
{
kern_return_t ret;
add_target (&m3_ops);
ret = mach_port_allocate(mach_task_self(),
MACH_PORT_RIGHT_PORT_SET,
&inferior_wait_port_set);
if (ret != KERN_SUCCESS)
fatal("initial port set %s",mach_error_string(ret));
/* mach_really_wait now waits for this */
currently_waiting_for = inferior_wait_port_set;
ret = netname_look_up(name_server_port, hostname, "MachID", &mid_server);
if (ret != KERN_SUCCESS)
{
mid_server = MACH_PORT_NULL;
message ("initialize machid: netname_lookup_up(MachID) : %s",
mach_error_string(ret));
message ("Some (most?) features disabled...");
}
mid_auth = mach_privileged_host_port();
if (mid_auth == MACH_PORT_NULL)
mid_auth = mach_task_self();
obstack_init (port_chain_obstack);
ret = mach_port_allocate (mach_task_self (),
MACH_PORT_RIGHT_RECEIVE,
&thread_exception_port);
CHK ("Creating thread_exception_port for single stepping", ret);
ret = mach_port_insert_right (mach_task_self (),
thread_exception_port,
thread_exception_port,
MACH_MSG_TYPE_MAKE_SEND);
CHK ("Inserting send right to thread_exception_port", ret);
/* Allocate message port */
ret = mach_port_allocate (mach_task_self (),
MACH_PORT_RIGHT_RECEIVE,
&our_message_port);
if (ret != KERN_SUCCESS)
message ("Creating message port %s", mach_error_string (ret));
else
{
char buf[ MAX_NAME_LEN ];
ret = mach_port_move_member(mach_task_self (),
our_message_port,
inferior_wait_port_set);
if (ret != KERN_SUCCESS)
message ("message move member %s", mach_error_string (ret));
/* @@@@ No way to change message port name currently */
/* Foo. This assumes gdb has a unix pid */
sprintf (buf, "gdb-%d", getpid ());
gdb_register_port (buf, our_message_port);
}
/* Heap for thread commands */
obstack_init (cproc_obstack);
add_mach_specific_commands ();
}