blob: 471843b3f99d19e4a0dd02c6d98a4c39cf52e947 [file] [log] [blame]
Johnny Chen2341d352012-01-05 21:48:15 +00001//===-- ProcessPOSIX.cpp ----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Daniel Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Johnny Chen2341d352012-01-05 21:48:15 +000012// C Includes
13#include <errno.h>
14
15// C++ Includes
16// Other libraries and framework includes
Matt Kopec3d4d51c2013-05-07 19:29:28 +000017#include "lldb/Breakpoint/Watchpoint.h"
Greg Clayton8ac035d2012-09-04 14:55:50 +000018#include "lldb/Core/Module.h"
Johnny Chen2341d352012-01-05 21:48:15 +000019#include "lldb/Core/PluginManager.h"
20#include "lldb/Core/State.h"
Daniel Malea1e44fdd2013-01-08 14:49:22 +000021#include "lldb/Host/FileSpec.h"
Johnny Chen2341d352012-01-05 21:48:15 +000022#include "lldb/Host/Host.h"
23#include "lldb/Symbol/ObjectFile.h"
24#include "lldb/Target/DynamicLoader.h"
Andrew Kaylor6c1a8cf2013-05-07 22:46:38 +000025#include "lldb/Target/Platform.h"
Johnny Chen2341d352012-01-05 21:48:15 +000026#include "lldb/Target/Target.h"
27
28#include "ProcessPOSIX.h"
29#include "ProcessPOSIXLog.h"
30#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
31#include "ProcessMonitor.h"
32#include "POSIXThread.h"
33
34using namespace lldb;
35using namespace lldb_private;
36
37//------------------------------------------------------------------------------
38// Static functions.
39#if 0
40Process*
41ProcessPOSIX::CreateInstance(Target& target, Listener &listener)
42{
43 return new ProcessPOSIX(target, listener);
44}
45
46
47void
48ProcessPOSIX::Initialize()
49{
50 static bool g_initialized = false;
51
52 if (!g_initialized)
53 {
54 g_initialized = true;
55 PluginManager::RegisterPlugin(GetPluginNameStatic(),
56 GetPluginDescriptionStatic(),
57 CreateInstance);
58
59 Log::Callbacks log_callbacks = {
60 ProcessPOSIXLog::DisableLog,
61 ProcessPOSIXLog::EnableLog,
62 ProcessPOSIXLog::ListLogCategories
63 };
64
65 Log::RegisterLogChannel (ProcessPOSIX::GetPluginNameStatic(), log_callbacks);
66 }
67}
68#endif
69
70//------------------------------------------------------------------------------
71// Constructors and destructors.
72
73ProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener)
74 : Process(target, listener),
Johnny Chen78dae822012-04-14 00:54:42 +000075 m_byte_order(lldb::endian::InlHostByteOrder()),
Johnny Chen2341d352012-01-05 21:48:15 +000076 m_monitor(NULL),
77 m_module(NULL),
78 m_in_limbo(false),
79 m_exit_now(false)
80{
81 // FIXME: Putting this code in the ctor and saving the byte order in a
82 // member variable is a hack to avoid const qual issues in GetByteOrder.
Johnny Chen78dae822012-04-14 00:54:42 +000083 lldb::ModuleSP module = GetTarget().GetExecutableModule();
84 if (module != NULL && module->GetObjectFile() != NULL)
85 m_byte_order = module->GetObjectFile()->GetByteOrder();
Johnny Chen2341d352012-01-05 21:48:15 +000086}
87
88ProcessPOSIX::~ProcessPOSIX()
89{
90 delete m_monitor;
91}
92
93//------------------------------------------------------------------------------
94// Process protocol.
95
96bool
97ProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name)
98{
99 // For now we are just making sure the file exists for a given module
100 ModuleSP exe_module_sp(target.GetExecutableModule());
101 if (exe_module_sp.get())
102 return exe_module_sp->GetFileSpec().Exists();
Andrew Kaylor6c1a8cf2013-05-07 22:46:38 +0000103 // If there is no executable module, we return true since we might be preparing to attach.
104 return true;
Johnny Chen2341d352012-01-05 21:48:15 +0000105}
106
107Error
108ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid)
109{
110 Error error;
111 assert(m_monitor == NULL);
112
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000113 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen2341d352012-01-05 21:48:15 +0000114 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000115 log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000116
117 m_monitor = new ProcessMonitor(this, pid, error);
118
119 if (!error.Success())
120 return error;
121
Andrew Kaylor6c1a8cf2013-05-07 22:46:38 +0000122 PlatformSP platform_sp (m_target.GetPlatform ());
123 assert (platform_sp.get());
124 if (!platform_sp)
125 return error; // FIXME: Detatch?
126
127 // Find out what we can about this process
128 ProcessInstanceInfo process_info;
129 platform_sp->GetProcessInfo (pid, process_info);
130
131 // Resolve the executable module
132 ModuleSP exe_module_sp;
133 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
134 error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(),
135 m_target.GetArchitecture(),
136 exe_module_sp,
137 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
138
139 // Fix the target architecture if necessary
140 const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
141 if (module_arch.IsValid() && !m_target.GetArchitecture().IsExactMatch(module_arch))
142 m_target.SetArchitecture(module_arch);
143
144 // Initialize the target module list
145 m_target.SetExecutableModule (exe_module_sp, true);
146
147 if (!error.Success())
148 return error;
149
150 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
151
Johnny Chen2341d352012-01-05 21:48:15 +0000152 SetID(pid);
Andrew Kaylor6c1a8cf2013-05-07 22:46:38 +0000153
Johnny Chen2341d352012-01-05 21:48:15 +0000154 return error;
155}
156
157Error
Greg Claytonc6430772012-09-07 17:51:47 +0000158ProcessPOSIX::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info)
159{
160 return DoAttachToProcessWithID(pid);
161}
162
163Error
Johnny Chen2341d352012-01-05 21:48:15 +0000164ProcessPOSIX::WillLaunch(Module* module)
165{
166 Error error;
167 return error;
168}
169
170const char *
171ProcessPOSIX::GetFilePath(
172 const lldb_private::ProcessLaunchInfo::FileAction *file_action,
173 const char *default_path)
174{
175 const char *pts_name = "/dev/pts/";
176 const char *path = NULL;
177
178 if (file_action)
179 {
180 if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
181 path = file_action->GetPath();
182 // By default the stdio paths passed in will be pseudo-terminal
183 // (/dev/pts). If so, convert to using a different default path
184 // instead to redirect I/O to the debugger console. This should
185 // also handle user overrides to /dev/null or a different file.
186 if (::strncmp(path, pts_name, ::strlen(pts_name)) == 0)
187 path = default_path;
188 }
189
190 return path;
191}
192
193Error
194ProcessPOSIX::DoLaunch (Module *module,
195 const ProcessLaunchInfo &launch_info)
196{
197 Error error;
198 assert(m_monitor == NULL);
199
Daniel Malea1e44fdd2013-01-08 14:49:22 +0000200 const char* working_dir = launch_info.GetWorkingDirectory();
201 if (working_dir) {
202 FileSpec WorkingDir(working_dir, true);
203 if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
204 {
205 error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
206 return error;
207 }
208 }
209
Johnny Chen2341d352012-01-05 21:48:15 +0000210 SetPrivateState(eStateLaunching);
211
212 const lldb_private::ProcessLaunchInfo::FileAction *file_action;
213
214 // Default of NULL will mean to use existing open file descriptors
215 const char *stdin_path = NULL;
216 const char *stdout_path = NULL;
217 const char *stderr_path = NULL;
Daniel Malea1e44fdd2013-01-08 14:49:22 +0000218
Johnny Chen2341d352012-01-05 21:48:15 +0000219 file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
220 stdin_path = GetFilePath(file_action, stdin_path);
221
222 file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
223 stdout_path = GetFilePath(file_action, stdout_path);
224
225 file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
226 stderr_path = GetFilePath(file_action, stderr_path);
227
228 m_monitor = new ProcessMonitor (this,
229 module,
230 launch_info.GetArguments().GetConstArgumentVector(),
231 launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
232 stdin_path,
233 stdout_path,
234 stderr_path,
Daniel Malea1e44fdd2013-01-08 14:49:22 +0000235 working_dir,
Johnny Chen2341d352012-01-05 21:48:15 +0000236 error);
237
238 m_module = module;
239
240 if (!error.Success())
241 return error;
242
Matt Kopeca7cd95d2013-03-14 21:35:26 +0000243 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
244
Johnny Chen2341d352012-01-05 21:48:15 +0000245 SetID(m_monitor->GetPID());
246 return error;
247}
248
249void
250ProcessPOSIX::DidLaunch()
251{
252}
253
254Error
255ProcessPOSIX::DoResume()
256{
257 StateType state = GetPrivateState();
258
259 assert(state == eStateStopped || state == eStateCrashed);
260
261 // We are about to resume a thread that will cause the process to exit so
262 // set our exit status now. Do not change our state if the inferior
263 // crashed.
264 if (state == eStateStopped)
265 {
266 if (m_in_limbo)
267 SetExitStatus(m_exit_status, NULL);
268 else
269 SetPrivateState(eStateRunning);
270 }
271
272 bool did_resume = false;
273 uint32_t thread_count = m_thread_list.GetSize(false);
274 for (uint32_t i = 0; i < thread_count; ++i)
275 {
276 POSIXThread *thread = static_cast<POSIXThread*>(
277 m_thread_list.GetThreadAtIndex(i, false).get());
278 did_resume = thread->Resume() || did_resume;
279 }
280 assert(did_resume && "Process resume failed!");
281
282 return Error();
283}
284
285addr_t
286ProcessPOSIX::GetImageInfoAddress()
287{
288 Target *target = &GetTarget();
289 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
290 Address addr = obj_file->GetImageInfoAddress();
291
292 if (addr.IsValid())
293 return addr.GetLoadAddress(target);
294 else
295 return LLDB_INVALID_ADDRESS;
296}
297
298Error
299ProcessPOSIX::DoHalt(bool &caused_stop)
300{
301 Error error;
302
303 if (IsStopped())
304 {
305 caused_stop = false;
306 }
307 else if (kill(GetID(), SIGSTOP))
308 {
309 caused_stop = false;
310 error.SetErrorToErrno();
311 }
312 else
313 {
314 caused_stop = true;
315 }
Johnny Chen2341d352012-01-05 21:48:15 +0000316 return error;
317}
318
319Error
Jim Ingham761afb82013-05-02 00:27:30 +0000320ProcessPOSIX::DoDetach(bool keep_stopped)
Johnny Chen2341d352012-01-05 21:48:15 +0000321{
322 Error error;
Jim Ingham761afb82013-05-02 00:27:30 +0000323 if (keep_stopped)
324 {
325 // FIXME: If you want to implement keep_stopped on Linux,
326 // this would be the place to do it.
327 error.SetErrorString("Detaching with keep_stopped true is not currently supported on Linux.");
328 return error;
329 }
Johnny Chen2341d352012-01-05 21:48:15 +0000330
331 error = m_monitor->Detach();
332 if (error.Success())
333 SetPrivateState(eStateDetached);
334
335 return error;
336}
337
338Error
339ProcessPOSIX::DoSignal(int signal)
340{
341 Error error;
342
343 if (kill(GetID(), signal))
344 error.SetErrorToErrno();
345
346 return error;
347}
348
349Error
350ProcessPOSIX::DoDestroy()
351{
352 Error error;
353
354 if (!HasExited())
355 {
356 // Drive the exit event to completion (do not keep the inferior in
357 // limbo).
358 m_exit_now = true;
359
Greg Clayton972c4382012-03-30 19:56:32 +0000360 if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success())
Johnny Chen2341d352012-01-05 21:48:15 +0000361 {
362 error.SetErrorToErrno();
363 return error;
364 }
365
366 SetPrivateState(eStateExited);
367 }
368
369 return error;
370}
371
372void
373ProcessPOSIX::SendMessage(const ProcessMessage &message)
374{
375 Mutex::Locker lock(m_message_mutex);
376
377 switch (message.GetKind())
378 {
Johnny Chen2341d352012-01-05 21:48:15 +0000379 case ProcessMessage::eInvalidMessage:
380 return;
381
382 case ProcessMessage::eLimboMessage:
383 m_in_limbo = true;
384 m_exit_status = message.GetExitStatus();
385 if (m_exit_now)
386 {
387 SetPrivateState(eStateExited);
388 m_monitor->Detach();
389 }
390 else
391 SetPrivateState(eStateStopped);
392 break;
393
394 case ProcessMessage::eExitMessage:
395 m_exit_status = message.GetExitStatus();
396 SetExitStatus(m_exit_status, NULL);
397 break;
398
399 case ProcessMessage::eTraceMessage:
400 case ProcessMessage::eBreakpointMessage:
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000401 case ProcessMessage::eWatchpointMessage:
Johnny Chen2341d352012-01-05 21:48:15 +0000402 SetPrivateState(eStateStopped);
403 break;
404
405 case ProcessMessage::eSignalMessage:
406 case ProcessMessage::eSignalDeliveredMessage:
Matt Kopecf1fda372013-01-08 16:30:18 +0000407 {
408 lldb::tid_t tid = message.GetTID();
409 lldb::tid_t pid = GetID();
410 if (tid == pid) {
411 SetPrivateState(eStateStopped);
412 break;
413 } else {
414 // FIXME: Ignore any signals generated by children.
415 return;
416 }
417 }
Johnny Chen2341d352012-01-05 21:48:15 +0000418
419 case ProcessMessage::eCrashMessage:
Andrew Kaylor05a47892012-12-14 18:24:34 +0000420 // FIXME: Update stop reason as per bugzilla 14598
421 SetPrivateState(eStateStopped);
Johnny Chen2341d352012-01-05 21:48:15 +0000422 break;
Matt Kopecf1fda372013-01-08 16:30:18 +0000423
424 case ProcessMessage::eNewThreadMessage:
425 SetPrivateState(eStateStopped);
426 break;
Johnny Chen2341d352012-01-05 21:48:15 +0000427 }
428
429 m_message_queue.push(message);
430}
431
432void
433ProcessPOSIX::RefreshStateAfterStop()
434{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000435 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen2341d352012-01-05 21:48:15 +0000436 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
437 log->Printf ("ProcessPOSIX::%s()", __FUNCTION__);
438
439 Mutex::Locker lock(m_message_mutex);
440 if (m_message_queue.empty())
441 return;
442
443 ProcessMessage &message = m_message_queue.front();
444
445 // Resolve the thread this message corresponds to and pass it along.
446 // FIXME: we're really dealing with the pid here. This should get
447 // fixed when this code is fixed to handle multiple threads.
448 lldb::tid_t tid = message.GetTID();
449 if (log)
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000450 log->Printf ("ProcessPOSIX::%s() pid = %" PRIi64, __FUNCTION__, tid);
Johnny Chen2341d352012-01-05 21:48:15 +0000451 POSIXThread *thread = static_cast<POSIXThread*>(
452 GetThreadList().FindThreadByID(tid, false).get());
453
Matt Kopecf1fda372013-01-08 16:30:18 +0000454 if (message.GetKind() == ProcessMessage::eNewThreadMessage) {
455 ThreadSP thread_sp;
456 thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
457 m_thread_list.AddThread(thread_sp);
458 }
459
Johnny Chen2341d352012-01-05 21:48:15 +0000460 assert(thread);
461 thread->Notify(message);
462
463 m_message_queue.pop();
464}
465
466bool
467ProcessPOSIX::IsAlive()
468{
469 StateType state = GetPrivateState();
Daniel Malea0247cf52013-04-01 19:48:37 +0000470 return state != eStateDetached
471 && state != eStateExited
472 && state != eStateInvalid
473 && state != eStateUnloaded;
Johnny Chen2341d352012-01-05 21:48:15 +0000474}
475
476size_t
477ProcessPOSIX::DoReadMemory(addr_t vm_addr,
478 void *buf, size_t size, Error &error)
479{
480 assert(m_monitor);
481 return m_monitor->ReadMemory(vm_addr, buf, size, error);
482}
483
484size_t
485ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
486 Error &error)
487{
488 assert(m_monitor);
489 return m_monitor->WriteMemory(vm_addr, buf, size, error);
490}
491
492addr_t
493ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
494 Error &error)
495{
496 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
497
498 unsigned prot = 0;
499 if (permissions & lldb::ePermissionsReadable)
500 prot |= eMmapProtRead;
501 if (permissions & lldb::ePermissionsWritable)
502 prot |= eMmapProtWrite;
503 if (permissions & lldb::ePermissionsExecutable)
504 prot |= eMmapProtExec;
505
506 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
507 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
508 m_addr_to_mmap_size[allocated_addr] = size;
509 error.Clear();
510 } else {
511 allocated_addr = LLDB_INVALID_ADDRESS;
512 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
513 }
514
515 return allocated_addr;
516}
517
518Error
519ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
520{
521 Error error;
522 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
523 if (pos != m_addr_to_mmap_size.end() &&
524 InferiorCallMunmap(this, addr, pos->second))
525 m_addr_to_mmap_size.erase (pos);
526 else
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000527 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen2341d352012-01-05 21:48:15 +0000528
529 return error;
530}
531
Matt Kopec4f9103f2013-02-27 20:13:38 +0000532addr_t
533ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
534{
535 addr_t function_addr = LLDB_INVALID_ADDRESS;
536 if (address == NULL) {
537 error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
538 } else if (!InferiorCall(this, address, function_addr)) {
539 function_addr = LLDB_INVALID_ADDRESS;
Matt Kopec70125482013-03-01 17:44:31 +0000540 error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
541 address->CalculateSymbolContextSymbol()->GetName().AsCString());
Matt Kopec4f9103f2013-02-27 20:13:38 +0000542 }
543 return function_addr;
544}
545
Johnny Chen2341d352012-01-05 21:48:15 +0000546size_t
547ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
548{
549 static const uint8_t g_i386_opcode[] = { 0xCC };
550
551 ArchSpec arch = GetTarget().GetArchitecture();
552 const uint8_t *opcode = NULL;
553 size_t opcode_size = 0;
554
555 switch (arch.GetCore())
556 {
557 default:
558 assert(false && "CPU type not supported!");
559 break;
560
561 case ArchSpec::eCore_x86_32_i386:
562 case ArchSpec::eCore_x86_64_x86_64:
563 opcode = g_i386_opcode;
564 opcode_size = sizeof(g_i386_opcode);
565 break;
566 }
567
568 bp_site->SetTrapOpcode(opcode, opcode_size);
569 return opcode_size;
570}
571
572Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000573ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000574{
575 return EnableSoftwareBreakpoint(bp_site);
576}
577
578Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000579ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000580{
581 return DisableSoftwareBreakpoint(bp_site);
582}
583
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000584Error
585ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify)
586{
587 Error error;
588 if (wp)
589 {
590 user_id_t watchID = wp->GetID();
591 addr_t addr = wp->GetLoadAddress();
592 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
593 if (log)
594 log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")",
595 watchID);
596 if (wp->IsEnabled())
597 {
598 if (log)
599 log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64
600 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
601 watchID, (uint64_t)addr);
602 return error;
603 }
604
605 bool wp_enabled = true;
606 uint32_t thread_count = m_thread_list.GetSize(false);
607 for (uint32_t i = 0; i < thread_count; ++i)
608 {
609 POSIXThread *thread = static_cast<POSIXThread*>(
610 m_thread_list.GetThreadAtIndex(i, false).get());
611 if (thread)
612 wp_enabled &= thread->EnableHardwareWatchpoint(wp);
613 else
614 {
615 wp_enabled = false;
616 break;
617 }
618 }
619 if (wp_enabled)
620 {
621 wp->SetEnabled(true, notify);
622 return error;
623 }
624 else
625 {
626 // Watchpoint enabling failed on at least one
627 // of the threads so roll back all of them
628 DisableWatchpoint(wp, false);
629 error.SetErrorString("Setting hardware watchpoint failed");
630 }
631 }
632 else
633 error.SetErrorString("Watchpoint argument was NULL.");
634 return error;
635}
636
637Error
638ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify)
639{
640 Error error;
641 if (wp)
642 {
643 user_id_t watchID = wp->GetID();
644 addr_t addr = wp->GetLoadAddress();
645 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
646 if (log)
647 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")",
648 watchID);
649 if (!wp->IsEnabled())
650 {
651 if (log)
652 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64
653 ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
654 watchID, (uint64_t)addr);
655 // This is needed (for now) to keep watchpoints disabled correctly
656 wp->SetEnabled(false, notify);
657 return error;
658 }
659
660 if (wp->IsHardware())
661 {
662 bool wp_disabled = true;
663 uint32_t thread_count = m_thread_list.GetSize(false);
664 for (uint32_t i = 0; i < thread_count; ++i)
665 {
666 POSIXThread *thread = static_cast<POSIXThread*>(
667 m_thread_list.GetThreadAtIndex(i, false).get());
668 if (thread)
669 wp_disabled &= thread->DisableHardwareWatchpoint(wp);
670 else
671 wp_disabled = false;
672 }
673 if (wp_disabled)
674 {
675 wp->SetEnabled(false, notify);
676 return error;
677 }
678 else
679 error.SetErrorString("Disabling hardware watchpoint failed");
680 }
681 }
682 else
683 error.SetErrorString("Watchpoint argument was NULL.");
684 return error;
685}
686
687Error
688ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num)
689{
690 Error error;
691 POSIXThread *thread = static_cast<POSIXThread*>(
692 m_thread_list.GetThreadAtIndex(0, false).get());
693 if (thread)
694 num = thread->NumSupportedHardwareWatchpoints();
695 else
696 error.SetErrorString("Process does not exist.");
697 return error;
698}
699
700Error
701ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after)
702{
703 Error error = GetWatchpointSupportInfo(num);
704 // Watchpoints trigger and halt the inferior after
705 // the corresponding instruction has been executed.
706 after = true;
707 return error;
708}
709
Johnny Chen2341d352012-01-05 21:48:15 +0000710uint32_t
711ProcessPOSIX::UpdateThreadListIfNeeded()
712{
713 // Do not allow recursive updates.
714 return m_thread_list.GetSize(false);
715}
716
Greg Claytonc8dd5702012-04-12 19:04:34 +0000717bool
Johnny Chen2341d352012-01-05 21:48:15 +0000718ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
719{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000720 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +0000721 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000722 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000723
724 // Update the process thread list with this new thread.
725 // FIXME: We should be using tid, not pid.
726 assert(m_monitor);
727 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Claytone5eaa302012-02-21 18:40:07 +0000728 if (!thread_sp) {
Greg Clayton5e91e372012-10-12 16:23:23 +0000729 thread_sp.reset(new POSIXThread(*this, GetID()));
Greg Claytone5eaa302012-02-21 18:40:07 +0000730 }
Johnny Chen2341d352012-01-05 21:48:15 +0000731
732 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000733 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000734 new_thread_list.AddThread(thread_sp);
735
Greg Claytonc8dd5702012-04-12 19:04:34 +0000736 return new_thread_list.GetSize(false) > 0;
Johnny Chen2341d352012-01-05 21:48:15 +0000737}
738
739ByteOrder
740ProcessPOSIX::GetByteOrder() const
741{
742 // FIXME: We should be able to extract this value directly. See comment in
743 // ProcessPOSIX().
744 return m_byte_order;
745}
746
747size_t
748ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
749{
750 ssize_t status;
751 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
752 {
753 error.SetErrorToErrno();
754 return 0;
755 }
756 return status;
757}
758
Johnny Chen2341d352012-01-05 21:48:15 +0000759UnixSignals &
760ProcessPOSIX::GetUnixSignals()
761{
762 return m_signals;
763}
764
765//------------------------------------------------------------------------------
766// Utility functions.
767
768bool
769ProcessPOSIX::HasExited()
770{
771 switch (GetPrivateState())
772 {
773 default:
774 break;
775
776 case eStateDetached:
777 case eStateExited:
778 return true;
779 }
780
781 return false;
782}
783
784bool
785ProcessPOSIX::IsStopped()
786{
787 switch (GetPrivateState())
788 {
789 default:
790 break;
791
792 case eStateStopped:
793 case eStateCrashed:
794 case eStateSuspended:
795 return true;
796 }
797
798 return false;
799}