summaryrefslogtreecommitdiff
path: root/source/Plugins/Platform/Linux/PlatformLinux.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Platform/Linux/PlatformLinux.cpp')
-rw-r--r--source/Plugins/Platform/Linux/PlatformLinux.cpp408
1 files changed, 0 insertions, 408 deletions
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.cpp b/source/Plugins/Platform/Linux/PlatformLinux.cpp
deleted file mode 100644
index 7498c648d6e4..000000000000
--- a/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-//===-- 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"
-
-#include <stdio.h>
-#ifndef LLDB_DISABLE_POSIX
-#include <sys/utsname.h>
-#endif
-
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.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;
-
-//------------------------------------------------------------------
-
-PlatformSP PlatformLinux::CreateInstance(bool force, const ArchSpec *arch) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
- arch ? arch->GetArchitectureName() : "<null>",
- arch ? arch->GetTriple().getTriple() : "<null>");
-
- bool create = force;
- if (!create && 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;
- }
- }
-
- LLDB_LOG(log, "create = {0}", create);
- if (create) {
- return PlatformSP(new PlatformLinux(false));
- }
- 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, nullptr);
- }
-}
-
-void PlatformLinux::Terminate() {
- if (g_initialize_count > 0) {
- if (--g_initialize_count == 0) {
- PluginManager::UnregisterPlugin(PlatformLinux::CreateInstance);
- }
- }
-
- PlatformPOSIX::Terminate();
-}
-
-//------------------------------------------------------------------
-/// Default Constructor
-//------------------------------------------------------------------
-PlatformLinux::PlatformLinux(bool is_host)
- : PlatformPOSIX(is_host) // This is the local host platform
-{}
-
-PlatformLinux::~PlatformLinux() = default;
-
-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
- Status &error) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- LLDB_LOG(log, "target {0}", 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) {
- 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;
- }
- }
-
- // Mark target as currently selected target.
- debugger.GetTargetList().SetSelectedTarget(target);
-
- // 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);
-
- 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, NULL, 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().ReleaseMasterFileDescriptor();
- 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, "process launch failed: {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 PlatformLinux::CalculateTrapHandlerSymbolNames() {
- m_trap_handlers.push_back(ConstString("_sigtramp"));
-}
-
-MmapArgList PlatformLinux::GetMmapArgumentList(const ArchSpec &arch,
- addr_t addr, addr_t length,
- unsigned prot, unsigned flags,
- addr_t fd, addr_t offset) {
- 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;
-
- MmapArgList args({addr, length, prot, flags_platform, fd, offset});
- return args;
-}
-