close
Skip to content

[lldb] Add PlatformEmscripten - #223200

Open
anutosh491 wants to merge 3 commits into
llvm:mainfrom
anutosh491:lldb-emscripten-platform
Open

[lldb] Add PlatformEmscripten#223200
anutosh491 wants to merge 3 commits into
llvm:mainfrom
anutosh491:lldb-emscripten-platform

Conversation

@anutosh491

Copy link
Copy Markdown
Member

This follows #223169, where I introduced HostInfoEmscripten.

While getting libLLDB and its SB API working in the browser, I initially used PlatformLinux as the host platform under Emscripten. That was enough for the first experiment, but Emscripten is not really Linux and we shouldn't keep inheriting Linux-specific behavior going forward.

This patch introduces a separate PlatformEmscripten, based on PlatformPOSIX, and makes it the host platform when LLDB itself is running under Emscripten.

For now, it:

  • reports the Emscripten host architecture;
  • supports wasm32 and wasm64 Emscripten targets;
  • moves Emscripten host initialization out of PlatformLinux;
  • does not claim that live process debugging works yet.

PlatformWasm remains separate. My understanding is that PlatformEmscripten describes the environment in which LLDB itself is running, while PlatformWasm describes the WebAssembly program being debugged.

I am keeping this patch small on purpose. Browser-specific launching, attachment and live execution can be added separately once we connect LLDB to an actual in-browser execution backend.

I added a small test confirming that an Emscripten triple selects this platform, and also compiled the new plugin source successfully with Emscripten 6.0.8.

@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-lldb

Author: Anutosh Bhat (anutosh491)

Changes

This follows #223169, where I introduced HostInfoEmscripten.

While getting libLLDB and its SB API working in the browser, I initially used PlatformLinux as the host platform under Emscripten. That was enough for the first experiment, but Emscripten is not really Linux and we shouldn't keep inheriting Linux-specific behavior going forward.

This patch introduces a separate PlatformEmscripten, based on PlatformPOSIX, and makes it the host platform when LLDB itself is running under Emscripten.

For now, it:

  • reports the Emscripten host architecture;
  • supports wasm32 and wasm64 Emscripten targets;
  • moves Emscripten host initialization out of PlatformLinux;
  • does not claim that live process debugging works yet.

PlatformWasm remains separate. My understanding is that PlatformEmscripten describes the environment in which LLDB itself is running, while PlatformWasm describes the WebAssembly program being debugged.

I am keeping this patch small on purpose. Browser-specific launching, attachment and live execution can be added separately once we connect LLDB to an actual in-browser execution backend.

I added a small test confirming that an Emscripten triple selects this platform, and also compiled the new plugin source successfully with Emscripten 6.0.8.


Full diff: https://github.com/llvm/llvm-project/pull/223200.diff

10 Files Affected:

  • (modified) lldb/include/lldb/Host/HostInfo.h (+4-1)
  • (added) lldb/include/lldb/Host/emscripten/HostInfoEmscripten.h (+29)
  • (modified) lldb/source/Host/CMakeLists.txt (+4-2)
  • (added) lldb/source/Host/emscripten/HostInfoEmscripten.cpp (+17)
  • (modified) lldb/source/Plugins/Platform/CMakeLists.txt (+1)
  • (added) lldb/source/Plugins/Platform/Emscripten/CMakeLists.txt (+9)
  • (added) lldb/source/Plugins/Platform/Emscripten/PlatformEmscripten.cpp (+82)
  • (added) lldb/source/Plugins/Platform/Emscripten/PlatformEmscripten.h (+50)
  • (modified) lldb/unittests/Platform/CMakeLists.txt (+2)
  • (added) lldb/unittests/Platform/PlatformEmscriptenTest.cpp (+18)
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..ef99c79deab82 100644
--- a/lldb/source/Host/CMakeLists.txt
+++ b/lldb/source/Host/CMakeLists.txt
@@ -135,8 +135,10 @@ 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/HostInfoEmscripten.cpp
+      )
   elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
     add_host_subdirectory(linux
       linux/AbstractSocket.cpp
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() : "<null>",
+           arch ? arch->GetTriple().getTriple() : "<null>");
+
+  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<ArchSpec> 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<ArchSpec>
+  GetSupportedArchitectures(const ArchSpec &process_host_arch) override;
+
+  bool CanDebugProcess() override;
+
+private:
+  std::vector<ArchSpec> 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));
+}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant