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

标签 ubuntu gdb

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

li  a0,64

我希望它显示十六进制立即数,而不是十进制。例如

li  a0,0x40

是否可以在 RISC-V 的 GBD 中执行此操作?

(我猜测 gdb 强制采用十进制,因此它可以以十进制而不是十六进制显示带符号的负值(这可能会让某些人感到困惑),但我只是想以防万一来配置它。)

最佳答案

没有。

GDB 使用的 risc-v 反汇编程序没有将立即数格式化为十六进制的选项。

但是,使用当前开发(未发布)版本的 GDB 可能可以完成您想要的操作。

自 GDB 13 起,有一个包装反汇编器的 Python API。 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 session 中使用它,如下所示:

$ 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 位。

关于ubuntu - 是否可以在 gdb 中更改反汇编中的立即数是否以十六进制与十进制显示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76918384/

相关文章:

c++ - gdb 前端与 vim 一起使用?

c - 检查局部变量返回函数

ubuntu - 无法将 SIP 客户端与 Asterisk 连接

node.js - NPM install 在安装 express 时出现错误

authentication - LDAP 身份验证 apache 2.2 错误 500

c - 如何一次性设置GDB调试打印选项?

我可以在 C 源代码中找到具有一定大小的结构吗?

linux - 将 nokaslr 添加到内核命令行

ubuntu - unit ark.service 加载不正确 :Exec format error

c++ - 好的 Linux/Ubuntu OpenGL 教程?