https://github.com/eronnen created https://github.com/llvm/llvm-project/pull/136755
Improves the lldb-dap disassembly by showing load addresses in disassembly, same as in a regular LLDB `disassemble` command by default. Before:  After:  >From c1c072875b9a7ad3d11a03d3c1e4a8b6452749f9 Mon Sep 17 00:00:00 2001 From: Ely Ronnen <elyron...@gmail.com> Date: Tue, 22 Apr 2025 21:58:19 +0200 Subject: [PATCH] [lldb-dap]: show load addresses in disassembly --- lldb/include/lldb/API/SBFrame.h | 1 + lldb/include/lldb/API/SBInstructionList.h | 7 +++-- lldb/source/API/SBInstructionList.cpp | 29 ++++++++++++++----- .../lldb-dap/Handler/SourceRequestHandler.cpp | 2 +- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h index 3635ee5a537ad..66db059d531a8 100644 --- a/lldb/include/lldb/API/SBFrame.h +++ b/lldb/include/lldb/API/SBFrame.h @@ -221,6 +221,7 @@ class LLDB_API SBFrame { friend class SBBlock; friend class SBExecutionContext; friend class SBInstruction; + friend class SBInstructionList; friend class SBThread; friend class SBValue; diff --git a/lldb/include/lldb/API/SBInstructionList.h b/lldb/include/lldb/API/SBInstructionList.h index 4c26ec9a294e0..b337c91721653 100644 --- a/lldb/include/lldb/API/SBInstructionList.h +++ b/lldb/include/lldb/API/SBInstructionList.h @@ -54,6 +54,10 @@ class LLDB_API SBInstructionList { bool GetDescription(lldb::SBStream &description); + // Writes assembly instructions to `description` with load addresses using + // `frame`. + bool GetDescription(lldb::SBStream &description, lldb::SBFrame &frame); + bool DumpEmulationForAllInstructions(const char *triple); protected: @@ -62,8 +66,7 @@ class LLDB_API SBInstructionList { friend class SBTarget; void SetDisassembler(const lldb::DisassemblerSP &opaque_sp); - bool GetDescription(lldb_private::Stream &description); - + bool GetDescription(lldb_private::Stream &description, lldb::SBFrame *frame); private: lldb::DisassemblerSP m_opaque_sp; diff --git a/lldb/source/API/SBInstructionList.cpp b/lldb/source/API/SBInstructionList.cpp index c18204375dff1..79432e8c6c91a 100644 --- a/lldb/source/API/SBInstructionList.cpp +++ b/lldb/source/API/SBInstructionList.cpp @@ -15,8 +15,10 @@ #include "lldb/Core/Module.h" #include "lldb/Host/StreamFile.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/Instrumentation.h" #include "lldb/Utility/Stream.h" +#include <memory> using namespace lldb; using namespace lldb_private; @@ -114,7 +116,7 @@ void SBInstructionList::Print(FILE *out) { if (out == nullptr) return; StreamFile stream(out, false); - GetDescription(stream); + GetDescription(stream, nullptr); } void SBInstructionList::Print(SBFile out) { @@ -122,7 +124,7 @@ void SBInstructionList::Print(SBFile out) { if (!out.IsValid()) return; StreamFile stream(out.m_opaque_sp); - GetDescription(stream); + GetDescription(stream, nullptr); } void SBInstructionList::Print(FileSP out_sp) { @@ -130,15 +132,21 @@ void SBInstructionList::Print(FileSP out_sp) { if (!out_sp || !out_sp->IsValid()) return; StreamFile stream(out_sp); - GetDescription(stream); + GetDescription(stream, nullptr); } bool SBInstructionList::GetDescription(lldb::SBStream &stream) { LLDB_INSTRUMENT_VA(this, stream); - return GetDescription(stream.ref()); + return GetDescription(stream.ref(), nullptr); } -bool SBInstructionList::GetDescription(Stream &sref) { +bool SBInstructionList::GetDescription(lldb::SBStream &stream, + lldb::SBFrame &frame) { + LLDB_INSTRUMENT_VA(this, stream); + return GetDescription(stream.ref(), &frame); +} + +bool SBInstructionList::GetDescription(Stream &sref, lldb::SBFrame *frame) { if (m_opaque_sp) { size_t num_instructions = GetSize(); @@ -148,10 +156,15 @@ bool SBInstructionList::GetDescription(Stream &sref) { const uint32_t max_opcode_byte_size = m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize(); FormatEntity::Entry format; - FormatEntity::Parse("${addr}: ", format); + FormatEntity::Parse("${addr-file-or-load}: ", format); SymbolContext sc; SymbolContext prev_sc; + std::shared_ptr<ExecutionContext> exec_ctx; + if (nullptr != frame) { + exec_ctx = std::make_shared<ExecutionContext>(frame->GetFrameSP()); + } + // Expected address of the next instruction. Used to print an empty line // for non-contiguous blocks of insns. std::optional<Address> next_addr; @@ -172,8 +185,8 @@ bool SBInstructionList::GetDescription(Stream &sref) { if (next_addr && *next_addr != addr) sref.EOL(); inst->Dump(&sref, max_opcode_byte_size, true, false, - /*show_control_flow_kind=*/false, nullptr, &sc, &prev_sc, - &format, 0); + /*show_control_flow_kind=*/false, exec_ctx.get(), &sc, + &prev_sc, &format, 0); sref.EOL(); next_addr = addr; next_addr->Slide(inst->GetOpcode().GetByteSize()); diff --git a/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp index 1a7a13d9f267a..bd4fc981475f4 100644 --- a/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp @@ -43,7 +43,7 @@ SourceRequestHandler::Run(const protocol::SourceArguments &args) const { lldb::SBInstructionList insts = frame.GetSymbol().GetInstructions(dap.target); lldb::SBStream stream; - insts.GetDescription(stream); + insts.GetDescription(stream, frame); return protocol::SourceResponseBody{/*content=*/stream.GetData(), /*mimeType=*/"text/x-lldb.disassembly"}; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits