[Lldb-commits] [lldb] [lldb] Implement WebAssembly debugging (PR #77949)

2024-02-22 Thread Xu Jun via lldb-commits


@@ -0,0 +1,108 @@
+//=== wasmRegisterContext.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 "wasmRegisterContext.h"
+#include "Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h"
+#include "ProcessWasm.h"
+#include "ThreadWasm.h"
+#include "lldb/Utility/RegisterValue.h"
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_gdb_remote;
+using namespace lldb_private::wasm;
+
+WasmRegisterContext::WasmRegisterContext(
+wasm::ThreadWasm &thread, uint32_t concrete_frame_idx,
+GDBRemoteDynamicRegisterInfoSP reg_info_sp)
+: GDBRemoteRegisterContext(thread, concrete_frame_idx, reg_info_sp, false,
+   false) {}
+
+WasmRegisterContext::~WasmRegisterContext() = default;
+
+uint32_t WasmRegisterContext::ConvertRegisterKindToRegisterNumber(
+lldb::RegisterKind kind, uint32_t num) {
+  return num;
+}
+
+size_t WasmRegisterContext::GetRegisterCount() { return 0; }
+
+const RegisterInfo *WasmRegisterContext::GetRegisterInfoAtIndex(size_t reg) {
+  uint32_t tag = (reg >> 30) & 0x03;
+  if (tag == 0) {
+return m_reg_info_sp->GetRegisterInfoAtIndex(reg);
+  }
+
+  auto it = m_register_map.find(reg);
+  if (it == m_register_map.end()) {
+WasmVirtualRegisterKinds kind =
+static_cast(tag - 1);

xujuntwt95329 wrote:

Thanks for the suggestion, that would be better.

@paolosevMSFT Maybe we can modify the `eLocal` to `1` in 
`wasmRegisterContext.h:WasmVirtualRegisterKinds` so we don't need to do 
addition and subtracting on the tag
https://github.com/paolosevMSFT/llvm-project/blob/89c4ec1b1dec51df187e84c83ad3cb25eb7e847a/lldb/source/Plugins/Process/wasm/wasmRegisterContext.h#L25

https://github.com/llvm/llvm-project/pull/77949
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement WebAssembly debugging (PR #77949)

2024-02-20 Thread Xu Jun via lldb-commits


@@ -24,17 +24,33 @@ def format_register_value(val):
 return result
 
 
+def make_code_address(module_id, offset):
+return 0x4000 | (module_id << 32) | offset
+

xujuntwt95329 wrote:

@paolosevMSFT Seems the rule require two empty lines before class definition

```suggestion


```

https://github.com/llvm/llvm-project/pull/77949
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Support DW_OP_WASM_location in DWARFExpression (PR #78977)

2024-02-20 Thread Xu Jun via lldb-commits

xujuntwt95329 wrote:

Hi @JDevlieghere Could you please give us some suggestions about the next steps 
for this PR and https://github.com/llvm/llvm-project/pull/77949?

Thanks a lot!

https://github.com/llvm/llvm-project/pull/78977
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement WebAssembly debugging (PR #77949)

2024-02-05 Thread Xu Jun via lldb-commits

xujuntwt95329 wrote:

> > I see, thanks for the clarification. In the patch, the WasmLocal and 
> > WasmGlobal calls are done in ReadRegister, so it seems like those are being 
> > presented as register values? `register read` should show them. BTW, we 
> > shouldn't make a top level `wasm` command, we really try hard not to occupy 
> > more of the "easy to type" parts of the lldb command set than we can help, 
> > so there is lots left free for users to customize. There's a `language 
> > cplusplus` command (and on the swift fork `language swift`, so it would 
> > make sense to have wasm commands be vended as `language wasm`. Then people 
> > who do a lot of WebAssembly debugging can make an alias to wasm if that 
> > helps. Jim
> 
> However, `language` plugins do not seem to work for the Wasm case here. When 
> we are debugging Wasm code, WebAssembly is the architecture and the source 
> language is the whatever was compiled to Wasm, commonly C/C++ or Rust.
> 
> If we implement a `WasmLanguage` plugin we should override virtual methods 
> like `bool IsTopLevelFunction(Function &function)`, `bool 
> IsSourceFile(StringRef &file_path) `GetFormatters()` which do not really 
> apply here.
> 
> But I agree that it is not nice to make a top level `wasm` command, so maybe 
> the best way is to leave everything as it is and to just specify the plugin 
> name at connection time: `process connect --plugin wasm 
> connect://localhost:`

Yes, the top level `wasm` command may be useful to WebAssembly users but may 
cause confusion to other users who doesn't use WebAssembly (Just like their 
isn't a top level `arm` command, `wasm` here should be conceptually equivalent 
with `arm`). Maybe we can remove this command from this PR, and users can add 
their own alias for convenience.

https://github.com/llvm/llvm-project/pull/77949
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement WebAssembly debugging (PR #77949)

2024-02-05 Thread Xu Jun via lldb-commits

xujuntwt95329 wrote:

> > On the other hand, as a managed language, I think most people won't need to 
> > read specific local/global of an instance, just like most of the JavaScript 
> > developer won't care about the value of a register in V8 during debugging, 
> > they just care about the value of their variables.
> 
> I agree that the average developer will not have much use of the possibility 
> of accessing Wasm locals and globals. I also understand that Wasm locals and 
> global are a very specific, Wasm-only concept and that adding this concept in 
> LLVM core is not pertinent. However for people working on the inner workings 
> of Wasm (like me), it may be very useful. I'm not sure it belongs to this PR 
> but implementing support for accessing Wasm locals/globals in the future 
> (using perhaps a command like `language wasm`) seems an interesting thing to 
> do to complete the debugging experience on Wasm with lldb.
> 
> What I'm wondering is, does these potential added commands have an impact on 
> this PR ? Or can we imagine commands that will send a specific, Wasm-only 
> request to the debugging server to get the values of the variables without 
> using the implementation of locals and globals of this PR ?

I agree that implementing support for accessing Wasm locals/globals would be a 
very interesting and exciting thing, and as a WebAssembly runtime developer, 
such features will be extremely useful to me (currently I need to debug the 
runtime itself to retrieve the internal data structures to find the value of 
locals/globals). But since there isn't an existing concepts in lldb to support 
these, we think it should be better to focus this PR on the source level 
debugging support to control the complexity, and leave the local/global support 
as further enhancement.

> What I'm wondering is, does these potential added commands have an impact on 
> this PR ? Or can we imagine commands that will send a specific, Wasm-only 
> request to the debugging server to get the values of the variables without 
> using the implementation of locals and globals of this PR ?

I think a wasm-specific command which directly send message to debug server for 
getting local/global values would be a simple approach to support the nice 
features, maybe we can consider such solution in the future to improve the 
debugging experience.

https://github.com/llvm/llvm-project/pull/77949
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement WebAssembly debugging (PR #77949)

2024-01-28 Thread Xu Jun via lldb-commits

xujuntwt95329 wrote:

> > Hi @mh4ck-Thales this is caused by [#77949 
> > (comment)](https://github.com/llvm/llvm-project/pull/77949#discussion_r1463458728),
> >  currently we need to modify it manually.
> 
> Thanks! That did the trick for the breakpoint and disassembly problems. When 
> using `read register` I can only see `pc` and nothing else though. I'm not 
> sure assimilating Wasm variables to registers is the good way to go anyway, 
> because the number of Wasm variables is not fixed in advance, and subject to 
> the context of execution (with local variables). This is not the case at all 
> for classic CPU registers, and I'm not sure the generic code managing 
> registers in lldb will support that. Using a solution like @jimingham 
> proposed with subcommands of `language wasm` may be a easier, less bug prone 
> way to implement this.

Yes, the `virtual register` concepts is just used internally to allow us to 
process wasm locals/globals/operand stack values in a plugin without a huge 
modification to LLDB core part. This allows users to debug their source code, 
but doesn't support reading specific local/global values. 

Currently lldb doesn't have an exist model for representing wasm's 
local/global/operand stack values, I think encoding them as virtual registers 
is an easy approach for enabling WebAssembly debugging and without a huge 
modification to LLDB core part.

On the other hand, as a managed language, I think most people won't need to 
read specific local/global of an instance, just like most of the JavaScript 
developer won't care about the value of a register in V8 during debugging, they 
just care about the value of their variables. 

So I think the virtual register approach should be okay for the developer 
usage, with small engineering effort and limited quality influence to LLDB.

https://github.com/llvm/llvm-project/pull/77949
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement WebAssembly debugging (PR #77949)

2024-01-25 Thread Xu Jun via lldb-commits

xujuntwt95329 wrote:

> I already tried to use `register read` to access Wasm variables without 
> success. But it was the patch available 
> [here](https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/build-scripts/lldb_wasm.patch)
>  is part of WAMR, maybe this patch is different and will make it work. I 
> tried using this patch without success.
> 
> It seems like compiling lldb with this patch and use it to debug Wasm with 
> the latest version of WAMR / iwasm do not work correctly (at least for me). 
> lldb can connect to the server embedded into iwasm but doesn't seem to be 
> able to disassemble Wasm bytecode or set breakpoints. Just giving the info 
> here because I'm not sure this patch is supposed to be straightaway 
> compatible with WAMR.

Hi @mh4ck-Thales this is caused by 
https://github.com/llvm/llvm-project/pull/77949#discussion_r1463458728, 
currently we need to modify it manually. 

And since this PR is not merged, you need to use the [wasm_debug_2024] branch 
in my forked WAMR repo for testing: 
https://github.com/xujuntwt95329/wasm-micro-runtime/tree/wasm_debug_2024

https://github.com/llvm/llvm-project/pull/77949
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement WebAssembly debugging (PR #77949)

2024-01-23 Thread Xu Jun via lldb-commits

xujuntwt95329 wrote:

Thanks @paolosevMSFT for the great work! We have implemented debugger server in 
[WebAssembly Micro Runtime 
(WAMR)](https://github.com/bytecodealliance/wasm-micro-runtime) to work with 
this, and it works well!
![image](https://github.com/llvm/llvm-project/assets/20285361/bb2f2167-8389-4ac3-976e-8f9e6e35fe4b)

The experience of debugging dwarf-based WebAssembly modules is similar to the 
native elf, and with lldb‘s DAP tool, we can easily debug this in a UI friendly 
environment such as VSCode. This is really exciting and greatly improves the 
usability of WebAssembly  :)

Previously we maintain a huge patch file (which was created from 
@paolosevMSFT's patches) and tell the users to patch lldb source and build the 
customized lldb binary. We hope this can be upstream and shipped with official 
build, then people can enjoy debugging WebAssembly more conveniently

https://github.com/llvm/llvm-project/pull/77949
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement WebAssembly debugging (PR #77949)

2024-01-23 Thread Xu Jun via lldb-commits


@@ -0,0 +1,291 @@
+//===-- ProcessWasm.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 "ProcessWasm.h"
+#include "ThreadWasm.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Utility/DataBufferHeap.h"
+
+#include "lldb/Target/UnixSignals.h"
+#include "llvm/ADT/ArrayRef.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_gdb_remote;
+using namespace lldb_private::wasm;
+
+LLDB_PLUGIN_DEFINE(ProcessWasm)
+
+// ProcessGDBRemote constructor
+ProcessWasm::ProcessWasm(lldb::TargetSP target_sp, ListenerSP listener_sp)
+: ProcessGDBRemote(target_sp, listener_sp) {
+  /* always use linux signals for wasm process */
+  m_unix_signals_sp =
+  UnixSignals::Create(ArchSpec{"wasm32-unknown-unknown-wasm"});

xujuntwt95329 wrote:

WebAssembly doesn't define its own signal system, here we simply use 
UnixSignals and expect the WebAssembly runtime always use UnixSignals on all 
platforms.

https://github.com/llvm/llvm-project/pull/77949
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Implement WebAssembly debugging (PR #77949)

2024-01-23 Thread Xu Jun via lldb-commits


@@ -0,0 +1,293 @@
+//===-- ProcessWasm.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 "ProcessWasm.h"
+#include "ThreadWasm.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Utility/DataBufferHeap.h"
+
+#include "lldb/Target/UnixSignals.h"
+#include "llvm/ADT/ArrayRef.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_gdb_remote;
+using namespace lldb_private::wasm;
+
+LLDB_PLUGIN_DEFINE(ProcessWasm)
+
+// ProcessGDBRemote constructor
+ProcessWasm::ProcessWasm(lldb::TargetSP target_sp, ListenerSP listener_sp)
+: ProcessGDBRemote(target_sp, listener_sp) {
+  /* always use linux signals for wasm process */
+  m_unix_signals_sp =
+  UnixSignals::Create(ArchSpec{"wasm32-unknown-unknown-wasm"});
+}
+
+void ProcessWasm::Initialize() {
+  static llvm::once_flag g_once_flag;
+
+  llvm::call_once(g_once_flag, []() {
+PluginManager::RegisterPlugin(GetPluginNameStatic(),
+  GetPluginDescriptionStatic(), CreateInstance,
+  DebuggerInitialize);
+  });
+}
+
+void ProcessWasm::DebuggerInitialize(Debugger &debugger) {
+  ProcessGDBRemote::DebuggerInitialize(debugger);
+}
+
+llvm::StringRef ProcessWasm::GetPluginName() { return GetPluginNameStatic(); }
+
+llvm::StringRef ProcessWasm::GetPluginNameStatic() {
+  static ConstString g_name("wasm");
+  return g_name;
+}
+
+llvm::StringRef ProcessWasm::GetPluginDescriptionStatic() {
+  return "GDB Remote protocol based WebAssembly debugging plug-in.";
+}
+
+void ProcessWasm::Terminate() {
+  PluginManager::UnregisterPlugin(ProcessWasm::CreateInstance);
+}
+
+lldb::ProcessSP ProcessWasm::CreateInstance(lldb::TargetSP target_sp,
+ListenerSP listener_sp,
+const FileSpec *crash_file_path,
+bool can_connect) {
+  lldb::ProcessSP process_sp;
+  if (crash_file_path == nullptr)
+process_sp = std::make_shared(target_sp, listener_sp);
+  return process_sp;
+}
+
+bool ProcessWasm::CanDebug(lldb::TargetSP target_sp,
+   bool plugin_specified_by_name) {
+  if (plugin_specified_by_name)
+return true;
+
+  Module *exe_module = target_sp->GetExecutableModulePointer();
+  if (exe_module) {
+ObjectFile *exe_objfile = exe_module->GetObjectFile();
+return exe_objfile->GetArchitecture().GetMachine() == llvm::Triple::wasm32;
+  }
+  // However, if there is no wasm module, we return false, otherwise,
+  // we might use ProcessWasm to attach gdb remote.
+  return false;
+}
+
+std::shared_ptr ProcessWasm::CreateThread(lldb::tid_t tid) {
+  return std::make_shared(*this, tid);
+}
+
+size_t ProcessWasm::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+   Status &error) {
+  wasm_addr_t wasm_addr(vm_addr);
+
+  switch (wasm_addr.GetType()) {
+  case WasmAddressType::Memory:
+if (wasm_addr.module_id != 0) {
+  if (WasmReadMemory(wasm_addr.module_id, wasm_addr.offset, buf, size)) {
+return size;
+  }
+  error.SetErrorStringWithFormat("Wasm memory read failed for 0x%" PRIx64,
+ vm_addr);
+  return 0;
+} else {
+  return ProcessGDBRemote::ReadMemory(vm_addr, buf, size, error);
+}
+  case WasmAddressType::Code:
+wasm_addr.type = 0;

xujuntwt95329 wrote:

Seems this should be `1`?

```suggestion
wasm_addr.type = 1;
```

https://github.com/llvm/llvm-project/pull/77949
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][dap] always add column field in StackFrame body (PR #73393)

2023-11-26 Thread Xu Jun via lldb-commits


@@ -817,8 +817,7 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) {
 if (line && line != LLDB_INVALID_LINE_NUMBER)
   object.try_emplace("line", line);

xujuntwt95329 wrote:

Thanks! Updated

https://github.com/llvm/llvm-project/pull/73393
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][dap] always add column field in StackFrame body (PR #73393)

2023-11-26 Thread Xu Jun via lldb-commits

https://github.com/xujuntwt95329 updated 
https://github.com/llvm/llvm-project/pull/73393

>From 4621be9af9a8003c52850ed57ae7a24f26769b2c Mon Sep 17 00:00:00 2001
From: Xu Jun <693788...@qq.com>
Date: Sat, 25 Nov 2023 22:52:53 +0800
Subject: [PATCH 1/2] [lldb][dap] always add column field in StackFrame body

Signed-off-by: Xu Jun <693788...@qq.com>
---
 lldb/tools/lldb-dap/JSONUtils.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 03a43f9da87f241..e65b05243df7066 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -817,8 +817,7 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) {
 if (line && line != LLDB_INVALID_LINE_NUMBER)
   object.try_emplace("line", line);
 auto column = line_entry.GetColumn();
-if (column && column != LLDB_INVALID_COLUMN_NUMBER)
-  object.try_emplace("column", column);
+object.try_emplace("column", column);
   } else {
 object.try_emplace("line", 0);
 object.try_emplace("column", 0);

>From 2e2c7cd63d9855016e3dff99720188dc912bb64e Mon Sep 17 00:00:00 2001
From: Xu Jun <693788...@qq.com>
Date: Mon, 27 Nov 2023 06:25:17 +
Subject: [PATCH 2/2] [lldb][dap] always add line field in StackFrame body

---
 lldb/tools/lldb-dap/JSONUtils.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index e65b05243df7066..d5edafccfedc3c6 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -816,6 +816,8 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) {
 auto line = line_entry.GetLine();
 if (line && line != LLDB_INVALID_LINE_NUMBER)
   object.try_emplace("line", line);
+else
+  object.try_emplace("line", 0);
 auto column = line_entry.GetColumn();
 object.try_emplace("column", column);
   } else {

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][dap] always add column field in StackFrame body (PR #73393)

2023-11-25 Thread Xu Jun via lldb-commits

https://github.com/xujuntwt95329 created 
https://github.com/llvm/llvm-project/pull/73393

The `column` field is mandatory in StackTraceResponse, otherwise the debugger 
client may raise error (e.g. VSCode can't correctly open an editor without the 
column field) 

>From 4621be9af9a8003c52850ed57ae7a24f26769b2c Mon Sep 17 00:00:00 2001
From: Xu Jun <693788...@qq.com>
Date: Sat, 25 Nov 2023 22:52:53 +0800
Subject: [PATCH] [lldb][dap] always add column field in StackFrame body

Signed-off-by: Xu Jun <693788...@qq.com>
---
 lldb/tools/lldb-dap/JSONUtils.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 03a43f9da87f241..e65b05243df7066 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -817,8 +817,7 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) {
 if (line && line != LLDB_INVALID_LINE_NUMBER)
   object.try_emplace("line", line);
 auto column = line_entry.GetColumn();
-if (column && column != LLDB_INVALID_COLUMN_NUMBER)
-  object.try_emplace("column", column);
+object.try_emplace("column", column);
   } else {
 object.try_emplace("line", 0);
 object.try_emplace("column", 0);

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] enable wasm source debugging (PR #72634)

2023-11-17 Thread Xu Jun via lldb-commits

https://github.com/xujuntwt95329 closed 
https://github.com/llvm/llvm-project/pull/72634
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] enable wasm source debugging (PR #72634)

2023-11-17 Thread Xu Jun via lldb-commits

https://github.com/xujuntwt95329 created 
https://github.com/llvm/llvm-project/pull/72634

Rebase https://reviews.llvm.org/D78978 on latest code base, with less 
modification to LLDB core part:

I treat wasm locals, globals and operand stack values as virtual registers, and 
implement a wasmRegisterContext to handle this. 

2 high bits in the reg_num are used as a tag to distinguish wasm values

>From b9f6f4c03b6f72f44f9270a7de377deab3e0d8f6 Mon Sep 17 00:00:00 2001
From: Xu Jun <693788...@qq.com>
Date: Fri, 17 Nov 2023 16:07:09 +0800
Subject: [PATCH] [lldb] enable wasm source debugging

---
 lldb/source/Expression/DWARFExpression.cpp|  42 +++
 lldb/source/Plugins/Process/CMakeLists.txt|   1 +
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |   7 +-
 .../Process/gdb-remote/ProcessGDBRemote.h |   2 +
 .../Plugins/Process/wasm/CMakeLists.txt   |  15 +
 .../Plugins/Process/wasm/ProcessWasm.cpp  | 261 ++
 .../source/Plugins/Process/wasm/ProcessWasm.h | 132 +
 .../Plugins/Process/wasm/ThreadWasm.cpp   |  57 
 lldb/source/Plugins/Process/wasm/ThreadWasm.h |  47 
 .../Plugins/Process/wasm/UnwindWasm.cpp   |  79 ++
 lldb/source/Plugins/Process/wasm/UnwindWasm.h |  58 
 .../Process/wasm/wasmRegisterContext.cpp  | 103 +++
 .../Process/wasm/wasmRegisterContext.h|  70 +
 lldb/source/Target/Platform.cpp   |   8 +
 14 files changed, 881 insertions(+), 1 deletion(-)
 create mode 100644 lldb/source/Plugins/Process/wasm/CMakeLists.txt
 create mode 100644 lldb/source/Plugins/Process/wasm/ProcessWasm.cpp
 create mode 100644 lldb/source/Plugins/Process/wasm/ProcessWasm.h
 create mode 100644 lldb/source/Plugins/Process/wasm/ThreadWasm.cpp
 create mode 100644 lldb/source/Plugins/Process/wasm/ThreadWasm.h
 create mode 100644 lldb/source/Plugins/Process/wasm/UnwindWasm.cpp
 create mode 100644 lldb/source/Plugins/Process/wasm/UnwindWasm.h
 create mode 100644 lldb/source/Plugins/Process/wasm/wasmRegisterContext.cpp
 create mode 100644 lldb/source/Plugins/Process/wasm/wasmRegisterContext.h

diff --git a/lldb/source/Expression/DWARFExpression.cpp 
b/lldb/source/Expression/DWARFExpression.cpp
index fe4928d4f43a434..1693e390c2e9203 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -346,6 +346,17 @@ static offset_t GetOpcodeDataSize(const DataExtractor 
&data,
 return (offset - data_offset) + subexpr_len;
   }
 
+  case DW_OP_WASM_location: {
+uint8_t wasm_op = data.GetU8(&offset);
+if (wasm_op == 3) {
+  data.GetU32(&offset);
+}
+else {
+  data.GetULEB128(&offset);
+}
+return offset - data_offset;
+  }
+
   default:
 if (!dwarf_cu) {
   return LLDB_INVALID_OFFSET;
@@ -2595,6 +2606,37 @@ bool DWARFExpression::Evaluate(
   break;
 }
 
+case DW_OP_WASM_location: {
+  uint8_t wasm_op = opcodes.GetU8(&offset);
+  uint32_t index;
+
+  /* LLDB doesn't have an address space to represents WebAssembly Locals,
+   * GLobals and operand stacks.
+   * We encode these elements into virtual registers: 
+   *   | tag: 2 bits | index: 30 bits |
+   *   where tag is:
+   *0: Not a WebAssembly location
+   *1: Local
+   *2: Global
+   *3: Operand stack value 
+   */
+  if (wasm_op == 3) {
+index = opcodes.GetU32(&offset);
+wasm_op = 1;
+  } else {
+index = opcodes.GetULEB128(&offset);
+  }
+
+  reg_num = (((wasm_op + 1) & 0x03) << 30) | (index & 0x3fff);
+
+  if (ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, error_ptr, 
tmp))
+stack.push_back(tmp);
+  else
+return false;
+
+  break;
+}
+
 default:
   if (dwarf_cu) {
 if (dwarf_cu->GetSymbolFileDWARF().ParseVendorDWARFOpcode(
diff --git a/lldb/source/Plugins/Process/CMakeLists.txt 
b/lldb/source/Plugins/Process/CMakeLists.txt
index a51d0f7afd17591..be109a303e86691 100644
--- a/lldb/source/Plugins/Process/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/CMakeLists.txt
@@ -19,3 +19,4 @@ add_subdirectory(elf-core)
 add_subdirectory(mach-core)
 add_subdirectory(minidump)
 add_subdirectory(FreeBSDKernel)
+add_subdirectory(wasm)
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp 
b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index e653ef5d8ac54e4..f82c85ffbe20ffb 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1627,6 +1627,11 @@ void ProcessGDBRemote::ParseExpeditedRegisters(
   }
 }
 
+std::shared_ptr
+ProcessGDBRemote::CreateThread(lldb::tid_t tid) {
+  return std::make_shared(*this, tid);
+}
+
 ThreadSP ProcessGDBRemote::SetThreadStopInfo(
 lldb::tid_t tid, ExpeditedRegisterMap &expedited_register_map,
 uint8_t signo, const std::string &thread_name, const std::string &reason,
@@ -1651,7 +1656,7 @@ T