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