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

#include "PlatformLinux.h"
#include "lldb/Host/Config.h"

// C Includes
#include <stdio.h>
#ifndef LLDB_DISABLE_POSIX
#include <sys/utsname.h>
#endif

// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/Property.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"

// Define these constants from Linux mman.h for use when targeting
// remote linux systems even when host has different values.
#define MAP_PRIVATE 2
#define MAP_ANON 0x20

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_linux;

static uint32_t g_initialize_count = 0;

//------------------------------------------------------------------
/// Code to handle the PlatformLinux settings
//------------------------------------------------------------------

namespace
{
    class PlatformLinuxProperties : public Properties
    {
    public:
        PlatformLinuxProperties();

        ~PlatformLinuxProperties() override = default;

        static ConstString&
        GetSettingName ();

    private:
        static const PropertyDefinition*
        GetStaticPropertyDefinitions();
    };

    typedef std::shared_ptr<PlatformLinuxProperties> PlatformLinuxPropertiesSP;

} // anonymous namespace

PlatformLinuxProperties::PlatformLinuxProperties() :
    Properties ()
{
    m_collection_sp.reset (new OptionValueProperties(GetSettingName ()));
    m_collection_sp->Initialize (GetStaticPropertyDefinitions ());
}

ConstString&
PlatformLinuxProperties::GetSettingName ()
{
    static ConstString g_setting_name("linux");
    return g_setting_name;
}

const PropertyDefinition*
PlatformLinuxProperties::GetStaticPropertyDefinitions()
{
    static PropertyDefinition
    g_properties[] =
    {
        {  NULL        , OptionValue::eTypeInvalid, false, 0  , NULL, NULL, NULL  }
    };

    return g_properties;
}

static const PlatformLinuxPropertiesSP &
GetGlobalProperties()
{
    static PlatformLinuxPropertiesSP g_settings_sp;
    if (!g_settings_sp)
        g_settings_sp.reset (new PlatformLinuxProperties ());
    return g_settings_sp;
}

void
PlatformLinux::DebuggerInitialize (Debugger &debugger)
{
    if (!PluginManager::GetSettingForPlatformPlugin (debugger, PlatformLinuxProperties::GetSettingName()))
    {
        const bool is_global_setting = true;
        PluginManager::CreateSettingForPlatformPlugin (debugger,
                                                       GetGlobalProperties()->GetValueProperties(),
                                                       ConstString ("Properties for the PlatformLinux plug-in."),
                                                       is_global_setting);
    }
}

//------------------------------------------------------------------

PlatformSP
PlatformLinux::CreateInstance (bool force, const ArchSpec *arch)
{
    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
    if (log)
    {
        const char *arch_name;
        if (arch && arch->GetArchitectureName ())
            arch_name = arch->GetArchitectureName ();
        else
            arch_name = "<null>";

        const char *triple_cstr = arch ? arch->GetTriple ().getTriple ().c_str() : "<null>";

        log->Printf ("PlatformLinux::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
    }

    bool create = force;
    if (create == false && arch && arch->IsValid())
    {
        const llvm::Triple &triple = arch->GetTriple();
        switch (triple.getOS())
        {
            case llvm::Triple::Linux:
                create = true;
                break;

#if defined(__linux__)
            // Only accept "unknown" for the OS if the host is linux and
            // it "unknown" wasn't specified (it was just returned because it
            // was NOT specified)
            case llvm::Triple::OSType::UnknownOS:
                create = !arch->TripleOSWasSpecified();
                break;
#endif
            default:
                break;
        }
    }

    if (create)
    {
        if (log)
            log->Printf ("PlatformLinux::%s() creating remote-linux platform", __FUNCTION__);
        return PlatformSP(new PlatformLinux(false));
    }

    if (log)
        log->Printf ("PlatformLinux::%s() aborting creation of remote-linux platform", __FUNCTION__);

    return PlatformSP();
}

ConstString
PlatformLinux::GetPluginNameStatic (bool is_host)
{
    if (is_host)
    {
        static ConstString g_host_name(Platform::GetHostPlatformName ());
        return g_host_name;
    }
    else
    {
        static ConstString g_remote_name("remote-linux");
        return g_remote_name;
    }
}

const char *
PlatformLinux::GetPluginDescriptionStatic (bool is_host)
{
    if (is_host)
        return "Local Linux user platform plug-in.";
    else
        return "Remote Linux user platform plug-in.";
}

ConstString
PlatformLinux::GetPluginName()
{
    return GetPluginNameStatic(IsHost());
}

void
PlatformLinux::Initialize ()
{
    PlatformPOSIX::Initialize ();

    if (g_initialize_count++ == 0)
    {
#if defined(__linux__) && !defined(__ANDROID__)
        PlatformSP default_platform_sp (new PlatformLinux(true));
        default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
        Platform::SetHostPlatform (default_platform_sp);
#endif
        PluginManager::RegisterPlugin(PlatformLinux::GetPluginNameStatic(false),
                                      PlatformLinux::GetPluginDescriptionStatic(false),
                                      PlatformLinux::CreateInstance,
                                      PlatformLinux::DebuggerInitialize);
    }
}

void
PlatformLinux::Terminate ()
{
    if (g_initialize_count > 0)
    {
        if (--g_initialize_count == 0)
        {
            PluginManager::UnregisterPlugin (PlatformLinux::CreateInstance);
        }
    }

    PlatformPOSIX::Terminate ();
}

Error
PlatformLinux::ResolveExecutable (const ModuleSpec &ms,
                                  lldb::ModuleSP &exe_module_sp,
                                  const FileSpecList *module_search_paths_ptr)
{
    Error error;
    // Nothing special to do here, just use the actual file and architecture

    char exe_path[PATH_MAX];
    ModuleSpec resolved_module_spec (ms);

    if (IsHost())
    {
        // If we have "ls" as the exe_file, resolve the executable location based on
        // the current path variables
        if (!resolved_module_spec.GetFileSpec().Exists())
        {
            resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
            resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
        }

        if (!resolved_module_spec.GetFileSpec().Exists())
            resolved_module_spec.GetFileSpec().ResolveExecutableLocation ();

        if (resolved_module_spec.GetFileSpec().Exists())
            error.Clear();
        else
        {
            error.SetErrorStringWithFormat("unable to find executable for '%s'", resolved_module_spec.GetFileSpec().GetPath().c_str());
        }
    }
    else
    {
        if (m_remote_platform_sp)
        {
            error = GetCachedExecutable (resolved_module_spec, exe_module_sp, module_search_paths_ptr, *m_remote_platform_sp);
        }
        else
        {
            // We may connect to a process and use the provided executable (Don't use local $PATH).

            if (resolved_module_spec.GetFileSpec().Exists())
                error.Clear();
            else
                error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path);
        }
    }

    if (error.Success())
    {
        if (resolved_module_spec.GetArchitecture().IsValid())
        {
            error = ModuleList::GetSharedModule (resolved_module_spec,
                                                 exe_module_sp,
                                                 NULL,
                                                 NULL,
                                                 NULL);
            if (error.Fail())
            {
                // If we failed, it may be because the vendor and os aren't known. If that is the
                // case, try setting them to the host architecture and give it another try.
                llvm::Triple &module_triple = resolved_module_spec.GetArchitecture().GetTriple();
                bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor);
                bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS);
                if (!is_vendor_specified || !is_os_specified)
                {
                    const llvm::Triple &host_triple = HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();

                    if (!is_vendor_specified)
                        module_triple.setVendorName (host_triple.getVendorName());
                    if (!is_os_specified)
                        module_triple.setOSName (host_triple.getOSName());

                    error = ModuleList::GetSharedModule (resolved_module_spec,
                                                         exe_module_sp,
                                                         NULL,
                                                         NULL,
                                                         NULL);
                }
            }

            // TODO find out why exe_module_sp might be NULL
            if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
            {
                exe_module_sp.reset();
                error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
                                                resolved_module_spec.GetFileSpec().GetPath().c_str(),
                                                resolved_module_spec.GetArchitecture().GetArchitectureName());
            }
        }
        else
        {
            // No valid architecture was specified, ask the platform for
            // the architectures that we should be using (in the correct order)
            // and see if we can find a match that way
            StreamString arch_names;
            for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
            {
                error = ModuleList::GetSharedModule (resolved_module_spec,
                                                     exe_module_sp,
                                                     NULL,
                                                     NULL,
                                                     NULL);
                // Did we find an executable using one of the
                if (error.Success())
                {
                    if (exe_module_sp && exe_module_sp->GetObjectFile())
                        break;
                    else
                        error.SetErrorToGenericError();
                }

                if (idx > 0)
                    arch_names.PutCString (", ");
                arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
            }

            if (error.Fail() || !exe_module_sp)
            {
                if (resolved_module_spec.GetFileSpec().Readable())
                {
                    error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
                                                    resolved_module_spec.GetFileSpec().GetPath().c_str(),
                                                    GetPluginName().GetCString(),
                                                    arch_names.GetString().c_str());
                }
                else
                {
                    error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
                }
            }
        }
    }

    return error;
}

Error
PlatformLinux::GetFileWithUUID (const FileSpec &platform_file,
                                const UUID *uuid_ptr, FileSpec &local_file)
{
    if (IsRemote())
    {
        if (m_remote_platform_sp)
            return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file);
    }

    // Default to the local case
    local_file = platform_file;
    return Error();
}

//------------------------------------------------------------------
/// Default Constructor
//------------------------------------------------------------------
PlatformLinux::PlatformLinux (bool is_host) :
    PlatformPOSIX(is_host)  // This is the local host platform
{
}

//------------------------------------------------------------------
/// Destructor.
///
/// The destructor is virtual since this class is designed to be
/// inherited from by the plug-in instance.
//------------------------------------------------------------------
PlatformLinux::~PlatformLinux() = default;

bool
PlatformLinux::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
{
    bool success = false;
    if (IsHost())
    {
        success = Platform::GetProcessInfo (pid, process_info);
    }
    else
    {
        if (m_remote_platform_sp)
            success = m_remote_platform_sp->GetProcessInfo (pid, process_info);
    }
    return success;
}

uint32_t
PlatformLinux::FindProcesses (const ProcessInstanceInfoMatch &match_info,
                              ProcessInstanceInfoList &process_infos)
{
    uint32_t match_count = 0;
    if (IsHost())
    {
        // Let the base class figure out the host details
        match_count = Platform::FindProcesses (match_info, process_infos);
    }
    else
    {
        // If we are remote, we can only return results if we are connected
        if (m_remote_platform_sp)
            match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos);
    }
    return match_count;
}

bool
PlatformLinux::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
{
    if (IsHost())
    {
        ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
        if (hostArch.GetTriple().isOSLinux())
        {
            if (idx == 0)
            {
                arch = hostArch;
                return arch.IsValid();
            }
            else if (idx == 1)
            {
                // If the default host architecture is 64-bit, look for a 32-bit variant
                if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit())
                {
                    arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
                    return arch.IsValid();
                }
            }
        }
    }
    else
    {
        if (m_remote_platform_sp)
            return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch);

        llvm::Triple triple;
        // Set the OS to linux
        triple.setOS(llvm::Triple::Linux);
        // Set the architecture
        switch (idx)
        {
            case 0: triple.setArchName("x86_64"); break;
            case 1: triple.setArchName("i386"); break;
            case 2: triple.setArchName("arm"); break;
            case 3: triple.setArchName("aarch64"); break;
            case 4: triple.setArchName("mips64"); break;
            case 5: triple.setArchName("hexagon"); break;
            case 6: triple.setArchName("mips"); break;
            case 7: triple.setArchName("mips64el"); break;
            case 8: triple.setArchName("mipsel"); break;
            case 9: triple.setArchName("s390x"); break;
            default: return false;
        }
        // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the vendor by
        // calling triple.SetVendorName("unknown") so that it is a "unspecified unknown".
        // This means when someone calls triple.GetVendorName() it will return an empty string
        // which indicates that the vendor can be set when two architectures are merged

        // Now set the triple into "arch" and return true
        arch.SetTriple(triple);
        return true;
    }
    return false;
}

void
PlatformLinux::GetStatus (Stream &strm)
{
    Platform::GetStatus(strm);

#ifndef LLDB_DISABLE_POSIX
    // Display local kernel information only when we are running in host mode.
    // Otherwise, we would end up printing non-Linux information (when running
    // on Mac OS for example).
    if (IsHost())
    {
        struct utsname un;

        if (uname(&un))
            return;

        strm.Printf ("    Kernel: %s\n", un.sysname);
        strm.Printf ("   Release: %s\n", un.release);
        strm.Printf ("   Version: %s\n", un.version);
    }
#endif
}

int32_t
PlatformLinux::GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info)
{
    int32_t resume_count = 0;

    // Always resume past the initial stop when we use eLaunchFlagDebug
    if (launch_info.GetFlags ().Test (eLaunchFlagDebug))
    {
        // Resume past the stop for the final exec into the true inferior.
        ++resume_count;
    }

    // If we're not launching a shell, we're done.
    const FileSpec &shell = launch_info.GetShell();
    if (!shell)
        return resume_count;

    std::string shell_string = shell.GetPath();
    // We're in a shell, so for sure we have to resume past the shell exec.
    ++resume_count;

    // Figure out what shell we're planning on using.
    const char *shell_name = strrchr (shell_string.c_str(), '/');
    if (shell_name == NULL)
        shell_name = shell_string.c_str();
    else
        shell_name++;

    if (strcmp (shell_name, "csh") == 0
             || strcmp (shell_name, "tcsh") == 0
             || strcmp (shell_name, "zsh") == 0
             || strcmp (shell_name, "sh") == 0)
    {
        // These shells seem to re-exec themselves.  Add another resume.
        ++resume_count;
    }

    return resume_count;
}

bool
PlatformLinux::CanDebugProcess ()
{
    if (IsHost ())
    {
        return true;
    }
    else
    {
        // If we're connected, we can debug.
        return IsConnected ();
    }
}

