LLDB mainline
UnwindWasm.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "UnwindWasm.h"
11#include "ProcessWasm.h"
12#include "RegisterContextWasm.h"
13#include "ThreadWasm.h"
15#include "lldb/Utility/Log.h"
16
17using namespace lldb;
18using namespace lldb_private;
19using namespace process_gdb_remote;
20using namespace wasm;
21
22/// Base for synthesized Wasm frame call frame addresses. It sits above any
23/// call depth a Wasm stack can reach and clear of zero and the invalid-address
24/// sentinel, so the derived addresses stay distinct and valid.
25static constexpr lldb::addr_t kWasmSyntheticCFABase = 0x40000000;
26
29 if (m_frames.size() <= frame->GetFrameIndex())
31
32 ThreadSP thread = frame->GetThread();
33 ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *>(thread.get());
34 ProcessWasm *wasm_process =
35 static_cast<ProcessWasm *>(thread->GetProcess().get());
36
37 return std::make_shared<RegisterContextWasm>(*gdb_thread,
38 frame->GetConcreteFrameIndex(),
39 wasm_process->GetRegisterInfo());
40}
41
44 return m_frames.size();
45
46 m_unwind_complete = true;
47 m_frames.clear();
48
49 ThreadWasm &wasm_thread = static_cast<ThreadWasm &>(GetThread());
50 llvm::Expected<std::vector<lldb::addr_t>> call_stack_pcs =
51 wasm_thread.GetWasmCallStack();
52 if (!call_stack_pcs) {
53 LLDB_LOG_ERROR(GetLog(LLDBLog::Unwind), call_stack_pcs.takeError(),
54 "Failed to get Wasm callstack: {0}");
55 m_frames.clear();
56 return 0;
57 }
58
59 m_frames = *call_stack_pcs;
60 return m_frames.size();
61}
62
63bool UnwindWasm::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
65 bool &behaves_like_zeroth_frame) {
66 if (m_frames.size() == 0)
68
69 if (frame_idx >= m_frames.size())
70 return false;
71
72 behaves_like_zeroth_frame = (frame_idx == 0);
73 // StackID orders frames by call frame address, expecting a younger frame to
74 // sit below its caller. Wasm has no in-memory frame address to read, so
75 // derive one from the frame's distance to the outermost frame, which stays
76 // fixed as frames are pushed and popped above it, inverted so younger frames
77 // compare lower.
78 const size_t depth_from_outermost = m_frames.size() - 1 - frame_idx;
79 cfa = kWasmSyntheticCFABase - depth_from_outermost;
80 pc = m_frames[frame_idx];
81 return true;
82}
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:406
static constexpr lldb::addr_t kWasmSyntheticCFABase
Base for synthesized Wasm frame call frame addresses.
This base class provides an interface to stack frames.
Definition StackFrame.h:44
lldb::ThreadSP GetThread() const
Definition StackFrame.h:135
virtual uint32_t GetConcreteFrameIndex()
Query this frame to find what frame it is in this Thread's StackFrameList, not counting inlined frame...
Definition StackFrame.h:486
virtual uint32_t GetFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList.
Thread & GetThread()
Definition Unwind.h:61
ProcessWasm provides the access to the Wasm program state retrieved from the Wasm engine.
Definition ProcessWasm.h:49
lldb::DynamicRegisterInfoSP & GetRegisterInfo()
Definition ProcessWasm.h:90
ProcessWasm provides the access to the Wasm program state retrieved from the Wasm engine.
Definition ThreadWasm.h:19
llvm::Expected< std::vector< lldb::addr_t > > GetWasmCallStack()
Retrieve the current call stack from the WebAssembly remote process.
std::vector< lldb::addr_t > m_frames
Definition UnwindWasm.h:41
lldb::RegisterContextSP DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override
bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, lldb::addr_t &pc, bool &behaves_like_zeroth_frame) override
uint32_t DoGetFrameCount() override
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:339
std::shared_ptr< lldb_private::Thread > ThreadSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP