diff --git a/lldb/include/lldb/Host/HostInfo.h b/lldb/include/lldb/Host/HostInfo.h index 0f7ec0e0aa0d2..46973edaf8c75 100644 --- a/lldb/include/lldb/Host/HostInfo.h +++ b/lldb/include/lldb/Host/HostInfo.h @@ -35,7 +35,10 @@ #if defined(_WIN32) #include "lldb/Host/windows/HostInfoWindows.h" #define HOST_INFO_TYPE HostInfoWindows -#elif defined(__linux__) || defined(__EMSCRIPTEN__) +#elif defined(__EMSCRIPTEN__) +#include "lldb/Host/emscripten/HostInfoEmscripten.h" +#define HOST_INFO_TYPE HostInfoEmscripten +#elif defined(__linux__) #if defined(__ANDROID__) #include "lldb/Host/android/HostInfoAndroid.h" #define HOST_INFO_TYPE HostInfoAndroid diff --git a/lldb/include/lldb/Host/emscripten/HostInfoEmscripten.h b/lldb/include/lldb/Host/emscripten/HostInfoEmscripten.h new file mode 100644 index 0000000000000..8c1cdcf58765b --- /dev/null +++ b/lldb/include/lldb/Host/emscripten/HostInfoEmscripten.h @@ -0,0 +1,29 @@ +//===-- HostInfoEmscripten.h -----------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_HOST_EMSCRIPTEN_HOSTINFOEMSCRIPTEN_H +#define LLDB_HOST_EMSCRIPTEN_HOSTINFOEMSCRIPTEN_H + +#include "lldb/Host/posix/HostInfoPosix.h" +#include "lldb/Utility/FileSpec.h" + +namespace lldb_private { + +class HostInfoEmscripten : public HostInfoPosix { + friend class HostInfoBase; + +public: + static void Initialize(); + static void Terminate(); + + static FileSpec GetProgramFileSpec(); +}; + +} // namespace lldb_private + +#endif // LLDB_HOST_EMSCRIPTEN_HOSTINFOEMSCRIPTEN_H diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt index ebcad8f63e4f3..45821aa410912 100644 --- a/lldb/source/Host/CMakeLists.txt +++ b/lldb/source/Host/CMakeLists.txt @@ -111,10 +111,15 @@ else() posix/LockFilePosix.cpp posix/MainLoopPosix.cpp posix/PipePosix.cpp - posix/ProcessLauncherPosixFork.cpp posix/Support.cpp ) + if (NOT EMSCRIPTEN) + add_host_subdirectory(posix + posix/ProcessLauncherPosixFork.cpp + ) + endif() + if (CMAKE_SYSTEM_NAME MATCHES "Darwin") add_subdirectory(macosx/objcxx) set(LLDBObjCLibs lldbHostMacOSXObjCXX) @@ -135,8 +140,11 @@ else() set_property(SOURCE macosx/Host.mm APPEND PROPERTY COMPILE_DEFINITIONS "NO_XPC_SERVICES=1") endif() - - + elseif (CMAKE_SYSTEM_NAME MATCHES "Emscripten") + add_host_subdirectory(emscripten + emscripten/Host.cpp + emscripten/HostInfoEmscripten.cpp + ) elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") add_host_subdirectory(linux linux/AbstractSocket.cpp diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp index c4e1500fe68ab..fdf17db53ec3e 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -67,7 +67,7 @@ #if defined(_WIN32) #include "lldb/Host/windows/ConnectionGenericFileWindows.h" #include "lldb/Host/windows/ProcessLauncherWindows.h" -#else +#elif !defined(__EMSCRIPTEN__) #include "lldb/Host/posix/ProcessLauncherPosixFork.h" #endif @@ -581,7 +581,7 @@ Status Host::RunShellCommand(llvm::StringRef shell_path, const Args &args, // The functions below implement process launching for non-Apple-based // platforms -#if !defined(__APPLE__) +#if !defined(__APPLE__) && !defined(__EMSCRIPTEN__) Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) { std::unique_ptr delegate_launcher; #if defined(_WIN32) @@ -600,7 +600,7 @@ Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) { return error; } -#endif // !defined(__APPLE__) +#endif // !defined(__APPLE__) && !defined(__EMSCRIPTEN__) #ifndef _WIN32 void Host::Kill(lldb::pid_t pid, int signo) { ::kill(pid, signo); } diff --git a/lldb/source/Host/emscripten/Host.cpp b/lldb/source/Host/emscripten/Host.cpp new file mode 100644 index 0000000000000..005a2f83f4ec7 --- /dev/null +++ b/lldb/source/Host/emscripten/Host.cpp @@ -0,0 +1,29 @@ +//===-- Host.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 "lldb/Host/Host.h" +#include "lldb/Utility/Status.h" + +using namespace lldb_private; + +uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &, + ProcessInstanceInfoList &) { + return 0; +} + +bool Host::GetProcessInfo(lldb::pid_t, ProcessInstanceInfo &) { return false; } + +Status Host::LaunchProcess(ProcessLaunchInfo &) { + return Status::FromErrorString( + "launching a host process is not supported under Emscripten"); +} + +Status Host::ShellExpandArguments(ProcessLaunchInfo &) { + return Status::FromErrorString( + "shell expansion is not supported under Emscripten"); +} diff --git a/lldb/source/Host/emscripten/HostInfoEmscripten.cpp b/lldb/source/Host/emscripten/HostInfoEmscripten.cpp new file mode 100644 index 0000000000000..10f0e2fc1dc4a --- /dev/null +++ b/lldb/source/Host/emscripten/HostInfoEmscripten.cpp @@ -0,0 +1,17 @@ +//===-- HostInfoEmscripten.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 "lldb/Host/emscripten/HostInfoEmscripten.h" + +using namespace lldb_private; + +void HostInfoEmscripten::Initialize() { HostInfoPosix::Initialize(); } + +void HostInfoEmscripten::Terminate() { HostInfoBase::Terminate(); } + +FileSpec HostInfoEmscripten::GetProgramFileSpec() { return {}; } diff --git a/lldb/source/Plugins/Platform/CMakeLists.txt b/lldb/source/Plugins/Platform/CMakeLists.txt index cc1432aa4754b..8ad1c4ef31218 100644 --- a/lldb/source/Plugins/Platform/CMakeLists.txt +++ b/lldb/source/Plugins/Platform/CMakeLists.txt @@ -7,6 +7,7 @@ set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES add_subdirectory(AIX) add_subdirectory(Android) +add_subdirectory(Emscripten) add_subdirectory(FreeBSD) add_subdirectory(gdb-server) add_subdirectory(Linux) diff --git a/lldb/source/Plugins/Platform/Emscripten/CMakeLists.txt b/lldb/source/Plugins/Platform/Emscripten/CMakeLists.txt new file mode 100644 index 0000000000000..3022c7692441a --- /dev/null +++ b/lldb/source/Plugins/Platform/Emscripten/CMakeLists.txt @@ -0,0 +1,9 @@ +add_lldb_library(lldbPluginPlatformEmscripten PLUGIN + PlatformEmscripten.cpp + + LINK_LIBS + lldbCore + lldbHost + lldbPluginPlatformPOSIX + lldbTarget + ) diff --git a/lldb/source/Plugins/Platform/Emscripten/PlatformEmscripten.cpp b/lldb/source/Plugins/Platform/Emscripten/PlatformEmscripten.cpp new file mode 100644 index 0000000000000..01659e5556df4 --- /dev/null +++ b/lldb/source/Plugins/Platform/Emscripten/PlatformEmscripten.cpp @@ -0,0 +1,82 @@ +//===-- PlatformEmscripten.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 "PlatformEmscripten.h" + +#include "lldb/Core/PluginManager.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::platform_emscripten; + +LLDB_PLUGIN_DEFINE(PlatformEmscripten) + +static uint32_t g_initialize_count = 0; + +PlatformSP PlatformEmscripten::CreateInstance(bool force, + const ArchSpec *arch) { + Log *log = GetLog(LLDBLog::Platform); + LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force, + arch ? arch->GetArchitectureName() : "", + arch ? arch->GetTriple().getTriple() : ""); + + bool create = + force || (arch && arch->IsValid() && arch->GetTriple().isOSEmscripten()); + LLDB_LOG(log, "create = {0}", create); + return create ? PlatformSP(new PlatformEmscripten(false)) : PlatformSP(); +} + +llvm::StringRef PlatformEmscripten::GetPluginDescriptionStatic(bool is_host) { + if (is_host) + return "Local Emscripten user platform plug-in."; + return "Remote Emscripten user platform plug-in."; +} + +void PlatformEmscripten::Initialize() { + PlatformPOSIX::Initialize(); + + if (g_initialize_count++ == 0) { +#if defined(__EMSCRIPTEN__) + PlatformSP platform_sp(new PlatformEmscripten(true)); + platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); + Platform::SetHostPlatform(platform_sp); +#endif + PluginManager::RegisterPlugin(GetPluginNameStatic(false), + GetPluginDescriptionStatic(false), + PlatformEmscripten::CreateInstance, nullptr); + } +} + +void PlatformEmscripten::Terminate() { + if (g_initialize_count > 0 && --g_initialize_count == 0) + PluginManager::UnregisterPlugin(PlatformEmscripten::CreateInstance); + + PlatformPOSIX::Terminate(); +} + +PlatformEmscripten::PlatformEmscripten(bool is_host) : PlatformPOSIX(is_host) { + if (is_host) + m_supported_architectures.push_back(HostInfo::GetArchitecture()); + else + m_supported_architectures = CreateArchList( + {llvm::Triple::wasm32, llvm::Triple::wasm64}, llvm::Triple::Emscripten); +} + +std::vector PlatformEmscripten::GetSupportedArchitectures( + const ArchSpec &process_host_arch) { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetSupportedArchitectures(process_host_arch); + return m_supported_architectures; +} + +bool PlatformEmscripten::CanDebugProcess() { + return !IsHost() && IsConnected(); +} diff --git a/lldb/source/Plugins/Platform/Emscripten/PlatformEmscripten.h b/lldb/source/Plugins/Platform/Emscripten/PlatformEmscripten.h new file mode 100644 index 0000000000000..2b71001c2daf9 --- /dev/null +++ b/lldb/source/Plugins/Platform/Emscripten/PlatformEmscripten.h @@ -0,0 +1,50 @@ +//===-- PlatformEmscripten.h -----------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_EMSCRIPTEN_PLATFORMEMSCRIPTEN_H +#define LLDB_SOURCE_PLUGINS_PLATFORM_EMSCRIPTEN_PLATFORMEMSCRIPTEN_H + +#include "Plugins/Platform/POSIX/PlatformPOSIX.h" + +namespace lldb_private::platform_emscripten { + +class PlatformEmscripten : public PlatformPOSIX { +public: + explicit PlatformEmscripten(bool is_host); + + static void Initialize(); + static void Terminate(); + + static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch); + + static llvm::StringRef GetPluginNameStatic(bool is_host) { + return is_host ? Platform::GetHostPlatformName() : "remote-emscripten"; + } + + static llvm::StringRef GetPluginDescriptionStatic(bool is_host); + + llvm::StringRef GetPluginName() override { + return GetPluginNameStatic(IsHost()); + } + + llvm::StringRef GetDescription() override { + return GetPluginDescriptionStatic(IsHost()); + } + + std::vector + GetSupportedArchitectures(const ArchSpec &process_host_arch) override; + + bool CanDebugProcess() override; + +private: + std::vector m_supported_architectures; +}; + +} // namespace lldb_private::platform_emscripten + +#endif // LLDB_SOURCE_PLUGINS_PLATFORM_EMSCRIPTEN_PLATFORMEMSCRIPTEN_H diff --git a/lldb/unittests/Platform/CMakeLists.txt b/lldb/unittests/Platform/CMakeLists.txt index 693faa07e53f8..f08d48ddfc203 100644 --- a/lldb/unittests/Platform/CMakeLists.txt +++ b/lldb/unittests/Platform/CMakeLists.txt @@ -2,6 +2,7 @@ add_lldb_unittest(LLDBPlatformTests TestUtils.cpp PlatformAppleSimulatorTest.cpp PlatformDarwinTest.cpp + PlatformEmscriptenTest.cpp PlatformMacOSXTest.cpp PlatformSiginfoTest.cpp PlatformTest.cpp @@ -10,6 +11,7 @@ add_lldb_unittest(LLDBPlatformTests LINK_COMPONENTS Support LINK_LIBS + lldbPluginPlatformEmscripten lldbPluginPlatformFreeBSD lldbPluginPlatformLinux lldbPluginPlatformMacOSX diff --git a/lldb/unittests/Platform/PlatformEmscriptenTest.cpp b/lldb/unittests/Platform/PlatformEmscriptenTest.cpp new file mode 100644 index 0000000000000..e9c75ea9d4a97 --- /dev/null +++ b/lldb/unittests/Platform/PlatformEmscriptenTest.cpp @@ -0,0 +1,18 @@ +//===-- PlatformEmscriptenTest.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 "Plugins/Platform/Emscripten/PlatformEmscripten.h" +#include "gtest/gtest.h" + +using namespace lldb_private; +using namespace lldb_private::platform_emscripten; + +TEST(PlatformEmscriptenTest, RecognizesEmscriptenTriple) { + ArchSpec emscripten_arch("wasm32-unknown-emscripten"); + EXPECT_TRUE(PlatformEmscripten::CreateInstance(false, &emscripten_arch)); +}