Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / debug_stub / target.cc
1 /*
2  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7 #include <string.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10
11 #include <algorithm>
12
13 #include "native_client/src/include/nacl_scoped_ptr.h"
14 #include "native_client/src/shared/platform/nacl_check.h"
15 #include "native_client/src/shared/platform/nacl_exit.h"
16 #include "native_client/src/shared/platform/nacl_log.h"
17 #include "native_client/src/trusted/debug_stub/abi.h"
18 #include "native_client/src/trusted/debug_stub/packet.h"
19 #include "native_client/src/trusted/debug_stub/platform.h"
20 #include "native_client/src/trusted/debug_stub/session.h"
21 #include "native_client/src/trusted/debug_stub/target.h"
22 #include "native_client/src/trusted/debug_stub/thread.h"
23 #include "native_client/src/trusted/debug_stub/util.h"
24 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
25 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
26 #include "native_client/src/trusted/service_runtime/thread_suspension.h"
27
28 #if NACL_WINDOWS
29 #define snprintf sprintf_s
30 #endif
31
32 using std::string;
33
34 using port::IPlatform;
35 using port::IThread;
36 using port::MutexLock;
37
38 namespace gdb_rsp {
39
40
41 Target::Target(struct NaClApp *nap, const Abi* abi)
42   : nap_(nap),
43     abi_(abi),
44     session_(NULL),
45     initial_breakpoint_addr_(0),
46     ctx_(NULL),
47     cur_signal_(0),
48     sig_thread_(0),
49     reg_thread_(0),
50     step_over_breakpoint_thread_(0),
51     all_threads_suspended_(false),
52     detaching_(false),
53     should_exit_(false) {
54   if (NULL == abi_) abi_ = Abi::Get();
55 }
56
57 Target::~Target() {
58   Destroy();
59 }
60
61 bool Target::Init() {
62   string targ_xml = "l<target><architecture>";
63
64   targ_xml += abi_->GetName();
65   targ_xml += "</architecture><osabi>NaCl</osabi>";
66   targ_xml += abi_->GetTargetXml();
67   targ_xml += "</target>";
68
69   // Set a more specific result which won't change.
70   properties_["target.xml"] = targ_xml;
71   properties_["Supported"] =
72     "PacketSize=1000;qXfer:features:read+";
73
74   NaClXMutexCtor(&mutex_);
75   ctx_ = new uint8_t[abi_->GetContextSize()];
76
77   initial_breakpoint_addr_ = (uint32_t) nap_->initial_entry_pt;
78   if (!AddBreakpoint(initial_breakpoint_addr_))
79     return false;
80   return true;
81 }
82
83 void Target::Destroy() {
84   NaClMutexDtor(&mutex_);
85
86   delete[] ctx_;
87 }
88
89 bool Target::AddBreakpoint(uint32_t user_address) {
90   const Abi::BPDef *bp = abi_->GetBreakpointDef();
91
92   // If we already have a breakpoint here then don't add it
93   if (breakpoint_map_.find(user_address) != breakpoint_map_.end())
94     return false;
95
96   uintptr_t sysaddr = NaClUserToSysAddrRange(nap_, user_address, bp->size_);
97   if (sysaddr == kNaClBadAddress)
98     return false;
99   // We allow setting breakpoints in the code area but not the data area.
100   if (user_address + bp->size_ > nap_->dynamic_text_end)
101     return false;
102
103   // We add the breakpoint by overwriting the start of an instruction
104   // with a breakpoint instruction.  (At least, we assume that we have
105   // been given the address of the start of an instruction.)  In order
106   // to be able to remove the breakpoint later, we save a copy of the
107   // locations we are overwriting into breakpoint_map_.
108   uint8_t *data = new uint8_t[bp->size_];
109
110   // Copy the old code from here
111   if (!IPlatform::GetMemory(sysaddr, bp->size_, data)) {
112     delete[] data;
113     return false;
114   }
115   if (!IPlatform::SetMemory(nap_, sysaddr, bp->size_, bp->code_)) {
116     delete[] data;
117     return false;
118   }
119
120   breakpoint_map_[user_address] = data;
121   return true;
122 }
123
124 bool Target::RemoveBreakpoint(uint32_t user_address) {
125   const Abi::BPDef *bp_def = abi_->GetBreakpointDef();
126
127   BreakpointMap_t::iterator iter = breakpoint_map_.find(user_address);
128   if (iter == breakpoint_map_.end())
129     return false;
130
131   uintptr_t sysaddr = NaClUserToSys(nap_, user_address);
132   uint8_t *data = iter->second;
133   // Copy back the old code, and free the data
134   if (!IPlatform::SetMemory(nap_, sysaddr, bp_def->size_, data)) {
135     NaClLog(LOG_ERROR, "Failed to undo breakpoint.\n");
136     return false;
137   }
138   delete[] data;
139   breakpoint_map_.erase(iter);
140   return true;
141 }
142
143 void Target::CopyFaultSignalFromAppThread(IThread *thread) {
144   if (thread->GetFaultSignal() == 0 && thread->HasThreadFaulted()) {
145     int signal =
146         IThread::ExceptionToSignal(thread->GetAppThread()->fault_signal);
147     // If a thread hits a breakpoint, we want to ensure that it is
148     // reported as SIGTRAP rather than SIGSEGV.  This is necessary
149     // because we use HLT (which produces SIGSEGV) rather than the
150     // more usual INT3 (which produces SIGTRAP) on x86, in order to
151     // work around a Mac OS X bug.
152     //
153     // We need to check each thread to see whether it hit a
154     // breakpoint.  We record this on the thread object because:
155     //  * We need to check the threads before accepting any commands
156     //    from GDB which might remove breakpoints from
157     //    breakpoint_map_, which would remove our ability to tell
158     //    whether a thread hit a breakpoint.
159     //  * Although we deliver fault events to GDB one by one, we might
160     //    have multiple threads that have hit breakpoints.
161     if (signal == NACL_ABI_SIGSEGV) {
162       // Casting to uint32_t is necessary to drop the top 32 bits of
163       // %rip on x86-64.
164       uint32_t prog_ctr = (uint32_t) thread->GetContext()->prog_ctr;
165       if (breakpoint_map_.find(prog_ctr) != breakpoint_map_.end()) {
166         signal = NACL_ABI_SIGTRAP;
167       }
168     }
169     thread->SetFaultSignal(signal);
170   }
171 }
172
173 void Target::RemoveInitialBreakpoint() {
174   if (initial_breakpoint_addr_ != 0) {
175     if (!RemoveBreakpoint(initial_breakpoint_addr_)) {
176       NaClLog(LOG_FATAL,
177               "RemoveInitialBreakpoint: Failed to remove breakpoint\n");
178     }
179     initial_breakpoint_addr_ = 0;
180   }
181 }
182
183 // When the debugger reads memory, we want to report the original
184 // memory contents without the modifications we made to add
185 // breakpoints.  This function undoes the modifications from a copy of
186 // memory.
187 void Target::EraseBreakpointsFromCopyOfMemory(uint32_t user_address,
188                                               uint8_t *data, uint32_t size) {
189   uint32_t user_end = user_address + size;
190   const Abi::BPDef *bp = abi_->GetBreakpointDef();
191   for (BreakpointMap_t::iterator iter = breakpoint_map_.begin();
192        iter != breakpoint_map_.end();
193        ++iter) {
194     uint32_t breakpoint_address = iter->first;
195     uint32_t breakpoint_end = breakpoint_address + bp->size_;
196     uint8_t *original_data = iter->second;
197
198     uint32_t overlap_start = std::max(user_address, breakpoint_address);
199     uint32_t overlap_end = std::min(user_end, breakpoint_end);
200     if (overlap_start < overlap_end) {
201       uint8_t *dest = data + (overlap_start - user_address);
202       uint8_t *src = original_data + (overlap_start - breakpoint_address);
203       size_t copy_size = overlap_end - overlap_start;
204       // Sanity check: do some bounds checks.
205       CHECK(data <= dest && dest + copy_size <= data + size);
206       CHECK(original_data <= src
207             && src + copy_size <= original_data + bp->size_);
208       memcpy(dest, src, copy_size);
209     }
210   }
211 }
212
213 void Target::Run(Session *ses) {
214   NaClXMutexLock(&mutex_);
215   session_ = ses;
216   NaClXMutexUnlock(&mutex_);
217
218   do {
219     WaitForDebugEvent();
220
221     // Lock to prevent anyone else from modifying threads
222     // or updating the signal information.
223     MutexLock lock(&mutex_);
224
225     ProcessDebugEvent();
226     ProcessCommands();
227   } while (session_->Connected());
228
229   NaClXMutexLock(&mutex_);
230   session_ = NULL;
231   NaClXMutexUnlock(&mutex_);
232 }
233
234 bool Target::IsInitialBreakpointActive() {
235   return initial_breakpoint_addr_ != 0;
236 }
237
238 void Target::WaitForDebugEvent() {
239   if (all_threads_suspended_) {
240     // If all threads are suspended (which may be left over from a previous
241     // connection), we are already ready to handle commands from GDB.
242     return;
243   }
244   // Wait for either:
245   //   * an untrusted thread to fault (or single-step)
246   //   * an interrupt from GDB
247   bool ignore_input_from_gdb = step_over_breakpoint_thread_ != 0 ||
248     IsInitialBreakpointActive();
249   session_->WaitForDebugStubEvent(nap_, ignore_input_from_gdb);
250 }
251
252 void Target::ProcessDebugEvent() {
253   if (all_threads_suspended_) {
254     // We are already in a suspended state.
255     return;
256   } else if (step_over_breakpoint_thread_ != 0) {
257     // We are waiting for a specific thread to fault while all other
258     // threads are suspended.  Note that faulted_thread_count might
259     // be >1, because multiple threads can fault simultaneously
260     // before the debug stub gets a chance to suspend all threads.
261     // This is why we must check the status of a specific thread --
262     // we cannot call UnqueueAnyFaultedThread() and expect it to
263     // return step_over_breakpoint_thread_.
264     IThread *thread = threads_[step_over_breakpoint_thread_];
265     if (!thread->HasThreadFaulted()) {
266       // The thread has not faulted.  Nothing to do, so try again.
267       // Note that we do not respond to input from GDB while in this
268       // state.
269       // TODO(mseaborn): We should allow GDB to interrupt execution.
270       return;
271     }
272     // All threads but one are already suspended.  We only need to
273     // suspend the single thread that we allowed to run.
274     thread->SuspendThread();
275     CopyFaultSignalFromAppThread(thread);
276     cur_signal_ = thread->GetFaultSignal();
277     thread->UnqueueFaultedThread();
278     sig_thread_ = step_over_breakpoint_thread_;
279     reg_thread_ = step_over_breakpoint_thread_;
280     step_over_breakpoint_thread_ = 0;
281   } else if (nap_->faulted_thread_count != 0) {
282     // At least one untrusted thread has got an exception.  First we
283     // need to ensure that all threads are suspended.  Then we can
284     // retrieve a thread from the set of faulted threads.
285     SuspendAllThreads();
286     UnqueueAnyFaultedThread(&sig_thread_, &cur_signal_);
287     reg_thread_ = sig_thread_;
288   } else {
289     // Otherwise look for messages from GDB.  To fix a potential
290     // race condition, we don't do this on the first run, because in
291     // that case we are waiting for the initial breakpoint to be
292     // reached.  We don't want GDB to observe states where the
293     // (internal) initial breakpoint is still registered or where
294     // the initial thread is suspended in NaClStartThreadInApp()
295     // before executing its first untrusted instruction.
296     if (IsInitialBreakpointActive() || !session_->IsDataAvailable()) {
297       // No input from GDB.  Nothing to do, so try again.
298       return;
299     }
300     // GDB should have tried to interrupt the target.
301     // See http://sourceware.org/gdb/current/onlinedocs/gdb/Interrupts.html
302     // TODO(eaeltsin): should we verify the interrupt sequence?
303
304     // Indicate we have no current thread.
305     // TODO(eaeltsin): or pick any thread? Add a test.
306     // See http://code.google.com/p/nativeclient/issues/detail?id=2743
307     sig_thread_ = 0;
308     SuspendAllThreads();
309   }
310
311   bool initial_breakpoint_was_active = IsInitialBreakpointActive();
312
313   if (sig_thread_ != 0) {
314     // Reset single stepping.
315     threads_[sig_thread_]->SetStep(false);
316     RemoveInitialBreakpoint();
317   }
318
319   // Next update the current thread info
320   char tmp[16];
321   snprintf(tmp, sizeof(tmp), "QC%x", sig_thread_);
322   properties_["C"] = tmp;
323
324   if (!initial_breakpoint_was_active) {
325     // First time on a connection, we don't send the signal.
326     // All other times, send the signal that triggered us.
327     Packet pktOut;
328     SetStopReply(&pktOut);
329     session_->SendPacketOnly(&pktOut);
330   }
331
332   all_threads_suspended_ = true;
333 }
334
335 void Target::ProcessCommands() {
336   if (!all_threads_suspended_) {
337     // Don't process commands if we haven't stopped all threads.
338     return;
339   }
340
341   // Now we are ready to process commands.
342   // Loop through packets until we process a continue packet or a detach.
343   Packet recv, reply;
344   do {
345     if (!session_->GetPacket(&recv))
346       continue;
347     reply.Clear();
348     if (ProcessPacket(&recv, &reply)) {
349       // If this is a continue type command, break out of this loop.
350       break;
351     }
352     // Otherwise send the response.
353     session_->SendPacket(&reply);
354
355     if (detaching_) {
356       detaching_ = false;
357       session_->Disconnect();
358       Resume();
359       return;
360     }
361
362     if (should_exit_) {
363       NaClExit(-9);
364     }
365   } while (session_->Connected());
366
367   if (session_->Connected()) {
368     // Continue if we're still connected.
369     Resume();
370   }
371 }
372
373 void Target::Resume() {
374   // Reset the signal value
375   cur_signal_ = 0;
376
377   // TODO(eaeltsin): it might make sense to resume signaled thread before
378   // others, though it is not required by GDB docs.
379   if (step_over_breakpoint_thread_ == 0) {
380     ResumeAllThreads();
381   } else {
382     // Resume one thread while leaving all others suspended.
383     threads_[step_over_breakpoint_thread_]->ResumeThread();
384   }
385
386   all_threads_suspended_ = false;
387 }
388
389 void Target::SetStopReply(Packet *pktOut) const {
390   pktOut->AddRawChar('T');
391   pktOut->AddWord8(cur_signal_);
392
393   // gdbserver handles GDB interrupt by sending SIGINT to the debuggee, thus
394   // GDB interrupt is also a case of a signalled thread.
395   // At the moment we handle GDB interrupt differently, without using a signal,
396   // so in this case sig_thread_ is 0.
397   // This might seem weird to GDB, so at least avoid reporting tid 0.
398   // TODO(eaeltsin): http://code.google.com/p/nativeclient/issues/detail?id=2743
399   if (sig_thread_ != 0) {
400     // Add 'thread:<tid>;' pair. Note terminating ';' is required.
401     pktOut->AddString("thread:");
402     pktOut->AddNumberSep(sig_thread_, ';');
403   }
404 }
405
406
407 bool Target::GetFirstThreadId(uint32_t *id) {
408   threadItr_ = threads_.begin();
409   return GetNextThreadId(id);
410 }
411
412 bool Target::GetNextThreadId(uint32_t *id) {
413   if (threadItr_ == threads_.end()) return false;
414
415   *id = (*threadItr_).first;
416   threadItr_++;
417
418   return true;
419 }
420
421
422 uint64_t Target::AdjustUserAddr(uint64_t addr) {
423   // On x86-64, GDB sometimes uses memory addresses with the %r15
424   // sandbox base included, so we must accept these addresses.
425   // TODO(eaeltsin): Fix GDB to not use addresses with %r15 added.
426   if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64 &&
427       NaClIsUserAddr(nap_, (uintptr_t) addr)) {
428     return NaClSysToUser(nap_, (uintptr_t) addr);
429   }
430   // Otherwise, we expect an untrusted address.
431   return addr;
432 }
433
434 bool Target::ProcessPacket(Packet* pktIn, Packet* pktOut) {
435   char cmd;
436   int32_t seq = -1;
437   ErrDef  err = NONE;
438
439   // Clear the outbound message
440   pktOut->Clear();
441
442   // Pull out the sequence.
443   pktIn->GetSequence(&seq);
444   if (seq != -1) pktOut->SetSequence(seq);
445
446   // Find the command
447   pktIn->GetRawChar(&cmd);
448
449   switch (cmd) {
450     // IN : $?
451     // OUT: $Sxx
452     case '?':
453       SetStopReply(pktOut);
454       break;
455
456     case 'c':
457       return true;
458
459     // IN : $D
460     // OUT: $OK
461     case 'D':
462       Detach();
463       pktOut->AddString("OK");
464       return false;
465
466     // IN : $k
467     // OUT: $OK
468     case 'k':
469       Kill();
470       pktOut->AddString("OK");
471       return false;
472
473     // IN : $g
474     // OUT: $xx...xx
475     case 'g': {
476       IThread *thread = GetRegThread();
477       if (NULL == thread) {
478         err = BAD_ARGS;
479         break;
480       }
481
482       // Copy OS preserved registers to GDB payload
483       for (uint32_t a = 0; a < abi_->GetRegisterCount(); a++) {
484         const Abi::RegDef *def = abi_->GetRegisterDef(a);
485         thread->GetRegister(a, &ctx_[def->offset_], def->bytes_);
486       }
487
488       pktOut->AddBlock(ctx_, abi_->GetContextSize());
489       break;
490     }
491
492     // IN : $Gxx..xx
493     // OUT: $OK
494     case 'G': {
495       IThread *thread = GetRegThread();
496       if (NULL == thread) {
497         err = BAD_ARGS;
498         break;
499       }
500
501       pktIn->GetBlock(ctx_, abi_->GetContextSize());
502
503       // GDB payload to OS registers
504       for (uint32_t a = 0; a < abi_->GetRegisterCount(); a++) {
505         const Abi::RegDef *def = abi_->GetRegisterDef(a);
506         thread->SetRegister(a, &ctx_[def->offset_], def->bytes_);
507       }
508
509       pktOut->AddString("OK");
510       break;
511     }
512
513     // IN : $H(c/g)(-1,0,xxxx)
514     // OUT: $OK
515     case 'H': {
516         char type;
517         uint64_t id;
518
519         if (!pktIn->GetRawChar(&type)) {
520           err = BAD_FORMAT;
521           break;
522         }
523         if (!pktIn->GetNumberSep(&id, 0)) {
524           err = BAD_FORMAT;
525           break;
526         }
527
528         if (threads_.begin() == threads_.end()) {
529             err = BAD_ARGS;
530             break;
531         }
532
533         // If we are using "any" get the first thread
534         if (id == static_cast<uint64_t>(-1)) id = threads_.begin()->first;
535
536         // Verify that we have the thread
537         if (threads_.find(static_cast<uint32_t>(id)) == threads_.end()) {
538           err = BAD_ARGS;
539           break;
540         }
541
542         pktOut->AddString("OK");
543         switch (type) {
544           case 'g':
545             reg_thread_ = static_cast<uint32_t>(id);
546             break;
547
548           case 'c':
549             // 'c' is deprecated in favor of vCont.
550           default:
551             err = BAD_ARGS;
552             break;
553         }
554         break;
555       }
556
557     // IN : $maaaa,llll
558     // OUT: $xx..xx
559     case 'm': {
560         uint64_t user_addr;
561         uint64_t wlen;
562         uint32_t len;
563         if (!pktIn->GetNumberSep(&user_addr, 0)) {
564           err = BAD_FORMAT;
565           break;
566         }
567         if (!pktIn->GetNumberSep(&wlen, 0)) {
568           err = BAD_FORMAT;
569           break;
570         }
571         user_addr = AdjustUserAddr(user_addr);
572         uint64_t sys_addr = NaClUserToSysAddrRange(nap_, (uintptr_t) user_addr,
573                                                    (size_t) wlen);
574         if (sys_addr == kNaClBadAddress) {
575           err = FAILED;
576           break;
577         }
578
579         len = static_cast<uint32_t>(wlen);
580         nacl::scoped_array<uint8_t> block(new uint8_t[len]);
581         if (!port::IPlatform::GetMemory(sys_addr, len, block.get())) {
582           err = FAILED;
583           break;
584         }
585         EraseBreakpointsFromCopyOfMemory((uint32_t) user_addr,
586                                          block.get(), len);
587
588         pktOut->AddBlock(block.get(), len);
589         break;
590       }
591
592     // IN : $Maaaa,llll:xx..xx
593     // OUT: $OK
594     case 'M':  {
595         uint64_t user_addr;
596         uint64_t wlen;
597         uint32_t len;
598
599         if (!pktIn->GetNumberSep(&user_addr, 0)) {
600           err = BAD_FORMAT;
601           break;
602         }
603         if (!pktIn->GetNumberSep(&wlen, 0)) {
604           err = BAD_FORMAT;
605           break;
606         }
607         user_addr = AdjustUserAddr(user_addr);
608         uint64_t sys_addr = NaClUserToSysAddrRange(nap_, (uintptr_t) user_addr,
609                                                    (size_t) wlen);
610         if (sys_addr == kNaClBadAddress) {
611           err = FAILED;
612           break;
613         }
614         len = static_cast<uint32_t>(wlen);
615         // We disallow the debugger from modifying code.
616         if (user_addr < nap_->dynamic_text_end) {
617           err = FAILED;
618           break;
619         }
620
621         nacl::scoped_array<uint8_t> block(new uint8_t[len]);
622         pktIn->GetBlock(block.get(), len);
623
624         if (!port::IPlatform::SetMemory(nap_, sys_addr, len, block.get())) {
625           err = FAILED;
626           break;
627         }
628
629         pktOut->AddString("OK");
630         break;
631       }
632
633     case 'q': {
634       string tmp;
635       const char *str = &pktIn->GetPayload()[1];
636       stringvec toks = StringSplit(str, ":;");
637       PropertyMap_t::const_iterator itr = properties_.find(toks[0]);
638
639       // If this is a thread query
640       if (!strcmp(str, "fThreadInfo") || !strcmp(str, "sThreadInfo")) {
641         uint32_t curr;
642         bool more = false;
643         if (str[0] == 'f') {
644           more = GetFirstThreadId(&curr);
645         } else {
646           more = GetNextThreadId(&curr);
647         }
648
649         if (!more) {
650           pktOut->AddString("l");
651         } else {
652           pktOut->AddString("m");
653           pktOut->AddNumberSep(curr, 0);
654         }
655         break;
656       }
657
658       // Check for architecture query
659       tmp = "Xfer:features:read:target.xml";
660       if (!strncmp(str, tmp.data(), tmp.length())) {
661         stringvec args = StringSplit(&str[tmp.length()+1], ",");
662         if (args.size() != 2) break;
663
664         const char *out = properties_["target.xml"].data();
665         int offs = strtol(args[0].data(), NULL, 16);
666         int max  = strtol(args[1].data(), NULL, 16) + offs;
667         int len  = static_cast<int>(strlen(out));
668
669         if (max >= len) max = len;
670
671         while (offs < max) {
672           pktOut->AddRawChar(out[offs]);
673           offs++;
674         }
675         break;
676       }
677
678       // Check the property cache
679       if (itr != properties_.end()) {
680         pktOut->AddString(itr->second.data());
681       }
682       break;
683     }
684
685     case 's': {
686       IThread *thread = GetRunThread();
687       if (thread) thread->SetStep(true);
688       return true;
689     }
690
691     case 'T': {
692       uint64_t id;
693       if (!pktIn->GetNumberSep(&id, 0)) {
694         err = BAD_FORMAT;
695         break;
696       }
697
698       if (GetThread(static_cast<uint32_t>(id)) == NULL) {
699         err = BAD_ARGS;
700         break;
701       }
702
703       pktOut->AddString("OK");
704       break;
705     }
706
707     case 'v': {
708       const char *str = pktIn->GetPayload() + 1;
709
710       if (strncmp(str, "Cont", 4) == 0) {
711         // vCont
712         const char *subcommand = str + 4;
713
714         if (strcmp(subcommand, "?") == 0) {
715           // Report supported vCont actions. These 4 are required.
716           pktOut->AddString("vCont;s;S;c;C");
717           break;
718         }
719
720         if (strcmp(subcommand, ";c") == 0) {
721           // Continue all threads.
722           return true;
723         }
724
725         if (strncmp(subcommand, ";s:", 3) == 0) {
726           // Single step one thread and optionally continue all other threads.
727           char *end;
728           uint32_t thread_id = static_cast<uint32_t>(
729               strtol(subcommand + 3, &end, 16));
730           if (end == subcommand + 3) {
731             err = BAD_ARGS;
732             break;
733           }
734
735           ThreadMap_t::iterator it = threads_.find(thread_id);
736           if (it == threads_.end()) {
737             err = BAD_ARGS;
738             break;
739           }
740
741           if (*end == 0) {
742             // Single step one thread and keep other threads stopped.
743             // GDB uses this to continue from a breakpoint, which works by:
744             // - replacing trap instruction with the original instruction;
745             // - single-stepping through the original instruction. Other threads
746             //   must remain stopped, otherwise they might execute the code at
747             //   the same address and thus miss the breakpoint;
748             // - replacing the original instruction with trap instruction;
749             // - continuing all threads;
750             if (thread_id != sig_thread_) {
751               err = BAD_ARGS;
752               break;
753             }
754             step_over_breakpoint_thread_ = sig_thread_;
755           } else if (strcmp(end, ";c") == 0) {
756             // Single step one thread and continue all other threads.
757           } else {
758             // Unsupported combination of single step and other args.
759             err = BAD_ARGS;
760             break;
761           }
762
763           it->second->SetStep(true);
764           return true;
765         }
766
767         // Continue one thread and keep other threads stopped.
768         //
769         // GDB sends this for software single step, which is used:
770         // - on Win64 to step over rsp modification and subsequent rsp
771         //   sandboxing at once. For details, see:
772         //     http://code.google.com/p/nativeclient/issues/detail?id=2903
773         // - TODO: on ARM, which has no hardware support for single step
774         // - TODO: to step over syscalls
775         //
776         // Unfortunately, we can't make this just Win-specific. We might
777         // use Linux GDB to connect to Win debug stub, so even Linux GDB
778         // should send software single step. Vice versa, software single
779         // step-enabled Win GDB might be connected to Linux debug stub,
780         // so even Linux debug stub should accept software single step.
781         if (strncmp(subcommand, ";c:", 3) == 0) {
782           char *end;
783           uint32_t thread_id = static_cast<uint32_t>(
784               strtol(subcommand + 3, &end, 16));
785           if (end != subcommand + 3 && *end == 0) {
786             if (thread_id == sig_thread_) {
787               step_over_breakpoint_thread_ = sig_thread_;
788               return true;
789             }
790           }
791
792           err = BAD_ARGS;
793           break;
794         }
795
796         // Unsupported form of vCont.
797         err = BAD_FORMAT;
798         break;
799       }
800
801       NaClLog(LOG_ERROR, "Unknown command: %s\n", pktIn->GetPayload());
802       return false;
803     }
804
805     case 'Z': {
806       uint64_t breakpoint_type;
807       uint64_t breakpoint_address;
808       uint64_t breakpoint_kind;
809       if (!pktIn->GetNumberSep(&breakpoint_type, 0) ||
810           breakpoint_type != 0 ||
811           !pktIn->GetNumberSep(&breakpoint_address, 0) ||
812           !pktIn->GetNumberSep(&breakpoint_kind, 0)) {
813         err = BAD_FORMAT;
814         break;
815       }
816       if (breakpoint_address != (uint32_t) breakpoint_address ||
817           !AddBreakpoint((uint32_t) breakpoint_address)) {
818         err = FAILED;
819         break;
820       }
821       pktOut->AddString("OK");
822       break;
823     }
824
825     case 'z': {
826       uint64_t breakpoint_type;
827       uint64_t breakpoint_address;
828       uint64_t breakpoint_kind;
829       if (!pktIn->GetNumberSep(&breakpoint_type, 0) ||
830           breakpoint_type != 0 ||
831           !pktIn->GetNumberSep(&breakpoint_address, 0) ||
832           !pktIn->GetNumberSep(&breakpoint_kind, 0)) {
833         err = BAD_FORMAT;
834         break;
835       }
836       if (breakpoint_address != (uint32_t) breakpoint_address ||
837           !RemoveBreakpoint((uint32_t) breakpoint_address)) {
838         err = FAILED;
839         break;
840       }
841       pktOut->AddString("OK");
842       break;
843     }
844
845     default: {
846       // If the command is not recognzied, ignore it by sending an
847       // empty reply.
848       string str;
849       pktIn->GetString(&str);
850       NaClLog(LOG_ERROR, "Unknown command: %s\n", pktIn->GetPayload());
851       return false;
852     }
853   }
854
855   // If there is an error, return the error code instead of a payload
856   if (err) {
857     pktOut->Clear();
858     pktOut->AddRawChar('E');
859     pktOut->AddWord8(err);
860   }
861   return false;
862 }
863
864
865 void Target::TrackThread(struct NaClAppThread *natp) {
866   // natp->thread_num values are 0-based indexes, but we treat 0 as
867   // "not a thread ID", so we add 1.
868   uint32_t id = natp->thread_num + 1;
869   MutexLock lock(&mutex_);
870   CHECK(threads_[id] == 0);
871   threads_[id] = IThread::Create(id, natp);
872 }
873
874 void Target::IgnoreThread(struct NaClAppThread *natp) {
875   uint32_t id = natp->thread_num + 1;
876   MutexLock lock(&mutex_);
877   ThreadMap_t::iterator iter = threads_.find(id);
878   CHECK(iter != threads_.end());
879   delete iter->second;
880   threads_.erase(iter);
881 }
882
883 void Target::Exit() {
884   MutexLock lock(&mutex_);
885   if (session_ != NULL) {
886     Packet exit_packet;
887     if (NACL_ABI_WIFSIGNALED(nap_->exit_status)) {
888       exit_packet.AddRawChar('X');
889       exit_packet.AddWord8(NACL_ABI_WTERMSIG(nap_->exit_status));
890     } else {
891       exit_packet.AddRawChar('W');
892       exit_packet.AddWord8(NACL_ABI_WEXITSTATUS(nap_->exit_status));
893     }
894     session_->SendPacket(&exit_packet);
895   }
896 }
897
898 void Target::Detach() {
899   NaClLog(LOG_INFO, "Requested Detach.\n");
900   detaching_ = true;
901 }
902
903 void Target::Kill() {
904   NaClLog(LOG_INFO, "Requested Kill.\n");
905   should_exit_ = true;
906 }
907
908 IThread* Target::GetRegThread() {
909   ThreadMap_t::const_iterator itr;
910
911   switch (reg_thread_) {
912     // If we want "any" then try the signal'd thread first
913     case 0:
914     case 0xFFFFFFFF:
915       itr = threads_.begin();
916       break;
917
918     default:
919       itr = threads_.find(reg_thread_);
920       break;
921   }
922
923   if (itr == threads_.end()) return 0;
924
925   return itr->second;
926 }
927
928 IThread* Target::GetRunThread() {
929   // This is used to select a thread for "s" (step) command only.
930   // For multi-threaded targets, "s" is deprecated in favor of "vCont", which
931   // always specifies the thread explicitly when needed. However, we want
932   // to keep backward compatibility here, as using "s" when debugging
933   // a single-threaded program might be a popular use case.
934   if (threads_.size() == 1) {
935     return threads_.begin()->second;
936   }
937   return NULL;
938 }
939
940 IThread* Target::GetThread(uint32_t id) {
941   ThreadMap_t::const_iterator itr;
942   itr = threads_.find(id);
943   if (itr != threads_.end()) return itr->second;
944
945   return NULL;
946 }
947
948 void Target::SuspendAllThreads() {
949   NaClUntrustedThreadsSuspendAll(nap_, /* save_registers= */ 1);
950   for (ThreadMap_t::const_iterator iter = threads_.begin();
951        iter != threads_.end();
952        ++iter) {
953     IThread *thread = iter->second;
954     thread->CopyRegistersFromAppThread();
955     CopyFaultSignalFromAppThread(thread);
956   }
957 }
958
959 void Target::ResumeAllThreads() {
960   for (ThreadMap_t::const_iterator iter = threads_.begin();
961        iter != threads_.end();
962        ++iter) {
963     iter->second->CopyRegistersToAppThread();
964   }
965   NaClUntrustedThreadsResumeAll(nap_);
966 }
967
968 // UnqueueAnyFaultedThread() picks a thread that has been blocked as a
969 // result of faulting and unblocks it.  It returns the thread's ID via
970 // |thread_id| and the type of fault via |signal|.  As a precondition,
971 // all threads must be currently suspended.
972 void Target::UnqueueAnyFaultedThread(uint32_t *thread_id, int8_t *signal) {
973   for (ThreadMap_t::const_iterator iter = threads_.begin();
974        iter != threads_.end();
975        ++iter) {
976     IThread *thread = iter->second;
977     if (thread->GetFaultSignal() != 0) {
978       *signal = thread->GetFaultSignal();
979       *thread_id = thread->GetId();
980       thread->UnqueueFaultedThread();
981       return;
982     }
983   }
984   NaClLog(LOG_FATAL, "UnqueueAnyFaultedThread: No threads queued\n");
985 }
986
987 }  // namespace gdb_rsp