eloparco updated this revision to Diff 488415.
eloparco added a comment.
Use single-line comments
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D140358/new/
https://reviews.llvm.org/D140358
Files:
lldb/bindings/interface/SBTarget.i
lldb/include/lldb/API/SBTarget.h
lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
lldb/source/API/SBTarget.cpp
lldb/test/API/python_api/target/TestTargetAPI.py
lldb/test/API/tools/lldb-vscode/disassemble/Makefile
lldb/test/API/tools/lldb-vscode/disassemble/TestVSCode_disassemble.py
lldb/test/API/tools/lldb-vscode/disassemble/main.cpp
lldb/tools/lldb-vscode/CMakeLists.txt
lldb/tools/lldb-vscode/DisassembledInstruction.cpp
lldb/tools/lldb-vscode/DisassembledInstruction.h
lldb/tools/lldb-vscode/JSONUtils.cpp
lldb/tools/lldb-vscode/JSONUtils.h
lldb/tools/lldb-vscode/LLDBUtils.cpp
lldb/tools/lldb-vscode/LLDBUtils.h
lldb/tools/lldb-vscode/VSCode.h
lldb/tools/lldb-vscode/VSCodeForward.h
lldb/tools/lldb-vscode/lldb-vscode.cpp
Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===================================================================
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1451,8 +1451,7 @@
// which may affect the outcome of tests.
bool source_init_file = GetBoolean(arguments, "sourceInitFile", true);
- g_vsc.debugger =
- lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
+ g_vsc.debugger = lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction);
// Start our event thread so we can receive events from the debugger, target,
@@ -1542,6 +1541,8 @@
// The debug adapter supports 'logMessage' in breakpoint.
body.try_emplace("supportsLogPoints", true);
+ body.try_emplace("supportsDisassembleRequest", true);
+
response.try_emplace("body", std::move(body));
g_vsc.SendJSON(llvm::json::Value(std::move(response)));
}
@@ -2117,6 +2118,173 @@
g_vsc.SendJSON(llvm::json::Value(std::move(response)));
}
+std::vector<lldb::SBInstruction>
+_get_instructions_from_memory(lldb::addr_t start, uint64_t count) {
+ lldb::SBProcess process = g_vsc.target.GetProcess();
+
+ lldb::SBError error;
+ std::vector<uint8_t> buffer(count, 0);
+ const size_t bytes_read __attribute__((unused)) = process.ReadMemory(
+ start, static_cast<void *>(buffer.data()), count, error);
+ assert(bytes_read == count && error.Success() &&
+ "unable to read byte range from memory");
+
+ // If base_addr starts in the middle of an instruction,
+ // that first instruction will not be parsed correctly (negligible)
+ std::vector<lldb::SBInstruction> sb_instructions;
+ const auto base_addr = lldb::SBAddress(start, g_vsc.target);
+ lldb::SBInstructionList instructions =
+ g_vsc.target.GetInstructions(base_addr, buffer.data(), count);
+
+ for (size_t i = 0; i < instructions.GetSize(); i++) {
+ auto instr = instructions.GetInstructionAtIndex(i);
+ sb_instructions.emplace_back(instr);
+ }
+ return sb_instructions;
+}
+
+auto _handle_disassemble_positive_offset(lldb::addr_t base_addr,
+ int64_t instruction_offset,
+ uint64_t instruction_count) {
+ llvm::json::Array response_instructions;
+
+ // For positive offsets, we use the `ReadInstructions()` API to get
+ // `instruction_offset + instruction_count` instructions after the
+ // `base_addr`.
+ auto start_addr = lldb::SBAddress(base_addr, g_vsc.target);
+ lldb::SBInstructionList instructions = g_vsc.target.ReadInstructions(
+ start_addr, instruction_offset + instruction_count);
+
+ const auto num_instrs_to_skip = static_cast<size_t>(instruction_offset);
+ for (size_t i = num_instrs_to_skip; i < instructions.GetSize(); ++i) {
+ lldb::SBInstruction instr = instructions.GetInstructionAtIndex(i);
+
+ auto disass_instr =
+ CreateDisassembledInstruction(DisassembledInstruction(instr));
+ response_instructions.emplace_back(std::move(disass_instr));
+ }
+
+ return response_instructions;
+}
+
+auto _handle_disassemble_negative_offset(
+ lldb::addr_t base_addr, int64_t instruction_offset,
+ uint64_t instruction_count,
+ std::optional<llvm::StringRef> memory_reference) {
+ llvm::json::Array response_instructions;
+
+ const auto max_instruction_size = g_vsc.target.GetMaximumOpcodeByteSize();
+ const auto bytes_offset = -instruction_offset * max_instruction_size;
+ auto start_addr = base_addr - bytes_offset;
+ const auto disassemble_bytes = instruction_count * max_instruction_size;
+
+ // For negative offsets, we do not know what `start_addr` corresponds to the
+ // instruction located `instruction_offset` instructions before `base_addr`
+ // since on some architectures opcodes have variable length.
+ // To address that, we need to read at least starting from `start_addr =
+ // base_addr + instruction_offset * max_instruction_size` (pruning is done if
+ // more than `instruction_count` instructions are fetched) and ensure we start
+ // disassembling on the correct instruction boundary since `start_addr` might
+ // be in between opcode boundaries. To address the latter concern, we use the
+ // following loop.
+ for (unsigned i = 0; i < max_instruction_size; i++) {
+ auto sb_instructions =
+ _get_instructions_from_memory(start_addr - i, disassemble_bytes);
+
+ // Find position of requested instruction
+ // in retrieved disassembled instructions
+ auto index = sb_instructions.size() + 1;
+ for (size_t i = 0; i < sb_instructions.size(); i++) {
+ if (sb_instructions[i].GetAddress().GetLoadAddress(g_vsc.target) ==
+ base_addr) {
+ index = i;
+ break;
+ }
+ }
+ if (index == sb_instructions.size() + 1)
+ continue;
+
+ // Copy instructions into queue to easily manipulate them
+ std::deque<DisassembledInstruction> disass_instructions;
+ for (auto &instr : sb_instructions)
+ disass_instructions.emplace_back(DisassembledInstruction(instr));
+
+ // Make sure the address in the disassemble request is at the right position
+ const uint64_t expected_index = -instruction_offset;
+ if (index < expected_index) {
+ for (uint64_t i = 0; i < (expected_index - index); i++) {
+ DisassembledInstruction nop_instruction;
+ disass_instructions.emplace_front(nop_instruction);
+ }
+ } else if (index > expected_index) {
+ const auto num_instr_to_remove = index - expected_index;
+ disass_instructions.erase(disass_instructions.begin(),
+ disass_instructions.begin() +
+ num_instr_to_remove);
+ }
+
+ // Truncate if too many instructions
+ if (disass_instructions.size() > instruction_count) {
+ disass_instructions.erase(disass_instructions.begin() + instruction_count,
+ disass_instructions.end());
+ }
+
+ assert(disass_instructions.size() > expected_index &&
+ disass_instructions[expected_index].m_address ==
+ memory_reference.value());
+
+ for (auto &instr : disass_instructions)
+ response_instructions.emplace_back(CreateDisassembledInstruction(instr));
+ return response_instructions;
+ }
+
+ return response_instructions;
+}
+
+void request_disassemble(const llvm::json::Object &request) {
+ llvm::json::Object response;
+ lldb::SBError error;
+ FillResponse(request, response);
+ auto arguments = request.getObject("arguments");
+ const auto memory_reference = arguments->getString("memoryReference");
+ const auto instruction_offset = GetSigned(arguments, "instructionOffset", 0);
+ const auto instruction_count = GetUnsigned(arguments, "instructionCount", 0);
+ llvm::json::Array response_instructions;
+
+ bool success = true;
+ auto base_addr = hex_string_to_addr(memory_reference);
+ if (base_addr == 0) {
+ success = false;
+ } else {
+ response_instructions =
+ instruction_offset >= 0
+ ? _handle_disassemble_positive_offset(base_addr, instruction_offset,
+ instruction_count)
+ : _handle_disassemble_negative_offset(base_addr, instruction_offset,
+ instruction_count,
+ memory_reference);
+ }
+
+ // Add padding if not enough instructions
+ if (response_instructions.size() < instruction_count) {
+ const auto padding_len = instruction_count - response_instructions.size();
+ for (size_t i = 0; i < padding_len; i++) {
+ const DisassembledInstruction nop_instruction;
+ auto disass_instr = CreateDisassembledInstruction(nop_instruction);
+ response_instructions.emplace_back(std::move(disass_instr));
+ }
+ }
+
+ assert((response_instructions.size() == instruction_count) &&
+ "should return exact number of requested instructions");
+
+ llvm::json::Object body;
+ body.try_emplace("instructions", std::move(response_instructions));
+ response.try_emplace("body", std::move(body));
+ response["success"] = llvm::json::Value(success);
+ g_vsc.SendJSON(llvm::json::Value(std::move(response)));
+}
+
// "SetExceptionBreakpointsRequest": {
// "allOf": [ { "$ref": "#/definitions/Request" }, {
// "type": "object",
@@ -3085,6 +3253,7 @@
g_vsc.RegisterRequestCallback("stepOut", request_stepOut);
g_vsc.RegisterRequestCallback("threads", request_threads);
g_vsc.RegisterRequestCallback("variables", request_variables);
+ g_vsc.RegisterRequestCallback("disassemble", request_disassemble);
// Custom requests
g_vsc.RegisterRequestCallback("compileUnits", request_compileUnits);
g_vsc.RegisterRequestCallback("modules", request_modules);
Index: lldb/tools/lldb-vscode/VSCodeForward.h
===================================================================
--- lldb/tools/lldb-vscode/VSCodeForward.h
+++ lldb/tools/lldb-vscode/VSCodeForward.h
@@ -15,6 +15,7 @@
struct FunctionBreakpoint;
struct SourceBreakpoint;
struct SourceReference;
+struct DisassembledInstruction;
} // namespace lldb_vscode
namespace lldb {
Index: lldb/tools/lldb-vscode/VSCode.h
===================================================================
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -46,6 +46,7 @@
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
+#include "DisassembledInstruction.h"
#include "ExceptionBreakpoint.h"
#include "FunctionBreakpoint.h"
#include "IOStream.h"
Index: lldb/tools/lldb-vscode/LLDBUtils.h
===================================================================
--- lldb/tools/lldb-vscode/LLDBUtils.h
+++ lldb/tools/lldb-vscode/LLDBUtils.h
@@ -10,6 +10,7 @@
#define LLDB_TOOLS_LLDB_VSCODE_LLDBUTILS_H
#include "VSCodeForward.h"
+#include "lldb/lldb-types.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
@@ -106,6 +107,27 @@
/// The LLDB frame index ID.
uint32_t GetLLDBFrameID(uint64_t dap_frame_id);
+/// Given an address, convert it to its hexadecimal representation.
+///
+/// \param[in] address
+/// The address to convert.
+///
+/// \return
+/// The hexadecimal representation of the address.
+std::string addr_to_hex_string(const lldb::addr_t address);
+
+/// Given an hexadecimal representation of an address, convert it to a number.
+///
+/// Reverse of `addr_to_hex_string()`.
+///
+/// \param[in] hex_address
+/// The hexadecimal address to convert.
+///
+/// \return
+/// The decimal representation of the hex address.
+lldb::addr_t
+hex_string_to_addr(const std::optional<llvm::StringRef> hex_address);
+
} // namespace lldb_vscode
#endif
Index: lldb/tools/lldb-vscode/LLDBUtils.cpp
===================================================================
--- lldb/tools/lldb-vscode/LLDBUtils.cpp
+++ lldb/tools/lldb-vscode/LLDBUtils.cpp
@@ -83,4 +83,13 @@
frame.GetFrameID());
}
+std::string addr_to_hex_string(const lldb::addr_t address) {
+ return "0x" + llvm::utohexstr(address, true);
+}
+
+lldb::addr_t
+hex_string_to_addr(const std::optional<llvm::StringRef> hex_address) {
+ return std::stoull(hex_address->data(), nullptr, 16);
+}
+
} // namespace lldb_vscode
Index: lldb/tools/lldb-vscode/JSONUtils.h
===================================================================
--- lldb/tools/lldb-vscode/JSONUtils.h
+++ lldb/tools/lldb-vscode/JSONUtils.h
@@ -349,6 +349,8 @@
/// "source" - source file information as a "Source" VSCode object
/// "line" - the source file line number as an integer
/// "column" - the source file column number as an integer
+/// "instructionPointerReference" - a memory reference for the current
+/// instruction pointer in this frame
///
/// \param[in] frame
/// The LLDB stack frame to use when populating out the "StackFrame"
@@ -463,6 +465,24 @@
int64_t varID, bool format_hex,
bool is_name_duplicated = false);
+/// Create a "DisassembledInstruction" object for a LLDB disassembled
+/// instruction object.
+///
+/// This function will fill in the following keys in the returned
+/// object:
+/// "address" - the address of the instruction
+/// "instruction" - the text representing the instruction and its operands
+///
+/// \param[in] instruction
+/// The LLDB disassembled instruction to use when populating out the
+/// "DisassembledInstruction" object.
+///
+/// \return
+/// A "DisassembledInstruction" JSON object with that follows the formal
+/// JSON definition outlined by Microsoft.
+llvm::json::Value
+CreateDisassembledInstruction(DisassembledInstruction instruction);
+
llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit unit);
/// Create a runInTerminal reverse request object
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===================================================================
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -782,6 +782,9 @@
object.try_emplace("line", line);
}
object.try_emplace("column", line_entry.GetColumn());
+
+ auto pc = addr_to_hex_string(frame.GetPC());
+ object.try_emplace("instructionPointerReference", pc);
return llvm::json::Value(std::move(object));
}
@@ -1097,6 +1100,14 @@
return llvm::json::Value(std::move(object));
}
+llvm::json::Value
+CreateDisassembledInstruction(DisassembledInstruction instruction) {
+ llvm::json::Object object;
+ EmplaceSafeString(object, "address", instruction.m_address);
+ EmplaceSafeString(object, "instruction", instruction.m_instruction);
+ return llvm::json::Value(std::move(object));
+}
+
/// See
/// https://microsoft.github.io/debug-adapter-protocol/specification#Reverse_Requests_RunInTerminal
llvm::json::Object
Index: lldb/tools/lldb-vscode/DisassembledInstruction.h
===================================================================
--- /dev/null
+++ lldb/tools/lldb-vscode/DisassembledInstruction.h
@@ -0,0 +1,19 @@
+#ifndef LLDB_TOOLS_LLDB_VSCODE_DISASSEMBLED_INSTRUCTION_H
+#define LLDB_TOOLS_LLDB_VSCODE_DISASSEMBLED_INSTRUCTION_H
+
+#include "VSCodeForward.h"
+#include <string>
+
+namespace lldb_vscode {
+
+struct DisassembledInstruction {
+ std::string m_address;
+ std::string m_instruction;
+
+ DisassembledInstruction();
+ DisassembledInstruction(lldb::SBInstruction &inst);
+};
+
+} // namespace lldb_vscode
+
+#endif // LLDB_TOOLS_LLDB_VSCODE_DISASSEMBLED_INSTRUCTION_H
\ No newline at end of file
Index: lldb/tools/lldb-vscode/DisassembledInstruction.cpp
===================================================================
--- /dev/null
+++ lldb/tools/lldb-vscode/DisassembledInstruction.cpp
@@ -0,0 +1,27 @@
+#include "DisassembledInstruction.h"
+
+#include "LLDBUtils.h"
+#include "VSCode.h"
+#include "lldb/API/SBInstruction.h"
+
+namespace lldb_vscode {
+
+DisassembledInstruction::DisassembledInstruction()
+ : m_address("0x0000000000000000"), m_instruction("<invalid>") {}
+
+DisassembledInstruction::DisassembledInstruction(lldb::SBInstruction &inst) {
+ const auto inst_addr = inst.GetAddress().GetLoadAddress(g_vsc.target);
+ const char *m = inst.GetMnemonic(g_vsc.target);
+ const char *o = inst.GetOperands(g_vsc.target);
+ const char *c = inst.GetComment(g_vsc.target);
+
+ std::string line;
+ llvm::raw_string_ostream line_strm(line);
+ const auto comment_sep = (c == nullptr || std::string(c) == "") ? "" : " ; ";
+ line_strm << llvm::formatv("{0,12} {1}{2}{3}", m, o, comment_sep, c);
+
+ m_address = addr_to_hex_string(inst_addr);
+ m_instruction = line_strm.str();
+}
+
+} // namespace lldb_vscode
\ No newline at end of file
Index: lldb/tools/lldb-vscode/CMakeLists.txt
===================================================================
--- lldb/tools/lldb-vscode/CMakeLists.txt
+++ lldb/tools/lldb-vscode/CMakeLists.txt
@@ -25,6 +25,7 @@
add_lldb_tool(lldb-vscode
lldb-vscode.cpp
BreakpointBase.cpp
+ DisassembledInstruction.cpp
ExceptionBreakpoint.cpp
FifoFiles.cpp
FunctionBreakpoint.cpp
Index: lldb/test/API/tools/lldb-vscode/disassemble/main.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/tools/lldb-vscode/disassemble/main.cpp
@@ -0,0 +1,8 @@
+int add(int x, int y) { return x + y; }
+
+int main() {
+ int sum = add(2, 3); // breakpoint
+ sum++;
+
+ return sum;
+}
\ No newline at end of file
Index: lldb/test/API/tools/lldb-vscode/disassemble/TestVSCode_disassemble.py
===================================================================
--- /dev/null
+++ lldb/test/API/tools/lldb-vscode/disassemble/TestVSCode_disassemble.py
@@ -0,0 +1,96 @@
+"""
+Test lldb-vscode disassemble request
+"""
+
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+import lldbvscode_testcase
+
+
+class TestVSCode_disassemble(lldbvscode_testcase.VSCodeTestCaseBase):
+ def setUp(self):
+ lldbvscode_testcase.VSCodeTestCaseBase.setUp(self)
+
+ program = self.getBuildArtifact("a.out")
+ self.build_and_launch(program)
+ source = "main.cpp"
+
+ breakpoint_line = line_number(source, "// breakpoint")
+ breakpoint_ids = self.set_source_breakpoints(source, [breakpoint_line])
+ self.continue_to_breakpoints(breakpoint_ids)
+
+ @skipIfWindows
+ @skipIfRemote
+ def test_disassemble_negative_offset(self):
+ # Retrieve program counter
+ stackFrames, _ = self.get_stackFrames_and_totalFramesCount()
+ pc = stackFrames[0]["instructionPointerReference"]
+
+ # Get disassembled instructions
+ num_instructions, offset = 8, -4
+ response = self.vscode.request_disassemble(
+ memoryReference=pc,
+ instructionOffset=offset,
+ instructionCount=num_instructions,
+ )
+ self.assertTrue(response["success"])
+
+ disas_instructions = response["body"]["instructions"]
+ self.assertEquals(len(disas_instructions), num_instructions)
+ self.assertEquals(disas_instructions[num_instructions + offset]["address"], pc)
+ for instr in disas_instructions:
+ self.assertTrue("invalid" not in instr["instruction"])
+
+ @skipIfWindows
+ @skipIfRemote
+ def test_disassemble_zero_offset(self):
+ # Retrieve program counter
+ stackFrames, _ = self.get_stackFrames_and_totalFramesCount()
+ pc = stackFrames[0]["instructionPointerReference"]
+
+ # Get disassembled instructions
+ num_instructions, offset = 4, 0
+ response = self.vscode.request_disassemble(
+ memoryReference=pc,
+ instructionOffset=offset,
+ instructionCount=num_instructions,
+ )
+ self.assertTrue(response["success"])
+
+ disas_instructions = response["body"]["instructions"]
+ self.assertEquals(len(disas_instructions), num_instructions)
+ self.assertEquals(disas_instructions[offset]["address"], pc)
+ for instr in disas_instructions:
+ self.assertTrue("invalid" not in instr["instruction"])
+
+ @skipIfWindows
+ @skipIfRemote
+ def test_disassemble_positive_offset(self):
+ # Retrieve program counter
+ stackFrames, _ = self.get_stackFrames_and_totalFramesCount()
+ pc = stackFrames[0]["instructionPointerReference"]
+
+ # Get disassembled instructions
+ num_instructions, offset = 4, 2
+ response = self.vscode.request_disassemble(
+ memoryReference=pc,
+ instructionOffset=offset,
+ instructionCount=num_instructions,
+ )
+ self.assertTrue(response["success"])
+
+ disas_instructions = response["body"]["instructions"]
+ self.assertEquals(len(disas_instructions), num_instructions)
+ for instr in disas_instructions:
+ self.assertTrue("invalid" not in instr["instruction"])
+
+ @skipIfWindows
+ @skipIfRemote
+ def test_disassemble_invalid_address(self):
+ response = self.vscode.request_disassemble(
+ memoryReference="0x0",
+ instructionOffset=-200,
+ instructionCount=400,
+ )
+ self.assertFalse(response["success"])
Index: lldb/test/API/tools/lldb-vscode/disassemble/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/tools/lldb-vscode/disassemble/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
\ No newline at end of file
Index: lldb/test/API/python_api/target/TestTargetAPI.py
===================================================================
--- lldb/test/API/python_api/target/TestTargetAPI.py
+++ lldb/test/API/python_api/target/TestTargetAPI.py
@@ -525,3 +525,14 @@
module = target.GetModuleAtIndex(i)
self.assertTrue(target.IsLoaded(module), "Running the target should "
"have loaded its modules.")
+
+ def test_get_max_opcode_byte_size(self):
+ """Exercise SBTarget.GetMaximumOpcodeByteSize() API."""
+
+ d = {'EXE': 'b.out'}
+ self.build(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('b.out')
+
+ maxOpcodeByteSize = target.GetMaximumOpcodeByteSize()
+ self.assertTrue(maxOpcodeByteSize > 0 and maxOpcodeByteSize < 16)
Index: lldb/source/API/SBTarget.cpp
===================================================================
--- lldb/source/API/SBTarget.cpp
+++ lldb/source/API/SBTarget.cpp
@@ -1965,6 +1965,16 @@
return sb_instructions;
}
+uint32_t SBTarget::GetMaximumOpcodeByteSize() const {
+ LLDB_INSTRUMENT_VA(this);
+
+ TargetSP target_sp(GetSP());
+ if (target_sp)
+ return target_sp->GetArchitecture().GetMaximumOpcodeByteSize();
+
+ return 0;
+}
+
lldb::SBInstructionList SBTarget::GetInstructions(lldb::SBAddress base_addr,
const void *buf,
size_t size) {
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
@@ -957,6 +957,19 @@
}
return self.send_recv(command_dict)
+ def request_disassemble(self, memoryReference, instructionOffset, instructionCount):
+ args_dict = {
+ 'memoryReference': memoryReference,
+ 'instructionOffset': instructionOffset,
+ 'instructionCount': instructionCount,
+ }
+ command_dict = {
+ 'command': 'disassemble',
+ 'type': 'request',
+ 'arguments': args_dict
+ }
+ return self.send_recv(command_dict)
+
def terminate(self):
self.send.close()
# self.recv.close()
Index: lldb/include/lldb/API/SBTarget.h
===================================================================
--- lldb/include/lldb/API/SBTarget.h
+++ lldb/include/lldb/API/SBTarget.h
@@ -841,6 +841,8 @@
lldb::addr_t GetStackRedZoneSize();
+ uint32_t GetMaximumOpcodeByteSize() const;
+
bool IsLoaded(const lldb::SBModule &module) const;
lldb::SBLaunchInfo GetLaunchInfo() const;
Index: lldb/bindings/interface/SBTarget.i
===================================================================
--- lldb/bindings/interface/SBTarget.i
+++ lldb/bindings/interface/SBTarget.i
@@ -944,6 +944,9 @@
lldb::addr_t
GetStackRedZoneSize();
+ uint32_t
+ GetMaximumOpcodeByteSize() const;
+
%feature("docstring", "
Returns true if the module has been loaded in this `SBTarget`.
A module can be loaded either by the dynamic loader or by being manually
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits