如何在GDB可以中断但不能算作功能的GNU GAS ELF输出中制作本地标签?

时间:2019-03-18 17:20:28

标签: gdb elf gas dwarf

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

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

Break at local label using GDB for NASM assembly上也对nasm提出了类似的问题,但我想在这里更精确地说明我想要GNU GAS和ELF输出。

例如如果我在以下位置定义了普通标签mylabel

main.S

.text
.global _start
_start:
    /* exit */
    mov $60, %rax
mylabel:
    mov $0, %rdi
    syscall

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

但是,如果按照Local labels in GNU assembler; gdb printing backtrace as though labels are functions的说明将mylabel替换为.Lmylabel,则_start是所需的函数名称,但是b .Lmylabel失败。 nm也不显示任何符号。

ELF / DWARF格式是否支持任何可以使用的格式,是否可以通过GNU GAS公开呢?

在Ubuntu 18.10,GDB 8.2,GNU GAS 2.31.1中进行了测试。

1 个答案:

答案 0 :(得分:2)

I'm not sure if this fits your needs, but you can do this (for a non-PIE binary, so link with -no-pie):

.text
.global _start
_start:
    /* exit */
    mov $60, %rax
.Lmylabel:
    mov $0, %rdi
    syscall
    .section .rodata
mylabel:
    .long .Lmylabel

Then, you can set a breakpoint using break *mylabel (note the *):

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

Since mylabel is more or less a function pointer, GDB does not know anything about it and will ignore it:

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

With a linker script, it should be possible to put the mylabel symbol into a section which is not loaded, to reduce run-time overhead.