aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/python')
-rw-r--r--gdb/python/lib/gdb/dap/disassemble.py59
1 files changed, 52 insertions, 7 deletions
diff --git a/gdb/python/lib/gdb/dap/disassemble.py b/gdb/python/lib/gdb/dap/disassemble.py
index 65bf3d4..d65790a 100644
--- a/gdb/python/lib/gdb/dap/disassemble.py
+++ b/gdb/python/lib/gdb/dap/disassemble.py
@@ -16,6 +16,50 @@
import gdb
from .server import capability, request
+from .sources import make_source
+
+
+# This tracks labels associated with a disassembly request and helps
+# with updating individual instructions.
+class _BlockTracker:
+ def __init__(self):
+ # Map from PC to symbol names. A given PC is assumed to have
+ # just one label -- DAP wouldn't let us return multiple labels
+ # anyway.
+ self.labels = {}
+ # List of blocks that have already been handled. Note that
+ # blocks aren't hashable so a set is not used.
+ self.blocks = []
+
+ # Add a gdb.Block and its superblocks, ignoring the static and
+ # global block. BLOCK can also be None, which is ignored.
+ def add_block(self, block):
+ while block is not None:
+ if block.is_static or block.is_global or block in self.blocks:
+ return
+ self.blocks.append(block)
+ if block.function is not None:
+ self.labels[block.start] = block.function.name
+ for sym in block:
+ if sym.addr_class == gdb.SYMBOL_LOC_LABEL:
+ self.labels[int(sym.value())] = sym.name
+ block = block.superblock
+
+ # Add PC to this tracker. Update RESULT as appropriate with
+ # information about the source and any label.
+ def add_pc(self, pc, result):
+ self.add_block(gdb.block_for_pc(pc))
+ if pc in self.labels:
+ result["symbol"] = self.labels[pc]
+ sal = gdb.find_pc_line(pc)
+ if sal.symtab is not None:
+ if sal.line != 0:
+ result["line"] = sal.line
+ if sal.symtab.filename is not None:
+ # The spec says this can be omitted in some
+ # situations, but it's a little simpler to just always
+ # supply it.
+ result["location"] = make_source(sal.symtab.filename)
@request("disassemble")
@@ -35,17 +79,18 @@ def disassemble(
except gdb.error:
# Maybe there was no frame.
arch = inf.architecture()
+ tracker = _BlockTracker()
result = []
total_count = instructionOffset + instructionCount
for elt in arch.disassemble(pc, count=total_count)[instructionOffset:]:
mem = inf.read_memory(elt["addr"], elt["length"])
- result.append(
- {
- "address": hex(elt["addr"]),
- "instruction": elt["asm"],
- "instructionBytes": mem.hex(),
- }
- )
+ insn = {
+ "address": hex(elt["addr"]),
+ "instruction": elt["asm"],
+ "instructionBytes": mem.hex(),
+ }
+ tracker.add_pc(elt["addr"], insn)
+ result.append(insn)
return {
"instructions": result,
}