Decouple target code from remote protocol.

* target.h (enum target_waitkind): New.
	(struct target_waitstatus): New.
	(struct target_ops) <wait>: Return an unsigned long.  Take a
	target_waitstatus pointer instead of a char pointer.
	(mywait): Likewise.
	* target.c (mywait): Change prototype to return an unsigned long.
	Take a target_waitstatus pointer instead of a char pointer.  Adjust.
	* server.h (thread_from_wait, old_thread_from_wait): Delete
	declarations.
	(prepare_resume_reply): Change prototype to take a
	target_waitstatus.
	* server.c (thread_from_wait, old_thread_from_wait): Delete.
	(last_status, last_ptid): New.
	(start_inferior): Remove "statusptr" argument.  Adjust.  Return a
	pid instead of a signal.
	(attach_inferior): Remove "status" and "signal" parameters.
	Adjust.
	(handle_query): For qGetTLSAddr, parse the thread id with strtol,
	not as an address.
	(handle_v_cont, handle_v_attach, handle_v_run, handle_v_kill)
	(handle_v_requests, myresume): Remove "status" and "signal"
	parameters.  Adjust.
	(handle_status): New.
	(main): Delete local `status'.  Adjust.
	* remote-utils.c: Include target.h.
	(prepare_resume_reply): Change prototype to take a
	target_waitstatus.  Adjust.

	* linux-low.c (linux_wait): Adjust to new target_ops->wait
	interface.
	* spu-low.c (spu_wait): Adjust.
	* win32-low.c (enum target_waitkind, struct target_waitstatus):
	Delete.
	(win32_wait): Adjust.
This commit is contained in:
Pedro Alves 2009-04-01 22:31:45 +00:00
parent 2bd7c093f6
commit 5b1c542ea1
9 changed files with 327 additions and 230 deletions

View File

@ -1,3 +1,42 @@
2009-04-01 Pedro Alves <pedro@codesourcery.com>
Decouple target code from remote protocol.
* target.h (enum target_waitkind): New.
(struct target_waitstatus): New.
(struct target_ops) <wait>: Return an unsigned long. Take a
target_waitstatus pointer instead of a char pointer.
(mywait): Likewise.
* target.c (mywait): Change prototype to return an unsigned long.
Take a target_waitstatus pointer instead of a char pointer. Adjust.
* server.h (thread_from_wait, old_thread_from_wait): Delete
declarations.
(prepare_resume_reply): Change prototype to take a
target_waitstatus.
* server.c (thread_from_wait, old_thread_from_wait): Delete.
(last_status, last_ptid): New.
(start_inferior): Remove "statusptr" argument. Adjust. Return a
pid instead of a signal.
(attach_inferior): Remove "status" and "signal" parameters.
Adjust.
(handle_query): For qGetTLSAddr, parse the thread id with strtol,
not as an address.
(handle_v_cont, handle_v_attach, handle_v_run, handle_v_kill)
(handle_v_requests, myresume): Remove "status" and "signal"
parameters. Adjust.
(handle_status): New.
(main): Delete local `status'. Adjust.
* remote-utils.c: Include target.h.
(prepare_resume_reply): Change prototype to take a
target_waitstatus. Adjust.
* linux-low.c (linux_wait): Adjust to new target_ops->wait
interface.
* spu-low.c (spu_wait): Adjust.
* win32-low.c (enum target_waitkind, struct target_waitstatus):
Delete.
(win32_wait): Adjust.
2009-04-01 Pedro Alves <pedro@codesourcery.com>
* target.h (struct thread_resume): Delete leave_stopped member.

View File

