When writing assembly manually with GNU GAS, within a function, I want to set a label such that:
- GDB won't treat that label as the function name
- I can use
b mylabel
to break on the label
A similar question for nasm
has been asked at: Break at local label using GDB for NASM assembly but I wanted to make it more precise here that I want GNU GAS and ELF output.
E.g. if I defined a normal label mylabel
as in:
main.S
.text
.global _start
_start:
/* exit */
mov $60, %rax
mylabel:
mov $0, %rdi
syscall
that does not satisfy me because when GDB reaches the mov $0, %rdi
, bt
shows mylabel
as the function name, and I would like it to be _start
instead. In particular, this can break backtraces because GDB can't find the stack frame: How gdb reconstructs stacktrace for C++?
However, if I replace mylabel
with .Lmylabel
as explained at: Local labels in GNU assembler; gdb printing backtrace as though labels are functions then _start
is the function name as desired, but b .Lmylabel
fails. nm
does not show the symbol at all either.
Does the ELF / DWARF formats support anything that could be used, and is there any way to expose that though GNU GAS?
Tested in Ubuntu 18.10, GDB 8.2, GNU GAS 2.31.1.
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.
来源:https://stackoverflow.com/questions/55226798/how-to-make-local-labels-in-gnu-gas-elf-output-that-gdb-can-break-on-but-not-cou