import gdb.disassembler
class riscv_dec_imm_disasm(gdb.disassembler.Disassembler):
def __init__(self):
super().__init__("riscv_dec_imm_disasm")
def __call__(self, info):
result = gdb.disassembler.builtin_disassemble(info)
parts = []
for p in result.parts:
if (
isinstance(p, gdb.disassembler.DisassemblerTextPart)
and (
p.style == gdb.disassembler.STYLE_IMMEDIATE
or p.style == gdb.disassembler.STYLE_ADDRESS_OFFSET
)
and p.string[0:2] != "0x"
):
# An immediate part that does not have '0x' prefix, so
# should be decimal. Lets reformat it as hex.
#
# TODO: This assumes that all immediates are 8-bits,
# which isn't going to be correct. I guess you'll
# need to map from mnemonic to immediate size in order
# to do this correctly.
v = int(p.string)
parts.append(info.text_part(p.style, ("0x%x" % (v & 0xFF))))
else:
# Don't change this part.
parts.append(p)
return gdb.disassembler.DisassemblerResult(length=result.length,
parts=parts)
gdb.disassembler.register_disassembler(riscv_dec_imm_disasm())
然后我们可以像这样在GDB会话中使用它:
$ gdb -q /tmp/hello.rv32imc.x
Reading symbols from /tmp/hello.rv32imc.x...
(gdb) disassemble main
Dump of assembler code for function main:
0x000101aa <+0>: add sp,sp,-16
0x000101ac <+2>: sw ra,12(sp)
0x000101ae <+4>: sw s0,8(sp)
0x000101b0 <+6>: add s0,sp,16
0x000101b2 <+8>: lui a5,0x18
0x000101b4 <+10>: add a0,a5,1756 # 0x186dc
0x000101b8 <+14>: jal 0x1040e <puts>
0x000101ba <+16>: li a7,7
0x000101bc <+18>: li a6,6
0x000101be <+20>: li a5,5
0x000101c0 <+22>: li a4,4
0x000101c2 <+24>: li a3,3
0x000101c4 <+26>: li a2,2
0x000101c6 <+28>: li a1,1
0x000101c8 <+30>: li a0,0
0x000101ca <+32>: jal 0x1014c <call_me>
0x000101cc <+34>: li a5,0
0x000101ce <+36>: mv a0,a5
0x000101d0 <+38>: lw ra,12(sp)
0x000101d2 <+40>: lw s0,8(sp)
0x000101d4 <+42>: add sp,sp,16
0x000101d6 <+44>: ret
End of assembler dump.
(gdb) source riscv-dis.py
(gdb) disassemble main
Dump of assembler code for function main:
0x000101aa <+0>: add sp,sp,0xf0
0x000101ac <+2>: sw ra,0xc(sp)
0x000101ae <+4>: sw s0,0x8(sp)
0x000101b0 <+6>: add s0,sp,0x10
0x000101b2 <+8>: lui a5,0x18
0x000101b4 <+10>: add a0,a5,0xdc
0x000101b8 <+14>: jal 0x1040e <puts>
0x000101ba <+16>: li a7,0x7
0x000101bc <+18>: li a6,0x6
0x000101be <+20>: li a5,0x5
0x000101c0 <+22>: li a4,0x4
0x000101c2 <+24>: li a3,0x3
0x000101c4 <+26>: li a2,0x2
0x000101c6 <+28>: li a1,0x1
0x000101c8 <+30>: li a0,0x0
0x000101ca <+32>: jal 0x1014c <call_me>
0x000101cc <+34>: li a5,0x0
0x000101ce <+36>: mv a0,a5
0x000101d0 <+38>: lw ra,0xc(sp)
0x000101d2 <+40>: lw s0,0x8(sp)
0x000101d4 <+42>: add sp,sp,0x10
0x000101d6 <+44>: ret
End of assembler dump.
(gdb)
1条答案
按热度按时间m1m5dgzv1#
号
GDB使用的risc-v反汇编器没有将立即数格式化为十六进制的选项。
然而,在那里,使用GDB的当前开发(未发布)版本可能会做你想做的事情。
从GDB 13开始,有一个Python API来 Package 反汇编器。GDB 13中的版本非常基本,对您的帮助并不像您希望的那样大。但是,这个API是在开发分支中扩展的,因此应该可以编写一个Python脚本,按照您的需要重新格式化立即数。
这是一个初始脚本,保存到文件
riscv-dis.py
中:请记住,这只适用于GDB 14,或使用GDB的当前开发分支。
然后我们可以像这样在GDB会话中使用它:
这有一个大问题--为了将负立即数显示为0xfff…我需要将立即数屏蔽到大小,这意味着我需要知道立即数有多大。唯一的方法是根据(我猜)指令助记符查找立即大小。在上面的脚本中,我假设所有立即数都是8位的。