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