blob: 769ccd7248ac1b0b35ab260183e51041a9fc15cd [file] [log] [blame]
Johnny Chen9ed5b492012-01-05 21:48:15 +00001//===-- ProcessFreeBSD.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
10// C Includes
11#include <errno.h>
12
13// C++ Includes
Benjamin Kramer3f69fa62015-04-03 10:55:00 +000014#include <mutex>
15
Johnny Chen9ed5b492012-01-05 21:48:15 +000016// Other libraries and framework includes
17#include "lldb/Core/PluginManager.h"
18#include "lldb/Core/State.h"
19#include "lldb/Host/Host.h"
20#include "lldb/Symbol/ObjectFile.h"
21#include "lldb/Target/DynamicLoader.h"
22#include "lldb/Target/Target.h"
23
24#include "ProcessFreeBSD.h"
25#include "ProcessPOSIXLog.h"
26#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
Todd Fiala4ceced32014-08-29 17:35:57 +000027#include "Plugins/Process/Utility/FreeBSDSignals.h"
Johnny Chen9ed5b492012-01-05 21:48:15 +000028#include "ProcessMonitor.h"
Ed Maste7fd845c2013-12-09 15:51:17 +000029#include "FreeBSDThread.h"
Johnny Chen9ed5b492012-01-05 21:48:15 +000030
Ed Mastefe5a6422015-07-28 15:45:57 +000031// Other libraries and framework includes
32#include "lldb/Breakpoint/BreakpointLocation.h"
33#include "lldb/Breakpoint/Watchpoint.h"
34#include "lldb/Core/Module.h"
35#include "lldb/Core/ModuleSpec.h"
36#include "lldb/Core/PluginManager.h"
37#include "lldb/Core/State.h"
38#include "lldb/Host/FileSpec.h"
39#include "lldb/Host/Host.h"
40#include "lldb/Symbol/ObjectFile.h"
41#include "lldb/Target/DynamicLoader.h"
42#include "lldb/Target/Platform.h"
43#include "lldb/Target/Target.h"
44
45#include "lldb/Host/posix/Fcntl.h"
46
47
Johnny Chen9ed5b492012-01-05 21:48:15 +000048using namespace lldb;
49using namespace lldb_private;
50
Todd Fiala4ceced32014-08-29 17:35:57 +000051namespace
52{
53 UnixSignalsSP&
54 GetFreeBSDSignals ()
55 {
56 static UnixSignalsSP s_freebsd_signals_sp (new FreeBSDSignals ());
57 return s_freebsd_signals_sp;
58 }
59}
60
Johnny Chen9ed5b492012-01-05 21:48:15 +000061//------------------------------------------------------------------------------
62// Static functions.
63
Greg Clayton29d19302012-02-27 18:40:48 +000064lldb::ProcessSP
Zachary Turner12004eb2015-09-02 16:47:47 +000065ProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp,
Greg Clayton29d19302012-02-27 18:40:48 +000066 Listener &listener,
67 const FileSpec *crash_file_path)
Johnny Chen9ed5b492012-01-05 21:48:15 +000068{
Greg Clayton29d19302012-02-27 18:40:48 +000069 lldb::ProcessSP process_sp;
70 if (crash_file_path == NULL)
Zachary Turner12004eb2015-09-02 16:47:47 +000071 process_sp.reset(new ProcessFreeBSD (target_sp, listener, GetFreeBSDSignals()));
Greg Clayton29d19302012-02-27 18:40:48 +000072 return process_sp;
Johnny Chen9ed5b492012-01-05 21:48:15 +000073}
74
75void
76ProcessFreeBSD::Initialize()
77{
Davide Italianoc8d69822015-04-03 04:24:32 +000078 static std::once_flag g_once_flag;
Johnny Chen9ed5b492012-01-05 21:48:15 +000079
Davide Italianoc8d69822015-04-03 04:24:32 +000080 std::call_once(g_once_flag, []() {
Johnny Chen9ed5b492012-01-05 21:48:15 +000081 PluginManager::RegisterPlugin(GetPluginNameStatic(),
82 GetPluginDescriptionStatic(),
83 CreateInstance);
Robert Flack5f4b6c72015-03-11 21:14:22 +000084 ProcessPOSIXLog::Initialize(GetPluginNameStatic());
Davide Italianoc8d69822015-04-03 04:24:32 +000085 });
Johnny Chen9ed5b492012-01-05 21:48:15 +000086}
87
Greg Clayton57abc5d2013-05-10 21:47:16 +000088lldb_private::ConstString
Johnny Chen9ed5b492012-01-05 21:48:15 +000089ProcessFreeBSD::GetPluginNameStatic()
90{
Greg Clayton57abc5d2013-05-10 21:47:16 +000091 static ConstString g_name("freebsd");
92 return g_name;
Johnny Chen9ed5b492012-01-05 21:48:15 +000093}
94
95const char *
96ProcessFreeBSD::GetPluginDescriptionStatic()
97{
98 return "Process plugin for FreeBSD";
99}
100
101//------------------------------------------------------------------------------
102// ProcessInterface protocol.
103
Greg Clayton57abc5d2013-05-10 21:47:16 +0000104lldb_private::ConstString
Johnny Chen9ed5b492012-01-05 21:48:15 +0000105ProcessFreeBSD::GetPluginName()
106{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000107 return GetPluginNameStatic();
Johnny Chen9ed5b492012-01-05 21:48:15 +0000108}
109
110uint32_t
111ProcessFreeBSD::GetPluginVersion()
112{
113 return 1;
114}
115
116void
Johnny Chen9ed5b492012-01-05 21:48:15 +0000117ProcessFreeBSD::Terminate()
118{
119}
120
Ed Maste7dcb77d2013-08-30 13:11:30 +0000121Error
122ProcessFreeBSD::DoDetach(bool keep_stopped)
123{
124 Error error;
125 if (keep_stopped)
126 {
127 error.SetErrorString("Detaching with keep_stopped true is not currently supported on FreeBSD.");
128 return error;
129 }
130
131 error = m_monitor->Detach(GetID());
132
133 if (error.Success())
134 SetPrivateState(eStateDetached);
135
136 return error;
137}
138
Ed Maste7fd845c2013-12-09 15:51:17 +0000139Error
140ProcessFreeBSD::DoResume()
141{
142 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
143
Ed Maste7fd845c2013-12-09 15:51:17 +0000144 SetPrivateState(eStateRunning);
145
146 Mutex::Locker lock(m_thread_list.GetMutex());
147 bool do_step = false;
148
149 for (tid_collection::const_iterator t_pos = m_run_tids.begin(), t_end = m_run_tids.end(); t_pos != t_end; ++t_pos)
150 {
151 m_monitor->ThreadSuspend(*t_pos, false);
152 }
153 for (tid_collection::const_iterator t_pos = m_step_tids.begin(), t_end = m_step_tids.end(); t_pos != t_end; ++t_pos)
154 {
155 m_monitor->ThreadSuspend(*t_pos, false);
156 do_step = true;
157 }
158 for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(), t_end = m_suspend_tids.end(); t_pos != t_end; ++t_pos)
159 {
160 m_monitor->ThreadSuspend(*t_pos, true);
161 // XXX Cannot PT_CONTINUE properly with suspended threads.
162 do_step = true;
163 }
164
165 if (log)
Joerg Sonnenberger420708a2014-05-02 19:00:27 +0000166 log->Printf("process %" PRIu64 " resuming (%s)", GetID(), do_step ? "step" : "continue");
Ed Maste7fd845c2013-12-09 15:51:17 +0000167 if (do_step)
Ed Mastec71f60f2014-02-28 17:13:39 +0000168 m_monitor->SingleStep(GetID(), m_resume_signo);
Ed Maste7fd845c2013-12-09 15:51:17 +0000169 else
Ed Mastec71f60f2014-02-28 17:13:39 +0000170 m_monitor->Resume(GetID(), m_resume_signo);
Ed Maste7fd845c2013-12-09 15:51:17 +0000171
172 return Error();
173}
174
Greg Claytonc3c0b0e2012-04-12 19:04:34 +0000175bool
Johnny Chen9ed5b492012-01-05 21:48:15 +0000176ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
177{
Ed Maste7fd845c2013-12-09 15:51:17 +0000178 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
179 if (log)
180 log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
Daniel Maleae0f8f572013-08-26 23:57:52 +0000181
Ed Maste7fd845c2013-12-09 15:51:17 +0000182 std::vector<lldb::pid_t> tds;
183 if (!GetMonitor().GetCurrentThreadIDs(tds))
184 {
185 return false;
Daniel Maleae0f8f572013-08-26 23:57:52 +0000186 }
187
Ed Maste7fd845c2013-12-09 15:51:17 +0000188 ThreadList old_thread_list_copy(old_thread_list);
189 for (size_t i = 0; i < tds.size(); ++i)
190 {
191 tid_t tid = tds[i];
192 ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByID(tid, false));
193 if (!thread_sp)
194 {
195 thread_sp.reset(new FreeBSDThread(*this, tid));
196 if (log)
197 log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid);
198 }
199 else
200 {
201 if (log)
202 log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__, tid);
203 }
204 new_thread_list.AddThread(thread_sp);
205 }
206 for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i)
207 {
208 ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
209 if (old_thread_sp)
210 {
211 if (log)
212 log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__);
213 }
214 }
Daniel Maleae0f8f572013-08-26 23:57:52 +0000215
Ed Maste7fd845c2013-12-09 15:51:17 +0000216 return true;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000217}
Ed Maste7fd845c2013-12-09 15:51:17 +0000218
219Error
220ProcessFreeBSD::WillResume()
221{
Ed Mastec71f60f2014-02-28 17:13:39 +0000222 m_resume_signo = 0;
Ed Maste7fd845c2013-12-09 15:51:17 +0000223 m_suspend_tids.clear();
224 m_run_tids.clear();
225 m_step_tids.clear();
Ed Mastefe5a6422015-07-28 15:45:57 +0000226 return Process::WillResume();
Ed Maste7fd845c2013-12-09 15:51:17 +0000227}
228
229void
230ProcessFreeBSD::SendMessage(const ProcessMessage &message)
231{
232 Mutex::Locker lock(m_message_mutex);
233
234 switch (message.GetKind())
235 {
236 case ProcessMessage::eInvalidMessage:
237 return;
238
239 case ProcessMessage::eAttachMessage:
240 SetPrivateState(eStateStopped);
241 return;
242
243 case ProcessMessage::eLimboMessage:
244 case ProcessMessage::eExitMessage:
Todd Fiala7b0917a2014-09-15 20:07:33 +0000245 SetExitStatus(message.GetExitStatus(), NULL);
Ed Maste7fd845c2013-12-09 15:51:17 +0000246 break;
247
248 case ProcessMessage::eSignalMessage:
249 case ProcessMessage::eSignalDeliveredMessage:
250 case ProcessMessage::eBreakpointMessage:
251 case ProcessMessage::eTraceMessage:
252 case ProcessMessage::eWatchpointMessage:
253 case ProcessMessage::eCrashMessage:
254 SetPrivateState(eStateStopped);
255 break;
256
257 case ProcessMessage::eNewThreadMessage:
Ed Maste63c9fa02015-07-28 16:57:36 +0000258 llvm_unreachable("eNewThreadMessage unexpected on FreeBSD");
Ed Maste7fd845c2013-12-09 15:51:17 +0000259 break;
260
261 case ProcessMessage::eExecMessage:
262 SetPrivateState(eStateStopped);
263 break;
264 }
265
266 m_message_queue.push(message);
267}
Ed Mastefe5a6422015-07-28 15:45:57 +0000268
269//------------------------------------------------------------------------------
270// Constructors and destructors.
271
Zachary Turner12004eb2015-09-02 16:47:47 +0000272ProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp, Listener &listener, UnixSignalsSP &unix_signals_sp)
273 : Process(target_sp, listener, unix_signals_sp),
Bruce Mitchener9ccb9702015-11-07 04:40:13 +0000274 m_byte_order(endian::InlHostByteOrder()),
Ed Mastefe5a6422015-07-28 15:45:57 +0000275 m_monitor(NULL),
276 m_module(NULL),
277 m_message_mutex (Mutex::eMutexTypeRecursive),
278 m_exit_now(false),
279 m_seen_initial_stop(),
280 m_resume_signo(0)
281{
282 // FIXME: Putting this code in the ctor and saving the byte order in a
283 // member variable is a hack to avoid const qual issues in GetByteOrder.
284 lldb::ModuleSP module = GetTarget().GetExecutableModule();
285 if (module && module->GetObjectFile())
286 m_byte_order = module->GetObjectFile()->GetByteOrder();
287}
288
289ProcessFreeBSD::~ProcessFreeBSD()
290{
291 delete m_monitor;
292}
293
294//------------------------------------------------------------------------------
295// Process protocol.
296void
297ProcessFreeBSD::Finalize()
298{
299 Process::Finalize();
300
301 if (m_monitor)
302 m_monitor->StopMonitor();
303}
304
305bool
Zachary Turner12004eb2015-09-02 16:47:47 +0000306ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
Ed Mastefe5a6422015-07-28 15:45:57 +0000307{
308 // For now we are just making sure the file exists for a given module
Zachary Turner12004eb2015-09-02 16:47:47 +0000309 ModuleSP exe_module_sp(target_sp->GetExecutableModule());
Ed Mastefe5a6422015-07-28 15:45:57 +0000310 if (exe_module_sp.get())
311 return exe_module_sp->GetFileSpec().Exists();
312 // If there is no executable module, we return true since we might be preparing to attach.
313 return true;
314}
315
316Error
317ProcessFreeBSD::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info)
318{
319 Error error;
320 assert(m_monitor == NULL);
321
322 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
323 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
324 log->Printf ("ProcessFreeBSD::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
325
326 m_monitor = new ProcessMonitor(this, pid, error);
327
328 if (!error.Success())
329 return error;
330
Zachary Turner12004eb2015-09-02 16:47:47 +0000331 PlatformSP platform_sp (GetTarget().GetPlatform ());
Ed Mastefe5a6422015-07-28 15:45:57 +0000332 assert (platform_sp.get());
333 if (!platform_sp)
334 return error; // FIXME: Detatch?
335
336 // Find out what we can about this process
337 ProcessInstanceInfo process_info;
338 platform_sp->GetProcessInfo (pid, process_info);
339
340 // Resolve the executable module
341 ModuleSP exe_module_sp;
342 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
Zachary Turner12004eb2015-09-02 16:47:47 +0000343 ModuleSpec exe_module_spec(process_info.GetExecutableFile(), GetTarget().GetArchitecture());
Ed Mastefe5a6422015-07-28 15:45:57 +0000344 error = platform_sp->ResolveExecutable(exe_module_spec,
345 exe_module_sp,
346 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
347 if (!error.Success())
348 return error;
349
350 // Fix the target architecture if necessary
351 const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
Zachary Turner12004eb2015-09-02 16:47:47 +0000352 if (module_arch.IsValid() && !GetTarget().GetArchitecture().IsExactMatch(module_arch))
353 GetTarget().SetArchitecture(module_arch);
Ed Mastefe5a6422015-07-28 15:45:57 +0000354
355 // Initialize the target module list
Zachary Turner12004eb2015-09-02 16:47:47 +0000356 GetTarget().SetExecutableModule (exe_module_sp, true);
Ed Mastefe5a6422015-07-28 15:45:57 +0000357
358 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
359
360 SetID(pid);
361
362 return error;
363}
364
365Error
366ProcessFreeBSD::WillLaunch(Module* module)
367{
368 Error error;
369 return error;
370}
371
372FileSpec
373ProcessFreeBSD::GetFileSpec(const lldb_private::FileAction *file_action,
374 const FileSpec &default_file_spec,
375 const FileSpec &dbg_pts_file_spec)
376{
377 FileSpec file_spec{};
378
379 if (file_action && file_action->GetAction() == FileAction::eFileActionOpen)
380 {
381 file_spec = file_action->GetFileSpec();
382 // By default the stdio paths passed in will be pseudo-terminal
383 // (/dev/pts). If so, convert to using a different default path
384 // instead to redirect I/O to the debugger console. This should
385 // also handle user overrides to /dev/null or a different file.
386 if (!file_spec || file_spec == dbg_pts_file_spec)
387 file_spec = default_file_spec;
388 }
389 return file_spec;
390}
391
392Error
393ProcessFreeBSD::DoLaunch (Module *module,
394 ProcessLaunchInfo &launch_info)
395{
396 Error error;
397 assert(m_monitor == NULL);
398
399 FileSpec working_dir = launch_info.GetWorkingDirectory();
400 if (working_dir &&
401 (!working_dir.ResolvePath() ||
402 working_dir.GetFileType() != FileSpec::eFileTypeDirectory))
403 {
404 error.SetErrorStringWithFormat("No such file or directory: %s",
405 working_dir.GetCString());
406 return error;
407 }
408
409 SetPrivateState(eStateLaunching);
410
411 const lldb_private::FileAction *file_action;
412
413 // Default of empty will mean to use existing open file descriptors
414 FileSpec stdin_file_spec{};
415 FileSpec stdout_file_spec{};
416 FileSpec stderr_file_spec{};
417
418 const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL,0), false};
419
420 file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
421 stdin_file_spec = GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec);
422
423 file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
424 stdout_file_spec = GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec);
425
426 file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
427 stderr_file_spec = GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec);
428
429 m_monitor = new ProcessMonitor(this,
430 module,
431 launch_info.GetArguments().GetConstArgumentVector(),
432 launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
433 stdin_file_spec,
434 stdout_file_spec,
435 stderr_file_spec,
436 working_dir,
437 launch_info,
438 error);
439
440 m_module = module;
441
442 if (!error.Success())
443 return error;
444
445 int terminal = m_monitor->GetTerminalFD();
446 if (terminal >= 0) {
447 // The reader thread will close the file descriptor when done, so we pass it a copy.
Sylvestre Ledru79cb0092015-08-28 12:24:07 +0000448#ifdef F_DUPFD_CLOEXEC
Ed Mastefe5a6422015-07-28 15:45:57 +0000449 int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0);
450 if (stdio == -1) {
451 error.SetErrorToErrno();
452 return error;
453 }
Sylvestre Ledru79cb0092015-08-28 12:24:07 +0000454#else
455 // Special case when F_DUPFD_CLOEXEC does not exist (Debian kFreeBSD)
456 int stdio = fcntl(terminal, F_DUPFD, 0);
457 if (stdio == -1) {
458 error.SetErrorToErrno();
459 return error;
460 }
461 stdio = fcntl(terminal, F_SETFD, FD_CLOEXEC);
462 if (stdio == -1) {
463 error.SetErrorToErrno();
464 return error;
465 }
466#endif
Ed Mastefe5a6422015-07-28 15:45:57 +0000467 SetSTDIOFileDescriptor(stdio);
468 }
469
470 SetID(m_monitor->GetPID());
471 return error;
472}
473
474void
475ProcessFreeBSD::DidLaunch()
476{
477}
478
479addr_t
480ProcessFreeBSD::GetImageInfoAddress()
481{
482 Target *target = &GetTarget();
483 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
484 Address addr = obj_file->GetImageInfoAddress(target);
485
486 if (addr.IsValid())
487 return addr.GetLoadAddress(target);
488 return LLDB_INVALID_ADDRESS;
489}
490
491Error
492ProcessFreeBSD::DoHalt(bool &caused_stop)
493{
494 Error error;
495
496 if (IsStopped())
497 {
498 caused_stop = false;
499 }
500 else if (kill(GetID(), SIGSTOP))
501 {
502 caused_stop = false;
503 error.SetErrorToErrno();
504 }
505 else
506 {
507 caused_stop = true;
508 }
509 return error;
510}
511
512Error
513ProcessFreeBSD::DoSignal(int signal)
514{
515 Error error;
516
517 if (kill(GetID(), signal))
518 error.SetErrorToErrno();
519
520 return error;
521}
522
523Error
524ProcessFreeBSD::DoDestroy()
525{
526 Error error;
527
528 if (!HasExited())
529 {
530 assert(m_monitor);
531 m_exit_now = true;
532 if (GetID() == LLDB_INVALID_PROCESS_ID)
533 {
534 error.SetErrorString("invalid process id");
535 return error;
536 }
537 if (!m_monitor->Kill())
538 {
539 error.SetErrorToErrno();
540 return error;
541 }
542
543 SetPrivateState(eStateExited);
544 }
545
546 return error;
547}
548
549void
550ProcessFreeBSD::DoDidExec()
551{
552 Target *target = &GetTarget();
553 if (target)
554 {
555 PlatformSP platform_sp (target->GetPlatform());
556 assert (platform_sp.get());
557 if (platform_sp)
558 {
559 ProcessInstanceInfo process_info;
560 platform_sp->GetProcessInfo(GetID(), process_info);
561 ModuleSP exe_module_sp;
562 ModuleSpec exe_module_spec(process_info.GetExecutableFile(), target->GetArchitecture());
563 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
564 Error error = platform_sp->ResolveExecutable(exe_module_spec,
565 exe_module_sp,
566 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
567 if (!error.Success())
568 return;
569 target->SetExecutableModule(exe_module_sp, true);
570 }
571 }
572}
573
574bool
575ProcessFreeBSD::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid)
576{
577 bool added_to_set = false;
578 ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
579 if (it == m_seen_initial_stop.end())
580 {
581 m_seen_initial_stop.insert(stop_tid);
582 added_to_set = true;
583 }
584 return added_to_set;
585}
586
587bool
588ProcessFreeBSD::WaitingForInitialStop(lldb::tid_t stop_tid)
589{
590 return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
591}
592
593FreeBSDThread *
594ProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process, lldb::tid_t tid)
595{
596 return new FreeBSDThread(process, tid);
597}
598
599void
600ProcessFreeBSD::RefreshStateAfterStop()
601{
602 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
603 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
604 log->Printf ("ProcessFreeBSD::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size());
605
606 Mutex::Locker lock(m_message_mutex);
607
608 // This method used to only handle one message. Changing it to loop allows
609 // it to handle the case where we hit a breakpoint while handling a different
610 // breakpoint.
611 while (!m_message_queue.empty())
612 {
613 ProcessMessage &message = m_message_queue.front();
614
615 // Resolve the thread this message corresponds to and pass it along.
616 lldb::tid_t tid = message.GetTID();
617 if (log)
618 log->Printf ("ProcessFreeBSD::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid);
619
Ed Mastefe5a6422015-07-28 15:45:57 +0000620 m_thread_list.RefreshStateAfterStop();
621
622 FreeBSDThread *thread = static_cast<FreeBSDThread*>(
623 GetThreadList().FindThreadByID(tid, false).get());
624 if (thread)
625 thread->Notify(message);
626
627 if (message.GetKind() == ProcessMessage::eExitMessage)
628 {
629 // FIXME: We should tell the user about this, but the limbo message is probably better for that.
630 if (log)
631 log->Printf ("ProcessFreeBSD::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
632
633 Mutex::Locker lock(m_thread_list.GetMutex());
634
635 ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
636 thread_sp.reset();
637 m_seen_initial_stop.erase(tid);
638 }
639
640 m_message_queue.pop();
641 }
642}
643
644bool
645ProcessFreeBSD::IsAlive()
646{
647 StateType state = GetPrivateState();
648 return state != eStateDetached
649 && state != eStateExited
650 && state != eStateInvalid
651 && state != eStateUnloaded;
652}
653
654size_t
655ProcessFreeBSD::DoReadMemory(addr_t vm_addr,
656 void *buf, size_t size, Error &error)
657{
658 assert(m_monitor);
659 return m_monitor->ReadMemory(vm_addr, buf, size, error);
660}
661
662size_t
663ProcessFreeBSD::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
664 Error &error)
665{
666 assert(m_monitor);
667 return m_monitor->WriteMemory(vm_addr, buf, size, error);
668}
669
670addr_t
671ProcessFreeBSD::DoAllocateMemory(size_t size, uint32_t permissions,
672 Error &error)
673{
674 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
675
676 unsigned prot = 0;
677 if (permissions & lldb::ePermissionsReadable)
678 prot |= eMmapProtRead;
679 if (permissions & lldb::ePermissionsWritable)
680 prot |= eMmapProtWrite;
681 if (permissions & lldb::ePermissionsExecutable)
682 prot |= eMmapProtExec;
683
684 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
685 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
686 m_addr_to_mmap_size[allocated_addr] = size;
687 error.Clear();
688 } else {
689 allocated_addr = LLDB_INVALID_ADDRESS;
690 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
691 }
692
693 return allocated_addr;
694}
695
696Error
697ProcessFreeBSD::DoDeallocateMemory(lldb::addr_t addr)
698{
699 Error error;
700 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
701 if (pos != m_addr_to_mmap_size.end() &&
702 InferiorCallMunmap(this, addr, pos->second))
703 m_addr_to_mmap_size.erase (pos);
704 else
705 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
706
707 return error;
708}
709
710size_t
711ProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
712{
713 static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xD4 };
714 static const uint8_t g_i386_opcode[] = { 0xCC };
715
716 ArchSpec arch = GetTarget().GetArchitecture();
717 const uint8_t *opcode = NULL;
718 size_t opcode_size = 0;
719
720 switch (arch.GetMachine())
721 {
722 default:
723 assert(false && "CPU type not supported!");
724 break;
725
726 case llvm::Triple::arm:
727 {
728 // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
729 // but the linux kernel does otherwise.
730 static const uint8_t g_arm_breakpoint_opcode[] = { 0xf0, 0x01, 0xf0, 0xe7 };
731 static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };
732
733 lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
734 AddressClass addr_class = eAddressClassUnknown;
735
736 if (bp_loc_sp)
737 addr_class = bp_loc_sp->GetAddress ().GetAddressClass ();
738
739 if (addr_class == eAddressClassCodeAlternateISA
740 || (addr_class == eAddressClassUnknown
741 && bp_loc_sp->GetAddress().GetOffset() & 1))
742 {
743 opcode = g_thumb_breakpoint_opcode;
744 opcode_size = sizeof(g_thumb_breakpoint_opcode);
745 }
746 else
747 {
748 opcode = g_arm_breakpoint_opcode;
749 opcode_size = sizeof(g_arm_breakpoint_opcode);
750 }
751 }
752 break;
753 case llvm::Triple::aarch64:
754 opcode = g_aarch64_opcode;
755 opcode_size = sizeof(g_aarch64_opcode);
756 break;
757
758 case llvm::Triple::x86:
759 case llvm::Triple::x86_64:
760 opcode = g_i386_opcode;
761 opcode_size = sizeof(g_i386_opcode);
762 break;
763 }
764
765 bp_site->SetTrapOpcode(opcode, opcode_size);
766 return opcode_size;
767}
768
769Error
770ProcessFreeBSD::EnableBreakpointSite(BreakpointSite *bp_site)
771{
772 return EnableSoftwareBreakpoint(bp_site);
773}
774
775Error
776ProcessFreeBSD::DisableBreakpointSite(BreakpointSite *bp_site)
777{
778 return DisableSoftwareBreakpoint(bp_site);
779}
780
781Error
782ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify)
783{
784 Error error;
785 if (wp)
786 {
787 user_id_t watchID = wp->GetID();
788 addr_t addr = wp->GetLoadAddress();
789 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
790 if (log)
791 log->Printf ("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
792 watchID);
793 if (wp->IsEnabled())
794 {
795 if (log)
796 log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
797 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
798 watchID, (uint64_t)addr);
799 return error;
800 }
801
802 // Try to find a vacant watchpoint slot in the inferiors' main thread
803 uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
804 Mutex::Locker lock(m_thread_list.GetMutex());
805 FreeBSDThread *thread = static_cast<FreeBSDThread*>(
806 m_thread_list.GetThreadAtIndex(0, false).get());
807
808 if (thread)
809 wp_hw_index = thread->FindVacantWatchpointIndex();
810
811 if (wp_hw_index == LLDB_INVALID_INDEX32)
812 {
813 error.SetErrorString("Setting hardware watchpoint failed.");
814 }
815 else
816 {
817 wp->SetHardwareIndex(wp_hw_index);
818 bool wp_enabled = true;
819 uint32_t thread_count = m_thread_list.GetSize(false);
820 for (uint32_t i = 0; i < thread_count; ++i)
821 {
822 thread = static_cast<FreeBSDThread*>(
823 m_thread_list.GetThreadAtIndex(i, false).get());
824 if (thread)
825 wp_enabled &= thread->EnableHardwareWatchpoint(wp);
826 else
827 wp_enabled = false;
828 }
829 if (wp_enabled)
830 {
831 wp->SetEnabled(true, notify);
832 return error;
833 }
834 else
835 {
836 // Watchpoint enabling failed on at least one
837 // of the threads so roll back all of them
838 DisableWatchpoint(wp, false);
839 error.SetErrorString("Setting hardware watchpoint failed");
840 }
841 }
842 }
843 else
844 error.SetErrorString("Watchpoint argument was NULL.");
845 return error;
846}
847
848Error
849ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify)
850{
851 Error error;
852 if (wp)
853 {
854 user_id_t watchID = wp->GetID();
855 addr_t addr = wp->GetLoadAddress();
856 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
857 if (log)
858 log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
859 watchID);
860 if (!wp->IsEnabled())
861 {
862 if (log)
863 log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
864 ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
865 watchID, (uint64_t)addr);
866 // This is needed (for now) to keep watchpoints disabled correctly
867 wp->SetEnabled(false, notify);
868 return error;
869 }
870
871 if (wp->IsHardware())
872 {
873 bool wp_disabled = true;
874 Mutex::Locker lock(m_thread_list.GetMutex());
875 uint32_t thread_count = m_thread_list.GetSize(false);
876 for (uint32_t i = 0; i < thread_count; ++i)
877 {
878 FreeBSDThread *thread = static_cast<FreeBSDThread*>(
879 m_thread_list.GetThreadAtIndex(i, false).get());
880 if (thread)
881 wp_disabled &= thread->DisableHardwareWatchpoint(wp);
882 else
883 wp_disabled = false;
884 }
885 if (wp_disabled)
886 {
887 wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
888 wp->SetEnabled(false, notify);
889 return error;
890 }
891 else
892 error.SetErrorString("Disabling hardware watchpoint failed");
893 }
894 }
895 else
896 error.SetErrorString("Watchpoint argument was NULL.");
897 return error;
898}
899
900Error
901ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num)
902{
903 Error error;
904 Mutex::Locker lock(m_thread_list.GetMutex());
905 FreeBSDThread *thread = static_cast<FreeBSDThread*>(
906 m_thread_list.GetThreadAtIndex(0, false).get());
907 if (thread)
908 num = thread->NumSupportedHardwareWatchpoints();
909 else
910 error.SetErrorString("Process does not exist.");
911 return error;
912}
913
914Error
915ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after)
916{
917 Error error = GetWatchpointSupportInfo(num);
918 // Watchpoints trigger and halt the inferior after
919 // the corresponding instruction has been executed.
920 after = true;
921 return error;
922}
923
924uint32_t
925ProcessFreeBSD::UpdateThreadListIfNeeded()
926{
927 Mutex::Locker lock(m_thread_list.GetMutex());
928 // Do not allow recursive updates.
929 return m_thread_list.GetSize(false);
930}
931
932#if 0
933bool
934ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
935{
936 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
937 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
938 log->Printf ("ProcessFreeBSD::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
939
940 bool has_updated = false;
941 // Update the process thread list with this new thread.
942 // FIXME: We should be using tid, not pid.
943 assert(m_monitor);
944 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
945 if (!thread_sp) {
946 thread_sp.reset(CreateNewFreeBSDThread(*this, GetID()));
947 has_updated = true;
948 }
949
950 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
951 log->Printf ("ProcessFreeBSD::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
952 new_thread_list.AddThread(thread_sp);
953
954 return has_updated; // the list has been updated
955}
956#endif
957
958ByteOrder
959ProcessFreeBSD::GetByteOrder() const
960{
961 // FIXME: We should be able to extract this value directly. See comment in
962 // ProcessFreeBSD().
963 return m_byte_order;
964}
965
966size_t
967ProcessFreeBSD::PutSTDIN(const char *buf, size_t len, Error &error)
968{
969 ssize_t status;
970 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
971 {
972 error.SetErrorToErrno();
973 return 0;
974 }
975 return status;
976}
977
978//------------------------------------------------------------------------------
979// Utility functions.
980
981bool
982ProcessFreeBSD::HasExited()
983{
984 switch (GetPrivateState())
985 {
986 default:
987 break;
988
989 case eStateDetached:
990 case eStateExited:
991 return true;
992 }
993
994 return false;
995}
996
997bool
998ProcessFreeBSD::IsStopped()
999{
1000 switch (GetPrivateState())
1001 {
1002 default:
1003 break;
1004
1005 case eStateStopped:
1006 case eStateCrashed:
1007 case eStateSuspended:
1008 return true;
1009 }
1010
1011 return false;
1012}
1013
1014bool
1015ProcessFreeBSD::IsAThreadRunning()
1016{
1017 bool is_running = false;
1018 Mutex::Locker lock(m_thread_list.GetMutex());
1019 uint32_t thread_count = m_thread_list.GetSize(false);
1020 for (uint32_t i = 0; i < thread_count; ++i)
1021 {
1022 FreeBSDThread *thread = static_cast<FreeBSDThread*>(
1023 m_thread_list.GetThreadAtIndex(i, false).get());
1024 StateType thread_state = thread->GetState();
1025 if (thread_state == eStateRunning || thread_state == eStateStepping)
1026 {
1027 is_running = true;
1028 break;
1029 }
1030 }
1031 return is_running;
1032}
1033
1034const DataBufferSP
1035ProcessFreeBSD::GetAuxvData ()
1036{
1037 // If we're the local platform, we can ask the host for auxv data.
Zachary Turner12004eb2015-09-02 16:47:47 +00001038 PlatformSP platform_sp = GetTarget().GetPlatform ();
Ed Mastefe5a6422015-07-28 15:45:57 +00001039 if (platform_sp && platform_sp->IsHost ())
1040 return lldb_private::Host::GetAuxvData(this);
1041
1042 // Somewhat unexpected - the process is not running locally or we don't have a platform.
1043 assert (false && "no platform or not the host - how did we get here with ProcessFreeBSD?");
1044 return DataBufferSP ();
1045}