+ switch (buf[0])
+ {
+ case 'T': /* Status with PC, SP, FP, ... */
+ {
+ gdb_byte regs[MAX_REGISTER_SIZE];
+
+ /* Expedited reply, containing Signal, {regno, reg} repeat. */
+ /* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where
+ ss = signal number
+ n... = register number
+ r... = register contents
+ */
+
+ p = &buf[3]; /* after Txx */
+ while (*p)
+ {
+ char *p1;
+ char *p_temp;
+ int fieldsize;
+ LONGEST pnum = 0;
+
+ /* If the packet contains a register number, save it in
+ pnum and set p1 to point to the character following it.
+ Otherwise p1 points to p. */
+
+ /* If this packet is an awatch packet, don't parse the 'a'
+ as a register number. */
+
+ if (strncmp (p, "awatch", strlen("awatch")) != 0)
+ {
+ /* Read the ``P'' register number. */
+ pnum = strtol (p, &p_temp, 16);
+ p1 = p_temp;
+ }
+ else
+ p1 = p;
+
+ if (p1 == p) /* No register number present here. */
+ {
+ p1 = strchr (p, ':');
+ if (p1 == NULL)
+ error (_("Malformed packet(a) (missing colon): %s\n\
+Packet: '%s'\n"),
+ p, buf);
+ if (strncmp (p, "thread", p1 - p) == 0)
+ event->ptid = read_ptid (++p1, &p);
+ else if ((strncmp (p, "watch", p1 - p) == 0)
+ || (strncmp (p, "rwatch", p1 - p) == 0)
+ || (strncmp (p, "awatch", p1 - p) == 0))
+ {
+ event->stopped_by_watchpoint_p = 1;
+ p = unpack_varlen_hex (++p1, &addr);
+ event->watch_data_address = (CORE_ADDR) addr;
+ }
+ else if (strncmp (p, "library", p1 - p) == 0)
+ {
+ p1++;
+ p_temp = p1;
+ while (*p_temp && *p_temp != ';')
+ p_temp++;
+
+ event->solibs_changed = 1;
+ p = p_temp;
+ }
+ else if (strncmp (p, "replaylog", p1 - p) == 0)
+ {
+ /* NO_HISTORY event.
+ p1 will indicate "begin" or "end", but
+ it makes no difference for now, so ignore it. */
+ event->replay_event = 1;
+ p_temp = strchr (p1 + 1, ';');
+ if (p_temp)
+ p = p_temp;
+ }
+ else
+ {
+ /* Silently skip unknown optional info. */
+ p_temp = strchr (p1 + 1, ';');
+ if (p_temp)
+ p = p_temp;
+ }
+ }
+ else
+ {
+ struct packet_reg *reg = packet_reg_from_pnum (rsa, pnum);
+ cached_reg_t cached_reg;
+
+ cached_reg.num = reg->regnum;
+
+ p = p1;
+
+ if (*p != ':')
+ error (_("Malformed packet(b) (missing colon): %s\n\
+Packet: '%s'\n"),
+ p, buf);
+ ++p;
+
+ if (reg == NULL)
+ error (_("Remote sent bad register number %s: %s\n\
+Packet: '%s'\n"),
+ phex_nz (pnum, 0), p, buf);
+
+ fieldsize = hex2bin (p, cached_reg.data,
+ register_size (target_gdbarch,
+ reg->regnum));
+ p += 2 * fieldsize;
+ if (fieldsize < register_size (target_gdbarch,
+ reg->regnum))
+ warning (_("Remote reply is too short: %s"), buf);
+
+ VEC_safe_push (cached_reg_t, event->regcache, &cached_reg);
+ }
+
+ if (*p != ';')
+ error (_("Remote register badly formatted: %s\nhere: %s"),
+ buf, p);
+ ++p;
+ }
+ }
+ /* fall through */
+ case 'S': /* Old style status, just signal only. */
+ if (event->solibs_changed)
+ event->ws.kind = TARGET_WAITKIND_LOADED;
+ else if (event->replay_event)
+ event->ws.kind = TARGET_WAITKIND_NO_HISTORY;
+ else
+ {
+ event->ws.kind = TARGET_WAITKIND_STOPPED;
+ event->ws.value.sig = (enum target_signal)
+ (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+ }
+ break;
+ case 'W': /* Target exited. */
+ case 'X':
+ {
+ char *p;
+ int pid;
+ ULONGEST value;
+
+ /* GDB used to accept only 2 hex chars here. Stubs should
+ only send more if they detect GDB supports multi-process
+ support. */
+ p = unpack_varlen_hex (&buf[1], &value);
+
+ if (buf[0] == 'W')
+ {
+ /* The remote process exited. */
+ event->ws.kind = TARGET_WAITKIND_EXITED;
+ event->ws.value.integer = value;
+ }
+ else
+ {
+ /* The remote process exited with a signal. */
+ event->ws.kind = TARGET_WAITKIND_SIGNALLED;
+ event->ws.value.sig = (enum target_signal) value;
+ }
+
+ /* If no process is specified, assume inferior_ptid. */
+ pid = ptid_get_pid (inferior_ptid);
+ if (*p == '\0')
+ ;
+ else if (*p == ';')
+ {
+ p++;
+
+ if (p == '\0')
+ ;
+ else if (strncmp (p,
+ "process:", sizeof ("process:") - 1) == 0)
+ {
+ ULONGEST upid;
+ p += sizeof ("process:") - 1;
+ unpack_varlen_hex (p, &upid);
+ pid = upid;
+ }
+ else
+ error (_("unknown stop reply packet: %s"), buf);
+ }
+ else
+ error (_("unknown stop reply packet: %s"), buf);
+ event->ptid = pid_to_ptid (pid);
+ }
+ break;
+ }
+
+ if (non_stop && ptid_equal (event->ptid, null_ptid))
+ error (_("No process or thread specified in stop reply: %s"), buf);
+}
+
+/* When the stub wants to tell GDB about a new stop reply, it sends a
+ stop notification (%Stop). Those can come it at any time, hence,
+ we have to make sure that any pending putpkt/getpkt sequence we're
+ making is finished, before querying the stub for more events with
+ vStopped. E.g., if we started a vStopped sequence immediatelly
+ upon receiving the %Stop notification, something like this could
+ happen:
+
+ 1.1) --> Hg 1
+ 1.2) <-- OK
+ 1.3) --> g
+ 1.4) <-- %Stop
+ 1.5) --> vStopped
+ 1.6) <-- (registers reply to step #1.3)
+
+ Obviously, the reply in step #1.6 would be unexpected to a vStopped
+ query.
+
+ To solve this, whenever we parse a %Stop notification sucessfully,
+ we mark the REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN, and carry on
+ doing whatever we were doing:
+
+ 2.1) --> Hg 1
+ 2.2) <-- OK
+ 2.3) --> g
+ 2.4) <-- %Stop
+ <GDB marks the REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN>
+ 2.5) <-- (registers reply to step #2.3)
+
+ Eventualy after step #2.5, we return to the event loop, which
+ notices there's an event on the
+ REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN event and calls the
+ associated callback --- the function below. At this point, we're
+ always safe to start a vStopped sequence. :
+
+ 2.6) --> vStopped
+ 2.7) <-- T05 thread:2
+ 2.8) --> vStopped
+ 2.9) --> OK
+*/
+
+static void
+remote_get_pending_stop_replies (void)
+{
+ struct remote_state *rs = get_remote_state ();
+ int ret;
+
+ if (pending_stop_reply)