@ -929,11 +929,12 @@ linux_wait_for_event (struct thread_info *child)
/* Wait for process, returns status. */
static unsigned char
linux_wait (char *status)
static unsigned long
linux_wait (struct target_waitstatus *ourstatus)
{
int w;
struct thread_info *child = NULL;
struct lwp_info *lwp;
retry:
/* If we were only supposed to resume one thread, only wait for
@ -966,6 +967,8 @@ retry:
must_set_ptrace_flags = 0;
}
lwp = get_thread_lwp (current_inferior);
/* If we are waiting for a particular child, and it exited,
linux_wait_for_event will return its exit status. Similarly if
the last child exited. If this is not the last child, however,
@ -980,25 +983,34 @@ retry:
if (all_threads.head == all_threads.tail)
{
int pid = pid_of (lwp);
if (WIFEXITED (w))
{
fprintf (stderr, "\nChild exited with retcode = %x \n",
WEXITSTATUS (w));
*status = 'W';
if (debug_threads)
fprintf (stderr, "\nChild exited with retcode = %x \n",
WEXITSTATUS (w));
ourstatus->kind = TARGET_WAITKIND_EXITED;
ourstatus->value.integer = WEXITSTATUS (w);
clear_inferiors ();
free (all_lwps.head);
all_lwps.head = all_lwps.tail = NULL;
return WEXITSTATUS (w);
return pid;
}
else if (!WIFSTOPPED (w))
{
fprintf (stderr, "\nChild terminated with signal = %x \n",
WTERMSIG (w));
*status = 'X';
if (debug_threads)
fprintf (stderr, "\nChild terminated with signal = %x \n",
WTERMSIG (w));
ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
ourstatus->value.sig = target_signal_from_host (WTERMSIG (w));
clear_inferiors ();
free (all_lwps.head);
all_lwps.head = all_lwps.tail = NULL;
return target_signal_from_host (WTERMSIG (w));
return pid;
}
}
else
@ -1007,8 +1019,10 @@ retry:
goto retry;
}
*status = 'T';
return target_signal_from_host (WSTOPSIG (w));
ourstatus->kind = TARGET_WAITKIND_STOPPED;
ourstatus->value.sig = target_signal_from_host (WSTOPSIG (w));
return lwp->lwpid;
}
/* Send a signal to an LWP. For LinuxThreads, kill is enough; however, if

View File

@ -20,6 +20,7 @@
#include "server.h"
#include "terminal.h"
#include "target.h"
#include <stdio.h>
#include <string.h>
#if HAVE_SYS_IOCTL_H
@ -933,88 +934,98 @@ dead_thread_notify (int id)
}
void
prepare_resume_reply (char *buf, char status, unsigned char sig)
prepare_resume_reply (char *buf, unsigned long ptid,
struct target_waitstatus *status)
{
int nib;
if (debug_threads)
fprintf (stderr, "Writing resume reply for %lu:%d\n\n",
ptid, status->kind);
*buf++ = status;
nib = ((sig & 0xf0) >> 4);
*buf++ = tohex (nib);
nib = sig & 0x0f;
*buf++ = tohex (nib);
if (status == 'T')
switch (status->kind)
{
const char **regp = gdbserver_expedite_regs;
case TARGET_WAITKIND_STOPPED:
{
struct thread_info *saved_inferior;
const char **regp;
if (the_target->stopped_by_watchpoint != NULL
&& (*the_target->stopped_by_watchpoint) ())
{
CORE_ADDR addr;
int i;
sprintf (buf, "T%02x", status->value.sig);
buf += strlen (buf);
strncpy (buf, "watch:", 6);
buf += 6;
regp = gdbserver_expedite_regs;
addr = (*the_target->stopped_data_address) ();
saved_inferior = current_inferior;
/* Convert each byte of the address into two hexadecimal chars.
Note that we take sizeof (void *) instead of sizeof (addr);
this is to avoid sending a 64-bit address to a 32-bit GDB. */
for (i = sizeof (void *) * 2; i > 0; i--)
{
current_inferior = gdb_id_to_thread (ptid);
if (the_target->stopped_by_watchpoint != NULL
&& (*the_target->stopped_by_watchpoint) ())
{
CORE_ADDR addr;
int i;
strncpy (buf, "watch:", 6);
buf += 6;
addr = (*the_target->stopped_data_address) ();
/* Convert each byte of the address into two hexadecimal
chars. Note that we take sizeof (void *) instead of
sizeof (addr); this is to avoid sending a 64-bit
address to a 32-bit GDB. */
for (i = sizeof (void *) * 2; i > 0; i--)
*buf++ = tohex ((addr >> (i - 1) * 4) & 0xf);
}
*buf++ = ';';
}
*buf++ = ';';
}
while (*regp)
{
buf = outreg (find_regno (*regp), buf);
regp ++;
}
while (*regp)
{
buf = outreg (find_regno (*regp), buf);
regp ++;
}
/* Formerly, if the debugger had not used any thread features we would not
burden it with a thread status response. This was for the benefit of
GDB 4.13 and older. However, in recent GDB versions the check
(``if (cont_thread != 0)'') does not have the desired effect because of
sillyness in the way that the remote protocol handles specifying a thread.
Since thread support relies on qSymbol support anyway, assume GDB can handle
threads. */
/* Formerly, if the debugger had not used any thread features
we would not burden it with a thread status response. This
was for the benefit of GDB 4.13 and older. However, in
recent GDB versions the check (``if (cont_thread != 0)'')
does not have the desired effect because of sillyness in
the way that the remote protocol handles specifying a
thread. Since thread support relies on qSymbol support
anyway, assume GDB can handle threads. */
if (using_threads && !disable_packet_Tthread)
{
unsigned int gdb_id_from_wait;
if (using_threads && !disable_packet_Tthread)
{
/* This if (1) ought to be unnecessary. But remote_wait
in GDB will claim this event belongs to inferior_ptid
if we do not specify a thread, and there's no way for
gdbserver to know what inferior_ptid is. */
if (1 || general_thread != ptid)
{
general_thread = ptid;
sprintf (buf, "thread:%lx;", ptid);
buf += strlen (buf);
}
}
/* FIXME right place to set this? */
thread_from_wait = ((struct inferior_list_entry *)current_inferior)->id;
gdb_id_from_wait = thread_to_gdb_id (current_inferior);
if (dlls_changed)
{
strcpy (buf, "library:;");
buf += strlen (buf);
dlls_changed = 0;
}
if (debug_threads)
fprintf (stderr, "Writing resume reply for %ld\n\n", thread_from_wait);
/* This if (1) ought to be unnecessary. But remote_wait in GDB
will claim this event belongs to inferior_ptid if we do not
specify a thread, and there's no way for gdbserver to know
what inferior_ptid is. */
if (1 || old_thread_from_wait != thread_from_wait)
{
general_thread = thread_from_wait;
sprintf (buf, "thread:%x;", gdb_id_from_wait);
buf += strlen (buf);
old_thread_from_wait = thread_from_wait;
}
}
if (dlls_changed)
{
strcpy (buf, "library:;");
buf += strlen (buf);
dlls_changed = 0;
}
current_inferior = saved_inferior;
}
break;
case TARGET_WAITKIND_EXITED:
sprintf (buf, "W%02x", status->value.integer);
break;
case TARGET_WAITKIND_SIGNALLED:
sprintf (buf, "X%02x", status->value.sig);
break;
default:
error ("unhandled waitkind");
break;
}
/* For W and X, we're done. */
*buf++ = 0;
}
void

View File

@ -35,8 +35,7 @@
unsigned long cont_thread;
unsigned long general_thread;
unsigned long step_thread;
unsigned long thread_from_wait;
unsigned long old_thread_from_wait;
int server_waiting;
static int extended_protocol;
@ -87,6 +86,10 @@ int disable_packet_Tthread;
int disable_packet_qC;
int disable_packet_qfThreadInfo;
/* Last status reported to GDB. */
static struct target_waitstatus last_status;
static unsigned long last_ptid;
static int
target_running (void)
{
@ -94,7 +97,7 @@ target_running (void)
}
static int
start_inferior (char **argv, char *statusptr)
start_inferior (char **argv)
{
char **new_argv = argv;
attached = 0;
@ -141,36 +144,38 @@ start_inferior (char **argv, char *statusptr)
if (wrapper_argv != NULL)
{
struct thread_resume resume_info;
int sig;
unsigned long ptid;
resume_info.thread = -1;
resume_info.step = 0;
resume_info.sig = 0;
sig = mywait (statusptr, 0);
if (*statusptr != 'T')
return sig;
ptid = mywait (&last_status, 0);
if (last_status.kind != TARGET_WAITKIND_STOPPED)
return signal_pid;
do
{
(*the_target->resume) (&resume_info, 1);
sig = mywait (statusptr, 0);
if (*statusptr != 'T')
return sig;
mywait (&last_status, 0);
if (last_status.kind != TARGET_WAITKIND_STOPPED)
return signal_pid;
}
while (sig != TARGET_SIGNAL_TRAP);
while (last_status.value.sig != TARGET_SIGNAL_TRAP);
return sig;
return signal_pid;
}
/* Wait till we are at 1st instruction in program, return signal
number (assuming success). */
return mywait (statusptr, 0);
/* Wait till we are at 1st instruction in program, return new pid
(assuming success). */
last_ptid = mywait (&last_status, 0);
return signal_pid;
}
static int
attach_inferior (int pid, char *statusptr, int *sigptr)
attach_inferior (int pid)
{
/* myattach should return -1 if attaching is unsupported,
0 if it succeeded, and call error() otherwise. */
@ -188,13 +193,14 @@ attach_inferior (int pid, char *statusptr, int *sigptr)
whichever we were told to attach to. */
signal_pid = pid;
*sigptr = mywait (statusptr, 0);
last_ptid = mywait (&last_status, 0);
/* GDB knows to ignore the first SIGSTOP after attaching to a running
process using the "attach" command, but this is different; it's
just using "target remote". Pretend it's just starting up. */
if (*statusptr == 'T' && *sigptr == TARGET_SIGNAL_STOP)
*sigptr = TARGET_SIGNAL_TRAP;
if (last_status.kind == TARGET_WAITKIND_STOPPED
&& last_status.value.sig == TARGET_SIGNAL_STOP)
last_status.value.sig = TARGET_SIGNAL_TRAP;
return 0;
}
@ -917,8 +923,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
&& strncmp ("qGetTLSAddr:", own_buf, 12) == 0)
{
char *p = own_buf + 12;
CORE_ADDR parts[3], address = 0;
CORE_ADDR parts[2], address = 0;
int i, err;
unsigned long ptid;
require_running (own_buf);
@ -942,7 +949,10 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
p2 = NULL;
}
decode_address (&parts[i], p, len);
if (i == 0)
ptid = strtoul (p, NULL, 16);
else
decode_address (&parts[i - 1], p, len);
p = p2;
}
@ -950,12 +960,12 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
err = 1;
else
{
struct thread_info *thread = gdb_id_to_thread (parts[0]);
struct thread_info *thread = gdb_id_to_thread (ptid);
if (thread == NULL)
err = 2;
else
err = the_target->get_tls_address (thread, parts[1], parts[2],
err = the_target->get_tls_address (thread, parts[0], parts[1],
&address);
}
@ -1051,7 +1061,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
/* Parse vCont packets. */
void
handle_v_cont (char *own_buf, char *status, int *signal)
handle_v_cont (char *own_buf)
{
char *p, *q;
int n = 0, i = 0;
@ -1146,8 +1156,8 @@ handle_v_cont (char *own_buf, char *status, int *signal)
free (resume_info);
*signal = mywait (status, 1);
prepare_resume_reply (own_buf, *status, *signal);
last_ptid = mywait (&last_status, 1);
prepare_resume_reply (own_buf, last_ptid, &last_status);
disable_async_io ();
return;
@ -1159,19 +1169,19 @@ err:
/* Attach to a new program. Return 1 if successful, 0 if failure. */
int
handle_v_attach (char *own_buf, char *status, int *signal)
handle_v_attach (char *own_buf)
{
int pid;
pid = strtol (own_buf + 8, NULL, 16);
if (pid != 0 && attach_inferior (pid, status, signal) == 0)
if (pid != 0 && attach_inferior (pid) == 0)
{
/* Don't report shared library events after attaching, even if
some libraries are preloaded. GDB will always poll the
library list. Avoids the "stopped by shared library event"
notice on the GDB side. */
dlls_changed = 0;
prepare_resume_reply (own_buf, *status, *signal);
prepare_resume_reply (own_buf, last_ptid, &last_status);
return 1;
}
else
@ -1183,7 +1193,7 @@ handle_v_attach (char *own_buf, char *status, int *signal)
/* Run a new program. Return 1 if successful, 0 if failure. */
static int
handle_v_run (char *own_buf, char *status, int *signal)
handle_v_run (char *own_buf)
{
char *p, *next_p, **new_argv;
int i, new_argc;
@ -1250,10 +1260,10 @@ handle_v_run (char *own_buf, char *status, int *signal)
freeargv (program_argv);
program_argv = new_argv;
*signal = start_inferior (program_argv, status);
if (*status == 'T')
start_inferior (program_argv);
if (last_status.kind == TARGET_WAITKIND_STOPPED)
{
prepare_resume_reply (own_buf, *status, *signal);
prepare_resume_reply (own_buf, last_ptid, &last_status);
return 1;
}
else
@ -1265,15 +1275,14 @@ handle_v_run (char *own_buf, char *status, int *signal)
/* Handle all of the extended 'v' packets. */
void
handle_v_requests (char *own_buf, char *status, int *signal,
int packet_len, int *new_packet_len)
handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
{
if (!disable_packet_vCont)
{
if (strncmp (own_buf, "vCont;", 6) == 0)
{
require_running (own_buf);
handle_v_cont (own_buf, status, signal);
handle_v_cont (own_buf);
return;
}
@ -1296,7 +1305,7 @@ handle_v_requests (char *own_buf, char *status, int *signal,
write_enn (own_buf);
return;
}
handle_v_attach (own_buf, status, signal);
handle_v_attach (own_buf);
return;
}
@ -1308,7 +1317,7 @@ handle_v_requests (char *own_buf, char *status, int *signal,
write_enn (own_buf);
return;
}
handle_v_run (own_buf, status, signal);
handle_v_run (own_buf);
return;
}
@ -1319,11 +1328,10 @@ handle_v_requests (char *own_buf, char *status, int *signal,
}
void
myresume (char *own_buf, int step, int *signalp, char *statusp)
myresume (char *own_buf, int step, int sig)
{
struct thread_resume resume_info[2];
int n = 0;
int sig = *signalp;
int valid_cont_thread;
set_desired_inferior (0);
@ -1349,11 +1357,23 @@ myresume (char *own_buf, int step, int *signalp, char *statusp)
enable_async_io ();
(*the_target->resume) (resume_info, n);
*signalp = mywait (statusp, 1);
prepare_resume_reply (own_buf, *statusp, *signalp);
last_ptid = mywait (&last_status, 1);
prepare_resume_reply (own_buf, last_ptid, &last_status);
disable_async_io ();
}
/* Status handler for the '?' packet. */
static void
handle_status (char *own_buf)
{
if (all_threads.head)
prepare_resume_reply (own_buf,
all_threads.head->id, &last_status);
else
strcpy (own_buf, "W00");
}
static void
gdbserver_version (void)
{
@ -1406,7 +1426,7 @@ gdbserver_show_disableable (FILE *stream)
int
main (int argc, char *argv[])
{
char ch, status, *own_buf;
char ch, *own_buf;
unsigned char *mem_buf;
int i = 0;
int signal;
@ -1563,7 +1583,7 @@ main (int argc, char *argv[])
program_argv[i] = NULL;
/* Wait till we are at first instruction in program. */
signal = start_inferior (program_argv, &status);
start_inferior (program_argv);
/* We are now (hopefully) stopped at the first instruction of
the target process. This assumes that the target process was
@ -1571,15 +1591,16 @@ main (int argc, char *argv[])
}
else if (pid != 0)
{
if (attach_inferior (pid, &status, &signal) == -1)
if (attach_inferior (pid) == -1)
error ("Attaching not supported on this target");
/* Otherwise succeeded. */
}
else
{
status = 'W';
signal = 0;
last_status.kind = TARGET_WAITKIND_EXITED;
last_status.value.integer = 0;
last_ptid = -1;
}
/* Don't report shared library events on the initial connection,
@ -1594,7 +1615,8 @@ main (int argc, char *argv[])
exit (1);
}
if (status == 'W' || status == 'X')
if (last_status.kind == TARGET_WAITKIND_EXITED
|| last_status.kind == TARGET_WAITKIND_SIGNALLED)
was_running = 0;
else
was_running = 1;
@ -1656,8 +1678,9 @@ main (int argc, char *argv[])
if (extended_protocol)
{
/* Treat this like a normal program exit. */
signal = 0;
status = 'W';
last_status.kind = TARGET_WAITKIND_EXITED;
last_status.value.integer = 0;
last_ptid = signal_pid;
}
else
{
@ -1679,7 +1702,7 @@ main (int argc, char *argv[])
write_ok (own_buf);
break;
case '?':
prepare_resume_reply (own_buf, status, signal);
handle_status (own_buf);
break;
case 'H':
if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's')
@ -1762,7 +1785,7 @@ main (int argc, char *argv[])
signal = target_signal_to_host (sig);
else
signal = 0;
myresume (own_buf, 0, &signal, &status);
myresume (own_buf, 0, signal);
break;
case 'S':
require_running (own_buf);
@ -1771,17 +1794,17 @@ main (int argc, char *argv[])
signal = target_signal_to_host (sig);
else
signal = 0;
myresume (own_buf, 1, &signal, &status);
myresume (own_buf, 1, signal);
break;
case 'c':
require_running (own_buf);
signal = 0;
myresume (own_buf, 0, &signal, &status);
myresume (own_buf, 0, signal);
break;
case 's':
require_running (own_buf);
signal = 0;
myresume (own_buf, 1, &signal, &status);
myresume (own_buf, 1, signal);
break;
case 'Z':
{
@ -1860,8 +1883,8 @@ main (int argc, char *argv[])
instead. */
if (extended_protocol)
{
status = 'X';
signal = TARGET_SIGNAL_KILL;
last_status.kind = TARGET_WAITKIND_EXITED;
last_status.value.sig = TARGET_SIGNAL_KILL;
was_running = 0;
goto restart;
}
@ -1902,11 +1925,11 @@ main (int argc, char *argv[])
/* Wait till we are at 1st instruction in prog. */
if (program_argv != NULL)
signal = start_inferior (program_argv, &status);
start_inferior (program_argv);
else
{
status = 'X';
signal = TARGET_SIGNAL_KILL;
last_status.kind = TARGET_WAITKIND_EXITED;
last_status.value.sig = TARGET_SIGNAL_KILL;
}
goto restart;
}
@ -1920,8 +1943,7 @@ main (int argc, char *argv[])
}
case 'v':
/* Extended (long) request. */
handle_v_requests (own_buf, &status, &signal,
packet_len, &new_packet_len);
handle_v_requests (own_buf, packet_len, &new_packet_len);
break;
default:
@ -1939,17 +1961,20 @@ main (int argc, char *argv[])
response_needed = 0;
if (was_running && (status == 'W' || status == 'X'))
if (was_running
&& (last_status.kind == TARGET_WAITKIND_EXITED
|| last_status.kind == TARGET_WAITKIND_SIGNALLED))
{
was_running = 0;
if (status == 'W')
if (last_status.kind == TARGET_WAITKIND_EXITED)
fprintf (stderr,
"\nChild exited with status %d\n", signal);
if (status == 'X')
"\nChild exited with status %d\n",
last_status.value.integer);
else if (last_status.kind == TARGET_WAITKIND_SIGNALLED)
fprintf (stderr, "\nChild terminated with signal = 0x%x (%s)\n",
target_signal_to_host (signal),
target_signal_to_name (signal));
target_signal_to_host (last_status.value.sig),
target_signal_to_name (last_status.value.sig));
if (extended_protocol)
goto restart;
@ -1961,7 +1986,8 @@ main (int argc, char *argv[])
}
}
if (status != 'W' && status != 'X')
if (last_status.kind != TARGET_WAITKIND_EXITED
&& last_status.kind != TARGET_WAITKIND_SIGNALLED)
was_running = 1;
}

View File

@ -160,8 +160,7 @@ void unloaded_dll (const char *name, CORE_ADDR base_addr);
extern unsigned long cont_thread;
extern unsigned long general_thread;
extern unsigned long step_thread;
extern unsigned long thread_from_wait;
extern unsigned long old_thread_from_wait;
extern int server_waiting;
extern int debug_threads;
extern int pass_signals[];
@ -201,7 +200,8 @@ void convert_ascii_to_int (char *from, unsigned char *to, int n);
void convert_int_to_ascii (unsigned char *from, char *to, int n);
void new_thread_notify (int id);
void dead_thread_notify (int id);
void prepare_resume_reply (char *buf, char status, unsigned char sig);
void prepare_resume_reply (char *buf, unsigned long thread_id,
struct target_waitstatus *status);
const char *decode_address_to_semicolon (CORE_ADDR *addrp, const char *start);
void decode_address (CORE_ADDR *addrp, const char *start, int len);

View File

@ -371,8 +371,8 @@ spu_resume (struct thread_resume *resume_info, size_t n)
}
/* Wait for process, returns status. */
static unsigned char
spu_wait (char *status)
static unsigned long
spu_wait (struct target_waitstatus *ourstatus)
{
int tid = current_tid;
int w;
@ -407,31 +407,37 @@ spu_wait (char *status)
}
}
ret = current_tid;
if (WIFEXITED (w))
{
fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
*status = 'W';
ourstatus->kind = TARGET_WAITKIND_EXITED;
ourstatus->value.integer = WEXITSTATUS (w);
clear_inferiors ();
return ((unsigned char) WEXITSTATUS (w));
return ret;
}
else if (!WIFSTOPPED (w))
{
fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
*status = 'X';
ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
ourstatus->value.sig = target_signal_from_host (WTERMSIG (w));
clear_inferiors ();
return ((unsigned char) WTERMSIG (w));
return ret;
}
/* After attach, we may have received a SIGSTOP. Do not return this
as signal to GDB, or else it will try to continue with SIGSTOP ... */
if (!server_waiting)
{
*status = 'T';
return 0;
ourstatus->kind = TARGET_WAITKIND_STOPPED;
ourstatus->value.sig = TARGET_SIGNAL_0;
return ret;
}
*status = 'T';
return ((unsigned char) WSTOPSIG (w));
ourstatus->kind = TARGET_WAITKIND_STOPPED;
ourstatus->value.sig = target_signal_from_host (WSTOPSIG (w));
return ret;
}
/* Fetch inferior registers. */

View File

@ -88,15 +88,15 @@ write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
return res;
}
unsigned char
mywait (char *statusp, int connected_wait)
unsigned long
mywait (struct target_waitstatus *ourstatus, int connected_wait)
{
unsigned char ret;
unsigned long ret;
if (connected_wait)
server_waiting = 1;
ret = (*the_target->wait) (statusp);
ret = (*the_target->wait) (ourstatus);
if (connected_wait)
server_waiting = 0;

View File

@ -38,6 +38,53 @@ struct thread_resume
int sig;
};
/* Generally, what has the program done? */
enum target_waitkind
{
/* The program has exited. The exit status is in
value.integer. */
TARGET_WAITKIND_EXITED,
/* The program has stopped with a signal. Which signal is in
value.sig. */
TARGET_WAITKIND_STOPPED,
/* The program has terminated with a signal. Which signal is in
value.sig. */
TARGET_WAITKIND_SIGNALLED,
/* The program is letting us know that it dynamically loaded
something. */
TARGET_WAITKIND_LOADED,
/* The program has exec'ed a new executable file. The new file's
pathname is pointed to by value.execd_pathname. */
TARGET_WAITKIND_EXECD,
/* Nothing of interest to GDB happened, but we stopped anyway. */
TARGET_WAITKIND_SPURIOUS,
/* An event has occurred, but we should wait again. In this case,
we want to go back to the event loop and wait there for another
event from the inferior. */
TARGET_WAITKIND_IGNORE
};
struct target_waitstatus
{
enum target_waitkind kind;
/* Forked child pid, execd pathname, exit status or signal number. */
union
{
int integer;
enum target_signal sig;
unsigned long related_pid;
char *execd_pathname;
}
value;
};
struct target_ops
{
/* Start a new process.
@ -82,15 +129,10 @@ struct target_ops
void (*resume) (struct thread_resume *resume_info, size_t n);
/* Wait for the inferior process to change state.
/* Wait for the inferior process or thread to change state. Store
status through argument pointer STATUS. */
STATUS will be filled in with a response code to send to GDB.
Returns the signal which caused the process to stop, in the
remote protocol numbering (e.g. TARGET_SIGNAL_STOP), or the
exit code as an integer if *STATUS is 'W'. */
unsigned char (*wait) (char *status);
unsigned long (*wait) (struct target_waitstatus *status);
/* Fetch registers from the inferior process.
@ -225,7 +267,7 @@ void set_target_ops (struct target_ops *);
#define join_inferior() \
(*the_target->join) ()
unsigned char mywait (char *statusp, int connected_wait);
unsigned long mywait (struct target_waitstatus *ourstatus, int connected_wait);
int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len);

View File

@ -241,45 +241,6 @@ child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
return done;
}
/* Generally, what has the program done? */
enum target_waitkind
{
/* The program has exited. The exit status is in value.integer. */
TARGET_WAITKIND_EXITED,
/* The program has stopped with a signal. Which signal is in
value.sig. */
TARGET_WAITKIND_STOPPED,
/* The program is letting us know that it dynamically loaded
or unloaded something. */
TARGET_WAITKIND_LOADED,
/* The program has exec'ed a new executable file. The new file's
pathname is pointed to by value.execd_pathname. */
TARGET_WAITKIND_EXECD,
/* Nothing interesting happened, but we stopped anyway. We take the
chance to check if GDB requested an interrupt. */
TARGET_WAITKIND_SPURIOUS,
};
struct target_waitstatus
{
enum target_waitkind kind;
/* Forked child pid, execd pathname, exit status or signal number. */
union
{
int integer;
enum target_signal sig;
int related_pid;
char *execd_pathname;
int syscall_id;
}
value;
};
/* Clear out any old thread list and reinitialize it to a pristine
state. */
static void
@ -1514,37 +1475,30 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
/* Wait for the inferior process to change state.
STATUS will be filled in with a response code to send to GDB.
Returns the signal which caused the process to stop. */
static unsigned char
win32_wait (char *status)
static unsigned long
win32_wait (struct target_waitstatus *ourstatus)
{
struct target_waitstatus our_status;
*status = 'T';
while (1)
{
if (!get_child_debug_event (&our_status))
if (!get_child_debug_event (ourstatus))
continue;
switch (our_status.kind)
switch (ourstatus->kind)
{
case TARGET_WAITKIND_EXITED:
OUTMSG2 (("Child exited with retcode = %x\n",
our_status.value.integer));
ourstatus->value.integer));
*status = 'W';
win32_clear_inferiors ();
return our_status.value.integer;
return current_event.dwProcessId;
case TARGET_WAITKIND_STOPPED:
case TARGET_WAITKIND_LOADED:
OUTMSG2 (("Child Stopped with signal = %d \n",
our_status.value.sig));
*status = 'T';
child_fetch_inferior_registers (-1);
if (our_status.kind == TARGET_WAITKIND_LOADED
if (ourstatus->kind == TARGET_WAITKIND_LOADED
&& !server_waiting)
{
/* When gdb connects, we want to be stopped at the
@ -1553,9 +1507,14 @@ win32_wait (char *status)
break;
}
return our_status.value.sig;
/* We don't expose _LOADED events to gdbserver core. See
the `dlls_changed' global. */
if (ourstatus->kind == TARGET_WAITKIND_LOADED)
ourstatus->kind = TARGET_WAITKIND_STOPPED;
return current_event.dwThreadId;
default:
OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind));
OUTMSG (("Ignoring unknown internal event, %d\n", ourstatus->kind));
/* fall-through */
case TARGET_WAITKIND_SPURIOUS:
case TARGET_WAITKIND_EXECD: