Search code examples
gccgdbbitbake

In gdb can I save or pass values like the symbol-filename for later use?


I am running gdb like this:

x-compiler-gdb path/to/u-boot

Where "x-compiler" is just whatever cross compiler suffix I am using and /path/to is the path where my u-boot file lives.

Then in GDB I do something like:

1. Connect to the remove session - ok

(gdb) target extended-remote :3333
Remote debugging using :3333

2. Find relocation address - ok

(gdb) p/x (*(struct global_data*)$r9)->relocaddr
$1 = 0x27f7a000

This is cool because it stores the relocation address in a variable called $1

3. Remove symbol file - ok

(gdb) symbol-file
Discard symbol table from `/home/...../u-boot'? (y or n) y
No symbol file now.

4. Reload symbol file at the relocation address

(gdb) add-symbol-file u-boot $1          <------------- HERE
add symbol table from file "u-boot" at
        .text_addr = 0x12345678
(y or n) y
Reading symbols from u-boot...
(gdb)

I was able to use variable $1 to use the relocation address. But next I want to reload the original filename that I passed in because I want to script this up and make it more generic.

Things I don't know how to do

  1. I don't know how to pass in variables to gdb like gdb <binary> U_BOOT_FILE=/path/to/binary/u-boot so that I can use that inside the gdb environment.

  2. Or better still, I don't know how to print / store the name of the symbol (binary) file that I have passed in so that I can reference it later.

My script so far

set confirm off
target extended-remote <remote_ip>:3333             <----- pass in the remote IP address
p/x (*(struct global_data*)$x18)->relocaddr
symbol-file
add-symbol-file u-boot-v2020.04+git999/u-boot $1    <---- Hardcoded symbol filename

You can see I have to hard-code the file name u-boot-v2020.04+git999/u-boot which could be a different version or path.

Ideally I would store that into $2 or such - but I can't see how this is done. Any reference to "gdb variable storage" or such just references program variables from the binary.

Also I would like to pass in the remote IP address perhaps as $3

Note: this is to debug yocto/bitbake gcc built u-boot.


Solution

  • I'd use the Python API to create a new command. Place the following into a Python file, e.g. /tmp/gdb-command.py:

    class ConnectAndRelocateCommand (gdb.Command):
        """
        Usage: connect-and-relocate IP
    
        Connect to IP:3333, establish the relocation address and reload
        the current symbol-file at that address.
        """
    
        def __init__ (self):
            gdb.Command.__init__ (self, "connect-and-relocate", gdb.COMMAND_NONE)
    
        def invoke(self, args, from_tty):
            # 1. Grab the IP address from the arguments.
            argv = gdb.string_to_argv(args)
            if len(argv) != 1:
                raise gdb.GdbError("usage: connect-and-relocate IP")
            ip = argv[0]
    
            # 2. Connect to the remote server.
            gdb.execute(f"target extended-remote {ip}:3333")
    
            # 3. Find filename of current symfile.
            pspace = gdb.selected_inferior().progspace
            symbol_file = pspace.symbol_file
            if symbol_file is None:
                raise gdb.GdbError("no symbol file loaded")
            filename = symbol_file.filename
    
            # 4. Find relocation address.
            reloc_addr = gdb.parse_and_eval("(*(struct global_data*)$r9)->relocaddr")
    
            # 5. Remove symbol file.
            gdb.execute("symbol-file")
    
            # 6. Reload symbol file at relocation address.
            reload_cmd = f"add-symbol-file {filename} {reloc_addr}"
            gdb.execute(reload_cmd)
    
            print("relocation complete")
    
    ConnectAndRelocateCommand ()
    
    print("Command script loaded OK")
    

    Then in a GDB session just source /tmp/gdb-command.py.

    Assuming that loading the script worked without errors you should see the Command script loaded OK message. Your GDB session now has the command connect-and-relocate available. Use help connect-and-relocate for more details.

    With luck this should do what you want. If you have some basic Python knowledge you should be able to tweak the script to meet your needs.

    The GDB Python API docs can be found here.