blob: 32dfdd74aa7f1022f83327516129fa0caca6849f [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
Matt Kopecc350e132013-05-31 22:00:07 +0000332 uint32_t thread_count = m_thread_list.GetSize(false);
333 for (uint32_t i = 0; i < thread_count; ++i)
334 {
335 POSIXThread *thread = static_cast<POSIXThread*>(
336 m_thread_list.GetThreadAtIndex(i, false).get());
337 error = m_monitor->Detach(thread->GetID());
338 }
339
Johnny Chen2341d352012-01-05 21:48:15 +0000340 if (error.Success())
341 SetPrivateState(eStateDetached);
342
343 return error;
344}
345
346Error
347ProcessPOSIX::DoSignal(int signal)
348{
349 Error error;
350
351 if (kill(GetID(), signal))
352 error.SetErrorToErrno();
353
354 return error;
355}
356
357Error
358ProcessPOSIX::DoDestroy()
359{
360 Error error;
361
362 if (!HasExited())
363 {
364 // Drive the exit event to completion (do not keep the inferior in
365 // limbo).
366 m_exit_now = true;
367
Greg Clayton972c4382012-03-30 19:56:32 +0000368 if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success())
Johnny Chen2341d352012-01-05 21:48:15 +0000369 {
370 error.SetErrorToErrno();
371 return error;
372 }
373
374 SetPrivateState(eStateExited);
375 }
376
377 return error;
378}
379
380void
381ProcessPOSIX::SendMessage(const ProcessMessage &message)
382{
383 Mutex::Locker lock(m_message_mutex);
384
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000385 POSIXThread *thread = static_cast<POSIXThread*>(
386 m_thread_list.FindThreadByID(message.GetTID(), false).get());
387
Johnny Chen2341d352012-01-05 21:48:15 +0000388 switch (message.GetKind())
389 {
Johnny Chen2341d352012-01-05 21:48:15 +0000390 case ProcessMessage::eInvalidMessage:
391 return;
392
393 case ProcessMessage::eLimboMessage:
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000394 assert(thread);
395 thread->SetState(eStateStopped);
396 if (message.GetTID() == GetID())
Johnny Chen2341d352012-01-05 21:48:15 +0000397 {
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000398 m_in_limbo = true;
399 m_exit_status = message.GetExitStatus();
400 if (m_exit_now)
401 {
402 SetPrivateState(eStateExited);
Matt Kopecc350e132013-05-31 22:00:07 +0000403 m_monitor->Detach(GetID());
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000404 }
405 else
406 {
407 StopAllThreads(message.GetTID());
408 SetPrivateState(eStateStopped);
409 }
Johnny Chen2341d352012-01-05 21:48:15 +0000410 }
411 else
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000412 {
413 StopAllThreads(message.GetTID());
Johnny Chen2341d352012-01-05 21:48:15 +0000414 SetPrivateState(eStateStopped);
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000415 }
Johnny Chen2341d352012-01-05 21:48:15 +0000416 break;
417
418 case ProcessMessage::eExitMessage:
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000419 assert(thread);
420 thread->SetState(eStateExited);
421 // FIXME: I'm not sure we need to do this.
422 if (message.GetTID() == GetID())
423 {
424 m_exit_status = message.GetExitStatus();
425 SetExitStatus(m_exit_status, NULL);
426 }
Johnny Chen2341d352012-01-05 21:48:15 +0000427 break;
428
Johnny Chen2341d352012-01-05 21:48:15 +0000429 case ProcessMessage::eBreakpointMessage:
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000430 case ProcessMessage::eTraceMessage:
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000431 case ProcessMessage::eWatchpointMessage:
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000432 case ProcessMessage::eNewThreadMessage:
433 case ProcessMessage::eCrashMessage:
434 assert(thread);
435 thread->SetState(eStateStopped);
436 StopAllThreads(message.GetTID());
Johnny Chen2341d352012-01-05 21:48:15 +0000437 SetPrivateState(eStateStopped);
438 break;
439
440 case ProcessMessage::eSignalMessage:
441 case ProcessMessage::eSignalDeliveredMessage:
Matt Kopecf1fda372013-01-08 16:30:18 +0000442 {
443 lldb::tid_t tid = message.GetTID();
444 lldb::tid_t pid = GetID();
445 if (tid == pid) {
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000446 assert(thread);
447 thread->SetState(eStateStopped);
448 StopAllThreads(message.GetTID());
Matt Kopecf1fda372013-01-08 16:30:18 +0000449 SetPrivateState(eStateStopped);
450 break;
451 } else {
452 // FIXME: Ignore any signals generated by children.
453 return;
454 }
455 }
Johnny Chen2341d352012-01-05 21:48:15 +0000456
Johnny Chen2341d352012-01-05 21:48:15 +0000457 }
458
459 m_message_queue.push(message);
460}
461
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000462void
463ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid)
464{
465 // FIXME: Will this work the same way on FreeBSD and Linux?
466}
467
Johnny Chen2341d352012-01-05 21:48:15 +0000468void
469ProcessPOSIX::RefreshStateAfterStop()
470{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000471 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
Johnny Chen2341d352012-01-05 21:48:15 +0000472 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000473 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size());
Johnny Chen2341d352012-01-05 21:48:15 +0000474
475 Mutex::Locker lock(m_message_mutex);
Johnny Chen2341d352012-01-05 21:48:15 +0000476
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000477 // This method used to only handle one message. Changing it to loop allows
478 // it to handle the case where we hit a breakpoint while handling a different
479 // breakpoint.
480 while (!m_message_queue.empty())
481 {
482 ProcessMessage &message = m_message_queue.front();
Johnny Chen2341d352012-01-05 21:48:15 +0000483
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000484 // Resolve the thread this message corresponds to and pass it along.
485 lldb::tid_t tid = message.GetTID();
486 if (log)
487 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid);
488 POSIXThread *thread = static_cast<POSIXThread*>(
489 GetThreadList().FindThreadByID(tid, false).get());
Johnny Chen2341d352012-01-05 21:48:15 +0000490
Andrew Kaylor3bd2ebd2013-05-28 23:04:25 +0000491 if (message.GetKind() == ProcessMessage::eNewThreadMessage)
492 {
493 if (log)
494 log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID());
495 ThreadSP thread_sp;
496 thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
497 m_thread_list.AddThread(thread_sp);
498 }
499
500 m_thread_list.RefreshStateAfterStop();
501
502 if (thread)
503 thread->Notify(message);
504
505 if (message.GetKind() == ProcessMessage::eExitMessage)
506 {
507 // FIXME: We should tell the user about this, but the limbo message is probably better for that.
508 if (log)
509 log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
510 ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
511 thread_sp.reset();
512 }
513
514 m_message_queue.pop();
Matt Kopecf1fda372013-01-08 16:30:18 +0000515 }
Johnny Chen2341d352012-01-05 21:48:15 +0000516}
517
518bool
519ProcessPOSIX::IsAlive()
520{
521 StateType state = GetPrivateState();
Daniel Malea0247cf52013-04-01 19:48:37 +0000522 return state != eStateDetached
523 && state != eStateExited
524 && state != eStateInvalid
525 && state != eStateUnloaded;
Johnny Chen2341d352012-01-05 21:48:15 +0000526}
527
528size_t
529ProcessPOSIX::DoReadMemory(addr_t vm_addr,
530 void *buf, size_t size, Error &error)
531{
532 assert(m_monitor);
533 return m_monitor->ReadMemory(vm_addr, buf, size, error);
534}
535
536size_t
537ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
538 Error &error)
539{
540 assert(m_monitor);
541 return m_monitor->WriteMemory(vm_addr, buf, size, error);
542}
543
544addr_t
545ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
546 Error &error)
547{
548 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
549
550 unsigned prot = 0;
551 if (permissions & lldb::ePermissionsReadable)
552 prot |= eMmapProtRead;
553 if (permissions & lldb::ePermissionsWritable)
554 prot |= eMmapProtWrite;
555 if (permissions & lldb::ePermissionsExecutable)
556 prot |= eMmapProtExec;
557
558 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
559 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
560 m_addr_to_mmap_size[allocated_addr] = size;
561 error.Clear();
562 } else {
563 allocated_addr = LLDB_INVALID_ADDRESS;
564 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
565 }
566
567 return allocated_addr;
568}
569
570Error
571ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
572{
573 Error error;
574 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
575 if (pos != m_addr_to_mmap_size.end() &&
576 InferiorCallMunmap(this, addr, pos->second))
577 m_addr_to_mmap_size.erase (pos);
578 else
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000579 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
Johnny Chen2341d352012-01-05 21:48:15 +0000580
581 return error;
582}
583
Matt Kopec4f9103f2013-02-27 20:13:38 +0000584addr_t
585ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
586{
587 addr_t function_addr = LLDB_INVALID_ADDRESS;
588 if (address == NULL) {
589 error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
590 } else if (!InferiorCall(this, address, function_addr)) {
591 function_addr = LLDB_INVALID_ADDRESS;
Matt Kopec70125482013-03-01 17:44:31 +0000592 error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
593 address->CalculateSymbolContextSymbol()->GetName().AsCString());
Matt Kopec4f9103f2013-02-27 20:13:38 +0000594 }
595 return function_addr;
596}
597
Johnny Chen2341d352012-01-05 21:48:15 +0000598size_t
599ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
600{
601 static const uint8_t g_i386_opcode[] = { 0xCC };
602
603 ArchSpec arch = GetTarget().GetArchitecture();
604 const uint8_t *opcode = NULL;
605 size_t opcode_size = 0;
606
607 switch (arch.GetCore())
608 {
609 default:
610 assert(false && "CPU type not supported!");
611 break;
612
613 case ArchSpec::eCore_x86_32_i386:
614 case ArchSpec::eCore_x86_64_x86_64:
615 opcode = g_i386_opcode;
616 opcode_size = sizeof(g_i386_opcode);
617 break;
618 }
619
620 bp_site->SetTrapOpcode(opcode, opcode_size);
621 return opcode_size;
622}
623
624Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000625ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000626{
627 return EnableSoftwareBreakpoint(bp_site);
628}
629
630Error
Daniel Malea52d8dd92013-02-15 20:23:25 +0000631ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
Johnny Chen2341d352012-01-05 21:48:15 +0000632{
633 return DisableSoftwareBreakpoint(bp_site);
634}
635
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000636Error
637ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify)
638{
639 Error error;
640 if (wp)
641 {
642 user_id_t watchID = wp->GetID();
643 addr_t addr = wp->GetLoadAddress();
644 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
645 if (log)
646 log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")",
647 watchID);
648 if (wp->IsEnabled())
649 {
650 if (log)
651 log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64
652 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
653 watchID, (uint64_t)addr);
654 return error;
655 }
656
Matt Kopec12c5bf32013-06-03 17:40:20 +0000657 // Try to find a vacant watchpoint slot in the inferiors' main thread
658 uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
659 POSIXThread *thread = static_cast<POSIXThread*>(
660 m_thread_list.GetThreadAtIndex(0, false).get());
661
662 if (thread)
663 wp_hw_index = thread->FindVacantWatchpointIndex();
664
665 if (wp_hw_index == LLDB_INVALID_INDEX32)
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000666 {
Matt Kopec12c5bf32013-06-03 17:40:20 +0000667 error.SetErrorString("Setting hardware watchpoint failed.");
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000668 }
669 else
670 {
Matt Kopec12c5bf32013-06-03 17:40:20 +0000671 wp->SetHardwareIndex(wp_hw_index);
672 bool wp_enabled = true;
673 uint32_t thread_count = m_thread_list.GetSize(false);
674 for (uint32_t i = 0; i < thread_count; ++i)
675 {
676 thread = static_cast<POSIXThread*>(
677 m_thread_list.GetThreadAtIndex(i, false).get());
678 if (thread)
679 wp_enabled &= thread->EnableHardwareWatchpoint(wp);
680 else
681 wp_enabled = false;
682 }
683 if (wp_enabled)
684 {
685 wp->SetEnabled(true, notify);
686 return error;
687 }
688 else
689 {
690 // Watchpoint enabling failed on at least one
691 // of the threads so roll back all of them
692 DisableWatchpoint(wp, false);
693 error.SetErrorString("Setting hardware watchpoint failed");
694 }
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000695 }
696 }
697 else
698 error.SetErrorString("Watchpoint argument was NULL.");
699 return error;
700}
701
702Error
703ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify)
704{
705 Error error;
706 if (wp)
707 {
708 user_id_t watchID = wp->GetID();
709 addr_t addr = wp->GetLoadAddress();
710 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
711 if (log)
712 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")",
713 watchID);
714 if (!wp->IsEnabled())
715 {
716 if (log)
717 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64
718 ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
719 watchID, (uint64_t)addr);
720 // This is needed (for now) to keep watchpoints disabled correctly
721 wp->SetEnabled(false, notify);
722 return error;
723 }
724
725 if (wp->IsHardware())
726 {
727 bool wp_disabled = true;
728 uint32_t thread_count = m_thread_list.GetSize(false);
729 for (uint32_t i = 0; i < thread_count; ++i)
730 {
731 POSIXThread *thread = static_cast<POSIXThread*>(
732 m_thread_list.GetThreadAtIndex(i, false).get());
733 if (thread)
734 wp_disabled &= thread->DisableHardwareWatchpoint(wp);
735 else
736 wp_disabled = false;
737 }
738 if (wp_disabled)
739 {
Matt Kopec12c5bf32013-06-03 17:40:20 +0000740 wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
Matt Kopec3d4d51c2013-05-07 19:29:28 +0000741 wp->SetEnabled(false, notify);
742 return error;
743 }
744 else
745 error.SetErrorString("Disabling hardware watchpoint failed");
746 }
747 }
748 else
749 error.SetErrorString("Watchpoint argument was NULL.");
750 return error;
751}
752
753Error
754ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num)
755{
756 Error error;
757 POSIXThread *thread = static_cast<POSIXThread*>(
758 m_thread_list.GetThreadAtIndex(0, false).get());
759 if (thread)
760 num = thread->NumSupportedHardwareWatchpoints();
761 else
762 error.SetErrorString("Process does not exist.");
763 return error;
764}
765
766Error
767ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after)
768{
769 Error error = GetWatchpointSupportInfo(num);
770 // Watchpoints trigger and halt the inferior after
771 // the corresponding instruction has been executed.
772 after = true;
773 return error;
774}
775
Johnny Chen2341d352012-01-05 21:48:15 +0000776uint32_t
777ProcessPOSIX::UpdateThreadListIfNeeded()
778{
779 // Do not allow recursive updates.
780 return m_thread_list.GetSize(false);
781}
782
Greg Claytonc8dd5702012-04-12 19:04:34 +0000783bool
Johnny Chen2341d352012-01-05 21:48:15 +0000784ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
785{
Ashok Thirumurthid8f6b642013-03-28 16:02:31 +0000786 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
Johnny Chen2341d352012-01-05 21:48:15 +0000787 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000788 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000789
790 // Update the process thread list with this new thread.
791 // FIXME: We should be using tid, not pid.
792 assert(m_monitor);
793 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
Greg Claytone5eaa302012-02-21 18:40:07 +0000794 if (!thread_sp) {
Greg Clayton5e91e372012-10-12 16:23:23 +0000795 thread_sp.reset(new POSIXThread(*this, GetID()));
Greg Claytone5eaa302012-02-21 18:40:07 +0000796 }
Johnny Chen2341d352012-01-05 21:48:15 +0000797
798 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000799 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
Johnny Chen2341d352012-01-05 21:48:15 +0000800 new_thread_list.AddThread(thread_sp);
801
Greg Claytonc8dd5702012-04-12 19:04:34 +0000802 return new_thread_list.GetSize(false) > 0;
Johnny Chen2341d352012-01-05 21:48:15 +0000803}
804
805ByteOrder
806ProcessPOSIX::GetByteOrder() const
807{
808 // FIXME: We should be able to extract this value directly. See comment in
809 // ProcessPOSIX().
810 return m_byte_order;
811}
812
813size_t
814ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
815{
816 ssize_t status;
817 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
818 {
819 error.SetErrorToErrno();
820 return 0;
821 }
822 return status;
823}
824
Johnny Chen2341d352012-01-05 21:48:15 +0000825UnixSignals &
826ProcessPOSIX::GetUnixSignals()
827{
828 return m_signals;
829}
830
831//------------------------------------------------------------------------------
832// Utility functions.
833
834bool
835ProcessPOSIX::HasExited()
836{
837 switch (GetPrivateState())
838 {
839 default:
840 break;
841
842 case eStateDetached:
843 case eStateExited:
844 return true;
845 }
846
847 return false;
848}
849
850bool
851ProcessPOSIX::IsStopped()
852{
853 switch (GetPrivateState())
854 {
855 default:
856 break;
857
858 case eStateStopped:
859 case eStateCrashed:
860 case eStateSuspended:
861 return true;
862 }
863
864 return false;
865}