Add instruction bytes to DAP disassembly response
Commit Message
The DAP disassemble command lets the client return the underlying
bytes of the instruction in an implementation-defined format. This
patch updates gdb to return this, and simply uses a hex string of the
bytes as the format.
---
gdb/doc/gdb.texinfo | 5 +++++
gdb/python/lib/gdb/dap/disassemble.py | 5 ++++-
gdb/testsuite/gdb.dap/basic-dap.exp | 9 +++++++++
3 files changed, 18 insertions(+), 1 deletion(-)
Comments
> Cc: Tom Tromey <tromey@adacore.com>
> Date: Mon, 3 Jul 2023 07:59:02 -0600
> From: Tom Tromey via Gdb-patches <gdb-patches@sourceware.org>
>
> The DAP disassemble command lets the client return the underlying
> bytes of the instruction in an implementation-defined format. This
> patch updates gdb to return this, and simply uses a hex string of the
> bytes as the format.
> ---
> gdb/doc/gdb.texinfo | 5 +++++
> gdb/python/lib/gdb/dap/disassemble.py | 5 ++++-
> gdb/testsuite/gdb.dap/basic-dap.exp | 9 +++++++++
> 3 files changed, 18 insertions(+), 1 deletion(-)
Thanks, the documentation part is OK.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
>>>>> "Tom" == Tom Tromey <tromey@adacore.com> writes:
Tom> The DAP disassemble command lets the client return the underlying
Tom> bytes of the instruction in an implementation-defined format. This
Tom> patch updates gdb to return this, and simply uses a hex string of the
Tom> bytes as the format.
I'm checking this in.
Tom
@@ -39087,6 +39087,11 @@ The target to which @value{GDBN} should connect. This is a string and
is passed to the @code{target remote} command. @xref{Connecting}.
@end table
+In response to the @code{disassemble} request, DAP allows the client
+to return the bytes of each instruction in an implementation-defined
+format. @value{GDBN} implements this by sending a string with the
+bytes encoded in hex, like @code{"55a2b900"}.
+
@node JIT Interface
@chapter JIT Compilation Interface
@cindex just-in-time compilation
@@ -21,18 +21,21 @@ from .startup import send_gdb_with_response, in_gdb_thread
@in_gdb_thread
def _disassemble(pc, skip_insns, count):
+ inf = gdb.selected_inferior()
try:
arch = gdb.selected_frame().architecture()
except gdb.error:
# Maybe there was no frame.
- arch = gdb.selected_inferior().architecture()
+ arch = inf.architecture()
result = []
total_count = skip_insns + count
for elt in arch.disassemble(pc, count=total_count)[skip_insns:]:
+ mem = inf.read_memory(elt["addr"], elt["length"])
result.append(
{
"address": hex(elt["addr"]),
"instruction": elt["asm"],
+ "instructionBytes": mem.hex(),
}
)
return {
@@ -191,6 +191,15 @@ set obj [dap_check_request_and_response "disassemble one instruction" \
$insn_pc]]
set response [lindex $obj 0]
gdb_assert { [dict exists $response body instructions] } "instructions in disassemble output"
+foreach insn [dict get $response body instructions] {
+ gdb_assert {[dict exists $insn instructionBytes]} \
+ "instruction bytes in disassemble output"
+ set bytes [dict get $insn instructionBytes]
+ gdb_assert {[string length $bytes] % 2 == 0} \
+ "even number of digits"
+ gdb_assert {[regexp "^\[0-9A-Fa-f\]+\$" $bytes]} \
+ "instructionBytes is hex"
+}
set obj [dap_check_request_and_response "command repl" \
evaluate {o expression [s {output 23}] context [s repl]}]