1314564Sdim//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++
2314564Sdim//-*-===//
3254721Semaste//
4353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5353358Sdim// See https://llvm.org/LICENSE.txt for license information.
6353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include <errno.h>
11321369Sdim#include <pthread.h>
12321369Sdim#include <pthread_np.h>
13321369Sdim#include <stdlib.h>
14321369Sdim#include <sys/sysctl.h>
15321369Sdim#include <sys/types.h>
16321369Sdim#include <sys/user.h>
17321369Sdim#include <machine/elf.h>
18254721Semaste
19288943Sdim#include <mutex>
20321369Sdim#include <unordered_map>
21288943Sdim
22254721Semaste#include "lldb/Core/PluginManager.h"
23344779Sdim#include "lldb/Host/FileSystem.h"
24254721Semaste#include "lldb/Host/Host.h"
25254721Semaste#include "lldb/Symbol/ObjectFile.h"
26254721Semaste#include "lldb/Target/DynamicLoader.h"
27254721Semaste#include "lldb/Target/Target.h"
28344779Sdim#include "lldb/Utility/RegisterValue.h"
29344779Sdim#include "lldb/Utility/State.h"
30254721Semaste
31314564Sdim#include "FreeBSDThread.h"
32321369Sdim#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
33314564Sdim#include "Plugins/Process/Utility/FreeBSDSignals.h"
34314564Sdim#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
35254721Semaste#include "ProcessFreeBSD.h"
36314564Sdim#include "ProcessMonitor.h"
37254721Semaste
38296417Sdim#include "lldb/Breakpoint/BreakpointLocation.h"
39296417Sdim#include "lldb/Breakpoint/Watchpoint.h"
40296417Sdim#include "lldb/Core/Module.h"
41296417Sdim#include "lldb/Core/ModuleSpec.h"
42296417Sdim#include "lldb/Core/PluginManager.h"
43296417Sdim#include "lldb/Host/Host.h"
44296417Sdim#include "lldb/Symbol/ObjectFile.h"
45296417Sdim#include "lldb/Target/DynamicLoader.h"
46296417Sdim#include "lldb/Target/Platform.h"
47296417Sdim#include "lldb/Target/Target.h"
48321369Sdim#include "lldb/Utility/DataBufferHeap.h"
49321369Sdim#include "lldb/Utility/FileSpec.h"
50344779Sdim#include "lldb/Utility/State.h"
51296417Sdim
52296417Sdim#include "lldb/Host/posix/Fcntl.h"
53296417Sdim
54321369Sdim#include "llvm/Support/FileSystem.h"
55321369Sdim#include "llvm/Support/Threading.h"
56321369Sdim
57254721Semasteusing namespace lldb;
58254721Semasteusing namespace lldb_private;
59254721Semaste
60314564Sdimnamespace {
61314564SdimUnixSignalsSP &GetFreeBSDSignals() {
62314564Sdim  static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals());
63314564Sdim  return s_freebsd_signals_sp;
64276479Sdim}
65314564Sdim}
66276479Sdim
67254721Semaste// Static functions.
68254721Semaste
69254721Semastelldb::ProcessSP
70296417SdimProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp,
71309124Sdim                               lldb::ListenerSP listener_sp,
72314564Sdim                               const FileSpec *crash_file_path) {
73314564Sdim  lldb::ProcessSP process_sp;
74314564Sdim  if (crash_file_path == NULL)
75314564Sdim    process_sp.reset(
76314564Sdim        new ProcessFreeBSD(target_sp, listener_sp, GetFreeBSDSignals()));
77314564Sdim  return process_sp;
78254721Semaste}
79254721Semaste
80314564Sdimvoid ProcessFreeBSD::Initialize() {
81321369Sdim  static llvm::once_flag g_once_flag;
82254721Semaste
83321369Sdim  llvm::call_once(g_once_flag, []() {
84314564Sdim    PluginManager::RegisterPlugin(GetPluginNameStatic(),
85314564Sdim                                  GetPluginDescriptionStatic(), CreateInstance);
86314564Sdim  });
87254721Semaste}
88254721Semaste
89314564Sdimlldb_private::ConstString ProcessFreeBSD::GetPluginNameStatic() {
90314564Sdim  static ConstString g_name("freebsd");
91314564Sdim  return g_name;
92254721Semaste}
93254721Semaste
94314564Sdimconst char *ProcessFreeBSD::GetPluginDescriptionStatic() {
95314564Sdim  return "Process plugin for FreeBSD";
96254721Semaste}
97254721Semaste
98254721Semaste// ProcessInterface protocol.
99254721Semaste
100314564Sdimlldb_private::ConstString ProcessFreeBSD::GetPluginName() {
101314564Sdim  return GetPluginNameStatic();
102254721Semaste}
103254721Semaste
104314564Sdimuint32_t ProcessFreeBSD::GetPluginVersion() { return 1; }
105254721Semaste
106314564Sdimvoid ProcessFreeBSD::Terminate() {}
107254721Semaste
108321369SdimStatus ProcessFreeBSD::DoDetach(bool keep_stopped) {
109321369Sdim  Status error;
110314564Sdim  if (keep_stopped) {
111314564Sdim    error.SetErrorString("Detaching with keep_stopped true is not currently "
112314564Sdim                         "supported on FreeBSD.");
113314564Sdim    return error;
114314564Sdim  }
115258054Semaste
116314564Sdim  error = m_monitor->Detach(GetID());
117258054Semaste
118314564Sdim  if (error.Success())
119314564Sdim    SetPrivateState(eStateDetached);
120258054Semaste
121314564Sdim  return error;
122258054Semaste}
123258054Semaste
124321369SdimStatus ProcessFreeBSD::DoResume() {
125314564Sdim  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
126258892Semaste
127314564Sdim  SetPrivateState(eStateRunning);
128258892Semaste
129314564Sdim  std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
130314564Sdim  bool do_step = false;
131321369Sdim  bool software_single_step = !SupportHardwareSingleStepping();
132258892Semaste
133314564Sdim  for (tid_collection::const_iterator t_pos = m_run_tids.begin(),
134314564Sdim                                      t_end = m_run_tids.end();
135314564Sdim       t_pos != t_end; ++t_pos) {
136314564Sdim    m_monitor->ThreadSuspend(*t_pos, false);
137314564Sdim  }
138314564Sdim  for (tid_collection::const_iterator t_pos = m_step_tids.begin(),
139314564Sdim                                      t_end = m_step_tids.end();
140314564Sdim       t_pos != t_end; ++t_pos) {
141314564Sdim    m_monitor->ThreadSuspend(*t_pos, false);
142314564Sdim    do_step = true;
143321369Sdim    if (software_single_step) {
144321369Sdim      Status error = SetupSoftwareSingleStepping(*t_pos);
145321369Sdim      if (error.Fail())
146321369Sdim        return error;
147321369Sdim    }
148314564Sdim  }
149314564Sdim  for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(),
150314564Sdim                                      t_end = m_suspend_tids.end();
151314564Sdim       t_pos != t_end; ++t_pos) {
152314564Sdim    m_monitor->ThreadSuspend(*t_pos, true);
153314564Sdim    // XXX Cannot PT_CONTINUE properly with suspended threads.
154314564Sdim    do_step = true;
155314564Sdim  }
156258892Semaste
157360784Sdim  LLDB_LOGF(log, "process %" PRIu64 " resuming (%s)", GetID(),
158360784Sdim            do_step ? "step" : "continue");
159321369Sdim  if (do_step && !software_single_step)
160314564Sdim    m_monitor->SingleStep(GetID(), m_resume_signo);
161314564Sdim  else
162314564Sdim    m_monitor->Resume(GetID(), m_resume_signo);
163258892Semaste
164321369Sdim  return Status();
165258892Semaste}
166258892Semaste
167314564Sdimbool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list,
168314564Sdim                                      ThreadList &new_thread_list) {
169314564Sdim  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
170360784Sdim  LLDB_LOGF(log, "ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__,
171360784Sdim            GetID());
172258054Semaste
173314564Sdim  std::vector<lldb::pid_t> tds;
174314564Sdim  if (!GetMonitor().GetCurrentThreadIDs(tds)) {
175314564Sdim    return false;
176314564Sdim  }
177258054Semaste
178314564Sdim  ThreadList old_thread_list_copy(old_thread_list);
179314564Sdim  for (size_t i = 0; i < tds.size(); ++i) {
180314564Sdim    tid_t tid = tds[i];
181314564Sdim    ThreadSP thread_sp(old_thread_list_copy.RemoveThreadByID(tid, false));
182314564Sdim    if (!thread_sp) {
183314564Sdim      thread_sp.reset(new FreeBSDThread(*this, tid));
184360784Sdim      LLDB_LOGF(log, "ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__,
185360784Sdim                tid);
186314564Sdim    } else {
187360784Sdim      LLDB_LOGF(log, "ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__,
188360784Sdim                tid);
189258892Semaste    }
190314564Sdim    new_thread_list.AddThread(thread_sp);
191314564Sdim  }
192314564Sdim  for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) {
193314564Sdim    ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
194314564Sdim    if (old_thread_sp) {
195360784Sdim      LLDB_LOGF(log, "ProcessFreeBSD::%s remove tid", __FUNCTION__);
196258892Semaste    }
197314564Sdim  }
198258054Semaste
199314564Sdim  return true;
200258892Semaste}
201258054Semaste
202321369SdimStatus ProcessFreeBSD::WillResume() {
203314564Sdim  m_resume_signo = 0;
204314564Sdim  m_suspend_tids.clear();
205314564Sdim  m_run_tids.clear();
206314564Sdim  m_step_tids.clear();
207314564Sdim  return Process::WillResume();
208254721Semaste}
209258892Semaste
210314564Sdimvoid ProcessFreeBSD::SendMessage(const ProcessMessage &message) {
211314564Sdim  std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
212258892Semaste
213314564Sdim  switch (message.GetKind()) {
214314564Sdim  case ProcessMessage::eInvalidMessage:
215314564Sdim    return;
216258892Semaste
217314564Sdim  case ProcessMessage::eAttachMessage:
218314564Sdim    SetPrivateState(eStateStopped);
219314564Sdim    return;
220258892Semaste
221314564Sdim  case ProcessMessage::eLimboMessage:
222314564Sdim  case ProcessMessage::eExitMessage:
223314564Sdim    SetExitStatus(message.GetExitStatus(), NULL);
224314564Sdim    break;
225258892Semaste
226314564Sdim  case ProcessMessage::eSignalMessage:
227314564Sdim  case ProcessMessage::eSignalDeliveredMessage:
228314564Sdim  case ProcessMessage::eBreakpointMessage:
229314564Sdim  case ProcessMessage::eTraceMessage:
230314564Sdim  case ProcessMessage::eWatchpointMessage:
231314564Sdim  case ProcessMessage::eCrashMessage:
232314564Sdim    SetPrivateState(eStateStopped);
233314564Sdim    break;
234258892Semaste
235314564Sdim  case ProcessMessage::eNewThreadMessage:
236314564Sdim    llvm_unreachable("eNewThreadMessage unexpected on FreeBSD");
237314564Sdim    break;
238258892Semaste
239314564Sdim  case ProcessMessage::eExecMessage:
240314564Sdim    SetPrivateState(eStateStopped);
241314564Sdim    break;
242314564Sdim  }
243258892Semaste
244314564Sdim  m_message_queue.push(message);
245258892Semaste}
246296417Sdim
247296417Sdim// Constructors and destructors.
248296417Sdim
249314564SdimProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp,
250314564Sdim                               lldb::ListenerSP listener_sp,
251314564Sdim                               UnixSignalsSP &unix_signals_sp)
252309124Sdim    : Process(target_sp, listener_sp, unix_signals_sp),
253314564Sdim      m_byte_order(endian::InlHostByteOrder()), m_monitor(NULL), m_module(NULL),
254314564Sdim      m_message_mutex(), m_exit_now(false), m_seen_initial_stop(),
255314564Sdim      m_resume_signo(0) {
256314564Sdim  // FIXME: Putting this code in the ctor and saving the byte order in a
257314564Sdim  // member variable is a hack to avoid const qual issues in GetByteOrder.
258314564Sdim  lldb::ModuleSP module = GetTarget().GetExecutableModule();
259314564Sdim  if (module && module->GetObjectFile())
260314564Sdim    m_byte_order = module->GetObjectFile()->GetByteOrder();
261296417Sdim}
262296417Sdim
263314564SdimProcessFreeBSD::~ProcessFreeBSD() { delete m_monitor; }
264296417Sdim
265296417Sdim// Process protocol.
266314564Sdimvoid ProcessFreeBSD::Finalize() {
267296417Sdim  Process::Finalize();
268296417Sdim
269296417Sdim  if (m_monitor)
270296417Sdim    m_monitor->StopMonitor();
271296417Sdim}
272296417Sdim
273314564Sdimbool ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp,
274314564Sdim                              bool plugin_specified_by_name) {
275314564Sdim  // For now we are just making sure the file exists for a given module
276314564Sdim  ModuleSP exe_module_sp(target_sp->GetExecutableModule());
277314564Sdim  if (exe_module_sp.get())
278344779Sdim    return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec());
279314564Sdim  // If there is no executable module, we return true since we might be
280314564Sdim  // preparing to attach.
281314564Sdim  return true;
282296417Sdim}
283296417Sdim
284321369SdimStatus
285321369SdimProcessFreeBSD::DoAttachToProcessWithID(lldb::pid_t pid,
286321369Sdim                                        const ProcessAttachInfo &attach_info) {
287321369Sdim  Status error;
288314564Sdim  assert(m_monitor == NULL);
289296417Sdim
290314564Sdim  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
291321369Sdim  LLDB_LOGV(log, "pid = {0}", GetID());
292296417Sdim
293314564Sdim  m_monitor = new ProcessMonitor(this, pid, error);
294296417Sdim
295314564Sdim  if (!error.Success())
296314564Sdim    return error;
297296417Sdim
298314564Sdim  PlatformSP platform_sp(GetTarget().GetPlatform());
299314564Sdim  assert(platform_sp.get());
300314564Sdim  if (!platform_sp)
301314564Sdim    return error; // FIXME: Detatch?
302296417Sdim
303314564Sdim  // Find out what we can about this process
304314564Sdim  ProcessInstanceInfo process_info;
305314564Sdim  platform_sp->GetProcessInfo(pid, process_info);
306296417Sdim
307314564Sdim  // Resolve the executable module
308314564Sdim  ModuleSP exe_module_sp;
309314564Sdim  FileSpecList executable_search_paths(
310314564Sdim      Target::GetDefaultExecutableSearchPaths());
311314564Sdim  ModuleSpec exe_module_spec(process_info.GetExecutableFile(),
312314564Sdim                             GetTarget().GetArchitecture());
313314564Sdim  error = platform_sp->ResolveExecutable(
314314564Sdim      exe_module_spec, exe_module_sp,
315314564Sdim      executable_search_paths.GetSize() ? &executable_search_paths : NULL);
316314564Sdim  if (!error.Success())
317314564Sdim    return error;
318296417Sdim
319314564Sdim  // Fix the target architecture if necessary
320314564Sdim  const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
321314564Sdim  if (module_arch.IsValid() &&
322314564Sdim      !GetTarget().GetArchitecture().IsExactMatch(module_arch))
323314564Sdim    GetTarget().SetArchitecture(module_arch);
324296417Sdim
325314564Sdim  // Initialize the target module list
326344779Sdim  GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsYes);
327296417Sdim
328314564Sdim  SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
329296417Sdim
330314564Sdim  SetID(pid);
331296417Sdim
332314564Sdim  return error;
333296417Sdim}
334296417Sdim
335321369SdimStatus ProcessFreeBSD::WillLaunch(Module *module) {
336321369Sdim  Status error;
337314564Sdim  return error;
338296417Sdim}
339296417Sdim
340296417SdimFileSpec
341296417SdimProcessFreeBSD::GetFileSpec(const lldb_private::FileAction *file_action,
342314564Sdim                            const FileSpec &default_file_spec,
343314564Sdim                            const FileSpec &dbg_pts_file_spec) {
344314564Sdim  FileSpec file_spec{};
345296417Sdim
346314564Sdim  if (file_action && file_action->GetAction() == FileAction::eFileActionOpen) {
347314564Sdim    file_spec = file_action->GetFileSpec();
348341825Sdim    // By default the stdio paths passed in will be pseudo-terminal (/dev/pts).
349341825Sdim    // If so, convert to using a different default path instead to redirect I/O
350341825Sdim    // to the debugger console. This should also handle user overrides to
351341825Sdim    // /dev/null or a different file.
352314564Sdim    if (!file_spec || file_spec == dbg_pts_file_spec)
353314564Sdim      file_spec = default_file_spec;
354314564Sdim  }
355314564Sdim  return file_spec;
356296417Sdim}
357296417Sdim
358321369SdimStatus ProcessFreeBSD::DoLaunch(Module *module,
359321369Sdim                                ProcessLaunchInfo &launch_info) {
360321369Sdim  Status error;
361314564Sdim  assert(m_monitor == NULL);
362296417Sdim
363314564Sdim  FileSpec working_dir = launch_info.GetWorkingDirectory();
364344779Sdim  if (working_dir) {
365344779Sdim    FileSystem::Instance().Resolve(working_dir);
366344779Sdim    if (!FileSystem::Instance().IsDirectory(working_dir.GetPath())) {
367344779Sdim      error.SetErrorStringWithFormat("No such file or directory: %s",
368314564Sdim                                   working_dir.GetCString());
369344779Sdim      return error;
370344779Sdim    }
371314564Sdim  }
372296417Sdim
373314564Sdim  SetPrivateState(eStateLaunching);
374296417Sdim
375314564Sdim  const lldb_private::FileAction *file_action;
376296417Sdim
377314564Sdim  // Default of empty will mean to use existing open file descriptors
378314564Sdim  FileSpec stdin_file_spec{};
379314564Sdim  FileSpec stdout_file_spec{};
380314564Sdim  FileSpec stderr_file_spec{};
381296417Sdim
382344779Sdim  const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0)};
383296417Sdim
384314564Sdim  file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
385314564Sdim  stdin_file_spec =
386314564Sdim      GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec);
387296417Sdim
388314564Sdim  file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);
389314564Sdim  stdout_file_spec =
390314564Sdim      GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec);
391296417Sdim
392314564Sdim  file_action = launch_info.GetFileActionForFD(STDERR_FILENO);
393314564Sdim  stderr_file_spec =
394314564Sdim      GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec);
395296417Sdim
396314564Sdim  m_monitor = new ProcessMonitor(
397314564Sdim      this, module, launch_info.GetArguments().GetConstArgumentVector(),
398341825Sdim      launch_info.GetEnvironment(), stdin_file_spec, stdout_file_spec,
399341825Sdim      stderr_file_spec, working_dir, launch_info, error);
400296417Sdim
401314564Sdim  m_module = module;
402296417Sdim
403314564Sdim  if (!error.Success())
404314564Sdim    return error;
405296417Sdim
406314564Sdim  int terminal = m_monitor->GetTerminalFD();
407314564Sdim  if (terminal >= 0) {
408314564Sdim// The reader thread will close the file descriptor when done, so we pass it a
409314564Sdim// copy.
410296417Sdim#ifdef F_DUPFD_CLOEXEC
411314564Sdim    int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0);
412314564Sdim    if (stdio == -1) {
413314564Sdim      error.SetErrorToErrno();
414314564Sdim      return error;
415314564Sdim    }
416296417Sdim#else
417314564Sdim    // Special case when F_DUPFD_CLOEXEC does not exist (Debian kFreeBSD)
418314564Sdim    int stdio = fcntl(terminal, F_DUPFD, 0);
419314564Sdim    if (stdio == -1) {
420314564Sdim      error.SetErrorToErrno();
421314564Sdim      return error;
422314564Sdim    }
423314564Sdim    stdio = fcntl(terminal, F_SETFD, FD_CLOEXEC);
424314564Sdim    if (stdio == -1) {
425314564Sdim      error.SetErrorToErrno();
426314564Sdim      return error;
427314564Sdim    }
428296417Sdim#endif
429314564Sdim    SetSTDIOFileDescriptor(stdio);
430314564Sdim  }
431296417Sdim
432314564Sdim  SetID(m_monitor->GetPID());
433314564Sdim  return error;
434296417Sdim}
435296417Sdim
436314564Sdimvoid ProcessFreeBSD::DidLaunch() {}
437296417Sdim
438314564Sdimaddr_t ProcessFreeBSD::GetImageInfoAddress() {
439314564Sdim  Target *target = &GetTarget();
440314564Sdim  ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
441314564Sdim  Address addr = obj_file->GetImageInfoAddress(target);
442296417Sdim
443314564Sdim  if (addr.IsValid())
444314564Sdim    return addr.GetLoadAddress(target);
445314564Sdim  return LLDB_INVALID_ADDRESS;
446296417Sdim}
447296417Sdim
448321369SdimStatus ProcessFreeBSD::DoHalt(bool &caused_stop) {
449321369Sdim  Status error;
450296417Sdim
451314564Sdim  if (IsStopped()) {
452314564Sdim    caused_stop = false;
453314564Sdim  } else if (kill(GetID(), SIGSTOP)) {
454314564Sdim    caused_stop = false;
455314564Sdim    error.SetErrorToErrno();
456314564Sdim  } else {
457314564Sdim    caused_stop = true;
458314564Sdim  }
459314564Sdim  return error;
460296417Sdim}
461296417Sdim
462321369SdimStatus ProcessFreeBSD::DoSignal(int signal) {
463321369Sdim  Status error;
464296417Sdim
465314564Sdim  if (kill(GetID(), signal))
466314564Sdim    error.SetErrorToErrno();
467296417Sdim
468314564Sdim  return error;
469296417Sdim}
470296417Sdim
471321369SdimStatus ProcessFreeBSD::DoDestroy() {
472321369Sdim  Status error;
473296417Sdim
474314564Sdim  if (!HasExited()) {
475314564Sdim    assert(m_monitor);
476314564Sdim    m_exit_now = true;
477314564Sdim    if (GetID() == LLDB_INVALID_PROCESS_ID) {
478314564Sdim      error.SetErrorString("invalid process id");
479314564Sdim      return error;
480296417Sdim    }
481314564Sdim    if (!m_monitor->Kill()) {
482314564Sdim      error.SetErrorToErrno();
483314564Sdim      return error;
484314564Sdim    }
485296417Sdim
486314564Sdim    SetPrivateState(eStateExited);
487314564Sdim  }
488314564Sdim
489314564Sdim  return error;
490296417Sdim}
491296417Sdim
492314564Sdimvoid ProcessFreeBSD::DoDidExec() {
493314564Sdim  Target *target = &GetTarget();
494314564Sdim  if (target) {
495314564Sdim    PlatformSP platform_sp(target->GetPlatform());
496314564Sdim    assert(platform_sp.get());
497314564Sdim    if (platform_sp) {
498314564Sdim      ProcessInstanceInfo process_info;
499314564Sdim      platform_sp->GetProcessInfo(GetID(), process_info);
500314564Sdim      ModuleSP exe_module_sp;
501314564Sdim      ModuleSpec exe_module_spec(process_info.GetExecutableFile(),
502314564Sdim                                 target->GetArchitecture());
503314564Sdim      FileSpecList executable_search_paths(
504314564Sdim          Target::GetDefaultExecutableSearchPaths());
505321369Sdim      Status error = platform_sp->ResolveExecutable(
506314564Sdim          exe_module_spec, exe_module_sp,
507314564Sdim          executable_search_paths.GetSize() ? &executable_search_paths : NULL);
508314564Sdim      if (!error.Success())
509314564Sdim        return;
510344779Sdim      target->SetExecutableModule(exe_module_sp, eLoadDependentsYes);
511296417Sdim    }
512314564Sdim  }
513296417Sdim}
514296417Sdim
515314564Sdimbool ProcessFreeBSD::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) {
516314564Sdim  bool added_to_set = false;
517314564Sdim  ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
518314564Sdim  if (it == m_seen_initial_stop.end()) {
519314564Sdim    m_seen_initial_stop.insert(stop_tid);
520314564Sdim    added_to_set = true;
521314564Sdim  }
522314564Sdim  return added_to_set;
523296417Sdim}
524296417Sdim
525314564Sdimbool ProcessFreeBSD::WaitingForInitialStop(lldb::tid_t stop_tid) {
526314564Sdim  return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
527296417Sdim}
528296417Sdim
529296417SdimFreeBSDThread *
530314564SdimProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process,
531314564Sdim                                       lldb::tid_t tid) {
532314564Sdim  return new FreeBSDThread(process, tid);
533296417Sdim}
534296417Sdim
535314564Sdimvoid ProcessFreeBSD::RefreshStateAfterStop() {
536314564Sdim  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
537321369Sdim  LLDB_LOGV(log, "message_queue size = {0}", m_message_queue.size());
538296417Sdim
539314564Sdim  std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
540296417Sdim
541314564Sdim  // This method used to only handle one message.  Changing it to loop allows
542314564Sdim  // it to handle the case where we hit a breakpoint while handling a different
543314564Sdim  // breakpoint.
544314564Sdim  while (!m_message_queue.empty()) {
545314564Sdim    ProcessMessage &message = m_message_queue.front();
546296417Sdim
547314564Sdim    // Resolve the thread this message corresponds to and pass it along.
548314564Sdim    lldb::tid_t tid = message.GetTID();
549321369Sdim    LLDB_LOGV(log, " message_queue size = {0}, pid = {1}",
550321369Sdim              m_message_queue.size(), tid);
551296417Sdim
552314564Sdim    m_thread_list.RefreshStateAfterStop();
553296417Sdim
554314564Sdim    FreeBSDThread *thread = static_cast<FreeBSDThread *>(
555314564Sdim        GetThreadList().FindThreadByID(tid, false).get());
556314564Sdim    if (thread)
557314564Sdim      thread->Notify(message);
558296417Sdim
559314564Sdim    if (message.GetKind() == ProcessMessage::eExitMessage) {
560314564Sdim      // FIXME: We should tell the user about this, but the limbo message is
561314564Sdim      // probably better for that.
562321369Sdim      LLDB_LOG(log, "removing thread, tid = {0}", tid);
563314564Sdim      std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
564296417Sdim
565314564Sdim      ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
566314564Sdim      thread_sp.reset();
567314564Sdim      m_seen_initial_stop.erase(tid);
568314564Sdim    }
569296417Sdim
570314564Sdim    m_message_queue.pop();
571314564Sdim  }
572296417Sdim}
573296417Sdim
574314564Sdimbool ProcessFreeBSD::IsAlive() {
575314564Sdim  StateType state = GetPrivateState();
576314564Sdim  return state != eStateDetached && state != eStateExited &&
577314564Sdim         state != eStateInvalid && state != eStateUnloaded;
578296417Sdim}
579296417Sdim
580314564Sdimsize_t ProcessFreeBSD::DoReadMemory(addr_t vm_addr, void *buf, size_t size,
581321369Sdim                                    Status &error) {
582314564Sdim  assert(m_monitor);
583314564Sdim  return m_monitor->ReadMemory(vm_addr, buf, size, error);
584296417Sdim}
585296417Sdim
586314564Sdimsize_t ProcessFreeBSD::DoWriteMemory(addr_t vm_addr, const void *buf,
587321369Sdim                                     size_t size, Status &error) {
588314564Sdim  assert(m_monitor);
589314564Sdim  return m_monitor->WriteMemory(vm_addr, buf, size, error);
590296417Sdim}
591296417Sdim
592314564Sdimaddr_t ProcessFreeBSD::DoAllocateMemory(size_t size, uint32_t permissions,
593321369Sdim                                        Status &error) {
594314564Sdim  addr_t allocated_addr = LLDB_INVALID_ADDRESS;
595296417Sdim
596314564Sdim  unsigned prot = 0;
597314564Sdim  if (permissions & lldb::ePermissionsReadable)
598314564Sdim    prot |= eMmapProtRead;
599314564Sdim  if (permissions & lldb::ePermissionsWritable)
600314564Sdim    prot |= eMmapProtWrite;
601314564Sdim  if (permissions & lldb::ePermissionsExecutable)
602314564Sdim    prot |= eMmapProtExec;
603296417Sdim
604314564Sdim  if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
605314564Sdim                       eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
606314564Sdim    m_addr_to_mmap_size[allocated_addr] = size;
607314564Sdim    error.Clear();
608314564Sdim  } else {
609314564Sdim    allocated_addr = LLDB_INVALID_ADDRESS;
610314564Sdim    error.SetErrorStringWithFormat(
611314564Sdim        "unable to allocate %zu bytes of memory with permissions %s", size,
612314564Sdim        GetPermissionsAsCString(permissions));
613314564Sdim  }
614296417Sdim
615314564Sdim  return allocated_addr;
616296417Sdim}
617296417Sdim
618321369SdimStatus ProcessFreeBSD::DoDeallocateMemory(lldb::addr_t addr) {
619321369Sdim  Status error;
620314564Sdim  MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
621314564Sdim  if (pos != m_addr_to_mmap_size.end() &&
622314564Sdim      InferiorCallMunmap(this, addr, pos->second))
623314564Sdim    m_addr_to_mmap_size.erase(pos);
624314564Sdim  else
625314564Sdim    error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64,
626314564Sdim                                   addr);
627296417Sdim
628314564Sdim  return error;
629296417Sdim}
630296417Sdim
631296417Sdimsize_t
632314564SdimProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) {
633314564Sdim  static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xD4};
634314564Sdim  static const uint8_t g_i386_opcode[] = {0xCC};
635296417Sdim
636314564Sdim  ArchSpec arch = GetTarget().GetArchitecture();
637314564Sdim  const uint8_t *opcode = NULL;
638314564Sdim  size_t opcode_size = 0;
639296417Sdim
640314564Sdim  switch (arch.GetMachine()) {
641314564Sdim  default:
642314564Sdim    assert(false && "CPU type not supported!");
643314564Sdim    break;
644296417Sdim
645314564Sdim  case llvm::Triple::arm: {
646341825Sdim    // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the
647341825Sdim    // linux kernel does otherwise.
648314564Sdim    static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
649314564Sdim    static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
650296417Sdim
651314564Sdim    lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
652341825Sdim    AddressClass addr_class = AddressClass::eUnknown;
653296417Sdim
654314564Sdim    if (bp_loc_sp)
655314564Sdim      addr_class = bp_loc_sp->GetAddress().GetAddressClass();
656296417Sdim
657341825Sdim    if (addr_class == AddressClass::eCodeAlternateISA ||
658341825Sdim        (addr_class == AddressClass::eUnknown &&
659314564Sdim         bp_loc_sp->GetAddress().GetOffset() & 1)) {
660314564Sdim      opcode = g_thumb_breakpoint_opcode;
661314564Sdim      opcode_size = sizeof(g_thumb_breakpoint_opcode);
662314564Sdim    } else {
663314564Sdim      opcode = g_arm_breakpoint_opcode;
664314564Sdim      opcode_size = sizeof(g_arm_breakpoint_opcode);
665296417Sdim    }
666314564Sdim  } break;
667314564Sdim  case llvm::Triple::aarch64:
668314564Sdim    opcode = g_aarch64_opcode;
669314564Sdim    opcode_size = sizeof(g_aarch64_opcode);
670314564Sdim    break;
671296417Sdim
672314564Sdim  case llvm::Triple::x86:
673314564Sdim  case llvm::Triple::x86_64:
674314564Sdim    opcode = g_i386_opcode;
675314564Sdim    opcode_size = sizeof(g_i386_opcode);
676314564Sdim    break;
677314564Sdim  }
678314564Sdim
679314564Sdim  bp_site->SetTrapOpcode(opcode, opcode_size);
680314564Sdim  return opcode_size;
681296417Sdim}
682296417Sdim
683321369SdimStatus ProcessFreeBSD::EnableBreakpointSite(BreakpointSite *bp_site) {
684314564Sdim  return EnableSoftwareBreakpoint(bp_site);
685296417Sdim}
686296417Sdim
687321369SdimStatus ProcessFreeBSD::DisableBreakpointSite(BreakpointSite *bp_site) {
688314564Sdim  return DisableSoftwareBreakpoint(bp_site);
689296417Sdim}
690296417Sdim
691321369SdimStatus ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) {
692321369Sdim  Status error;
693314564Sdim  if (wp) {
694314564Sdim    user_id_t watchID = wp->GetID();
695314564Sdim    addr_t addr = wp->GetLoadAddress();
696314564Sdim    Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
697360784Sdim    LLDB_LOGF(log, "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
698360784Sdim              watchID);
699314564Sdim    if (wp->IsEnabled()) {
700360784Sdim      LLDB_LOGF(log,
701360784Sdim                "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
702360784Sdim                ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
703360784Sdim                watchID, (uint64_t)addr);
704314564Sdim      return error;
705314564Sdim    }
706296417Sdim
707314564Sdim    // Try to find a vacant watchpoint slot in the inferiors' main thread
708314564Sdim    uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
709314564Sdim    std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
710314564Sdim    FreeBSDThread *thread = static_cast<FreeBSDThread *>(
711314564Sdim        m_thread_list.GetThreadAtIndex(0, false).get());
712296417Sdim
713314564Sdim    if (thread)
714314564Sdim      wp_hw_index = thread->FindVacantWatchpointIndex();
715314564Sdim
716314564Sdim    if (wp_hw_index == LLDB_INVALID_INDEX32) {
717314564Sdim      error.SetErrorString("Setting hardware watchpoint failed.");
718314564Sdim    } else {
719314564Sdim      wp->SetHardwareIndex(wp_hw_index);
720314564Sdim      bool wp_enabled = true;
721314564Sdim      uint32_t thread_count = m_thread_list.GetSize(false);
722314564Sdim      for (uint32_t i = 0; i < thread_count; ++i) {
723314564Sdim        thread = static_cast<FreeBSDThread *>(
724314564Sdim            m_thread_list.GetThreadAtIndex(i, false).get());
725296417Sdim        if (thread)
726314564Sdim          wp_enabled &= thread->EnableHardwareWatchpoint(wp);
727296417Sdim        else
728314564Sdim          wp_enabled = false;
729314564Sdim      }
730314564Sdim      if (wp_enabled) {
731314564Sdim        wp->SetEnabled(true, notify);
732314564Sdim        return error;
733314564Sdim      } else {
734341825Sdim        // Watchpoint enabling failed on at least one of the threads so roll
735341825Sdim        // back all of them
736314564Sdim        DisableWatchpoint(wp, false);
737314564Sdim        error.SetErrorString("Setting hardware watchpoint failed");
738314564Sdim      }
739296417Sdim    }
740314564Sdim  } else
741314564Sdim    error.SetErrorString("Watchpoint argument was NULL.");
742314564Sdim  return error;
743296417Sdim}
744296417Sdim
745321369SdimStatus ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify) {
746321369Sdim  Status error;
747314564Sdim  if (wp) {
748314564Sdim    user_id_t watchID = wp->GetID();
749314564Sdim    addr_t addr = wp->GetLoadAddress();
750314564Sdim    Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
751360784Sdim    LLDB_LOGF(log, "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
752360784Sdim              watchID);
753314564Sdim    if (!wp->IsEnabled()) {
754360784Sdim      LLDB_LOGF(log,
755360784Sdim                "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
756360784Sdim                ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
757360784Sdim                watchID, (uint64_t)addr);
758314564Sdim      // This is needed (for now) to keep watchpoints disabled correctly
759314564Sdim      wp->SetEnabled(false, notify);
760314564Sdim      return error;
761314564Sdim    }
762296417Sdim
763314564Sdim    if (wp->IsHardware()) {
764314564Sdim      bool wp_disabled = true;
765314564Sdim      std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
766314564Sdim      uint32_t thread_count = m_thread_list.GetSize(false);
767314564Sdim      for (uint32_t i = 0; i < thread_count; ++i) {
768314564Sdim        FreeBSDThread *thread = static_cast<FreeBSDThread *>(
769314564Sdim            m_thread_list.GetThreadAtIndex(i, false).get());
770314564Sdim        if (thread)
771314564Sdim          wp_disabled &= thread->DisableHardwareWatchpoint(wp);
772314564Sdim        else
773314564Sdim          wp_disabled = false;
774314564Sdim      }
775314564Sdim      if (wp_disabled) {
776314564Sdim        wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
777314564Sdim        wp->SetEnabled(false, notify);
778314564Sdim        return error;
779314564Sdim      } else
780314564Sdim        error.SetErrorString("Disabling hardware watchpoint failed");
781296417Sdim    }
782314564Sdim  } else
783314564Sdim    error.SetErrorString("Watchpoint argument was NULL.");
784314564Sdim  return error;
785296417Sdim}
786296417Sdim
787321369SdimStatus ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num) {
788321369Sdim  Status error;
789314564Sdim  std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
790314564Sdim  FreeBSDThread *thread = static_cast<FreeBSDThread *>(
791314564Sdim      m_thread_list.GetThreadAtIndex(0, false).get());
792314564Sdim  if (thread)
793314564Sdim    num = thread->NumSupportedHardwareWatchpoints();
794314564Sdim  else
795314564Sdim    error.SetErrorString("Process does not exist.");
796314564Sdim  return error;
797296417Sdim}
798296417Sdim
799321369SdimStatus ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after) {
800321369Sdim  Status error = GetWatchpointSupportInfo(num);
801341825Sdim  // Watchpoints trigger and halt the inferior after the corresponding
802341825Sdim  // instruction has been executed.
803314564Sdim  after = true;
804314564Sdim  return error;
805296417Sdim}
806296417Sdim
807314564Sdimuint32_t ProcessFreeBSD::UpdateThreadListIfNeeded() {
808314564Sdim  std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
809314564Sdim  // Do not allow recursive updates.
810314564Sdim  return m_thread_list.GetSize(false);
811296417Sdim}
812296417Sdim
813314564SdimByteOrder ProcessFreeBSD::GetByteOrder() const {
814314564Sdim  // FIXME: We should be able to extract this value directly.  See comment in
815314564Sdim  // ProcessFreeBSD().
816314564Sdim  return m_byte_order;
817296417Sdim}
818296417Sdim
819321369Sdimsize_t ProcessFreeBSD::PutSTDIN(const char *buf, size_t len, Status &error) {
820314564Sdim  ssize_t status;
821314564Sdim  if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) {
822314564Sdim    error.SetErrorToErrno();
823314564Sdim    return 0;
824314564Sdim  }
825314564Sdim  return status;
826296417Sdim}
827296417Sdim
828296417Sdim// Utility functions.
829296417Sdim
830314564Sdimbool ProcessFreeBSD::HasExited() {
831314564Sdim  switch (GetPrivateState()) {
832314564Sdim  default:
833314564Sdim    break;
834296417Sdim
835314564Sdim  case eStateDetached:
836314564Sdim  case eStateExited:
837314564Sdim    return true;
838314564Sdim  }
839296417Sdim
840314564Sdim  return false;
841296417Sdim}
842296417Sdim
843314564Sdimbool ProcessFreeBSD::IsStopped() {
844314564Sdim  switch (GetPrivateState()) {
845314564Sdim  default:
846314564Sdim    break;
847296417Sdim
848314564Sdim  case eStateStopped:
849314564Sdim  case eStateCrashed:
850314564Sdim  case eStateSuspended:
851314564Sdim    return true;
852314564Sdim  }
853296417Sdim
854314564Sdim  return false;
855296417Sdim}
856296417Sdim
857314564Sdimbool ProcessFreeBSD::IsAThreadRunning() {
858314564Sdim  bool is_running = false;
859314564Sdim  std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
860314564Sdim  uint32_t thread_count = m_thread_list.GetSize(false);
861314564Sdim  for (uint32_t i = 0; i < thread_count; ++i) {
862314564Sdim    FreeBSDThread *thread = static_cast<FreeBSDThread *>(
863314564Sdim        m_thread_list.GetThreadAtIndex(i, false).get());
864314564Sdim    StateType thread_state = thread->GetState();
865314564Sdim    if (thread_state == eStateRunning || thread_state == eStateStepping) {
866314564Sdim      is_running = true;
867314564Sdim      break;
868296417Sdim    }
869314564Sdim  }
870314564Sdim  return is_running;
871296417Sdim}
872296417Sdim
873353358Sdimlldb_private::DataExtractor ProcessFreeBSD::GetAuxvData() {
874314564Sdim  // If we're the local platform, we can ask the host for auxv data.
875314564Sdim  PlatformSP platform_sp = GetTarget().GetPlatform();
876321369Sdim  assert(platform_sp && platform_sp->IsHost());
877296417Sdim
878321369Sdim  int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV, (int)m_process->GetID()};
879321369Sdim  size_t auxv_size = AT_COUNT * sizeof(Elf_Auxinfo);
880321369Sdim  DataBufferSP buf_sp(new DataBufferHeap(auxv_size, 0));
881321369Sdim
882321369Sdim  if (::sysctl(mib, 4, buf_sp->GetBytes(), &auxv_size, NULL, 0) != 0) {
883321369Sdim    perror("sysctl failed on auxv");
884321369Sdim    buf_sp.reset();
885321369Sdim  }
886321369Sdim
887353358Sdim  return DataExtractor(buf_sp, GetByteOrder(), GetAddressByteSize());
888296417Sdim}
889321369Sdim
890321369Sdimstruct EmulatorBaton {
891321369Sdim  ProcessFreeBSD *m_process;
892321369Sdim  RegisterContext *m_reg_context;
893321369Sdim
894321369Sdim  // eRegisterKindDWARF -> RegisterValue
895321369Sdim  std::unordered_map<uint32_t, RegisterValue> m_register_values;
896321369Sdim
897321369Sdim  EmulatorBaton(ProcessFreeBSD *process, RegisterContext *reg_context)
898321369Sdim      : m_process(process), m_reg_context(reg_context) {}
899321369Sdim};
900321369Sdim
901321369Sdimstatic size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
902321369Sdim                                 const EmulateInstruction::Context &context,
903321369Sdim                                 lldb::addr_t addr, void *dst, size_t length) {
904321369Sdim  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
905321369Sdim
906321369Sdim  Status error;
907321369Sdim  size_t bytes_read =
908321369Sdim      emulator_baton->m_process->DoReadMemory(addr, dst, length, error);
909321369Sdim  if (!error.Success())
910321369Sdim    bytes_read = 0;
911321369Sdim  return bytes_read;
912321369Sdim}
913321369Sdim
914321369Sdimstatic bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
915321369Sdim                                 const RegisterInfo *reg_info,
916321369Sdim                                 RegisterValue &reg_value) {
917321369Sdim  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
918321369Sdim
919321369Sdim  auto it = emulator_baton->m_register_values.find(
920321369Sdim      reg_info->kinds[eRegisterKindDWARF]);
921321369Sdim  if (it != emulator_baton->m_register_values.end()) {
922321369Sdim    reg_value = it->second;
923321369Sdim    return true;
924321369Sdim  }
925321369Sdim
926321369Sdim  // The emulator only fills in the dwarf register numbers (and in some cases
927321369Sdim  // the generic register numbers). Get the full register info from the
928321369Sdim  // register context based on the dwarf register numbers.
929321369Sdim  const RegisterInfo *full_reg_info =
930321369Sdim      emulator_baton->m_reg_context->GetRegisterInfo(
931321369Sdim          eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
932321369Sdim
933321369Sdim  bool error =
934321369Sdim      emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
935321369Sdim  return error;
936321369Sdim}
937321369Sdim
938321369Sdimstatic bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
939321369Sdim                                  const EmulateInstruction::Context &context,
940321369Sdim                                  const RegisterInfo *reg_info,
941321369Sdim                                  const RegisterValue &reg_value) {
942321369Sdim  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
943321369Sdim  emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] =
944321369Sdim      reg_value;
945321369Sdim  return true;
946321369Sdim}
947321369Sdim
948321369Sdimstatic size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
949321369Sdim                                  const EmulateInstruction::Context &context,
950321369Sdim                                  lldb::addr_t addr, const void *dst,
951321369Sdim                                  size_t length) {
952321369Sdim  return length;
953321369Sdim}
954321369Sdim
955321369Sdimbool ProcessFreeBSD::SingleStepBreakpointHit(
956321369Sdim    void *baton, lldb_private::StoppointCallbackContext *context,
957321369Sdim    lldb::user_id_t break_id, lldb::user_id_t break_loc_id) {
958321369Sdim  return false;
959321369Sdim}
960321369Sdim
961321369SdimStatus ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid,
962321369Sdim                                                       lldb::addr_t addr) {
963321369Sdim  Status error;
964321369Sdim
965321369Sdim  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
966321369Sdim  if (log) {
967360784Sdim    LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
968360784Sdim    LLDB_LOGF(log, "SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__,
969360784Sdim              addr);
970321369Sdim  }
971321369Sdim
972321369Sdim  // Validate the address.
973321369Sdim  if (addr == LLDB_INVALID_ADDRESS)
974321369Sdim    return Status("ProcessFreeBSD::%s invalid load address specified.",
975321369Sdim                  __FUNCTION__);
976321369Sdim
977321369Sdim  Breakpoint *const sw_step_break =
978321369Sdim      m_process->GetTarget().CreateBreakpoint(addr, true, false).get();
979321369Sdim  sw_step_break->SetCallback(SingleStepBreakpointHit, this, true);
980360784Sdim  sw_step_break->SetBreakpointKind("software-single-step");
981321369Sdim
982360784Sdim  LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS",
983360784Sdim            __FUNCTION__, addr);
984321369Sdim
985321369Sdim  m_threads_stepping_with_breakpoint.insert({tid, sw_step_break->GetID()});
986321369Sdim  return Status();
987321369Sdim}
988321369Sdim
989321369Sdimbool ProcessFreeBSD::IsSoftwareStepBreakpoint(lldb::tid_t tid) {
990321369Sdim  ThreadSP thread = GetThreadList().FindThreadByID(tid);
991321369Sdim  if (!thread)
992321369Sdim    return false;
993321369Sdim
994321369Sdim  assert(thread->GetRegisterContext());
995321369Sdim  lldb::addr_t stop_pc = thread->GetRegisterContext()->GetPC();
996321369Sdim
997321369Sdim  const auto &iter = m_threads_stepping_with_breakpoint.find(tid);
998321369Sdim  if (iter == m_threads_stepping_with_breakpoint.end())
999321369Sdim    return false;
1000321369Sdim
1001321369Sdim  lldb::break_id_t bp_id = iter->second;
1002321369Sdim  BreakpointSP bp = GetTarget().GetBreakpointByID(bp_id);
1003321369Sdim  if (!bp)
1004321369Sdim    return false;
1005321369Sdim
1006321369Sdim  BreakpointLocationSP bp_loc = bp->FindLocationByAddress(stop_pc);
1007321369Sdim  if (!bp_loc)
1008321369Sdim    return false;
1009321369Sdim
1010321369Sdim  GetTarget().RemoveBreakpointByID(bp_id);
1011321369Sdim  m_threads_stepping_with_breakpoint.erase(tid);
1012321369Sdim  return true;
1013321369Sdim}
1014321369Sdim
1015321369Sdimbool ProcessFreeBSD::SupportHardwareSingleStepping() const {
1016321369Sdim  lldb_private::ArchSpec arch = GetTarget().GetArchitecture();
1017353358Sdim  if (arch.GetMachine() == llvm::Triple::arm || arch.IsMIPS())
1018321369Sdim    return false;
1019321369Sdim  return true;
1020321369Sdim}
1021321369Sdim
1022321369SdimStatus ProcessFreeBSD::SetupSoftwareSingleStepping(lldb::tid_t tid) {
1023353358Sdim  std::unique_ptr<EmulateInstruction> emulator_up(
1024321369Sdim      EmulateInstruction::FindPlugin(GetTarget().GetArchitecture(),
1025321369Sdim                                     eInstructionTypePCModifying, nullptr));
1026321369Sdim
1027353358Sdim  if (emulator_up == nullptr)
1028321369Sdim    return Status("Instruction emulator not found!");
1029321369Sdim
1030321369Sdim  FreeBSDThread *thread = static_cast<FreeBSDThread *>(
1031321369Sdim      m_thread_list.FindThreadByID(tid, false).get());
1032321369Sdim  if (thread == NULL)
1033321369Sdim    return Status("Thread not found not found!");
1034321369Sdim
1035321369Sdim  lldb::RegisterContextSP register_context_sp = thread->GetRegisterContext();
1036321369Sdim
1037321369Sdim  EmulatorBaton baton(this, register_context_sp.get());
1038353358Sdim  emulator_up->SetBaton(&baton);
1039353358Sdim  emulator_up->SetReadMemCallback(&ReadMemoryCallback);
1040353358Sdim  emulator_up->SetReadRegCallback(&ReadRegisterCallback);
1041353358Sdim  emulator_up->SetWriteMemCallback(&WriteMemoryCallback);
1042353358Sdim  emulator_up->SetWriteRegCallback(&WriteRegisterCallback);
1043321369Sdim
1044353358Sdim  if (!emulator_up->ReadInstruction())
1045321369Sdim    return Status("Read instruction failed!");
1046321369Sdim
1047321369Sdim  bool emulation_result =
1048353358Sdim      emulator_up->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
1049321369Sdim  const RegisterInfo *reg_info_pc = register_context_sp->GetRegisterInfo(
1050321369Sdim      eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1051321369Sdim  auto pc_it =
1052321369Sdim      baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
1053321369Sdim
1054321369Sdim  lldb::addr_t next_pc;
1055321369Sdim  if (emulation_result) {
1056321369Sdim    assert(pc_it != baton.m_register_values.end() &&
1057321369Sdim           "Emulation was successful but PC wasn't updated");
1058321369Sdim    next_pc = pc_it->second.GetAsUInt64();
1059321369Sdim  } else if (pc_it == baton.m_register_values.end()) {
1060341825Sdim    // Emulate instruction failed and it haven't changed PC. Advance PC with
1061341825Sdim    // the size of the current opcode because the emulation of all
1062321369Sdim    // PC modifying instruction should be successful. The failure most
1063321369Sdim    // likely caused by a not supported instruction which don't modify PC.
1064321369Sdim    next_pc =
1065353358Sdim        register_context_sp->GetPC() + emulator_up->GetOpcode().GetByteSize();
1066321369Sdim  } else {
1067321369Sdim    // The instruction emulation failed after it modified the PC. It is an
1068321369Sdim    // unknown error where we can't continue because the next instruction is
1069321369Sdim    // modifying the PC but we don't  know how.
1070321369Sdim    return Status("Instruction emulation failed unexpectedly");
1071321369Sdim  }
1072321369Sdim
1073321369Sdim  SetSoftwareSingleStepBreakpoint(tid, next_pc);
1074321369Sdim  return Status();
1075321369Sdim}
1076