如何在 GNU GAS ELF 输出中制作 GDB 可以中断但不计为函数的本地标签?

Cir*_*四事件 5 gdb gnu-assembler elf dwarf

当使用 GNU GAS 手动编写程序集时,在函数内,我想设置一个标签,以便:

  • GDB 不会将该标签视为函数名称
  • 我可以用b mylabel打破标签

类似的问题nasm已在以下位置提出:Break at local label using GDB for NASM assembly,但我想在这里更精确地表示我想要 GNU GAS 和 ELF 输出。

例如,如果我定义了一个普通标签,mylabel如下所示:

电源

.text
.global _start
_start:
    /* exit */
    mov $60, %rax
mylabel:
    mov $0, %rdi
    syscall
Run Code Online (Sandbox Code Playgroud)

这并不令我满意,因为当 GDB 到达 时mov $0, %rdibt显示mylabel为函数名称,而我希望它是函数_start名称。特别是,这可能会破坏回溯,因为 GDB 无法找到堆栈帧:How gdbreconstructing stacktrace for C++?

但是,如果我按照以下解释替换mylabel.LmylabelLocal labels in GNU assembler; gdb 打印回溯,就像标签是函数一样,然后_start是所需的函数名称,但b .Lmylabel失败。nm也不显示该符号。

ELF / DWARF 格式是否支持任何可以使用的内容,是否有任何方法可以通过 GNU GAS 公开它?

在 Ubuntu 18.10、GDB 8.2、GNU GAS 2.31.1 中测试。

Flo*_*mer 3

我不确定这是否符合您的需求,但您可以这样做(对于非 PIE 二进制文件,因此链接为-no-pie):

.text
.global _start
_start:
    /* exit */
    mov $60, %rax
.Lmylabel:
    mov $0, %rdi
    syscall
    .section .rodata
mylabel:
    .long .Lmylabel
Run Code Online (Sandbox Code Playgroud)

break *mylabel然后,您可以使用(注意)设置断点*

(gdb) break *mylabel
Breakpoint 2 at 0x401007: file t.S, line 7.

Run Code Online (Sandbox Code Playgroud)

由于mylabel或多或少是一个函数指针,GDB 对它一无所知并且会忽略它:

Breakpoint 1, _start () at t.S:5
5       mov $60, %rax
(gdb) si
7       mov $0, %rdi
Run Code Online (Sandbox Code Playgroud)

使用链接器脚本,应该可以将mylabel符号放入未加载的节中,以减少运行时开销。