// For local debugging, Linux will override the debug logic to use llgs-launch rather than
// lldb-launch, llgs-attach.  This differs from current lldb-launch, debugserver-attach
// approach on MacOSX.
lldb::ProcessSP
PlatformLinux::DebugProcess (ProcessLaunchInfo &launch_info,
                             Debugger &debugger,
                             Target *target,       // Can be NULL, if NULL create a new target, else use existing one
                             Error &error)
{
    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
    if (log)
        log->Printf ("PlatformLinux::%s entered (target %p)", __FUNCTION__, static_cast<void*>(target));

    // If we're a remote host, use standard behavior from parent class.
    if (!IsHost ())
        return PlatformPOSIX::DebugProcess (launch_info, debugger, target, error);

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

    ProcessSP process_sp;

    // 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)
    {
        if (log)
            log->Printf ("PlatformLinux::%s creating new target", __FUNCTION__);

        TargetSP new_target_sp;
        error = debugger.GetTargetList().CreateTarget (debugger,
                                                       nullptr,
                                                       nullptr,
                                                       false,
                                                       nullptr,
                                                       new_target_sp);
        if (error.Fail ())
        {
            if (log)
                log->Printf ("PlatformLinux::%s failed to create new target: %s", __FUNCTION__, error.AsCString ());
            return process_sp;
        }

        target = new_target_sp.get();
        if (!target)
        {
            error.SetErrorString ("CreateTarget() returned nullptr");
            if (log)
                log->Printf ("PlatformLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
            return process_sp;
        }
    }
    else
    {
        if (log)
            log->Printf ("PlatformLinux::%s using provided target", __FUNCTION__);
    }

    // Mark target as currently selected target.
    debugger.GetTargetList().SetSelectedTarget(target);

    // Now create the gdb-remote process.
    if (log)
        log->Printf ("PlatformLinux::%s having target create process with gdb-remote plugin", __FUNCTION__);
    process_sp = target->CreateProcess (launch_info.GetListenerForProcess(debugger), "gdb-remote", nullptr);

    if (!process_sp)
    {
        error.SetErrorString ("CreateProcess() failed for gdb-remote process");
        if (log)
            log->Printf ("PlatformLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
        return process_sp;
    }
    else
    {
        if (log)
            log->Printf ("PlatformLinux::%s successfully created process", __FUNCTION__);
    }

    // Adjust launch for a hijacker.
    ListenerSP listener_sp;
    if (!launch_info.GetHijackListener ())
    {
        if (log)
            log->Printf ("PlatformLinux::%s setting up hijacker", __FUNCTION__);

        listener_sp = Listener::MakeListener("lldb.PlatformLinux.DebugProcess.hijack");
        launch_info.SetHijackListener (listener_sp);
        process_sp->HijackProcessEvents (listener_sp);
    }

    // Log file actions.
    if (log)
    {
        log->Printf ("PlatformLinux::%s launching process with the following file actions:", __FUNCTION__);

        StreamString stream;
        size_t i = 0;
        const FileAction *file_action;
        while ((file_action = launch_info.GetFileActionAtIndex (i++)) != nullptr)
        {
            file_action->Dump (stream);
            log->PutCString (stream.GetString().c_str ());
            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 (NULL, NULL, false, listener_sp);

            if (state == eStateStopped)
            {
                if (log)
                    log->Printf ("PlatformLinux::%s pid %" PRIu64 " state %s\n",
                                 __FUNCTION__, process_sp->GetID (), StateAsCString (state));
            }
            else
            {
                if (log)
                    log->Printf ("PlatformLinux::%s pid %" PRIu64 " state is not stopped - %s\n",
                                 __FUNCTION__, process_sp->GetID (), StateAsCString (state));
            }
        }

        // Hook up process PTY if we have one (which we should for local debugging with llgs).
        int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
        if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
        {
            process_sp->SetSTDIOFileDescriptor(pty_fd);
            if (log)
                log->Printf ("PlatformLinux::%s pid %" PRIu64 " hooked up STDIO pty to process", __FUNCTION__, process_sp->GetID ());
        }
        else
        {
            if (log)
                log->Printf ("PlatformLinux::%s pid %" PRIu64 " not using process STDIO pty", __FUNCTION__, process_sp->GetID ());
        }
    }
    else
    {
        if (log)
            log->Printf ("PlatformLinux::%s process launch failed: %s", __FUNCTION__, error.AsCString ());
        // 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
PlatformLinux::CalculateTrapHandlerSymbolNames ()
{
    m_trap_handlers.push_back (ConstString ("_sigtramp"));
}

uint64_t
PlatformLinux::ConvertMmapFlagsToPlatform(const ArchSpec &arch, unsigned flags)
{
    uint64_t flags_platform = 0;
    uint64_t map_anon = MAP_ANON;

    // To get correct flags for MIPS Architecture
    if (arch.GetTriple ().getArch () == llvm::Triple::mips64
       || arch.GetTriple ().getArch () == llvm::Triple::mips64el 
       || arch.GetTriple ().getArch () == llvm::Triple::mips 
       || arch.GetTriple ().getArch () == llvm::Triple::mipsel)
           map_anon = 0x800;

    if (flags & eMmapFlagsPrivate)
        flags_platform |= MAP_PRIVATE;
    if (flags & eMmapFlagsAnon)
        flags_platform |= map_anon;
    return flags_platform;
}

ConstString
PlatformLinux::GetFullNameForDylib (ConstString basename)
{
    if (basename.IsEmpty())
        return basename;
    
    StreamString stream;
    stream.Printf("lib%s.so", basename.GetCString());
    return ConstString(stream.GetData());
}
