ubuntu 是否可以在gdb中更改反汇编中的立即数是否以十六进制显示decimal?

62lalag4  于 2023-10-17  发布在  其他
关注(0)|答案(1)|浏览(109)

当我在gdb中使用“disas”指令来反汇编RISC-V指令时,它向我显示了以下内容:

li  a0,64

我宁愿它显示一个十六进制立即数,而不是十进制。例如

li  a0,0x40

是否可以在RISC-V的GBD中做到这一点?
(我猜gdb强制十进制,所以它可以用十进制而不是十六进制显示带符号的负值(这可能会让一些人感到困惑),但我只是在可能配置这个的情况下问。

m1m5dgzv

m1m5dgzv1#


GDB使用的risc-v反汇编器没有将立即数格式化为十六进制的选项。
然而,在那里,使用GDB的当前开发(未发布)版本可能会做你想做的事情。
从GDB 13开始,有一个Python API来 Package 反汇编器。GDB 13中的版本非常基本,对您的帮助并不像您希望的那样大。但是,这个API是在开发分支中扩展的,因此应该可以编写一个Python脚本,按照您的需要重新格式化立即数。
这是一个初始脚本,保存到文件riscv-dis.py中:

请记住,这只适用于GDB 14,或使用GDB的当前开发分支。

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)

这有一个大问题--为了将负立即数显示为0xfff…我需要将立即数屏蔽到大小,这意味着我需要知道立即数有多大。唯一的方法是根据(我猜)指令助记符查找立即大小。在上面的脚本中,我假设所有立即数都是8位的。

相关问题