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