blob: b2db43e35976a929ea644cd6a4d7cb3b7b1042bf [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),
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +000078 m_message_mutex (Mutex::eMutexTypeRecursive),
Johnny Chen2341d352012-01-05 21:48:15 +000079 m_in_limbo(false),
80 m_exit_now(false)
81{
82 // FIXME: Putting this code in the ctor and saving the byte order in a
83 // member variable is a hack to avoid const qual issues in GetByteOrder.
Johnny Chen78dae822012-04-14 00:54:42 +000084 lldb::ModuleSP module = GetTarget().GetExecutableModule();
85 if (module != NULL && module->GetObjectFile() != NULL)
86 m_byte_order = module->GetObjectFile()->GetByteOrder();
Johnny Chen2341d352012-01-05 21:48:15 +000087}
88
89ProcessPOSIX::~ProcessPOSIX()
90{
91 delete m_monitor;
92}
93
94//------------------------------------------------------------------------------
95// Process protocol.
96
97bool
98ProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name)
99{
100 // For now we are just making sure the file exists for a given module
101 ModuleSP exe_module_sp(target.GetExecutableModule());
102 if (exe_module_sp.get())
103 return exe_module_sp->GetFileSpec().Exists();
Andrew Kaylor6c1a8cf2013-05-07 22:46:38 +0000104 // If there is no executable module, we return true since we might be preparing to attach.
105 return true;
Johnny Chen2341d352012-01-05 21:48:15 +0000106}
107
108Error
109ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid)
110{
111 Error error;
112 assert(m_monitor == NULL);
113
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000114 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen2341d352012-01-05 21:48:15 +0000115 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000116 log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000117
118 m_monitor = new ProcessMonitor(this, pid, error);
119
120 if (!error.Success())
121 return error;
122
Andrew Kaylor6c1a8cf2013-05-07 22:46:38 +0000123 PlatformSP platform_sp (m_target.GetPlatform ());
124 assert (platform_sp.get());
125 if (!platform_sp)
126 return error; // FIXME: Detatch?
127
128 // Find out what we can about this process
129 ProcessInstanceInfo process_info;
130 platform_sp->GetProcessInfo (pid, process_info);
131
132 // Resolve the executable module
133 ModuleSP exe_module_sp;
134 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
135 error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(),
136 m_target.GetArchitecture(),
137 exe_module_sp,
138 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
139
140 // Fix the target architecture if necessary
141 const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
142 if (module_arch.IsValid() && !m_target.GetArchitecture().IsExactMatch(module_arch))
143 m_target.SetArchitecture(module_arch);
144
145 // Initialize the target module list
146 m_target.SetExecutableModule (exe_module_sp, true);
147
148 if (!error.Success())
149 return error;
150
151 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
152
Johnny Chen2341d352012-01-05 21:48:15 +0000153 SetID(pid);
Andrew Kaylor6c1a8cf2013-05-07 22:46:38 +0000154
Johnny Chen2341d352012-01-05 21:48:15 +0000155 return error;
156}
157
158Error
Greg Claytonc6430772012-09-07 17:51:47 +0000159ProcessPOSIX::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info)
160{
161 return DoAttachToProcessWithID(pid);
162}
163
164Error
Johnny Chen2341d352012-01-05 21:48:15 +0000165ProcessPOSIX::WillLaunch(Module* module)
166{
167 Error error;
168 return error;
169}
170
171const char *
172ProcessPOSIX::GetFilePath(
173 const lldb_private::ProcessLaunchInfo::FileAction *file_action,
174 const char *default_path)
175{
176 const char *pts_name = "/dev/pts/";
177 const char *path = NULL;
178
179 if (file_action)
180 {
181 if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
182 path = file_action->GetPath();
183 // By default the stdio paths passed in will be pseudo-terminal
184 // (/dev/pts). If so, convert to using a different default path
185 // instead to redirect I/O to the debugger console. This should
186 // also handle user overrides to /dev/null or a different file.
187 if (::strncmp(path, pts_name, ::strlen(pts_name)) == 0)
188 path = default_path;
189 }
190
191 return path;
192}
193
194Error
195ProcessPOSIX::DoLaunch (Module *module,
196 const ProcessLaunchInfo &launch_info)
197{
198 Error error;
199 assert(m_monitor == NULL);
200
Daniel Malea1e44fdd2013-01-08 14:49:22 +0000201 const char* working_dir = launch_info.GetWorkingDirectory();
202 if (working_dir) {
203 FileSpec WorkingDir(working_dir, true);
204 if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
205 {
206 error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
207 return error;
208 }
209 }
210
Johnny Chen2341d352012-01-05 21:48:15 +0000211 SetPrivateState(eStateLaunching);
212
213 const lldb_private::ProcessLaunchInfo::FileAction *file_action;
214
215 // Default of NULL will mean to use existing open file descriptors
216 const char *stdin_path = NULL;
217 const char *stdout_path = NULL;
218 const char *stderr_path = NULL;
Daniel Malea1e44fdd2013-01-08 14:49:22 +0000219
Johnny Chen2341d352012-01-05 21:48:15 +0000220 file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
221 stdin_path = GetFilePath(file_action, stdin_path);
222
223 file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
224 stdout_path = GetFilePath(file_action, stdout_path);
225
226 file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
227 stderr_path = GetFilePath(file_action, stderr_path);
228
229 m_monitor = new ProcessMonitor (this,
230 module,
231 launch_info.GetArguments().GetConstArgumentVector(),
232 launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
233 stdin_path,
234 stdout_path,
235 stderr_path,
Daniel Malea1e44fdd2013-01-08 14:49:22 +0000236 working_dir,
Johnny Chen2341d352012-01-05 21:48:15 +0000237 error);
238
239 m_module = module;
240
241 if (!error.Success())
242 return error;
243
Matt Kopeca7cd95d2013-03-14 21:35:26 +0000244 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
245
Johnny Chen2341d352012-01-05 21:48:15 +0000246 SetID(m_monitor->GetPID());
247 return error;
248}
249
250void
251ProcessPOSIX::DidLaunch()
252{
253}
254
255Error
256ProcessPOSIX::DoResume()
257{
258 StateType state = GetPrivateState();
259
260 assert(state == eStateStopped || state == eStateCrashed);
261
262 // We are about to resume a thread that will cause the process to exit so
263 // set our exit status now. Do not change our state if the inferior
264 // crashed.
265 if (state == eStateStopped)
266 {
267 if (m_in_limbo)
268 SetExitStatus(m_exit_status, NULL);
269 else
270 SetPrivateState(eStateRunning);
271 }
272
273 bool did_resume = false;
274 uint32_t thread_count = m_thread_list.GetSize(false);
275 for (uint32_t i = 0; i < thread_count; ++i)
276 {
277 POSIXThread *thread = static_cast<POSIXThread*>(
278 m_thread_list.GetThreadAtIndex(i, false).get());
279 did_resume = thread->Resume() || did_resume;
280 }
281 assert(did_resume && "Process resume failed!");
282
283 return Error();
284}
285
286addr_t
287ProcessPOSIX::GetImageInfoAddress()
288{
289 Target *target = &GetTarget();
290 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
291 Address addr = obj_file->GetImageInfoAddress();
292
293 if (addr.IsValid())
294 return addr.GetLoadAddress(target);
295 else
296 return LLDB_INVALID_ADDRESS;
297}
298
299Error
300ProcessPOSIX::DoHalt(bool &caused_stop)
301{
302 Error error;
303
304 if (IsStopped())
305 {
306 caused_stop = false;
307 }
308 else if (kill(GetID(), SIGSTOP))
309 {
310 caused_stop = false;
311 error.SetErrorToErrno();
312 }
313 else
314 {
315 caused_stop = true;
316 }
Johnny Chen2341d352012-01-05 21:48:15 +0000317 return error;
318}
319
320Error
Jim Ingham761afb82013-05-02 00:27:30 +0000321ProcessPOSIX::DoDetach(bool keep_stopped)
Johnny Chen2341d352012-01-05 21:48:15 +0000322{
323 Error error;
Jim Ingham761afb82013-05-02 00:27:30 +0000324 if (keep_stopped)
325 {
326 // FIXME: If you want to implement keep_stopped on Linux,
327 // this would be the place to do it.
328 error.SetErrorString("Detaching with keep_stopped true is not currently supported on Linux.");
329 return error;
330 }
Johnny Chen2341d352012-01-05 21:48:15 +0000331
332 error = m_monitor->Detach();
333 if (error.Success())
334 SetPrivateState(eStateDetached);
335
336 return error;
337}
338
339Error
340ProcessPOSIX::DoSignal(int signal)
341{
342 Error error;
343
344 if (kill(GetID(), signal))
345 error.SetErrorToErrno();
346
347 return error;
348}
349
350Error
351ProcessPOSIX::DoDestroy()
352{
353 Error error;
354
355 if (!HasExited())
356 {
357 // Drive the exit event to completion (do not keep the inferior in
358 // limbo).
359 m_exit_now = true;
360
Greg Clayton972c4382012-03-30 19:56:32 +0000361 if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success())
Johnny Chen2341d352012-01-05 21:48:15 +0000362 {
363 error.SetErrorToErrno();
364 return error;
365 }
366
367 SetPrivateState(eStateExited);
368 }
369
370 return error;
371}
372
373void
374ProcessPOSIX::SendMessage(const ProcessMessage &message)
375{
376 Mutex::Locker lock(m_message_mutex);
377
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000378 POSIXThread *thread = static_cast<POSIXThread*>(
379 m_thread_list.FindThreadByID(message.GetTID(), false).get());
380
Johnny Chen2341d352012-01-05 21:48:15 +0000381 switch (message.GetKind())
382 {
Johnny Chen2341d352012-01-05 21:48:15 +0000383 case ProcessMessage::eInvalidMessage:
384 return;
385
386 case ProcessMessage::eLimboMessage:
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000387 assert(thread);
388 thread->SetState(eStateStopped);
389 if (message.GetTID() == GetID())
Johnny Chen2341d352012-01-05 21:48:15 +0000390 {
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000391 m_in_limbo = true;
392 m_exit_status = message.GetExitStatus();
393 if (m_exit_now)
394 {
395 SetPrivateState(eStateExited);
396 m_monitor->Detach();
397 }
398 else
399 {
400 StopAllThreads(message.GetTID());
401 SetPrivateState(eStateStopped);
402 }
Johnny Chen2341d352012-01-05 21:48:15 +0000403 }
404 else
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000405 {
406 StopAllThreads(message.GetTID());
Johnny Chen2341d352012-01-05 21:48:15 +0000407 SetPrivateState(eStateStopped);
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000408 }
Johnny Chen2341d352012-01-05 21:48:15 +0000409 break;
410
411 case ProcessMessage::eExitMessage:
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000412 assert(thread);
413 thread->SetState(eStateExited);
414 // FIXME: I'm not sure we need to do this.
415 if (message.GetTID() == GetID())
416 {
417 m_exit_status = message.GetExitStatus();
418 SetExitStatus(m_exit_status, NULL);
419 }
Johnny Chen2341d352012-01-05 21:48:15 +0000420 break;
421
Johnny Chen2341d352012-01-05 21:48:15 +0000422 case ProcessMessage::eBreakpointMessage:
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000423 case ProcessMessage::eTraceMessage:
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000424 case ProcessMessage::eWatchpointMessage:
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000425 case ProcessMessage::eNewThreadMessage:
426 case ProcessMessage::eCrashMessage:
427 assert(thread);
428 thread->SetState(eStateStopped);
429 StopAllThreads(message.GetTID());
Johnny Chen2341d352012-01-05 21:48:15 +0000430 SetPrivateState(eStateStopped);
431 break;
432
433 case ProcessMessage::eSignalMessage:
434 case ProcessMessage::eSignalDeliveredMessage:
Matt Kopecf1fda372013-01-08 16:30:18 +0000435 {
436 lldb::tid_t tid = message.GetTID();
437 lldb::tid_t pid = GetID();
438 if (tid == pid) {
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000439 assert(thread);
440 thread->SetState(eStateStopped);
441 StopAllThreads(message.GetTID());
Matt Kopecf1fda372013-01-08 16:30:18 +0000442 SetPrivateState(eStateStopped);
443 break;
444 } else {
445 // FIXME: Ignore any signals generated by children.
446 return;
447 }
448 }
Johnny Chen2341d352012-01-05 21:48:15 +0000449
Johnny Chen2341d352012-01-05 21:48:15 +0000450 }
451
452 m_message_queue.push(message);
453}
454
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000455void
456ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid)
457{
458 // FIXME: Will this work the same way on FreeBSD and Linux?
459}
460
Johnny Chen2341d352012-01-05 21:48:15 +0000461void
462ProcessPOSIX::RefreshStateAfterStop()
463{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000464 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen2341d352012-01-05 21:48:15 +0000465 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000466 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size());
Johnny Chen2341d352012-01-05 21:48:15 +0000467
468 Mutex::Locker lock(m_message_mutex);
Johnny Chen2341d352012-01-05 21:48:15 +0000469
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000470 // This method used to only handle one message. Changing it to loop allows
471 // it to handle the case where we hit a breakpoint while handling a different
472 // breakpoint.
473 while (!m_message_queue.empty())
474 {
475 ProcessMessage &message = m_message_queue.front();
Johnny Chen2341d352012-01-05 21:48:15 +0000476
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000477 // Resolve the thread this message corresponds to and pass it along.
478 lldb::tid_t tid = message.GetTID();
479 if (log)
480 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid);
481 POSIXThread *thread = static_cast<POSIXThread*>(
482 GetThreadList().FindThreadByID(tid, false).get());
Johnny Chen2341d352012-01-05 21:48:15 +0000483
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000484 if (message.GetKind() == ProcessMessage::eNewThreadMessage)
485 {
486 if (log)
487 log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID());
488 ThreadSP thread_sp;
489 thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
490 m_thread_list.AddThread(thread_sp);
491 }
492
493 m_thread_list.RefreshStateAfterStop();
494
495 if (thread)
496 thread->Notify(message);
497
498 if (message.GetKind() == ProcessMessage::eExitMessage)
499 {
500 // FIXME: We should tell the user about this, but the limbo message is probably better for that.
501 if (log)
502 log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
503 ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
504 thread_sp.reset();
505 }
506
507 m_message_queue.pop();
Matt Kopecf1fda372013-01-08 16:30:18 +0000508 }
Johnny Chen2341d352012-01-05 21:48:15 +0000509}
510
511bool
512ProcessPOSIX::IsAlive()
513{
514 StateType state = GetPrivateState();
Daniel Malea0247cf52013-04-01 19:48:37 +0000515 return state != eStateDetached
516 && state != eStateExited
517 && state != eStateInvalid
518 && state != eStateUnloaded;
Johnny Chen2341d352012-01-05 21:48:15 +0000519}
520
521size_t
522ProcessPOSIX::DoReadMemory(addr_t vm_addr,
523 void *buf, size_t size, Error &error)
524{
525 assert(m_monitor);
526 return m_monitor->ReadMemory(vm_addr, buf, size, error);
527}
528
529size_t
530ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
531 Error &error)
532{
533 assert(m_monitor);
534 return m_monitor->WriteMemory(vm_addr, buf, size, error);
535}
536
537addr_t
538ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
539 Error &error)
540{
541 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
542
543 unsigned prot = 0;
544 if (permissions & lldb::ePermissionsReadable)
545 prot |= eMmapProtRead;
546 if (permissions & lldb::ePermissionsWritable)
547 prot |= eMmapProtWrite;
548 if (permissions & lldb::ePermissionsExecutable)
549 prot |= eMmapProtExec;
550
551 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
552 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
553 m_addr_to_mmap_size[allocated_addr] = size;
554 error.Clear();
555 } else {
556 allocated_addr = LLDB_INVALID_ADDRESS;
557 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
558 }
559
560 return allocated_addr;
561}
562
563Error
564ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
565{
566 Error error;
567 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
568 if (pos != m_addr_to_mmap_size.end() &&
569 InferiorCallMunmap(this, addr, pos->second))
570 m_addr_to_mmap_size.erase (pos);
571 else
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000572 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen2341d352012-01-05 21:48:15 +0000573
574 return error;
575}
576
Matt Kopec4f9103f2013-02-27 20:13:38 +0000577addr_t
578ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
579{
580 addr_t function_addr = LLDB_INVALID_ADDRESS;
581 if (address == NULL) {
582 error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
583 } else if (!InferiorCall(this, address, function_addr)) {
584 function_addr = LLDB_INVALID_ADDRESS;
Matt Kopec70125482013-03-01 17:44:31 +0000585 error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
586 address->CalculateSymbolContextSymbol()->GetName().AsCString());
Matt Kopec4f9103f2013-02-27 20:13:38 +0000587 }
588 return function_addr;
589}
590
Johnny Chen2341d352012-01-05 21:48:15 +0000591size_t
592ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
593{
594 static const uint8_t g_i386_opcode[] = { 0xCC };
595
596 ArchSpec arch = GetTarget().GetArchitecture();
597 const uint8_t *opcode = NULL;
598 size_t opcode_size = 0;
599
600 switch (arch.GetCore())
601 {
602 default:
603 assert(false && "CPU type not supported!");
604 break;
605
606 case ArchSpec::eCore_x86_32_i386:
607 case ArchSpec::eCore_x86_64_x86_64:
608 opcode = g_i386_opcode;
609 opcode_size = sizeof(g_i386_opcode);
610 break;
611 }
612
613 bp_site->SetTrapOpcode(opcode, opcode_size);
614 return opcode_size;
615}
616
617Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000618ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000619{
620 return EnableSoftwareBreakpoint(bp_site);
621}
622
623Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000624ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000625{
626 return DisableSoftwareBreakpoint(bp_site);
627}
628
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000629Error
630ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify)
631{
632 Error error;
633 if (wp)
634 {
635 user_id_t watchID = wp->GetID();
636 addr_t addr = wp->GetLoadAddress();
637 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
638 if (log)
639 log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")",
640 watchID);
641 if (wp->IsEnabled())
642 {
643 if (log)
644 log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64
645 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
646 watchID, (uint64_t)addr);
647 return error;
648 }
649
650 bool wp_enabled = true;
651 uint32_t thread_count = m_thread_list.GetSize(false);
652 for (uint32_t i = 0; i < thread_count; ++i)
653 {
654 POSIXThread *thread = static_cast<POSIXThread*>(
655 m_thread_list.GetThreadAtIndex(i, false).get());
656 if (thread)
657 wp_enabled &= thread->EnableHardwareWatchpoint(wp);
658 else
659 {
660 wp_enabled = false;
661 break;
662 }
663 }
664 if (wp_enabled)
665 {
666 wp->SetEnabled(true, notify);
667 return error;
668 }
669 else
670 {
671 // Watchpoint enabling failed on at least one
672 // of the threads so roll back all of them
673 DisableWatchpoint(wp, false);
674 error.SetErrorString("Setting hardware watchpoint failed");
675 }
676 }
677 else
678 error.SetErrorString("Watchpoint argument was NULL.");
679 return error;
680}
681
682Error
683ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify)
684{
685 Error error;
686 if (wp)
687 {
688 user_id_t watchID = wp->GetID();
689 addr_t addr = wp->GetLoadAddress();
690 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
691 if (log)
692 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")",
693 watchID);
694 if (!wp->IsEnabled())
695 {
696 if (log)
697 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64
698 ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
699 watchID, (uint64_t)addr);
700 // This is needed (for now) to keep watchpoints disabled correctly
701 wp->SetEnabled(false, notify);
702 return error;
703 }
704
705 if (wp->IsHardware())
706 {
707 bool wp_disabled = true;
708 uint32_t thread_count = m_thread_list.GetSize(false);
709 for (uint32_t i = 0; i < thread_count; ++i)
710 {
711 POSIXThread *thread = static_cast<POSIXThread*>(
712 m_thread_list.GetThreadAtIndex(i, false).get());
713 if (thread)
714 wp_disabled &= thread->DisableHardwareWatchpoint(wp);
715 else
716 wp_disabled = false;
717 }
718 if (wp_disabled)
719 {
720 wp->SetEnabled(false, notify);
721 return error;
722 }
723 else
724 error.SetErrorString("Disabling hardware watchpoint failed");
725 }
726 }
727 else
728 error.SetErrorString("Watchpoint argument was NULL.");
729 return error;
730}
731
732Error
733ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num)
734{
735 Error error;
736 POSIXThread *thread = static_cast<POSIXThread*>(
737 m_thread_list.GetThreadAtIndex(0, false).get());
738 if (thread)
739 num = thread->NumSupportedHardwareWatchpoints();
740 else
741 error.SetErrorString("Process does not exist.");
742 return error;
743}
744
745Error
746ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after)
747{
748 Error error = GetWatchpointSupportInfo(num);
749 // Watchpoints trigger and halt the inferior after
750 // the corresponding instruction has been executed.
751 after = true;
752 return error;
753}
754
Johnny Chen2341d352012-01-05 21:48:15 +0000755uint32_t
756ProcessPOSIX::UpdateThreadListIfNeeded()
757{
758 // Do not allow recursive updates.
759 return m_thread_list.GetSize(false);
760}
761
Greg Claytonc8dd5702012-04-12 19:04:34 +0000762bool
Johnny Chen2341d352012-01-05 21:48:15 +0000763ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
764{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000765 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +0000766 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000767 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000768
769 // Update the process thread list with this new thread.
770 // FIXME: We should be using tid, not pid.
771 assert(m_monitor);
772 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Claytone5eaa302012-02-21 18:40:07 +0000773 if (!thread_sp) {
Greg Clayton5e91e372012-10-12 16:23:23 +0000774 thread_sp.reset(new POSIXThread(*this, GetID()));
Greg Claytone5eaa302012-02-21 18:40:07 +0000775 }
Johnny Chen2341d352012-01-05 21:48:15 +0000776
777 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000778 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000779 new_thread_list.AddThread(thread_sp);
780
Greg Claytonc8dd5702012-04-12 19:04:34 +0000781 return new_thread_list.GetSize(false) > 0;
Johnny Chen2341d352012-01-05 21:48:15 +0000782}
783
784ByteOrder
785ProcessPOSIX::GetByteOrder() const
786{
787 // FIXME: We should be able to extract this value directly. See comment in
788 // ProcessPOSIX().
789 return m_byte_order;
790}
791
792size_t
793ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
794{
795 ssize_t status;
796 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
797 {
798 error.SetErrorToErrno();
799 return 0;
800 }
801 return status;
802}
803
Johnny Chen2341d352012-01-05 21:48:15 +0000804UnixSignals &
805ProcessPOSIX::GetUnixSignals()
806{
807 return m_signals;
808}
809
810//------------------------------------------------------------------------------
811// Utility functions.
812
813bool
814ProcessPOSIX::HasExited()
815{
816 switch (GetPrivateState())
817 {
818 default:
819 break;
820
821 case eStateDetached:
822 case eStateExited:
823 return true;
824 }
825
826 return false;
827}
828
829bool
830ProcessPOSIX::IsStopped()
831{
832 switch (GetPrivateState())
833 {
834 default:
835 break;
836
837 case eStateStopped:
838 case eStateCrashed:
839 case eStateSuspended:
840 return true;
841 }
842
843 return false;
844}