//===-- PlatformPOSIX.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "PlatformPOSIX.h"

#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/File.h"
#include "lldb/Host/FileCache.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/ProcessLaunchInfo.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/ScopeExit.h"

using namespace lldb;
using namespace lldb_private;

/// Default Constructor
PlatformPOSIX::PlatformPOSIX(bool is_host)
    : RemoteAwarePlatform(is_host), // This is the local host platform
      m_option_group_platform_rsync(new OptionGroupPlatformRSync()),
      m_option_group_platform_ssh(new OptionGroupPlatformSSH()),
      m_option_group_platform_caching(new OptionGroupPlatformCaching()) {}

/// Destructor.
///
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
PlatformPOSIX::~PlatformPOSIX() {}

lldb_private::OptionGroupOptions *PlatformPOSIX::GetConnectionOptions(
    lldb_private::CommandInterpreter &interpreter) {
  auto iter = m_options.find(&interpreter), end = m_options.end();
  if (iter == end) {
    std::unique_ptr<lldb_private::OptionGroupOptions> options(
        new OptionGroupOptions());
    options->Append(m_option_group_platform_rsync.get());
    options->Append(m_option_group_platform_ssh.get());
    options->Append(m_option_group_platform_caching.get());
    m_options[&interpreter] = std::move(options);
  }

  return m_options.at(&interpreter).get();
}

static uint32_t chown_file(Platform *platform, const char *path,
                           uint32_t uid = UINT32_MAX,
                           uint32_t gid = UINT32_MAX) {
  if (!platform || !path || *path == 0)
    return UINT32_MAX;

  if (uid == UINT32_MAX && gid == UINT32_MAX)
    return 0; // pretend I did chown correctly - actually I just didn't care

  StreamString command;
  command.PutCString("chown ");
  if (uid != UINT32_MAX)
    command.Printf("%d", uid);
  if (gid != UINT32_MAX)
    command.Printf(":%d", gid);
  command.Printf("%s", path);
  int status;
  platform->RunShellCommand(command.GetData(), FileSpec(), &status, nullptr,
                            nullptr, std::chrono::seconds(10));
  return status;
}

lldb_private::Status
PlatformPOSIX::PutFile(const lldb_private::FileSpec &source,
                       const lldb_private::FileSpec &destination, uint32_t uid,
                       uint32_t gid) {
  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));

  if (IsHost()) {
    if (source == destination)
      return Status();
    // cp src dst
    // chown uid:gid dst
    std::string src_path(source.GetPath());
    if (src_path.empty())
      return Status("unable to get file path for source");
    std::string dst_path(destination.GetPath());
    if (dst_path.empty())
      return Status("unable to get file path for destination");
    StreamString command;
    command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str());
    int status;
    RunShellCommand(command.GetData(), FileSpec(), &status, nullptr, nullptr,
                    std::chrono::seconds(10));
    if (status != 0)
      return Status("unable to perform copy");
    if (uid == UINT32_MAX && gid == UINT32_MAX)
      return Status();
    if (chown_file(this, dst_path.c_str(), uid, gid) != 0)
      return Status("unable to perform chown");
    return Status();
  } else if (m_remote_platform_sp) {
    if (GetSupportsRSync()) {
      std::string src_path(source.GetPath());
      if (src_path.empty())
        return Status("unable to get file path for source");
      std::string dst_path(destination.GetPath());
      if (dst_path.empty())
        return Status("unable to get file path for destination");
      StreamString command;
      if (GetIgnoresRemoteHostname()) {
        if (!GetRSyncPrefix())
          command.Printf("rsync %s %s %s", GetRSyncOpts(), src_path.c_str(),
                         dst_path.c_str());
        else
          command.Printf("rsync %s %s %s%s", GetRSyncOpts(), src_path.c_str(),
                         GetRSyncPrefix(), dst_path.c_str());
      } else
        command.Printf("rsync %s %s %s:%s", GetRSyncOpts(), src_path.c_str(),
                       GetHostname(), dst_path.c_str());
      LLDB_LOGF(log, "[PutFile] Running command: %s\n", command.GetData());
      int retcode;
      Host::RunShellCommand(command.GetData(), FileSpec(), &retcode, nullptr,
                            nullptr, std::chrono::minutes(1));
      if (retcode == 0) {
        // Don't chown a local file for a remote system
        //                if (chown_file(this,dst_path.c_str(),uid,gid) != 0)
        //                    return Status("unable to perform chown");
        return Status();
      }
      // if we are still here rsync has failed - let's try the slow way before
      // giving up
    }
  }
  return Platform::PutFile(source, destination, uid, gid);
}

lldb_private::Status PlatformPOSIX::GetFile(
    const lldb_private::FileSpec &source,      // remote file path
    const lldb_private::FileSpec &destination) // local file path
{
  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));

  // Check the args, first.
  std::string src_path(source.GetPath());
  if (src_path.empty())
    return Status("unable to get file path for source");
  std::string dst_path(destination.GetPath());
  if (dst_path.empty())
    return Status("unable to get file path for destination");
  if (IsHost()) {
    if (source == destination)
      return Status("local scenario->source and destination are the same file "
                    "path: no operation performed");
    // cp src dst
    StreamString cp_command;
    cp_command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str());
    int status;
    RunShellCommand(cp_command.GetData(), FileSpec(), &status, nullptr, nullptr,
                    std::chrono::seconds(10));
    if (status != 0)
      return Status("unable to perform copy");
    return Status();
  } else if (m_remote_platform_sp) {
    if (GetSupportsRSync()) {
      StreamString command;
      if (GetIgnoresRemoteHostname()) {
        if (!GetRSyncPrefix())
          command.Printf("rsync %s %s %s", GetRSyncOpts(), src_path.c_str(),
                         dst_path.c_str());
        else
          command.Printf("rsync %s %s%s %s", GetRSyncOpts(), GetRSyncPrefix(),
                         src_path.c_str(), dst_path.c_str());
      } else
        command.Printf("rsync %s %s:%s %s", GetRSyncOpts(),
                       m_remote_platform_sp->GetHostname(), src_path.c_str(),
                       dst_path.c_str());
      LLDB_LOGF(log, "[GetFile] Running command: %s\n", command.GetData());
      int retcode;
      Host::RunShellCommand(command.GetData(), FileSpec(), &retcode, nullptr,
                            nullptr, std::chrono::minutes(1));
      if (retcode == 0)
        return Status();
      // If we are here, rsync has failed - let's try the slow way before
      // giving up
    }
    // open src and dst
    // read/write, read/write, read/write, ...
    // close src
    // close dst
    LLDB_LOGF(log, "[GetFile] Using block by block transfer....\n");
    Status error;
    user_id_t fd_src = OpenFile(source, File::eOpenOptionRead,
                                lldb::eFilePermissionsFileDefault, error);

    if (fd_src == UINT64_MAX)
      return Status("unable to open source file");

    uint32_t permissions = 0;
    error = GetFilePermissions(source, permissions);

    if (permissions == 0)
      permissions = lldb::eFilePermissionsFileDefault;

    user_id_t fd_dst = FileCache::GetInstance().OpenFile(
        destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite |
                         File::eOpenOptionTruncate,
        permissions, error);

    if (fd_dst == UINT64_MAX) {
      if (error.Success())
        error.SetErrorString("unable to open destination file");
    }

    if (error.Success()) {
      lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
      uint64_t offset = 0;
      error.Clear();
      while (error.Success()) {
        const uint64_t n_read = ReadFile(fd_src, offset, buffer_sp->GetBytes(),
                                         buffer_sp->GetByteSize(), error);
        if (error.Fail())
          break;
        if (n_read == 0)
          break;
        if (FileCache::GetInstance().WriteFile(fd_dst, offset,
                                               buffer_sp->GetBytes(), n_read,
                                               error) != n_read) {
          if (!error.Fail())
            error.SetErrorString("unable to write to destination file");
          break;
        }
        offset += n_read;
      }
    }
    // Ignore the close error of src.
    if (fd_src != UINT64_MAX)
      CloseFile(fd_src, error);
    // And close the dst file descriptot.
    if (fd_dst != UINT64_MAX &&
        !FileCache::GetInstance().CloseFile(fd_dst, error)) {
      if (!error.Fail())
        error.SetErrorString("unable to close destination file");
    }
    return error;
  }
  return Platform::GetFile(source, destination);
}

std::string PlatformPOSIX::GetPlatformSpecificConnectionInformation() {
  StreamString stream;
  if (GetSupportsRSync()) {
    stream.PutCString("rsync");
    if ((GetRSyncOpts() && *GetRSyncOpts()) ||
        (GetRSyncPrefix() && *GetRSyncPrefix()) || GetIgnoresRemoteHostname()) {
      stream.Printf(", options: ");
      if (GetRSyncOpts() && *GetRSyncOpts())
        stream.Printf("'%s' ", GetRSyncOpts());
      stream.Printf(", prefix: ");
      if (GetRSyncPrefix() && *GetRSyncPrefix())
        stream.Printf("'%s' ", GetRSyncPrefix());
      if (GetIgnoresRemoteHostname())
        stream.Printf("ignore remote-hostname ");
    }
  }
  if (GetSupportsSSH()) {
    stream.PutCString("ssh");
    if (GetSSHOpts() && *GetSSHOpts())
      stream.Printf(", options: '%s' ", GetSSHOpts());
  }
  if (GetLocalCacheDirectory() && *GetLocalCacheDirectory())
    stream.Printf("cache dir: %s", GetLocalCacheDirectory());
  if (stream.GetSize())
    return std::string(stream.GetString());
  else
    return "";
}

const lldb::UnixSignalsSP &PlatformPOSIX::GetRemoteUnixSignals() {
  if (IsRemote() && m_remote_platform_sp)
    return m_remote_platform_sp->GetRemoteUnixSignals();
  return Platform::GetRemoteUnixSignals();
}

Status PlatformPOSIX::ConnectRemote(Args &args) {
  Status error;
  if (IsHost()) {
    error.SetErrorStringWithFormat(
        "can't connect to the host platform '%s', always connected",
        GetPluginName().GetCString());
  } else {
    if (!m_remote_platform_sp)
      m_remote_platform_sp =
          Platform::Create(ConstString("remote-gdb-server"), error);

    if (m_remote_platform_sp && error.Success())
      error = m_remote_platform_sp->ConnectRemote(args);
    else
      error.SetErrorString("failed to create a 'remote-gdb-server' platform");

    if (error.Fail())
      m_remote_platform_sp.reset();
  }

  if (error.Success() && m_remote_platform_sp) {
    if (m_option_group_platform_rsync.get() &&
        m_option_group_platform_ssh.get() &&
        m_option_group_platform_caching.get()) {
      if (m_option_group_platform_rsync->m_rsync) {
        SetSupportsRSync(true);
        SetRSyncOpts(m_option_group_platform_rsync->m_rsync_opts.c_str());
        SetRSyncPrefix(m_option_group_platform_rsync->m_rsync_prefix.c_str());
        SetIgnoresRemoteHostname(
            m_option_group_platform_rsync->m_ignores_remote_hostname);
      }
      if (m_option_group_platform_ssh->m_ssh) {
        SetSupportsSSH(true);
        SetSSHOpts(m_option_group_platform_ssh->m_ssh_opts.c_str());
      }
      SetLocalCacheDirectory(
          m_option_group_platform_caching->m_cache_dir.c_str());
    }
  }

  return error;
}

Status PlatformPOSIX::DisconnectRemote() {
  Status error;

  if (IsHost()) {
    error.SetErrorStringWithFormat(
        "can't disconnect from the host platform '%s', always connected",
        GetPluginName().GetCString());
  } else {
    if (m_remote_platform_sp)
      error = m_remote_platform_sp->DisconnectRemote();
    else
      error.SetErrorString("the platform is not currently connected");
  }
  return error;
}

lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info,
                                      Debugger &debugger, Target *target,
                                      Status &error) {
  lldb::ProcessSP process_sp;
  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));

  if (IsHost()) {
    if (target == nullptr) {
      TargetSP new_target_sp;

      error = debugger.GetTargetList().CreateTarget(
          debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
      target = new_target_sp.get();
      LLDB_LOGF(log, "PlatformPOSIX::%s created new target", __FUNCTION__);
    } else {
      error.Clear();
      LLDB_LOGF(log, "PlatformPOSIX::%s target already existed, setting target",
                __FUNCTION__);
    }

    if (target && error.Success()) {
      if (log) {
        ModuleSP exe_module_sp = target->GetExecutableModule();
        LLDB_LOGF(log, "PlatformPOSIX::%s set selected target to %p %s",
                  __FUNCTION__, (void *)target,
                  exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
                                : "<null>");
      }

      process_sp =
          target->CreateProcess(attach_info.GetListenerForProcess(debugger),
                                "gdb-remote", nullptr, true);

      if (process_sp) {
        ListenerSP listener_sp = attach_info.GetHijackListener();
        if (listener_sp == nullptr) {
          listener_sp =
              Listener::MakeListener("lldb.PlatformPOSIX.attach.hijack");
          attach_info.SetHijackListener(listener_sp);
        }
        process_sp->HijackProcessEvents(listener_sp);
        error = process_sp->Attach(attach_info);
      }
    }
  } else {
    if (m_remote_platform_sp)
      process_sp =
          m_remote_platform_sp->Attach(attach_info, debugger, target, error);
    else
      error.SetErrorString("the platform is not currently connected");
  }
  return process_sp;
}

