//===-- NativeProcessDarwin.cpp ---------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "NativeProcessDarwin.h"

// C includes
#include <mach/mach_init.h>
#include <mach/mach_traps.h>
#include <sys/ptrace.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/types.h>

// C++ includes
// LLDB includes
#include "lldb/Core/State.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"

#include "CFBundle.h"
#include "CFString.h"
#include "DarwinProcessLauncher.h"

#include "MachException.h"

#include "llvm/Support/FileSystem.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_darwin;
using namespace lldb_private::darwin_process_launcher;

// -----------------------------------------------------------------------------
// Hidden Impl
// -----------------------------------------------------------------------------

namespace {
struct hack_task_dyld_info {
  mach_vm_address_t all_image_info_addr;
  mach_vm_size_t all_image_info_size;
};
}

// -----------------------------------------------------------------------------
// Public Static Methods
// -----------------------------------------------------------------------------

Status NativeProcessProtocol::Launch(
    ProcessLaunchInfo &launch_info,
    NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
    NativeProcessProtocolSP &native_process_sp) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  Status error;

  // Verify the working directory is valid if one was specified.
  FileSpec working_dir(launch_info.GetWorkingDirectory());
  if (working_dir &&
      (!working_dir.ResolvePath() ||
       !llvm::sys::fs::is_directory(working_dir.GetPath())) {
    error.SetErrorStringWithFormat("No such file or directory: %s",
                                   working_dir.GetCString());
    return error;
  }

  // Launch the inferior.
  int pty_master_fd = -1;
  LaunchFlavor launch_flavor = LaunchFlavor::Default;

  error = LaunchInferior(launch_info, &pty_master_fd, &launch_flavor);

  // Handle launch failure.
  if (!error.Success()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() failed to launch process: "
                  "%s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Handle failure to return a pid.
  if (launch_info.GetProcessID() == LLDB_INVALID_PROCESS_ID) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() launch succeeded but no "
                  "pid was returned!  Aborting.",
                  __FUNCTION__);
    return error;
  }

  // Create the Darwin native process impl.
  std::shared_ptr<NativeProcessDarwin> np_darwin_sp(
      new NativeProcessDarwin(launch_info.GetProcessID(), pty_master_fd));
  if (!np_darwin_sp->RegisterNativeDelegate(native_delegate)) {
    native_process_sp.reset();
    error.SetErrorStringWithFormat("failed to register the native delegate");
    return error;
  }

  // Finalize the processing needed to debug the launched process with a
  // NativeProcessDarwin instance.
  error = np_darwin_sp->FinalizeLaunch(launch_flavor, mainloop);
  if (!error.Success()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() aborting, failed to finalize"
                  " the launching of the process: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Return the process and process id to the caller through the launch args.
  native_process_sp = np_darwin_sp;
  return error;
}

Status NativeProcessProtocol::Attach(
    lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
    MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  if (log)
    log->Printf("NativeProcessDarwin::%s(pid = %" PRIi64 ")", __FUNCTION__,
                pid);

  // Retrieve the architecture for the running process.
  ArchSpec process_arch;
  Status error = ResolveProcessArchitecture(pid, process_arch);
  if (!error.Success())
    return error;

  // TODO get attach to return this value.
  const int pty_master_fd = -1;
  std::shared_ptr<NativeProcessDarwin> native_process_darwin_sp(
      new NativeProcessDarwin(pid, pty_master_fd));

  if (!native_process_darwin_sp->RegisterNativeDelegate(native_delegate)) {
    error.SetErrorStringWithFormat("failed to register the native "
                                   "delegate");
    return error;
  }

  native_process_darwin_sp->AttachToInferior(mainloop, pid, error);
  if (!error.Success())
    return error;

  native_process_sp = native_process_darwin_sp;
  return error;
}

// -----------------------------------------------------------------------------
// ctor/dtor
// -----------------------------------------------------------------------------

NativeProcessDarwin::NativeProcessDarwin(lldb::pid_t pid, int pty_master_fd)
    : NativeProcessProtocol(pid), m_task(TASK_NULL), m_did_exec(false),
      m_cpu_type(0), m_exception_port(MACH_PORT_NULL), m_exc_port_info(),
      m_exception_thread(nullptr), m_exception_messages_mutex(),
      m_sent_interrupt_signo(0), m_auto_resume_signo(0), m_thread_list(),
      m_thread_actions(), m_waitpid_pipe(), m_waitpid_thread(nullptr),
      m_waitpid_reader_handle() {
  // TODO add this to the NativeProcessProtocol constructor.
  m_terminal_fd = pty_master_fd;
}

NativeProcessDarwin::~NativeProcessDarwin() {}

// -----------------------------------------------------------------------------
// Instance methods
// -----------------------------------------------------------------------------

Status NativeProcessDarwin::FinalizeLaunch(LaunchFlavor launch_flavor,
                                           MainLoop &main_loop) {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

#if 0
    m_path = path;
    size_t i;
    char const *arg;
    for (i=0; (arg = argv[i]) != NULL; i++)
        m_args.push_back(arg);
#endif

  error = StartExceptionThread();
  if (!error.Success()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failure starting the "
                  "mach exception port monitor thread: %s",
                  __FUNCTION__, error.AsCString());

    // Terminate the inferior process.  There's nothing meaningful we can do if
    // we can't receive signals and exceptions.  Since we launched the process,
    // it's fair game for us to kill it.
    ::ptrace(PT_KILL, m_pid, 0, 0);
    SetState(eStateExited);

    return error;
  }

  StartSTDIOThread();

  if (launch_flavor == LaunchFlavor::PosixSpawn) {
    SetState(eStateAttaching);
    errno = 0;
    int err = ::ptrace(PT_ATTACHEXC, m_pid, 0, 0);
    if (err == 0) {
      // m_flags |= eMachProcessFlagsAttached;
      if (log)
        log->Printf("NativeProcessDarwin::%s(): successfully spawned "
                    "process with pid %" PRIu64,
                    __FUNCTION__, m_pid);
    } else {
      error.SetErrorToErrno();
      SetState(eStateExited);
      if (log)
        log->Printf("NativeProcessDarwin::%s(): error: failed to "
                    "attach to spawned pid %" PRIu64 " (error=%d (%s))",
                    __FUNCTION__, m_pid, (int)error.GetError(),
                    error.AsCString());
      return error;
    }
  }

  if (log)
    log->Printf("NativeProcessDarwin::%s(): new pid is %" PRIu64 "...",
                __FUNCTION__, m_pid);

  // Spawn a thread to reap our child inferior process...
  error = StartWaitpidThread(main_loop);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failed to start waitpid() "
                  "thread: %s",
                  __FUNCTION__, error.AsCString());
    kill(SIGKILL, static_cast<::pid_t>(m_pid));
    return error;
  }

  if (TaskPortForProcessID(error) == TASK_NULL) {
    // We failed to get the task for our process ID which is bad. Kill our
    // process; otherwise, it will be stopped at the entry point and get
    // reparented to someone else and never go away.
    if (log)
      log->Printf("NativeProcessDarwin::%s(): could not get task port "
                  "for process, sending SIGKILL and exiting: %s",
                  __FUNCTION__, error.AsCString());
    kill(SIGKILL, static_cast<::pid_t>(m_pid));
    return error;
  }

  // Indicate that we're stopped, as we always launch suspended.
  SetState(eStateStopped);

  // Success.
  return error;
}

Status NativeProcessDarwin::SaveExceptionPortInfo() {
  return m_exc_port_info.Save(m_task);
}

bool NativeProcessDarwin::ProcessUsingSpringBoard() const {
  // TODO implement flags
  // return (m_flags & eMachProcessFlagsUsingSBS) != 0;
  return false;
}

bool NativeProcessDarwin::ProcessUsingBackBoard() const {
  // TODO implement flags
  // return (m_flags & eMachProcessFlagsUsingBKS) != 0;
  return false;
}

// Called by the exception thread when an exception has been received from our
// process. The exception message is completely filled and the exception data
// has already been copied.
void NativeProcessDarwin::ExceptionMessageReceived(
    const MachException::Message &message) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));

  std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
  if (m_exception_messages.empty()) {
    // Suspend the task the moment we receive our first exception message.
    SuspendTask();
  }

  // Use a locker to automatically unlock our mutex in case of exceptions Add
  // the exception to our internal exception stack
  m_exception_messages.push_back(message);

  if (log)
    log->Printf("NativeProcessDarwin::%s(): new queued message count: %lu",
                __FUNCTION__, m_exception_messages.size());
}

void *NativeProcessDarwin::ExceptionThread(void *arg) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
  if (!arg) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): cannot run mach exception "
                  "thread, mandatory process arg was null",
                  __FUNCTION__);
    return nullptr;
  }

  return reinterpret_cast<NativeProcessDarwin *>(arg)->DoExceptionThread();
}

void *NativeProcessDarwin::DoExceptionThread() {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));

  if (log)
    log->Printf("NativeProcessDarwin::%s(arg=%p) starting thread...",
                __FUNCTION__, this);

  pthread_setname_np("exception monitoring thread");

  // Ensure we don't get CPU starved.
  MaybeRaiseThreadPriority();

  // We keep a count of the number of consecutive exceptions received so we
  // know to grab all exceptions without a timeout. We do this to get a bunch
  // of related exceptions on our exception port so we can process then
  // together. When we have multiple threads, we can get an exception per
  // thread and they will come in consecutively. The main loop in this thread
  // can stop periodically if needed to service things related to this process.
  //
  // [did we lose some words here?]
  //
  // flag set in the options, so we will wait forever for an exception on
  // 0 our exception port. After we get one exception, we then will use the
  // MACH_RCV_TIMEOUT option with a zero timeout to grab all other current
  // exceptions for our process. After we have received the last pending
  // exception, we will get a timeout which enables us to then notify our main
  // thread that we have an exception bundle available. We then wait for the
  // main thread to tell this exception thread to start trying to get
  // exceptions messages again and we start again with a mach_msg read with
  // infinite timeout.
  //
  // We choose to park a thread on this, rather than polling, because the
  // polling is expensive.  On devices, we need to minimize overhead caused by
  // the process monitor.
  uint32_t num_exceptions_received = 0;
  Status error;
  task_t task = m_task;
  mach_msg_timeout_t periodic_timeout = 0;

#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
  mach_msg_timeout_t watchdog_elapsed = 0;
  mach_msg_timeout_t watchdog_timeout = 60 * 1000;
  ::pid_t pid = (::pid_t)process->GetID();
  CFReleaser<SBSWatchdogAssertionRef> watchdog;

  if (process->ProcessUsingSpringBoard()) {
    // Request a renewal for every 60 seconds if we attached using SpringBoard.
    watchdog.reset(::SBSWatchdogAssertionCreateForPID(nullptr, pid, 60));
    if (log)
      log->Printf("::SBSWatchdogAssertionCreateForPID(NULL, %4.4x, 60) "
                  "=> %p",
                  pid, watchdog.get());

    if (watchdog.get()) {
      ::SBSWatchdogAssertionRenew(watchdog.get());

      CFTimeInterval watchdogRenewalInterval =
          ::SBSWatchdogAssertionGetRenewalInterval(watchdog.get());
      if (log)
        log->Printf("::SBSWatchdogAssertionGetRenewalInterval(%p) => "
                    "%g seconds",
                    watchdog.get(), watchdogRenewalInterval);
      if (watchdogRenewalInterval > 0.0) {
        watchdog_timeout = (mach_msg_timeout_t)watchdogRenewalInterval * 1000;
        if (watchdog_timeout > 3000) {
          // Give us a second to renew our timeout.
          watchdog_timeout -= 1000;
        } else if (watchdog_timeout > 1000) {
          // Give us a quarter of a second to renew our timeout.
          watchdog_timeout -= 250;
        }
      }
    }
    if (periodic_timeout == 0 || periodic_timeout > watchdog_timeout)
      periodic_timeout = watchdog_timeout;
  }
#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)

#ifdef WITH_BKS
  CFReleaser<BKSWatchdogAssertionRef> watchdog;
  if (process->ProcessUsingBackBoard()) {
    ::pid_t pid = process->GetID();
    CFAllocatorRef alloc = kCFAllocatorDefault;
    watchdog.reset(::BKSWatchdogAssertionCreateForPID(alloc, pid));
  }
#endif // #ifdef WITH_BKS

  // Do we want to use a weak pointer to the NativeProcessDarwin here, in which
  // case we can guarantee we don't whack the process monitor if we race
  // between this thread and the main one on shutdown?
  while (IsExceptionPortValid()) {
    ::pthread_testcancel();

    MachException::Message exception_message;

    if (num_exceptions_received > 0) {
      // We don't want a timeout here, just receive as many exceptions as we
      // can since we already have one.  We want to get all currently available
      // exceptions for this task at once.
      error = exception_message.Receive(
          GetExceptionPort(),
          MACH_RCV_MSG | MACH_RCV_INTERRUPT | MACH_RCV_TIMEOUT, 0);
    } else if (periodic_timeout > 0) {
      // We need to stop periodically in this loop, so try and get a mach
      // message with a valid timeout (ms).
      error = exception_message.Receive(GetExceptionPort(),
                                        MACH_RCV_MSG | MACH_RCV_INTERRUPT |
                                            MACH_RCV_TIMEOUT,
                                        periodic_timeout);
    } else {
      // We don't need to parse all current exceptions or stop periodically,
      // just wait for an exception forever.
      error = exception_message.Receive(GetExceptionPort(),
                                        MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0);
    }

    if (error.Success()) {
      // We successfully received an exception.
      if (exception_message.CatchExceptionRaise(task)) {
        ++num_exceptions_received;
        ExceptionMessageReceived(exception_message);
      }
    } else {
      if (error.GetError() == MACH_RCV_INTERRUPTED) {
        // We were interrupted.

        // If we have no task port we should exit this thread, as it implies
        // the inferior went down.
        if (!IsExceptionPortValid()) {
          if (log)
            log->Printf("NativeProcessDarwin::%s(): the inferior "
                        "exception port is no longer valid, "
                        "canceling exception thread...",
                        __FUNCTION__);
          // Should we be setting a process state here?
          break;
        }

        // Make sure the inferior task is still valid.
        if (IsTaskValid()) {
          // Task is still ok.
          if (log)
            log->Printf("NativeProcessDarwin::%s(): interrupted, but "
                        "the inferior task iss till valid, "
                        "continuing...",
                        __FUNCTION__);
          continue;
        } else {
          // The inferior task is no longer valid.  Time to exit as the process
          // has gone away.
          if (log)
            log->Printf("NativeProcessDarwin::%s(): the inferior task "
                        "has exited, and so will we...",
                        __FUNCTION__);
          // Does this race at all with our waitpid()?
          SetState(eStateExited);
          break;
        }
      } else if (error.GetError() == MACH_RCV_TIMED_OUT) {
        // We timed out when waiting for exceptions.

        if (num_exceptions_received > 0) {
          // We were receiving all current exceptions with a timeout of zero.
          // It is time to go back to our normal looping mode.
          num_exceptions_received = 0;

          // Notify our main thread we have a complete exception message bundle
          // available.  Get the possibly updated task port back from the
          // process in case we exec'ed and our task port changed.
          task = ExceptionMessageBundleComplete();

          // In case we use a timeout value when getting exceptions, make sure
          // our task is still valid.
          if (IsTaskValid(task)) {
            // Task is still ok.
            if (log)
              log->Printf("NativeProcessDarwin::%s(): got a timeout, "
                          "continuing...",
                          __FUNCTION__);
            continue;
          } else {
            // The inferior task is no longer valid.  Time to exit as the
            // process has gone away.
            if (log)
              log->Printf("NativeProcessDarwin::%s(): the inferior "
                          "task has exited, and so will we...",
                          __FUNCTION__);
            // Does this race at all with our waitpid()?
            SetState(eStateExited);
            break;
          }
        }

#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
        if (watchdog.get()) {
          watchdog_elapsed += periodic_timeout;
          if (watchdog_elapsed >= watchdog_timeout) {
            if (log)
              log->Printf("SBSWatchdogAssertionRenew(%p)", watchdog.get());
            ::SBSWatchdogAssertionRenew(watchdog.get());
            watchdog_elapsed = 0;
          }
        }
#endif
      } else {
        if (log)
          log->Printf("NativeProcessDarwin::%s(): continuing after "
                      "receiving an unexpected error: %u (%s)",
                      __FUNCTION__, error.GetError(), error.AsCString());
        // TODO: notify of error?
      }
    }
  }

#if defined(WITH_SPRINGBOARD) && !defined(WITH_BKS)
  if (watchdog.get()) {
    // TODO: change SBSWatchdogAssertionRelease to SBSWatchdogAssertionCancel
    // when we
    // all are up and running on systems that support it. The SBS framework has
    // a #define that will forward SBSWatchdogAssertionRelease to
    // SBSWatchdogAssertionCancel for now so it should still build either way.
    DNBLogThreadedIf(LOG_TASK, "::SBSWatchdogAssertionRelease(%p)",
                     watchdog.get());
    ::SBSWatchdogAssertionRelease(watchdog.get());
  }
#endif // #if defined (WITH_SPRINGBOARD) && !defined (WITH_BKS)

  if (log)
    log->Printf("NativeProcessDarwin::%s(%p): thread exiting...", __FUNCTION__,
                this);
  return nullptr;
}

Status NativeProcessDarwin::StartExceptionThread() {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  if (log)
    log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);

  // Make sure we've looked up the inferior port.
  TaskPortForProcessID(error);

  // Ensure the inferior task is valid.
  if (!IsTaskValid()) {
    error.SetErrorStringWithFormat("cannot start exception thread: "
                                   "task 0x%4.4x is not valid",
                                   m_task);
    return error;
  }

  // Get the mach port for the process monitor.
  mach_port_t task_self = mach_task_self();

  // Allocate an exception port that we will use to track our child process
  auto mach_err = ::mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE,
                                       &m_exception_port);
  error.SetError(mach_err, eErrorTypeMachKernel);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): mach_port_allocate("
                  "task_self=0x%4.4x, MACH_PORT_RIGHT_RECEIVE, "
                  "&m_exception_port) failed: %u (%s)",
                  __FUNCTION__, task_self, error.GetError(), error.AsCString());
    return error;
  }

  // Add the ability to send messages on the new exception port
  mach_err = ::mach_port_insert_right(
      task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND);
  error.SetError(mach_err, eErrorTypeMachKernel);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): mach_port_insert_right("
                  "task_self=0x%4.4x, m_exception_port=0x%4.4x, "
                  "m_exception_port=0x%4.4x, MACH_MSG_TYPE_MAKE_SEND) "
                  "failed: %u (%s)",
                  __FUNCTION__, task_self, m_exception_port, m_exception_port,
                  error.GetError(), error.AsCString());
    return error;
  }

  // Save the original state of the exception ports for our child process.
  error = SaveExceptionPortInfo();
  if (error.Fail() || (m_exc_port_info.mask == 0)) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): SaveExceptionPortInfo() "
                  "failed, cannot install exception handler: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Set the ability to get all exceptions on this port.
  mach_err = ::task_set_exception_ports(
      m_task, m_exc_port_info.mask, m_exception_port,
      EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
  error.SetError(mach_err, eErrorTypeMachKernel);
  if (error.Fail()) {
    if (log)
      log->Printf("::task_set_exception_ports (task = 0x%4.4x, "
                  "exception_mask = 0x%8.8x, new_port = 0x%4.4x, "
                  "behavior = 0x%8.8x, new_flavor = 0x%8.8x) failed: "
                  "%u (%s)",
                  m_task, m_exc_port_info.mask, m_exception_port,
                  (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), THREAD_STATE_NONE,
                  error.GetError(), error.AsCString());
    return error;
  }

  // Create the exception thread.
  auto pthread_err =
      ::pthread_create(&m_exception_thread, nullptr, ExceptionThread, this);
  error.SetError(pthread_err, eErrorTypePOSIX);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failed to create Mach "
                  "exception-handling thread: %u (%s)",
                  __FUNCTION__, error.GetError(), error.AsCString());
  }

  return error;
}

lldb::addr_t
NativeProcessDarwin::GetDYLDAllImageInfosAddress(Status &error) const {
  error.Clear();

  struct hack_task_dyld_info dyld_info;
  mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
  // Make sure that COUNT isn't bigger than our hacked up struct
  // hack_task_dyld_info.  If it is, then make COUNT smaller to match.
  if (count > (sizeof(struct hack_task_dyld_info) / sizeof(natural_t))) {
    count = (sizeof(struct hack_task_dyld_info) / sizeof(natural_t));
  }

  TaskPortForProcessID(error);
  if (error.Fail())
    return LLDB_INVALID_ADDRESS;

  auto mach_err =
      ::task_info(m_task, TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
  error.SetError(mach_err, eErrorTypeMachKernel);
  if (error.Success()) {
    // We now have the address of the all image infos structure.
    return dyld_info.all_image_info_addr;
  }

  // We don't have it.
  return LLDB_INVALID_ADDRESS;
}

uint32_t NativeProcessDarwin::GetCPUTypeForLocalProcess(::pid_t pid) {
  int mib[CTL_MAXNAME] = {
      0,
  };
  size_t len = CTL_MAXNAME;

  if (::sysctlnametomib("sysctl.proc_cputype", mib, &len))
    return 0;

  mib[len] = pid;
  len++;

  cpu_type_t cpu;
  size_t cpu_len = sizeof(cpu);
  if (::sysctl(mib, static_cast<u_int>(len), &cpu, &cpu_len, 0, 0))
    cpu = 0;
  return cpu;
}

uint32_t NativeProcessDarwin::GetCPUType() const {
  if (m_cpu_type == 0 && m_pid != 0)
    m_cpu_type = GetCPUTypeForLocalProcess(m_pid);
  return m_cpu_type;
}

task_t NativeProcessDarwin::ExceptionMessageBundleComplete() {
  // We have a complete bundle of exceptions for our child process.
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));

  std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
  if (log)
    log->Printf("NativeProcessDarwin::%s(): processing %lu exception "
                "messages.",
                __FUNCTION__, m_exception_messages.size());

  if (m_exception_messages.empty()) {
    // Not particularly useful...
    return m_task;
  }

  bool auto_resume = false;
  m_did_exec = false;

  // First check for any SIGTRAP and make sure we didn't exec
  const task_t task = m_task;
  size_t i;
  if (m_pid != 0) {
    bool received_interrupt = false;
    uint32_t num_task_exceptions = 0;
    for (i = 0; i < m_exception_messages.size(); ++i) {
      if (m_exception_messages[i].state.task_port != task) {
        // This is an exception that is not for our inferior, ignore.
        continue;
      }

      // This is an exception for the inferior.
      ++num_task_exceptions;
      const int signo = m_exception_messages[i].state.SoftSignal();
      if (signo == SIGTRAP) {
        // SIGTRAP could mean that we exec'ed. We need to check the
        // dyld all_image_infos.infoArray to see if it is NULL and if so, say
        // that we exec'ed.
        const addr_t aii_addr = GetDYLDAllImageInfosAddress(error);
        if (aii_addr == LLDB_INVALID_ADDRESS)
          break;

        const addr_t info_array_count_addr = aii_addr + 4;
        uint32_t info_array_count = 0;
        size_t bytes_read = 0;
        Status read_error;
        read_error = ReadMemory(info_array_count_addr, // source addr
                                &info_array_count,     // dest addr
                                4,                     // byte count
                                bytes_read);           // #bytes read
        if (read_error.Success() && (bytes_read == 4)) {
          if (info_array_count == 0) {
            // We got the all infos address, and there are zero entries.  We
            // think we exec'd.
            m_did_exec = true;

            // Force the task port to update itself in case the task port
            // changed after exec
            const task_t old_task = m_task;
            const bool force_update = true;
            const task_t new_task = TaskPortForProcessID(error, force_update);
            if (old_task != new_task) {
              if (log)
                log->Printf("exec: inferior task port changed "
                            "from 0x%4.4x to 0x%4.4x",
                            old_task, new_task);
            }
          }
        } else {
          if (log)
            log->Printf("NativeProcessDarwin::%s() warning: "
                        "failed to read all_image_infos."
                        "infoArrayCount from 0x%8.8llx",
                        __FUNCTION__, info_array_count_addr);
        }
      } else if ((m_sent_interrupt_signo != 0) &&
                 (signo == m_sent_interrupt_signo)) {
        // We just received the interrupt that we sent to ourselves.
        received_interrupt = true;
      }
    }

    if (m_did_exec) {
      cpu_type_t process_cpu_type = GetCPUTypeForLocalProcess(m_pid);
      if (m_cpu_type != process_cpu_type) {
        if (log)
          log->Printf("NativeProcessDarwin::%s(): arch changed from "
                      "0x%8.8x to 0x%8.8x",
                      __FUNCTION__, m_cpu_type, process_cpu_type);
        m_cpu_type = process_cpu_type;
        // TODO figure out if we need to do something here.
        // DNBArchProtocol::SetArchitecture (process_cpu_type);
      }
      m_thread_list.Clear();

      // TODO hook up breakpoints.
      // m_breakpoints.DisableAll();
    }

    if (m_sent_interrupt_signo != 0) {
      if (received_interrupt) {
        if (log)
          log->Printf("NativeProcessDarwin::%s(): process "
                      "successfully interrupted with signal %i",
                      __FUNCTION__, m_sent_interrupt_signo);

        // Mark that we received the interrupt signal
        m_sent_interrupt_signo = 0;
        // Now check if we had a case where:
        // 1 - We called NativeProcessDarwin::Interrupt() but we stopped
        //     for another reason.
        // 2 - We called NativeProcessDarwin::Resume() (but still
        //     haven't gotten the interrupt signal).
        // 3 - We are now incorrectly stopped because we are handling
        //     the interrupt signal we missed.
        // 4 - We might need to resume if we stopped only with the
        //     interrupt signal that we never handled.
        if (m_auto_resume_signo != 0) {
          // Only auto_resume if we stopped with _only_ the interrupt signal.
          if (num_task_exceptions == 1) {
            auto_resume = true;
            if (log)
              log->Printf("NativeProcessDarwin::%s(): auto "
                          "resuming due to unhandled interrupt "
                          "signal %i",
                          __FUNCTION__, m_auto_resume_signo);
          }
          m_auto_resume_signo = 0;
        }
      } else {
        if (log)
          log->Printf("NativeProcessDarwin::%s(): didn't get signal "
                      "%i after MachProcess::Interrupt()",
                      __FUNCTION__, m_sent_interrupt_signo);
      }
    }
  }

  // Let all threads recover from stopping and do any clean up based on the
  // previous thread state (if any).
  m_thread_list.ProcessDidStop(*this);

  // Let each thread know of any exceptions
  for (i = 0; i < m_exception_messages.size(); ++i) {
    // Let the thread list forward all exceptions on down to each thread.
    if (m_exception_messages[i].state.task_port == task) {
      // This exception is for our inferior.
      m_thread_list.NotifyException(m_exception_messages[i].state);
    }

    if (log) {
      StreamString stream;
      m_exception_messages[i].Dump(stream);
      stream.Flush();
      log->PutCString(stream.GetString().c_str());
    }
  }

  if (log) {
    StreamString stream;
    m_thread_list.Dump(stream);
    stream.Flush();
    log->PutCString(stream.GetString().c_str());
  }

  bool step_more = false;
  if (m_thread_list.ShouldStop(step_more) && (auto_resume == false)) {
// TODO - need to hook up event system here. !!!!
#if 0
        // Wait for the eEventProcessRunningStateChanged event to be reset
        // before changing state to stopped to avoid race condition with very
        // fast start/stops.
        struct timespec timeout;

        //DNBTimer::OffsetTimeOfDay(&timeout, 0, 250 * 1000);   // Wait for 250 ms
        DNBTimer::OffsetTimeOfDay(&timeout, 1, 0);  // Wait for 250 ms
        m_events.WaitForEventsToReset(eEventProcessRunningStateChanged,
                                      &timeout);
#endif
    SetState(eStateStopped);
  } else {
    // Resume without checking our current state.
    PrivateResume();
  }

  return m_task;
}

void NativeProcessDarwin::StartSTDIOThread() {
  // TODO implement
}

Status NativeProcessDarwin::StartWaitpidThread(MainLoop &main_loop) {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  // Strategy: create a thread that sits on waitpid(), waiting for the inferior
  // process to die, reaping it in the process.  Arrange for the thread to have
  // a pipe file descriptor that it can send a byte over when the waitpid
  // completes.  Have the main loop have a read object for the other side of
  // the pipe, and have the callback for the read do the process termination
  // message sending.

  // Create a single-direction communication channel.
  const bool child_inherits = false;
  error = m_waitpid_pipe.CreateNew(child_inherits);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
                  "communication pipe: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Hook up the waitpid reader callback.

  // TODO make PipePOSIX derive from IOObject.  This is goofy here.
  const bool transfer_ownership = false;
  auto io_sp = IOObjectSP(
      new File(m_waitpid_pipe.GetReadFileDescriptor(), transfer_ownership));
  m_waitpid_reader_handle = main_loop.RegisterReadObject(
      io_sp, [this](MainLoopBase &) { HandleWaitpidResult(); }, error);

  // Create the thread.
  auto pthread_err =
      ::pthread_create(&m_waitpid_thread, nullptr, WaitpidThread, this);
  error.SetError(pthread_err, eErrorTypePOSIX);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failed to create waitpid "
                  "handling thread: %u (%s)",
                  __FUNCTION__, error.GetError(), error.AsCString());
    return error;
  }

  return error;
}

void *NativeProcessDarwin::WaitpidThread(void *arg) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  if (!arg) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): cannot run waitpid "
                  "thread, mandatory process arg was null",
                  __FUNCTION__);
    return nullptr;
  }

  return reinterpret_cast<NativeProcessDarwin *>(arg)->DoWaitpidThread();
}

void NativeProcessDarwin::MaybeRaiseThreadPriority() {
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
  struct sched_param thread_param;
  int thread_sched_policy;
  if (pthread_getschedparam(pthread_self(), &thread_sched_policy,
                            &thread_param) == 0) {
    thread_param.sched_priority = 47;
    pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
  }
#endif
}

void *NativeProcessDarwin::DoWaitpidThread() {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  if (m_pid == LLDB_INVALID_PROCESS_ID) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): inferior process ID is "
                  "not set, cannot waitpid on it",
                  __FUNCTION__);
    return nullptr;
  }

  // Name the thread.
  pthread_setname_np("waitpid thread");

  // Ensure we don't get CPU starved.
  MaybeRaiseThreadPriority();

  Status error;
  int status = -1;

  while (1) {
    // Do a waitpid.
    ::pid_t child_pid = ::waitpid(m_pid, &status, 0);
    if (child_pid < 0)
      error.SetErrorToErrno();
    if (error.Fail()) {
      if (error.GetError() == EINTR) {
        // This is okay, we can keep going.
        if (log)
          log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
                      ", &status, 0) interrupted, continuing",
                      __FUNCTION__, m_pid);
        continue;
      }

      // This error is not okay, abort.
      if (log)
        log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
                    ", &status, 0) aborting due to error: %u (%s)",
                    __FUNCTION__, m_pid, error.GetError(), error.AsCString());
      break;
    }

    // Log the successful result.
    if (log)
      log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
                  ", &status, 0) => %i, status = %i",
                  __FUNCTION__, m_pid, child_pid, status);

    // Handle the result.
    if (WIFSTOPPED(status)) {
      if (log)
        log->Printf("NativeProcessDarwin::%s(): waitpid(pid = %" PRIu64
                    ") received a stop, continuing waitpid() loop",
                    __FUNCTION__, m_pid);
      continue;
    } else // if (WIFEXITED(status) || WIFSIGNALED(status))
    {
      if (log)
        log->Printf("NativeProcessDarwin::%s(pid = %" PRIu64 "): "
                    "waitpid thread is setting exit status for pid = "
                    "%i to %i",
                    __FUNCTION__, m_pid, child_pid, status);

      error = SendInferiorExitStatusToMainLoop(child_pid, status);
      return nullptr;
    }
  }

  // We should never exit as long as our child process is alive.  If we get
  // here, something completely unexpected went wrong and we should exit.
  if (log)
    log->Printf(
        "NativeProcessDarwin::%s(): internal error: waitpid thread "
        "exited out of its main loop in an unexpected way. pid = %" PRIu64
        ". Sending exit status of -1.",
        __FUNCTION__, m_pid);

  error = SendInferiorExitStatusToMainLoop((::pid_t)m_pid, -1);
  return nullptr;
}

Status NativeProcessDarwin::SendInferiorExitStatusToMainLoop(::pid_t pid,
                                                             int status) {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  size_t bytes_written = 0;

  // Send the pid.
  error = m_waitpid_pipe.Write(&pid, sizeof(pid), bytes_written);
  if (error.Fail() || (bytes_written < sizeof(pid))) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() - failed to write "
                  "waitpid exiting pid to the pipe.  Client will not "
                  "hear about inferior exit status!",
                  __FUNCTION__);
    return error;
  }

  // Send the status.
  bytes_written = 0;
  error = m_waitpid_pipe.Write(&status, sizeof(status), bytes_written);
  if (error.Fail() || (bytes_written < sizeof(status))) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() - failed to write "
                  "waitpid exit result to the pipe.  Client will not "
                  "hear about inferior exit status!",
                  __FUNCTION__);
  }
  return error;
}

Status NativeProcessDarwin::HandleWaitpidResult() {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  // Read the pid.
  const bool notify_status = true;

  ::pid_t pid = -1;
  size_t bytes_read = 0;
  error = m_waitpid_pipe.Read(&pid, sizeof(pid), bytes_read);
  if (error.Fail() || (bytes_read < sizeof(pid))) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() - failed to read "
                  "waitpid exiting pid from the pipe.  Will notify "
                  "as if parent process died with exit status -1.",
                  __FUNCTION__);
    SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status);
    return error;
  }

  // Read the status.
  int status = -1;
  error = m_waitpid_pipe.Read(&status, sizeof(status), bytes_read);
  if (error.Fail() || (bytes_read < sizeof(status))) {
    if (log)
      log->Printf("NativeProcessDarwin::%s() - failed to read "
                  "waitpid exit status from the pipe.  Will notify "
                  "as if parent process died with exit status -1.",
                  __FUNCTION__);
    SetExitStatus(WaitStatus(WaitStatus::Exit, -1), notify_status);
    return error;
  }

  // Notify the monitor that our state has changed.
  if (log)
    log->Printf("NativeProcessDarwin::%s(): main loop received waitpid "
                "exit status info: pid=%i (%s), status=%i",
                __FUNCTION__, pid,
                (pid == m_pid) ? "the inferior" : "not the inferior", status);

  SetExitStatus(WaitStatus::Decode(status), notify_status);
  return error;
}

task_t NativeProcessDarwin::TaskPortForProcessID(Status &error,
                                                 bool force) const {
  if ((m_task == TASK_NULL) || force) {
    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
    if (m_pid == LLDB_INVALID_PROCESS_ID) {
      if (log)
        log->Printf("NativeProcessDarwin::%s(): cannot get task due "
                    "to invalid pid",
                    __FUNCTION__);
      return TASK_NULL;
    }

    const uint32_t num_retries = 10;
    const uint32_t usec_interval = 10000;

    mach_port_t task_self = mach_task_self();
    task_t task = TASK_NULL;

    for (uint32_t i = 0; i < num_retries; i++) {
      kern_return_t err = ::task_for_pid(task_self, m_pid, &task);
      if (err == 0) {
        // Succeeded.  Save and return it.
        error.Clear();
        m_task = task;
        log->Printf("NativeProcessDarwin::%s(): ::task_for_pid("
                    "stub_port = 0x%4.4x, pid = %llu, &task) "
                    "succeeded: inferior task port = 0x%4.4x",
                    __FUNCTION__, task_self, m_pid, m_task);
        return m_task;
      } else {
        // Failed to get the task for the inferior process.
        error.SetError(err, eErrorTypeMachKernel);
        if (log) {
          log->Printf("NativeProcessDarwin::%s(): ::task_for_pid("
                      "stub_port = 0x%4.4x, pid = %llu, &task) "
                      "failed, err = 0x%8.8x (%s)",
                      __FUNCTION__, task_self, m_pid, err, error.AsCString());
        }
      }

      // Sleep a bit and try again
      ::usleep(usec_interval);
    }

    // We failed to get the task for the inferior process. Ensure that it is
    // cleared out.
    m_task = TASK_NULL;
  }
  return m_task;
}

void NativeProcessDarwin::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
                                           Status &error) {
  error.SetErrorString("TODO: implement");
}

Status NativeProcessDarwin::PrivateResume() {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
  m_auto_resume_signo = m_sent_interrupt_signo;

  if (log) {
    if (m_auto_resume_signo)
      log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming (with "
                  "unhandled interrupt signal %i)...",
                  __FUNCTION__, m_task, m_auto_resume_signo);
    else
      log->Printf("NativeProcessDarwin::%s(): task 0x%x resuming...",
                  __FUNCTION__, m_task);
  }

  error = ReplyToAllExceptions();
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): aborting, failed to "
                  "reply to exceptions: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }
  //    bool stepOverBreakInstruction = step;

  // Let the thread prepare to resume and see if any threads want us to step
  // over a breakpoint instruction (ProcessWillResume will modify the value of
  // stepOverBreakInstruction).
  m_thread_list.ProcessWillResume(*this, m_thread_actions);

  // Set our state accordingly
  if (m_thread_actions.NumActionsWithState(eStateStepping))
    SetState(eStateStepping);
  else
    SetState(eStateRunning);

  // Now resume our task.
  error = ResumeTask();
  return error;
}

Status NativeProcessDarwin::ReplyToAllExceptions() {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));

  TaskPortForProcessID(error);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): no task port, aborting",
                  __FUNCTION__);
    return error;
  }

  std::lock_guard<std::recursive_mutex> locker(m_exception_messages_mutex);
  if (m_exception_messages.empty()) {
    // We're done.
    return error;
  }

  size_t index = 0;
  for (auto &message : m_exception_messages) {
    if (log) {
      log->Printf("NativeProcessDarwin::%s(): replying to exception "
                  "%zu...",
                  __FUNCTION__, index++);
    }

    int thread_reply_signal = 0;

    const tid_t tid =
        m_thread_list.GetThreadIDByMachPortNumber(message.state.thread_port);
    const ResumeAction *action = nullptr;
    if (tid != LLDB_INVALID_THREAD_ID)
      action = m_thread_actions.GetActionForThread(tid, false);

    if (action) {
      thread_reply_signal = action->signal;
      if (thread_reply_signal)
        m_thread_actions.SetSignalHandledForThread(tid);
    }

    error = message.Reply(m_pid, m_task, thread_reply_signal);
    if (error.Fail() && log) {
      // We log any error here, but we don't stop the exception response
      // handling.
      log->Printf("NativeProcessDarwin::%s(): failed to reply to "
                  "exception: %s",
                  __FUNCTION__, error.AsCString());
      error.Clear();
    }
  }

  // Erase all exception message as we should have used and replied to them all
  // already.
  m_exception_messages.clear();
  return error;
}

Status NativeProcessDarwin::ResumeTask() {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  TaskPortForProcessID(error);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failed to get task port "
                  "for process when attempting to resume: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }
  if (m_task == TASK_NULL) {
    error.SetErrorString("task port retrieval succeeded but task port is "
                         "null when attempting to resume the task");
    return error;
  }

  if (log)
    log->Printf("NativeProcessDarwin::%s(): requesting resume of task "
                "0x%4.4x",
                __FUNCTION__, m_task);

  // Get the BasicInfo struct to verify that we're suspended before we try to
  // resume the task.
  struct task_basic_info task_info;
  error = GetTaskBasicInfo(m_task, &task_info);
  if (error.Fail()) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): failed to get task "
                  "BasicInfo when attempting to resume: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // task_resume isn't counted like task_suspend calls are, so if the task is
  // not suspended, don't try and resume it since it is already running
  if (task_info.suspend_count > 0) {
    auto mach_err = ::task_resume(m_task);
    error.SetError(mach_err, eErrorTypeMachKernel);
    if (log) {
      if (error.Success())
        log->Printf("::task_resume(target_task = 0x%4.4x): success", m_task);
      else
        log->Printf("::task_resume(target_task = 0x%4.4x) error: %s", m_task,
                    error.AsCString());
    }
  } else {
    if (log)
      log->Printf("::task_resume(target_task = 0x%4.4x): ignored, "
                  "already running",
                  m_task);
  }

  return error;
}

