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;
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)
{
}
static int
-start_inferior (char **argv, char *statusptr)
+start_inferior (char **argv)
{
char **new_argv = argv;
attached = 0;
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. */
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;
}
&& 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);
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;
}
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);
}
/* 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;
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;
/* 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
/* 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;
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
/* 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;
}
write_enn (own_buf);
return;
}
- handle_v_attach (own_buf, status, signal);
+ handle_v_attach (own_buf);
return;
}
write_enn (own_buf);
return;
}
- handle_v_run (own_buf, status, signal);
+ handle_v_run (own_buf);
return;
}
}
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);
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)
{
int
main (int argc, char *argv[])
{
- char ch, status, *own_buf;
+ char ch, *own_buf;
unsigned char *mem_buf;
int i = 0;
int signal;
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
}
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,
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;
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
{
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')
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);
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':
{
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;
}
/* 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;
}
}
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:
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;
}
}
- if (status != 'W' && status != 'X')
+ if (last_status.kind != TARGET_WAITKIND_EXITED
+ && last_status.kind != TARGET_WAITKIND_SIGNALLED)
was_running = 1;
}