//===-- 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:
        static ConstString&
        GetSettingName ();

        PlatformLinuxProperties();

        virtual
        ~PlatformLinuxProperties() = default;

    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()
{
}

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;
            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
}

size_t
PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target,
                                                BreakpointSite *bp_site)
{
    ArchSpec arch = target.GetArchitecture();
    const uint8_t *trap_opcode = NULL;
    size_t trap_opcode_size = 0;

    switch (arch.GetMachine())
    {
    default:
        assert(false && "CPU type not supported!");
        break;

    case llvm::Triple::aarch64:
        {
            static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 };
            trap_opcode = g_aarch64_opcode;
            trap_opcode_size = sizeof(g_aarch64_opcode);
        }
        break;
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
        {
            static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
            trap_opcode = g_i386_breakpoint_opcode;
            trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
        }
        break;
    case llvm::Triple::hexagon:
        {
            static const uint8_t g_hex_opcode[] = { 0x0c, 0xdb, 0x00, 0x54 };
            trap_opcode = g_hex_opcode;
            trap_opcode_size = sizeof(g_hex_opcode);
        }
        break;
    case llvm::Triple::arm:
        {
            // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
            // but the linux kernel does otherwise.
            static const uint8_t g_arm_breakpoint_opcode[] = { 0xf0, 0x01, 0xf0, 0xe7 };
            static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };

            lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
            AddressClass addr_class = eAddressClassUnknown;

            if (bp_loc_sp)
                addr_class = bp_loc_sp->GetAddress ().GetAddressClass ();

            if (addr_class == eAddressClassCodeAlternateISA
                || (addr_class == eAddressClassUnknown && (bp_site->GetLoadAddress() & 1)))
            {
                trap_opcode = g_thumb_breakpoint_opcode;
                trap_opcode_size = sizeof(g_thumb_breakpoint_opcode);
            }
            else
            {
                trap_opcode = g_arm_breakpoint_opcode;
                trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
            }
        }
        break;
    case llvm::Triple::mips:
    case llvm::Triple::mips64:
        {
            static const uint8_t g_hex_opcode[] = { 0x00, 0x00, 0x00, 0x0d };
            trap_opcode = g_hex_opcode;
            trap_opcode_size = sizeof(g_hex_opcode);
        }
        break;
    case llvm::Triple::mipsel:
    case llvm::Triple::mips64el:
        {
            static const uint8_t g_hex_opcode[] = { 0x0d, 0x00, 0x00, 0x00 };
            trap_opcode = g_hex_opcode;
            trap_opcode_size = sizeof(g_hex_opcode);
        }
        break;
    }

    if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
        return trap_opcode_size;
    return 0;
}

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.reset (new Listener("lldb.PlatformLinux.DebugProcess.hijack"));
        launch_info.SetHijackListener (listener_sp);
        process_sp->HijackProcessEvents (listener_sp.get ());
    }

    // 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.get());

            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;
}