bool NativeProcessDarwin::IsTaskValid() const {
  if (m_task == TASK_NULL)
    return false;

  struct task_basic_info task_info;
  return GetTaskBasicInfo(m_task, &task_info).Success();
}

bool NativeProcessDarwin::IsTaskValid(task_t task) const {
  if (task == TASK_NULL)
    return false;

  struct task_basic_info task_info;
  return GetTaskBasicInfo(task, &task_info).Success();
}

mach_port_t NativeProcessDarwin::GetExceptionPort() const {
  return m_exception_port;
}

bool NativeProcessDarwin::IsExceptionPortValid() const {
  return MACH_PORT_VALID(m_exception_port);
}

Status
NativeProcessDarwin::GetTaskBasicInfo(task_t task,
                                      struct task_basic_info *info) const {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  // Validate args.
  if (info == NULL) {
    error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): mandatory "
                                   "info arg is null",
                                   __FUNCTION__);
    return error;
  }

  // Grab the task if we don't already have it.
  if (task == TASK_NULL) {
    error.SetErrorStringWithFormat("NativeProcessDarwin::%s(): given task "
                                   "is invalid",
                                   __FUNCTION__);
  }

  mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
  auto err = ::task_info(m_task, TASK_BASIC_INFO, (task_info_t)info, &count);
  error.SetError(err, eErrorTypeMachKernel);
  if (error.Fail()) {
    if (log)
      log->Printf("::task_info(target_task = 0x%4.4x, "
                  "flavor = TASK_BASIC_INFO, task_info_out => %p, "
                  "task_info_outCnt => %u) failed: %u (%s)",
                  m_task, info, count, error.GetError(), error.AsCString());
    return error;
  }

  Log *verbose_log(
      GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
  if (verbose_log) {
    float user = (float)info->user_time.seconds +
                 (float)info->user_time.microseconds / 1000000.0f;
    float system = (float)info->user_time.seconds +
                   (float)info->user_time.microseconds / 1000000.0f;
    verbose_log->Printf("task_basic_info = { suspend_count = %i, "
                        "virtual_size = 0x%8.8llx, resident_size = "
                        "0x%8.8llx, user_time = %f, system_time = %f }",
                        info->suspend_count, (uint64_t)info->virtual_size,
                        (uint64_t)info->resident_size, user, system);
  }
  return error;
}

Status NativeProcessDarwin::SuspendTask() {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  if (m_task == TASK_NULL) {
    error.SetErrorString("task port is null, cannot suspend task");
    if (log)
      log->Printf("NativeProcessDarwin::%s() failed: %s", __FUNCTION__,
                  error.AsCString());
    return error;
  }

  auto mach_err = ::task_suspend(m_task);
  error.SetError(mach_err, eErrorTypeMachKernel);
  if (error.Fail() && log)
    log->Printf("::task_suspend(target_task = 0x%4.4x)", m_task);

  return error;
}

Status NativeProcessDarwin::Resume(const ResumeActionList &resume_actions) {
  Status error;
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  if (log)
    log->Printf("NativeProcessDarwin::%s() called", __FUNCTION__);

  if (CanResume()) {
    m_thread_actions = resume_actions;
    error = PrivateResume();
    return error;
  }

  auto state = GetState();
  if (state == eStateRunning) {
    if (log)
      log->Printf("NativeProcessDarwin::%s(): task 0x%x is already "
                  "running, ignoring...",
                  __FUNCTION__, TaskPortForProcessID(error));
    return error;
  }

  // We can't resume from this state.
  error.SetErrorStringWithFormat("task 0x%x has state %s, can't resume",
                                 TaskPortForProcessID(error),
                                 StateAsCString(state));
  return error;
}

Status NativeProcessDarwin::Halt() {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::Detach() {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::Signal(int signo) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::Interrupt() {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::Kill() {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::GetMemoryRegionInfo(lldb::addr_t load_addr,
                                                MemoryRegionInfo &range_info) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::ReadMemory(lldb::addr_t addr, void *buf,
                                       size_t size, size_t &bytes_read) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
                                                  size_t size,
                                                  size_t &bytes_read) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::WriteMemory(lldb::addr_t addr, const void *buf,
                                        size_t size, size_t &bytes_written) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::AllocateMemory(size_t size, uint32_t permissions,
                                           lldb::addr_t &addr) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::DeallocateMemory(lldb::addr_t addr) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

lldb::addr_t NativeProcessDarwin::GetSharedLibraryInfoAddress() {
  return LLDB_INVALID_ADDRESS;
}

size_t NativeProcessDarwin::UpdateThreads() { return 0; }

bool NativeProcessDarwin::GetArchitecture(ArchSpec &arch) const {
  return false;
}

Status NativeProcessDarwin::SetBreakpoint(lldb::addr_t addr, uint32_t size,
                                          bool hardware) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

void NativeProcessDarwin::DoStopIDBumped(uint32_t newBumpId) {}

Status NativeProcessDarwin::GetLoadedModuleFileSpec(const char *module_path,
                                                    FileSpec &file_spec) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

Status NativeProcessDarwin::GetFileLoadAddress(const llvm::StringRef &file_name,
                                               lldb::addr_t &load_addr) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}

// -----------------------------------------------------------------
// NativeProcessProtocol protected interface
// -----------------------------------------------------------------
Status NativeProcessDarwin::GetSoftwareBreakpointTrapOpcode(
    size_t trap_opcode_size_hint, size_t &actual_opcode_size,
    const uint8_t *&trap_opcode_bytes) {
  Status error;
  error.SetErrorString("TODO: implement");
  return error;
}
