* Removing old symbols when debugging code that relocates itself
@ 2022-05-25 21:14 Wolfgang Wallner
2022-05-25 22:13 ` Shahab Vahedi
0 siblings, 1 reply; 3+ messages in thread
From: Wolfgang Wallner @ 2022-05-25 21:14 UTC (permalink / raw)
To: gdb
Hi all,
I have a question regarding adding and removing symbols.
I try to learn more about the inner workings of the U-Boot bootloader
[1] by stepping through it's execution.
There are some QEMU machines that are supported by U-Boot, and I choose
to use the 'virt' machine for ARM for my exercise.
The tricky part is that U-Boot relocates itself during runtime to
another address and continues execution from there.
I can successfully do the following:
* step through the code until relocation
* add the ELF file again (add-symbol-file) at the relocated address
* continue to step through the code at the new location
However, after relocation something is strange with symbols and
breakpoints. I would like to remove the symbols that I don't need any
more, but I can't figure out how to do that properly. What I have tried
is calling 'symbole-file' without arguments and 'remove-symbol-file'.
It seems I can only remove the symbols that I have added with
add-symbol-file, but not the initial ones ...
I will add a detailed description of what I'm doing below.
I hope you can help me here to figure it out, or point me to the
relevant documentation.
regards, Wolfgang
[1] https://source.denx.de/u-boot/u-boot
------------------------------------------------------------------
Detailed description:
I use revision f83bd23e2 (current master of a few day ago) of U-Boot.
git clone https://source.denx.de/u-boot/u-boot.git
git checkout f83bd23e2
Then I cross-compile U-Boot for the QEMU ARM 'virt' machine:
cd u-boot
export CROSS_COMPILE=arm-linux-gnueabihf-
make qemu_arm_defconfig
make
This provides me with the files 'u-boot' (ELF with debug info) and
'u-boot.bin (binary file for execution in QEMU).
I start QEMU as follows:
qemu-system-arm -machine virt -nographic -bios u-boot.bin -s -S
The simulated machine will have 128MB of RAM by default, which will be
mapped starting from address 0x40000000.
Mapped to address 0x00000000 is the simulated flash memory containing
the binary file passed via the "-bios" parameter (u-boot.bin).
In another shell I start gdb and connect to QEMU's gdb server:
gdb-multiarch -q u-boot
(gdb) target remote :1234
The function which carries out the relocation is called relocate_code
and is called from within the file crt0.S.
I set a breakpoint right before it is called:
(gdb) break crt0.S:156
Showing the current breakpoints with 'info breakpoints' gives me the
following (expected) result:
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00001668 arch/arm/lib/crt0.S:156
I 'continue' the execution and the breakpoint within crt0.S is hit.
The relocation address is calculated during runtime, so let's print it
via 'print/x gd->relocaddr':
(gdb) print/x gd->relocaddr
$1 = 0x47f3b000
The code will be relocated to RAM at addresss 0x47f3b000, which is at
the upper end of the simulated 128MB.
Next I step into relocate_code, run until its end at line 118, and print
the program counter (register r15 on ARM):
(gdb) step
(gdb) until 118
(gdb) print $r15
$2 = (void (*)()) 0x1754 <relocate_code+108>
We are still within the simulated flash, but the next instruction
(returning from relocate_code) will jump to the relocated code in RAM.
I load the file 'u-boot' ELF-file again via add-symbol-file, this time
at the relocation addresss 0x47F3B000:
(gdb) add-symbol-file u-boot 0x47F3B000
Stepping out of relocate_code and printing the program counter again:
(gdb) step
?? () at arch/arm/lib/crt0.S:162
162 bl relocate_vectors
(gdb) print $r15
$3 = (void (*)()) 0x47f3c66c
As expected, we are now at the relocated location, and I can step
through the code.
But now the trouble starts. Printing the currently set breakpoints shows
that some breakpoints are set multiple times.
This is expected, as I have loaded the same symbols at two different places.
info breakpoints
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y <MULTIPLE>
breakpoint already hit 1 time
1.1 y 0x00001668 arch/arm/lib/crt0.S:156
1.2 y 0x47f3c668 arch/arm/lib/crt0.S:156
At this point, I don't need the symbol at address 0x00000000 any more,
and I would like to remove them.
However, I can't figure out how.
I have tried remove-symbol-file and symbol-file without arguments.
If anything it seems I'm able to remove the symbols from the second
location (at 0x47F3B000), but not from the first location (at 0x00000000).
Any tips on how to remove the now unneeded symbols?
Adding new breakpoints also leads to multiple breakpoints:
(gdb) break board_init_r
Breakpoint 2 at 0x1dc24: board_init_r. (2 locations)
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y <MULTIPLE>
breakpoint already hit 1 time
1.1 y 0x00001668 arch/arm/lib/crt0.S:156
1.2 y 0x47f3c668 arch/arm/lib/crt0.S:156
2 breakpoint keep y <MULTIPLE>
2.1 y 0x0001dc24 in board_init_r at
common/board_r.c:817
2.2 y 0x47f58c24 in board_init_r at
common/board_r.c:817
If I try to drop all symbols and add the relocated ones again I get the
following:
(gdb) symbol-file
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y <PENDING> crt0.S:156
breakpoint already hit 1 time
2 breakpoint keep y <PENDING> board_init_r
(gdb) add-symbol-file u-boot 0x47F3B000
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x47f3c668 arch/arm/lib/crt0.S:156
breakpoint already hit 1 time
2 breakpoint keep y <MULTIPLE>
2.1 y 0x0001dc28 <board_init_r+4>
2.2 y 0x47f58c24 in board_init_r at
common/board_r.c:817
So, somehow the old symbols are still known, but the debug information
(file location) is gone ... ?
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Removing old symbols when debugging code that relocates itself
2022-05-25 21:14 Removing old symbols when debugging code that relocates itself Wolfgang Wallner
@ 2022-05-25 22:13 ` Shahab Vahedi
2022-05-26 19:28 ` Wolfgang Wallner
0 siblings, 1 reply; 3+ messages in thread
From: Shahab Vahedi @ 2022-05-25 22:13 UTC (permalink / raw)
To: Wolfgang Wallner; +Cc: gdb
Hi Wolfgang,
On Wed, May 25, 2022 at 11:14:28PM +0200, Wolfgang Wallner via Gdb wrote:
> It seems I can only remove the symbols that I have added with
> add-symbol-file, but not the initial ones ...
Maybe you could extract the symbol file [1] and then strip it away from
the binary [2]. This way, you have to use "add-symbol-file" to add it
in different stages and according to what you say you should be able
to remove it after each adding.
Cheers,
Shahab
[1]
$ objcopy --only-keep-debug uboot.bin uboot.sym
[2]
$ objcopy --strip-all uboot.bin uboot.strp
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Removing old symbols when debugging code that relocates itself
2022-05-25 22:13 ` Shahab Vahedi
@ 2022-05-26 19:28 ` Wolfgang Wallner
0 siblings, 0 replies; 3+ messages in thread
From: Wolfgang Wallner @ 2022-05-26 19:28 UTC (permalink / raw)
To: Shahab Vahedi; +Cc: gdb
Hi Shahab,
On 26.05.22 00:13, Shahab Vahedi wrote:
> Hi Wolfgang,
>
> On Wed, May 25, 2022 at 11:14:28PM +0200, Wolfgang Wallner via Gdb wrote:
>> It seems I can only remove the symbols that I have added with
>> add-symbol-file, but not the initial ones ...
>
> Maybe you could extract the symbol file [1] and then strip it away from
> the binary [2]. This way, you have to use "add-symbol-file" to add it
> in different stages and according to what you say you should be able
> to remove it after each adding.
>
> [1]
> $ objcopy --only-keep-debug uboot.bin uboot.sym
>
> [2]
> $ objcopy --strip-all uboot.bin uboot.strp
Thanks for the feedback!
I tried your recommendations, and while it seems to help somewhat,
unfortunately it does not fully solve my troubles.
Here is what I did:
1) Create the files as you described:
arm-linux-gnueabihf-objcopy --strip-all u-boot u-boot.strp
arm-linux-gnueabihf-objcopy --only-keep-debug u-boot my_u-boot.sym
Remark: The U-Boot build already creates a file called 'u-boot.sym', so
I gave my file another name (my_u-boot.sym).
The already existing u-boot.sym file is the symbol table as text file
created by calling 'objdump -t'.
2) I start QEMU as described in my first mail
3) I start GDB using the 'u-boot.strp' ELF file
4) As first command, I add 'my_u-boot.sym' via add-symbol-file
I then step through the code as described in my last mail, but
somehow in this configuration I cannot use GDB's 'until' command.
Using 'until' continues execution, and the temporary breakpoint is
never hit. It is interesting to note that this is *only in assembly*,
using 'until' works fine in C-files!
As a workaround for this issue I set explicit breakpoints.
5) I continue to step through the code, until I reach the relocated code. I
then drop all symbols via 'symbol-file', and add them back for the relocated
location via 'add-symbol-file'.
Showing information about breakpoints shows that there are no duplicate
breakpoints any more --> woohoo :)
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x47f3c668 arch/arm/lib/crt0.S:156
breakpoint already hit 1 time
2 breakpoint keep y 0x47f3c754 arch/arm/lib/relocate.S:134
breakpoint already hit 1 time
While these breakpoints were set at the old locations, now they already
point
to the symbols at the relocated locations.
But when I try to set a new breakpoint, it is again a duplicate:
(gdb) break board_init_r
Breakpoint 3 at 0x1dc28 (2 locations)
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x47f3c668 arch/arm/lib/crt0.S:156
breakpoint already hit 1 time
2 breakpoint keep y 0x47f3c754 arch/arm/lib/relocate.S:134
breakpoint already hit 1 time
3 breakpoint keep y <MULTIPLE>
3.1 y 0x0001dc28 <board_init_r+4>
3.2 y 0x47f58c24 in board_init_r at
common/board_r.c:817
So this leaves me with the following questions:
*) Does anyone know why the 'until' command stopped working with this
approach in assembly files? Is this expected, or is it a bug?
*) Why are there still duplicate breakpoints?
*) Are there other approaches to deal with relocated code?
While the objcopy steps have helped me, for a more permanent
workflow I would like to avoid them (e.g. it would be nice to
directly set up a debug environment in an IDE, and any required
extra steps between compilation and debugging would make that more
complicated)
regards, Wolfgang
Remark: I think there was a typo in my initial mail. The breakpoint in
relocate.S should be in line 134, not line 118.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-05-26 19:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-25 21:14 Removing old symbols when debugging code that relocates itself Wolfgang Wallner
2022-05-25 22:13 ` Shahab Vahedi
2022-05-26 19:28 ` Wolfgang Wallner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).