lldb::ProcessSP
PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
                            Target *target, // Can be NULL, if NULL create a new
                                            // target, else use existing one
                            Status &error) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
  LLDB_LOG(log, "target {0}", target);

  ProcessSP process_sp;

  if (!IsHost()) {
    if (m_remote_platform_sp)
      process_sp = m_remote_platform_sp->DebugProcess(launch_info, debugger,
                                                      target, error);
    else
      error.SetErrorString("the platform is not currently connected");
    return process_sp;
  }

  //
  // For local debugging, we'll insist on having ProcessGDBRemote create the
  // process.
  //

  // Make sure we stop at the entry point
  launch_info.GetFlags().Set(eLaunchFlagDebug);

  // We always launch the process we are going to debug in a separate process
  // group, since then we can handle ^C interrupts ourselves w/o having to
  // worry about the target getting them as well.
  launch_info.SetLaunchInSeparateProcessGroup(true);

  // Ensure we have a target.
  if (target == nullptr) {
    LLDB_LOG(log, "creating new target");
    TargetSP new_target_sp;
    error = debugger.GetTargetList().CreateTarget(
        debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
    if (error.Fail()) {
      LLDB_LOG(log, "failed to create new target: {0}", error);
      return process_sp;
    }

    target = new_target_sp.get();
    if (!target) {
      error.SetErrorString("CreateTarget() returned nullptr");
      LLDB_LOG(log, "error: {0}", error);
      return process_sp;
    }
  }

  // Now create the gdb-remote process.
  LLDB_LOG(log, "having target create process with gdb-remote plugin");
  process_sp =
      target->CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr,
                            true);

  if (!process_sp) {
    error.SetErrorString("CreateProcess() failed for gdb-remote process");
    LLDB_LOG(log, "error: {0}", error);
    return process_sp;
  }

  LLDB_LOG(log, "successfully created process");
  // Adjust launch for a hijacker.
  ListenerSP listener_sp;
  if (!launch_info.GetHijackListener()) {
    LLDB_LOG(log, "setting up hijacker");
    listener_sp =
        Listener::MakeListener("lldb.PlatformLinux.DebugProcess.hijack");
    launch_info.SetHijackListener(listener_sp);
    process_sp->HijackProcessEvents(listener_sp);
  }

  // Log file actions.
  if (log) {
    LLDB_LOG(log, "launching process with the following file actions:");
    StreamString stream;
    size_t i = 0;
    const FileAction *file_action;
    while ((file_action = launch_info.GetFileActionAtIndex(i++)) != nullptr) {
      file_action->Dump(stream);
      LLDB_LOG(log, "{0}", stream.GetData());
      stream.Clear();
    }
  }

  // Do the launch.
  error = process_sp->Launch(launch_info);
  if (error.Success()) {
    // Handle the hijacking of process events.
    if (listener_sp) {
      const StateType state = process_sp->WaitForProcessToStop(
          llvm::None, nullptr, false, listener_sp);

      LLDB_LOG(log, "pid {0} state {0}", process_sp->GetID(), state);
    }

    // Hook up process PTY if we have one (which we should for local debugging
    // with llgs).
    int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
    if (pty_fd != PseudoTerminal::invalid_fd) {
      process_sp->SetSTDIOFileDescriptor(pty_fd);
      LLDB_LOG(log, "hooked up STDIO pty to process");
    } else
      LLDB_LOG(log, "not using process STDIO pty");
  } else {
    LLDB_LOG(log, "{0}", error);
    // FIXME figure out appropriate cleanup here.  Do we delete the target? Do
    // we delete the process?  Does our caller do that?
  }

  return process_sp;
}

void PlatformPOSIX::CalculateTrapHandlerSymbolNames() {
  m_trap_handlers.push_back(ConstString("_sigtramp"));
}

Status PlatformPOSIX::EvaluateLibdlExpression(
    lldb_private::Process *process, const char *expr_cstr,
    llvm::StringRef expr_prefix, lldb::ValueObjectSP &result_valobj_sp) {
  DynamicLoader *loader = process->GetDynamicLoader();
  if (loader) {
    Status error = loader->CanLoadImage();
    if (error.Fail())
      return error;
  }

  ThreadSP thread_sp(process->GetThreadList().GetExpressionExecutionThread());
  if (!thread_sp)
    return Status("Selected thread isn't valid");

  StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
  if (!frame_sp)
    return Status("Frame 0 isn't valid");

  ExecutionContext exe_ctx;
  frame_sp->CalculateExecutionContext(exe_ctx);
  EvaluateExpressionOptions expr_options;
  expr_options.SetUnwindOnError(true);
  expr_options.SetIgnoreBreakpoints(true);
  expr_options.SetExecutionPolicy(eExecutionPolicyAlways);
  expr_options.SetLanguage(eLanguageTypeC_plus_plus);
  expr_options.SetTrapExceptions(false); // dlopen can't throw exceptions, so
                                         // don't do the work to trap them.
  expr_options.SetTimeout(process->GetUtilityExpressionTimeout());

  Status expr_error;
  ExpressionResults result =
      UserExpression::Evaluate(exe_ctx, expr_options, expr_cstr, expr_prefix,
                               result_valobj_sp, expr_error);
  if (result != eExpressionCompleted)
    return expr_error;

  if (result_valobj_sp->GetError().Fail())
    return result_valobj_sp->GetError();
  return Status();
}

std::unique_ptr<UtilityFunction>
PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
                                            Status &error) {
  // Remember to prepend this with the prefix from
  // GetLibdlFunctionDeclarations. The returned values are all in
  // __lldb_dlopen_result for consistency. The wrapper returns a void * but
  // doesn't use it because UtilityFunctions don't work with void returns at
  // present.
  static const char *dlopen_wrapper_code = R"(
  struct __lldb_dlopen_result {
    void *image_ptr;
    const char *error_str;
  };
  
  extern void *memcpy(void *, const void *, size_t size);
  extern size_t strlen(const char *);
  

  void * __lldb_dlopen_wrapper (const char *name, 
                                const char *path_strings,
                                char *buffer,
                                __lldb_dlopen_result *result_ptr)
  {
    // This is the case where the name is the full path:
    if (!path_strings) {
      result_ptr->image_ptr = dlopen(name, 2);
      if (result_ptr->image_ptr)
        result_ptr->error_str = nullptr;
      return nullptr;
    }
    
    // This is the case where we have a list of paths:
    size_t name_len = strlen(name);
    while (path_strings && path_strings[0] != '\0') {
      size_t path_len = strlen(path_strings);
      memcpy((void *) buffer, (void *) path_strings, path_len);
      buffer[path_len] = '/';
      char *target_ptr = buffer+path_len+1; 
      memcpy((void *) target_ptr, (void *) name, name_len + 1);
      result_ptr->image_ptr = dlopen(buffer, 2);
      if (result_ptr->image_ptr) {
        result_ptr->error_str = nullptr;
        break;
      }
      result_ptr->error_str = dlerror();
      path_strings = path_strings + path_len + 1;
    }
    return nullptr;
  }
  )";

  static const char *dlopen_wrapper_name = "__lldb_dlopen_wrapper";
  Process *process = exe_ctx.GetProcessSP().get();
  // Insert the dlopen shim defines into our generic expression:
  std::string expr(std::string(GetLibdlFunctionDeclarations(process)));
  expr.append(dlopen_wrapper_code);
  Status utility_error;
  DiagnosticManager diagnostics;

  auto utility_fn_or_error = process->GetTarget().CreateUtilityFunction(
      std::move(expr), dlopen_wrapper_name, eLanguageTypeObjC, exe_ctx);
  if (!utility_fn_or_error) {
    std::string error_str = llvm::toString(utility_fn_or_error.takeError());
    error.SetErrorStringWithFormat("dlopen error: could not create utility"
                                   "function: %s",
                                   error_str.c_str());
    return nullptr;
  }
  std::unique_ptr<UtilityFunction> dlopen_utility_func_up =
      std::move(*utility_fn_or_error);

  Value value;
  ValueList arguments;
  FunctionCaller *do_dlopen_function = nullptr;

  // Fetch the clang types we will need:
  TypeSystemClang *ast =
      ScratchTypeSystemClang::GetForTarget(process->GetTarget());
  if (!ast)
    return nullptr;

  CompilerType clang_void_pointer_type
      = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
  CompilerType clang_char_pointer_type
        = ast->GetBasicType(eBasicTypeChar).GetPointerType();

  // We are passing four arguments, the basename, the list of places to look,
  // a buffer big enough for all the path + name combos, and
  // a pointer to the storage we've made for the result:
  value.SetValueType(Value::ValueType::Scalar);
  value.SetCompilerType(clang_void_pointer_type);
  arguments.PushValue(value);
  value.SetCompilerType(clang_char_pointer_type);
  arguments.PushValue(value);
  arguments.PushValue(value);
  arguments.PushValue(value);
  
  do_dlopen_function = dlopen_utility_func_up->MakeFunctionCaller(
      clang_void_pointer_type, arguments, exe_ctx.GetThreadSP(), utility_error);
  if (utility_error.Fail()) {
    error.SetErrorStringWithFormat("dlopen error: could not make function"
                                   "caller: %s", utility_error.AsCString());
    return nullptr;
  }
  
  do_dlopen_function = dlopen_utility_func_up->GetFunctionCaller();
  if (!do_dlopen_function) {
    error.SetErrorString("dlopen error: could not get function caller.");
    return nullptr;
  }
  
  // We made a good utility function, so cache it in the process:
  return dlopen_utility_func_up;
}

uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
                                    const lldb_private::FileSpec &remote_file,
                                    const std::vector<std::string> *paths,
                                    lldb_private::Status &error,
                                    lldb_private::FileSpec *loaded_image) {
  if (loaded_image)
    loaded_image->Clear();

  std::string path;
  path = remote_file.GetPath();
  
  ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
  if (!thread_sp) {
    error.SetErrorString("dlopen error: no thread available to call dlopen.");
    return LLDB_INVALID_IMAGE_TOKEN;
  }
  
  DiagnosticManager diagnostics;
  
  ExecutionContext exe_ctx;
  thread_sp->CalculateExecutionContext(exe_ctx);

  Status utility_error;
  UtilityFunction *dlopen_utility_func;
  ValueList arguments;
  FunctionCaller *do_dlopen_function = nullptr;

  // The UtilityFunction is held in the Process.  Platforms don't track the
  // lifespan of the Targets that use them, we can't put this in the Platform.
  dlopen_utility_func = process->GetLoadImageUtilityFunction(
      this, [&]() -> std::unique_ptr<UtilityFunction> {
        return MakeLoadImageUtilityFunction(exe_ctx, error);
      });
  // If we couldn't make it, the error will be in error, so we can exit here.
  if (!dlopen_utility_func)
    return LLDB_INVALID_IMAGE_TOKEN;
    
  do_dlopen_function = dlopen_utility_func->GetFunctionCaller();
  if (!do_dlopen_function) {
    error.SetErrorString("dlopen error: could not get function caller.");
    return LLDB_INVALID_IMAGE_TOKEN;
  }
  arguments = do_dlopen_function->GetArgumentValues();
  
  // Now insert the path we are searching for and the result structure into the
  // target.
  uint32_t permissions = ePermissionsReadable|ePermissionsWritable;
  size_t path_len = path.size() + 1;
  lldb::addr_t path_addr = process->AllocateMemory(path_len, 
                                                   permissions,
                                                   utility_error);
  if (path_addr == LLDB_INVALID_ADDRESS) {
    error.SetErrorStringWithFormat("dlopen error: could not allocate memory"
                                    "for path: %s", utility_error.AsCString());
    return LLDB_INVALID_IMAGE_TOKEN;
  }

  // Make sure we deallocate the input string memory:
  auto path_cleanup = llvm::make_scope_exit([process, path_addr] {
    // Deallocate the buffer.
    process->DeallocateMemory(path_addr);
  });

  process->WriteMemory(path_addr, path.c_str(), path_len, utility_error);
  if (utility_error.Fail()) {
    error.SetErrorStringWithFormat("dlopen error: could not write path string:"
                                    " %s", utility_error.AsCString());
    return LLDB_INVALID_IMAGE_TOKEN;
  }
  
  // Make space for our return structure.  It is two pointers big: the token
  // and the error string.
  const uint32_t addr_size = process->GetAddressByteSize();
  lldb::addr_t return_addr = process->CallocateMemory(2*addr_size,
                                                      permissions,
                                                      utility_error);
  if (utility_error.Fail()) {
    error.SetErrorStringWithFormat("dlopen error: could not allocate memory"
                                    "for path: %s", utility_error.AsCString());
    return LLDB_INVALID_IMAGE_TOKEN;
  }
  
  // Make sure we deallocate the result structure memory
  auto return_cleanup = llvm::make_scope_exit([process, return_addr] {
    // Deallocate the buffer
    process->DeallocateMemory(return_addr);
  });

  // This will be the address of the storage for paths, if we are using them,
  // or nullptr to signal we aren't.
  lldb::addr_t path_array_addr = 0x0;
  llvm::Optional<llvm::detail::scope_exit<std::function<void()>>>
      path_array_cleanup;

  // This is the address to a buffer large enough to hold the largest path
  // conjoined with the library name we're passing in.  This is a convenience 
  // to avoid having to call malloc in the dlopen function.
  lldb::addr_t buffer_addr = 0x0;
  llvm::Optional<llvm::detail::scope_exit<std::function<void()>>>
      buffer_cleanup;

  // Set the values into our args and write them to the target:
  if (paths != nullptr) {
    // First insert the paths into the target.  This is expected to be a 
    // continuous buffer with the strings laid out null terminated and
    // end to end with an empty string terminating the buffer.
    // We also compute the buffer's required size as we go.
    size_t buffer_size = 0;
    std::string path_array;
    for (auto path : *paths) {
      // Don't insert empty paths, they will make us abort the path
      // search prematurely.
      if (path.empty())
        continue;
      size_t path_size = path.size();
      path_array.append(path);
      path_array.push_back('\0');
      if (path_size > buffer_size)
        buffer_size = path_size;
    }
    path_array.push_back('\0');
    
    path_array_addr = process->AllocateMemory(path_array.size(), 
                                              permissions,
                                              utility_error);
    if (path_array_addr == LLDB_INVALID_ADDRESS) {
      error.SetErrorStringWithFormat("dlopen error: could not allocate memory"
                                      "for path array: %s", 
                                      utility_error.AsCString());
      return LLDB_INVALID_IMAGE_TOKEN;
    }
    
    // Make sure we deallocate the paths array.
    path_array_cleanup.emplace([process, path_array_addr]() {
      // Deallocate the path array.
      process->DeallocateMemory(path_array_addr);
    });

    process->WriteMemory(path_array_addr, path_array.data(), 
                         path_array.size(), utility_error);

    if (utility_error.Fail()) {
      error.SetErrorStringWithFormat("dlopen error: could not write path array:"
                                     " %s", utility_error.AsCString());
      return LLDB_INVALID_IMAGE_TOKEN;
    }
    // Now make spaces in the target for the buffer.  We need to add one for
    // the '/' that the utility function will insert and one for the '\0':
    buffer_size += path.size() + 2;
    
    buffer_addr = process->AllocateMemory(buffer_size, 
                                          permissions,
                                          utility_error);
    if (buffer_addr == LLDB_INVALID_ADDRESS) {
      error.SetErrorStringWithFormat("dlopen error: could not allocate memory"
                                      "for buffer: %s", 
                                      utility_error.AsCString());
      return LLDB_INVALID_IMAGE_TOKEN;
    }
  
    // Make sure we deallocate the buffer memory:
    buffer_cleanup.emplace([process, buffer_addr]() {
      // Deallocate the buffer.
      process->DeallocateMemory(buffer_addr);
    });
  }
    
  arguments.GetValueAtIndex(0)->GetScalar() = path_addr;
  arguments.GetValueAtIndex(1)->GetScalar() = path_array_addr;
  arguments.GetValueAtIndex(2)->GetScalar() = buffer_addr;
  arguments.GetValueAtIndex(3)->GetScalar() = return_addr;

  lldb::addr_t func_args_addr = LLDB_INVALID_ADDRESS;
  
  diagnostics.Clear();
  if (!do_dlopen_function->WriteFunctionArguments(exe_ctx, 
                                                 func_args_addr,
                                                 arguments,
                                                 diagnostics)) {
    error.SetErrorStringWithFormat("dlopen error: could not write function "
                                   "arguments: %s", 
                                   diagnostics.GetString().c_str());
    return LLDB_INVALID_IMAGE_TOKEN;
  }
  
  // Make sure we clean up the args structure.  We can't reuse it because the
  // Platform lives longer than the process and the Platforms don't get a
  // signal to clean up cached data when a process goes away.
  auto args_cleanup =
      llvm::make_scope_exit([do_dlopen_function, &exe_ctx, func_args_addr] {
        do_dlopen_function->DeallocateFunctionResults(exe_ctx, func_args_addr);
      });

  // Now run the caller:
  EvaluateExpressionOptions options;
  options.SetExecutionPolicy(eExecutionPolicyAlways);
  options.SetLanguage(eLanguageTypeC_plus_plus);
  options.SetIgnoreBreakpoints(true);
  options.SetUnwindOnError(true);
  options.SetTrapExceptions(false); // dlopen can't throw exceptions, so
                                    // don't do the work to trap them.
  options.SetTimeout(process->GetUtilityExpressionTimeout());
  options.SetIsForUtilityExpr(true);

  Value return_value;
  // Fetch the clang types we will need:
  TypeSystemClang *ast =
      ScratchTypeSystemClang::GetForTarget(process->GetTarget());
  if (!ast) {
    error.SetErrorString("dlopen error: Unable to get TypeSystemClang");
    return LLDB_INVALID_IMAGE_TOKEN;
  }

  CompilerType clang_void_pointer_type
      = ast->GetBasicType(eBasicTypeVoid).GetPointerType();

  return_value.SetCompilerType(clang_void_pointer_type);
  
  ExpressionResults results = do_dlopen_function->ExecuteFunction(
      exe_ctx, &func_args_addr, options, diagnostics, return_value);
  if (results != eExpressionCompleted) {
    error.SetErrorStringWithFormat("dlopen error: failed executing "
                                   "dlopen wrapper function: %s", 
                                   diagnostics.GetString().c_str());
    return LLDB_INVALID_IMAGE_TOKEN;
  }
  
  // Read the dlopen token from the return area:
  lldb::addr_t token = process->ReadPointerFromMemory(return_addr, 
                                                      utility_error);
  if (utility_error.Fail()) {
    error.SetErrorStringWithFormat("dlopen error: could not read the return "
                                    "struct: %s", utility_error.AsCString());
    return LLDB_INVALID_IMAGE_TOKEN;
  }
  
  // The dlopen succeeded!
  if (token != 0x0) {
    if (loaded_image && buffer_addr != 0x0)
    {
      // Capture the image which was loaded.  We leave it in the buffer on
      // exit from the dlopen function, so we can just read it from there:
      std::string name_string;
      process->ReadCStringFromMemory(buffer_addr, name_string, utility_error);
      if (utility_error.Success())
        loaded_image->SetFile(name_string, llvm::sys::path::Style::posix);
    }
    return process->AddImageToken(token);
  }
    
  // We got an error, lets read in the error string:
  std::string dlopen_error_str;
  lldb::addr_t error_addr 
    = process->ReadPointerFromMemory(return_addr + addr_size, utility_error);
  if (utility_error.Fail()) {
    error.SetErrorStringWithFormat("dlopen error: could not read error string: "
                                    "%s", utility_error.AsCString());
    return LLDB_INVALID_IMAGE_TOKEN;
  }
  
  size_t num_chars = process->ReadCStringFromMemory(error_addr + addr_size, 
                                                    dlopen_error_str, 
                                                    utility_error);
  if (utility_error.Success() && num_chars > 0)
    error.SetErrorStringWithFormat("dlopen error: %s",
                                   dlopen_error_str.c_str());
  else
    error.SetErrorStringWithFormat("dlopen failed for unknown reasons.");

  return LLDB_INVALID_IMAGE_TOKEN;
}

Status PlatformPOSIX::UnloadImage(lldb_private::Process *process,
                                  uint32_t image_token) {
  const addr_t image_addr = process->GetImagePtrFromToken(image_token);
  if (image_addr == LLDB_INVALID_ADDRESS)
    return Status("Invalid image token");

  StreamString expr;
  expr.Printf("dlclose((void *)0x%" PRIx64 ")", image_addr);
  llvm::StringRef prefix = GetLibdlFunctionDeclarations(process);
  lldb::ValueObjectSP result_valobj_sp;
  Status error = EvaluateLibdlExpression(process, expr.GetData(), prefix,
                                         result_valobj_sp);
  if (error.Fail())
    return error;

  if (result_valobj_sp->GetError().Fail())
    return result_valobj_sp->GetError();

  Scalar scalar;
  if (result_valobj_sp->ResolveValue(scalar)) {
    if (scalar.UInt(1))
      return Status("expression failed: \"%s\"", expr.GetData());
    process->ResetImageToken(image_token);
  }
  return Status();
}

llvm::StringRef
PlatformPOSIX::GetLibdlFunctionDeclarations(lldb_private::Process *process) {
  return R"(
              extern "C" void* dlopen(const char*, int);
              extern "C" void* dlsym(void*, const char*);
              extern "C" int   dlclose(void*);
              extern "C" char* dlerror(void);
             )";
}

size_t PlatformPOSIX::ConnectToWaitingProcesses(Debugger &debugger,
                                                Status &error) {
  if (m_remote_platform_sp)
    return m_remote_platform_sp->ConnectToWaitingProcesses(debugger, error);
  return Platform::ConnectToWaitingProcesses(debugger, error);
}

ConstString PlatformPOSIX::GetFullNameForDylib(ConstString basename) {
  if (basename.IsEmpty())
    return basename;

  StreamString stream;
  stream.Printf("lib%s.so", basename.GetCString());
  return ConstString(stream.GetString());
}
