blob: 824d797cd79a07136e5c4a01724f25307234ec62 [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_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();
Michael Sartaina807cee2013-07-01 19:45:50 +000084 if (module && module->GetObjectFile())
Johnny Chen78dae822012-04-14 00:54:42 +000085 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
Matt Kopec52b8b752013-06-26 18:46:08 +0000259 assert(state == eStateStopped);
Johnny Chen2341d352012-01-05 21:48:15 +0000260
Matt Kopec52b8b752013-06-26 18:46:08 +0000261 SetPrivateState(eStateRunning);
Johnny Chen2341d352012-01-05 21:48:15 +0000262
263 bool did_resume = false;
264 uint32_t thread_count = m_thread_list.GetSize(false);
265 for (uint32_t i = 0; i < thread_count; ++i)
266 {
267 POSIXThread *thread = static_cast<POSIXThread*>(
268 m_thread_list.GetThreadAtIndex(i, false).get());
269 did_resume = thread->Resume() || did_resume;
270 }
271 assert(did_resume && "Process resume failed!");
272
273 return Error();
274}
275
276addr_t
277ProcessPOSIX::GetImageInfoAddress()
278{
279 Target *target = &GetTarget();
280 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
281 Address addr = obj_file->GetImageInfoAddress();
282
283 if (addr.IsValid())
284 return addr.GetLoadAddress(target);
285 else
286 return LLDB_INVALID_ADDRESS;
287}
288
289Error
290ProcessPOSIX::DoHalt(bool &caused_stop)
291{
292 Error error;
293
294 if (IsStopped())
295 {
296 caused_stop = false;
297 }
298 else if (kill(GetID(), SIGSTOP))
299 {
300 caused_stop = false;
301 error.SetErrorToErrno();
302 }
303 else
304 {
305 caused_stop = true;
306 }
Johnny Chen2341d352012-01-05 21:48:15 +0000307 return error;
308}
309
310Error
Jim Ingham761afb82013-05-02 00:27:30 +0000311ProcessPOSIX::DoDetach(bool keep_stopped)
Johnny Chen2341d352012-01-05 21:48:15 +0000312{
313 Error error;
Jim Ingham761afb82013-05-02 00:27:30 +0000314 if (keep_stopped)
315 {
316 // FIXME: If you want to implement keep_stopped on Linux,
317 // this would be the place to do it.
318 error.SetErrorString("Detaching with keep_stopped true is not currently supported on Linux.");
319 return error;
320 }
Johnny Chen2341d352012-01-05 21:48:15 +0000321
Matt Kopecc350e132013-05-31 22:00:07 +0000322 uint32_t thread_count = m_thread_list.GetSize(false);
323 for (uint32_t i = 0; i < thread_count; ++i)
324 {
325 POSIXThread *thread = static_cast<POSIXThread*>(
326 m_thread_list.GetThreadAtIndex(i, false).get());
327 error = m_monitor->Detach(thread->GetID());
328 }
329
Johnny Chen2341d352012-01-05 21:48:15 +0000330 if (error.Success())
331 SetPrivateState(eStateDetached);
332
333 return error;
334}
335
336Error
337ProcessPOSIX::DoSignal(int signal)
338{
339 Error error;
340
341 if (kill(GetID(), signal))
342 error.SetErrorToErrno();
343
344 return error;
345}
346
347Error
348ProcessPOSIX::DoDestroy()
349{
350 Error error;
351
352 if (!HasExited())
353 {
354 // Drive the exit event to completion (do not keep the inferior in
355 // limbo).
356 m_exit_now = true;
357
Greg Clayton972c4382012-03-30 19:56:32 +0000358 if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success())
Johnny Chen2341d352012-01-05 21:48:15 +0000359 {
360 error.SetErrorToErrno();
361 return error;
362 }
363
364 SetPrivateState(eStateExited);
365 }
366
367 return error;
368}
369
370void
371ProcessPOSIX::SendMessage(const ProcessMessage &message)
372{
373 Mutex::Locker lock(m_message_mutex);
374
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000375 POSIXThread *thread = static_cast<POSIXThread*>(
376 m_thread_list.FindThreadByID(message.GetTID(), false).get());
377
Johnny Chen2341d352012-01-05 21:48:15 +0000378 switch (message.GetKind())
379 {
Johnny Chen2341d352012-01-05 21:48:15 +0000380 case ProcessMessage::eInvalidMessage:
381 return;
382
383 case ProcessMessage::eLimboMessage:
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000384 assert(thread);
385 thread->SetState(eStateStopped);
386 if (message.GetTID() == GetID())
Johnny Chen2341d352012-01-05 21:48:15 +0000387 {
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000388 m_exit_status = message.GetExitStatus();
389 if (m_exit_now)
390 {
391 SetPrivateState(eStateExited);
Matt Kopecc350e132013-05-31 22:00:07 +0000392 m_monitor->Detach(GetID());
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000393 }
394 else
395 {
396 StopAllThreads(message.GetTID());
397 SetPrivateState(eStateStopped);
398 }
Johnny Chen2341d352012-01-05 21:48:15 +0000399 }
400 else
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000401 {
402 StopAllThreads(message.GetTID());
Johnny Chen2341d352012-01-05 21:48:15 +0000403 SetPrivateState(eStateStopped);
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000404 }
Johnny Chen2341d352012-01-05 21:48:15 +0000405 break;
406
407 case ProcessMessage::eExitMessage:
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000408 assert(thread);
409 thread->SetState(eStateExited);
410 // FIXME: I'm not sure we need to do this.
411 if (message.GetTID() == GetID())
412 {
413 m_exit_status = message.GetExitStatus();
414 SetExitStatus(m_exit_status, NULL);
415 }
Johnny Chen2341d352012-01-05 21:48:15 +0000416 break;
417
Johnny Chen2341d352012-01-05 21:48:15 +0000418 case ProcessMessage::eBreakpointMessage:
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000419 case ProcessMessage::eTraceMessage:
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000420 case ProcessMessage::eWatchpointMessage:
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000421 case ProcessMessage::eNewThreadMessage:
422 case ProcessMessage::eCrashMessage:
423 assert(thread);
424 thread->SetState(eStateStopped);
425 StopAllThreads(message.GetTID());
Johnny Chen2341d352012-01-05 21:48:15 +0000426 SetPrivateState(eStateStopped);
427 break;
428
429 case ProcessMessage::eSignalMessage:
430 case ProcessMessage::eSignalDeliveredMessage:
Matt Kopecf1fda372013-01-08 16:30:18 +0000431 {
432 lldb::tid_t tid = message.GetTID();
433 lldb::tid_t pid = GetID();
434 if (tid == pid) {
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000435 assert(thread);
436 thread->SetState(eStateStopped);
437 StopAllThreads(message.GetTID());
Matt Kopecf1fda372013-01-08 16:30:18 +0000438 SetPrivateState(eStateStopped);
439 break;
440 } else {
441 // FIXME: Ignore any signals generated by children.
442 return;
443 }
444 }
Johnny Chen2341d352012-01-05 21:48:15 +0000445
Johnny Chen2341d352012-01-05 21:48:15 +0000446 }
447
448 m_message_queue.push(message);
449}
450
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000451void
452ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid)
453{
454 // FIXME: Will this work the same way on FreeBSD and Linux?
455}
456
Johnny Chen2341d352012-01-05 21:48:15 +0000457void
458ProcessPOSIX::RefreshStateAfterStop()
459{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000460 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen2341d352012-01-05 21:48:15 +0000461 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000462 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size());
Johnny Chen2341d352012-01-05 21:48:15 +0000463
464 Mutex::Locker lock(m_message_mutex);
Johnny Chen2341d352012-01-05 21:48:15 +0000465
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000466 // This method used to only handle one message. Changing it to loop allows
467 // it to handle the case where we hit a breakpoint while handling a different
468 // breakpoint.
469 while (!m_message_queue.empty())
470 {
471 ProcessMessage &message = m_message_queue.front();
Johnny Chen2341d352012-01-05 21:48:15 +0000472
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000473 // Resolve the thread this message corresponds to and pass it along.
474 lldb::tid_t tid = message.GetTID();
475 if (log)
476 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid);
477 POSIXThread *thread = static_cast<POSIXThread*>(
478 GetThreadList().FindThreadByID(tid, false).get());
Johnny Chen2341d352012-01-05 21:48:15 +0000479
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000480 if (message.GetKind() == ProcessMessage::eNewThreadMessage)
481 {
482 if (log)
483 log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID());
484 ThreadSP thread_sp;
485 thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
486 m_thread_list.AddThread(thread_sp);
487 }
488
489 m_thread_list.RefreshStateAfterStop();
490
491 if (thread)
492 thread->Notify(message);
493
494 if (message.GetKind() == ProcessMessage::eExitMessage)
495 {
496 // FIXME: We should tell the user about this, but the limbo message is probably better for that.
497 if (log)
498 log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
499 ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
500 thread_sp.reset();
501 }
502
503 m_message_queue.pop();
Matt Kopecf1fda372013-01-08 16:30:18 +0000504 }
Johnny Chen2341d352012-01-05 21:48:15 +0000505}
506
507bool
508ProcessPOSIX::IsAlive()
509{
510 StateType state = GetPrivateState();
Daniel Malea0247cf52013-04-01 19:48:37 +0000511 return state != eStateDetached
512 && state != eStateExited
513 && state != eStateInvalid
514 && state != eStateUnloaded;
Johnny Chen2341d352012-01-05 21:48:15 +0000515}
516
517size_t
518ProcessPOSIX::DoReadMemory(addr_t vm_addr,
519 void *buf, size_t size, Error &error)
520{
521 assert(m_monitor);
522 return m_monitor->ReadMemory(vm_addr, buf, size, error);
523}
524
525size_t
526ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
527 Error &error)
528{
529 assert(m_monitor);
530 return m_monitor->WriteMemory(vm_addr, buf, size, error);
531}
532
533addr_t
534ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
535 Error &error)
536{
537 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
538
539 unsigned prot = 0;
540 if (permissions & lldb::ePermissionsReadable)
541 prot |= eMmapProtRead;
542 if (permissions & lldb::ePermissionsWritable)
543 prot |= eMmapProtWrite;
544 if (permissions & lldb::ePermissionsExecutable)
545 prot |= eMmapProtExec;
546
547 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
548 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
549 m_addr_to_mmap_size[allocated_addr] = size;
550 error.Clear();
551 } else {
552 allocated_addr = LLDB_INVALID_ADDRESS;
553 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
554 }
555
556 return allocated_addr;
557}
558
559Error
560ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
561{
562 Error error;
563 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
564 if (pos != m_addr_to_mmap_size.end() &&
565 InferiorCallMunmap(this, addr, pos->second))
566 m_addr_to_mmap_size.erase (pos);
567 else
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000568 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen2341d352012-01-05 21:48:15 +0000569
570 return error;
571}
572
Matt Kopec4f9103f2013-02-27 20:13:38 +0000573addr_t
574ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
575{
576 addr_t function_addr = LLDB_INVALID_ADDRESS;
577 if (address == NULL) {
578 error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
579 } else if (!InferiorCall(this, address, function_addr)) {
580 function_addr = LLDB_INVALID_ADDRESS;
Matt Kopec70125482013-03-01 17:44:31 +0000581 error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
582 address->CalculateSymbolContextSymbol()->GetName().AsCString());
Matt Kopec4f9103f2013-02-27 20:13:38 +0000583 }
584 return function_addr;
585}
586
Johnny Chen2341d352012-01-05 21:48:15 +0000587size_t
588ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
589{
590 static const uint8_t g_i386_opcode[] = { 0xCC };
591
592 ArchSpec arch = GetTarget().GetArchitecture();
593 const uint8_t *opcode = NULL;
594 size_t opcode_size = 0;
595
596 switch (arch.GetCore())
597 {
598 default:
599 assert(false && "CPU type not supported!");
600 break;
601
602 case ArchSpec::eCore_x86_32_i386:
603 case ArchSpec::eCore_x86_64_x86_64:
604 opcode = g_i386_opcode;
605 opcode_size = sizeof(g_i386_opcode);
606 break;
607 }
608
609 bp_site->SetTrapOpcode(opcode, opcode_size);
610 return opcode_size;
611}
612
613Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000614ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000615{
616 return EnableSoftwareBreakpoint(bp_site);
617}
618
619Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000620ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000621{
622 return DisableSoftwareBreakpoint(bp_site);
623}
624
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000625Error
626ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify)
627{
628 Error error;
629 if (wp)
630 {
631 user_id_t watchID = wp->GetID();
632 addr_t addr = wp->GetLoadAddress();
633 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
634 if (log)
635 log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")",
636 watchID);
637 if (wp->IsEnabled())
638 {
639 if (log)
640 log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64
641 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
642 watchID, (uint64_t)addr);
643 return error;
644 }
645
Matt Kopec12c5bf32013-06-03 17:40:20 +0000646 // Try to find a vacant watchpoint slot in the inferiors' main thread
647 uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
648 POSIXThread *thread = static_cast<POSIXThread*>(
649 m_thread_list.GetThreadAtIndex(0, false).get());
650
651 if (thread)
652 wp_hw_index = thread->FindVacantWatchpointIndex();
653
654 if (wp_hw_index == LLDB_INVALID_INDEX32)
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000655 {
Matt Kopec12c5bf32013-06-03 17:40:20 +0000656 error.SetErrorString("Setting hardware watchpoint failed.");
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000657 }
658 else
659 {
Matt Kopec12c5bf32013-06-03 17:40:20 +0000660 wp->SetHardwareIndex(wp_hw_index);
661 bool wp_enabled = true;
662 uint32_t thread_count = m_thread_list.GetSize(false);
663 for (uint32_t i = 0; i < thread_count; ++i)
664 {
665 thread = static_cast<POSIXThread*>(
666 m_thread_list.GetThreadAtIndex(i, false).get());
667 if (thread)
668 wp_enabled &= thread->EnableHardwareWatchpoint(wp);
669 else
670 wp_enabled = false;
671 }
672 if (wp_enabled)
673 {
674 wp->SetEnabled(true, notify);
675 return error;
676 }
677 else
678 {
679 // Watchpoint enabling failed on at least one
680 // of the threads so roll back all of them
681 DisableWatchpoint(wp, false);
682 error.SetErrorString("Setting hardware watchpoint failed");
683 }
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000684 }
685 }
686 else
687 error.SetErrorString("Watchpoint argument was NULL.");
688 return error;
689}
690
691Error
692ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify)
693{
694 Error error;
695 if (wp)
696 {
697 user_id_t watchID = wp->GetID();
698 addr_t addr = wp->GetLoadAddress();
699 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
700 if (log)
701 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")",
702 watchID);
703 if (!wp->IsEnabled())
704 {
705 if (log)
706 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64
707 ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
708 watchID, (uint64_t)addr);
709 // This is needed (for now) to keep watchpoints disabled correctly
710 wp->SetEnabled(false, notify);
711 return error;
712 }
713
714 if (wp->IsHardware())
715 {
716 bool wp_disabled = true;
717 uint32_t thread_count = m_thread_list.GetSize(false);
718 for (uint32_t i = 0; i < thread_count; ++i)
719 {
720 POSIXThread *thread = static_cast<POSIXThread*>(
721 m_thread_list.GetThreadAtIndex(i, false).get());
722 if (thread)
723 wp_disabled &= thread->DisableHardwareWatchpoint(wp);
724 else
725 wp_disabled = false;
726 }
727 if (wp_disabled)
728 {
Matt Kopec12c5bf32013-06-03 17:40:20 +0000729 wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000730 wp->SetEnabled(false, notify);
731 return error;
732 }
733 else
734 error.SetErrorString("Disabling hardware watchpoint failed");
735 }
736 }
737 else
738 error.SetErrorString("Watchpoint argument was NULL.");
739 return error;
740}
741
742Error
743ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num)
744{
745 Error error;
746 POSIXThread *thread = static_cast<POSIXThread*>(
747 m_thread_list.GetThreadAtIndex(0, false).get());
748 if (thread)
749 num = thread->NumSupportedHardwareWatchpoints();
750 else
751 error.SetErrorString("Process does not exist.");
752 return error;
753}
754
755Error
756ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after)
757{
758 Error error = GetWatchpointSupportInfo(num);
759 // Watchpoints trigger and halt the inferior after
760 // the corresponding instruction has been executed.
761 after = true;
762 return error;
763}
764
Johnny Chen2341d352012-01-05 21:48:15 +0000765uint32_t
766ProcessPOSIX::UpdateThreadListIfNeeded()
767{
768 // Do not allow recursive updates.
769 return m_thread_list.GetSize(false);
770}
771
Greg Claytonc8dd5702012-04-12 19:04:34 +0000772bool
Johnny Chen2341d352012-01-05 21:48:15 +0000773ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
774{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000775 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +0000776 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000777 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000778
779 // Update the process thread list with this new thread.
780 // FIXME: We should be using tid, not pid.
781 assert(m_monitor);
782 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Claytone5eaa302012-02-21 18:40:07 +0000783 if (!thread_sp) {
Greg Clayton5e91e372012-10-12 16:23:23 +0000784 thread_sp.reset(new POSIXThread(*this, GetID()));
Greg Claytone5eaa302012-02-21 18:40:07 +0000785 }
Johnny Chen2341d352012-01-05 21:48:15 +0000786
787 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000788 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000789 new_thread_list.AddThread(thread_sp);
790
Greg Claytonc8dd5702012-04-12 19:04:34 +0000791 return new_thread_list.GetSize(false) > 0;
Johnny Chen2341d352012-01-05 21:48:15 +0000792}
793
794ByteOrder
795ProcessPOSIX::GetByteOrder() const
796{
797 // FIXME: We should be able to extract this value directly. See comment in
798 // ProcessPOSIX().
799 return m_byte_order;
800}
801
802size_t
803ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
804{
805 ssize_t status;
806 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
807 {
808 error.SetErrorToErrno();
809 return 0;
810 }
811 return status;
812}
813
Johnny Chen2341d352012-01-05 21:48:15 +0000814UnixSignals &
815ProcessPOSIX::GetUnixSignals()
816{
817 return m_signals;
818}
819
820//------------------------------------------------------------------------------
821// Utility functions.
822
823bool
824ProcessPOSIX::HasExited()
825{
826 switch (GetPrivateState())
827 {
828 default:
829 break;
830
831 case eStateDetached:
832 case eStateExited:
833 return true;
834 }
835
836 return false;
837}
838
839bool
840ProcessPOSIX::IsStopped()
841{
842 switch (GetPrivateState())
843 {
844 default:
845 break;
846
847 case eStateStopped:
848 case eStateCrashed:
849 case eStateSuspended:
850 return true;
851 }
852
853 return false;
854}