gdb add-symbol-file all sections and load address


gdb add-symbol-file all sections and load address



I'm debugging a boot loader (syslinux) with gdb and the gdb-stub of qemu. At some point the main file load a shared object ldlinux.elf.


ldlinux.elf



I would like to add the symbols in gdb for that file. The command add-symbol-file seems like the way to go. However, as a relocatable file, I have to specify the memory address it has been loaded at. And here comes the problem.


add-symbol-file



Although I know the base address at which the LOAD segment has been loaded at, add-symbol-file works section-wise and want me to specify the address at which each section has been loaded.


LOAD


add-symbol-file



Can I tell gdb to load all the symbols of all the sections provided that I specify the base address of the file in memory?



Does the behavior of gdb make sens? The section headers aren't used for running an ELF and are even optional. I can't see a use case where specifying the load address of the sections would be useful.



Here are the program headers and section headers of the shared object.



If I try to load the file at the address 0x7fab000 then it will relocate the symbols so that the .text section starts at 0x7fab000.


0x7fab000


.text



And then all the symbols are off by 0x4c60 bytes.




2 Answers
2



So, finally, I made my own command with python and the readelf tool. It's not very clean since it runs readelf in a subprocess and parse its output instead of parsing the ELF file directly, but it works (for 32 bits ELF only).


readelf


readelf



It uses the section headers to generate and run an add-symbol-file command with all the sections correctly relocated. The usage is pretty simple, you give it the elf file and the base address of the file. And since the remove-symbol-file wasn't working properly by just giving it the filename, I made a remove-symbol-file-all that generate and run the right remove-symbol-file -a address command.


add-symbol-file


remove-symbol-file


remove-symbol-file-all


remove-symbol-file -a address


(gdb) add-symbol-file-all bios/com32/elflink/ldlinux/ldlinux.elf 0x7fab000
add symbol table from file "bios/com32/elflink/ldlinux/ldlinux.elf" at
.text_addr = 0x7fafc50
.gnu.hash_addr = 0x7fab094
.dynsym_addr = 0x7fab874
.dynstr_addr = 0x7face34
.rel.dyn_addr = 0x7fadf28
.rel.plt_addr = 0x7faec08
.plt_addr = 0x7faf170
.rodata_addr = 0x7fc34e0
.ctors_addr = 0x7fc7af0
.dtors_addr = 0x7fc7b00
.data.rel.ro_addr = 0x7fc7b20
.dynamic_addr = 0x7fc8658
.got_addr = 0x7fc86f0
.got.plt_addr = 0x7fc87bc
.data_addr = 0x7fc8a80
.bss_addr = 0x7fc8b60
(gdb) remove-symbol-file-all bios/com32/elflink/ldlinux/ldlinux.elf 0x7fab000



Here is the code to be added in the .gdbinit file.


.gdbinit


python
import subprocess
import re

def relocatesections(filename, addr):
p = subprocess.Popen(["readelf", "-S", filename], stdout = subprocess.PIPE)

sections =
textaddr = '0'
for line in p.stdout.readlines():
line = line.decode("utf-8").strip()
if not line.startswith('[') or line.startswith('[Nr]'):
continue

line = re.sub(r' +', ' ', line)
line = re.sub(r'[ *(d+)]', 'g<1>', line)
fieldsvalue = line.split(' ')
fieldsname = ['number', 'name', 'type', 'addr', 'offset', 'size', 'entsize', 'flags', 'link', 'info', 'addralign']
sec = dict(zip(fieldsname, fieldsvalue))

if sec['number'] == '0':
continue

sections.append(sec)

if sec['name'] == '.text':
textaddr = sec['addr']

return (textaddr, sections)


class AddSymbolFileAll(gdb.Command):
"""The right version for add-symbol-file"""

def __init__(self):
super(AddSymbolFileAll, self).__init__("add-symbol-file-all", gdb.COMMAND_USER)
self.dont_repeat()

def invoke(self, arg, from_tty):
argv = gdb.string_to_argv(arg)
filename = argv[0]

if len(argv) > 1:
offset = int(str(gdb.parse_and_eval(argv[1])), 0)
else:
offset = 0

(textaddr, sections) = relocatesections(filename, offset)

cmd = "add-symbol-file %s 0x%08x" % (filename, int(textaddr, 16) + offset)

for s in sections:
addr = int(s['addr'], 16)
if s['name'] == '.text' or addr == 0:
continue

cmd += " -s %s 0x%08x" % (s['name'], addr + offset)

gdb.execute(cmd)

class RemoveSymbolFileAll(gdb.Command):
"""The right version for remove-symbol-file"""

def __init__(self):
super(RemoveSymbolFileAll, self).__init__("remove-symbol-file-all", gdb.COMMAND_USER)
self.dont_repeat()

def invoke(self, arg, from_tty):
argv = gdb.string_to_argv(arg)
filename = argv[0]

if len(argv) > 1:
offset = int(str(gdb.parse_and_eval(argv[1])), 0)
else:
offset = 0

(textaddr, _) = relocatesections(filename, offset)

cmd = "remove-symbol-file -a 0x%08x" % (int(textaddr, 16) + offset)
gdb.execute(cmd)


AddSymbolFileAll()
RemoveSymbolFileAll()
end



Can I tell gdb to load all the symbols of all the sections provided that I specify the base address of the file in memory?



Yes, but you need to provide the address of .text section, i.e. 0x7fab000+0x00004c60 here. I agree: it's quite annoying to have to fish out address of .text, and I wanted to fix it many times, so that e.g.


.text


0x7fab000+0x00004c60


.text


(gdb) add-symbol-file foo.so @0x7abc0000



just works. Feel free to file a feature request in GDB bugzilla.



Does the behavior of gdb make sens?



I am guessing that this is rooted in how GDB was used to debug embedded ROMs, where each section can be at arbitrary memory address.





If I want to add the symbols of data, I'll have to add the options and addresses of .data, .rodata and .bss sections. And maybe more if I have specific things to debug. I'm writing a pythong script right now to generate the right gdb command.
– Celelibi
Oct 10 '15 at 3:37


.data


.rodata


.bss





@Celelibi No: usually adding foo.so with the address of .text instead of the load address is all you need for both .text and .data.
– Employed Russian
Oct 10 '15 at 3:44


foo.so


.text


.text


.data





No, I just tested, if I don't specify the load address of the .data section, the symbols pointing to it get loaded but won't get the offset.
– Celelibi
Oct 10 '15 at 4:15


.data





GDB complains: A syntax error in expression, near '0x7abc000'.
– Yorkwar
Jan 28 '16 at 8:44


A syntax error in expression, near '0x7abc000'.





@Yorkwar You are complaining about a missing feature that I wanted to fix. I have not fixed it yet, so of course GDB complains.
– Employed Russian
Jan 28 '16 at 15:50






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

How to input without newline? (Python)

C++ thread error: no type named ‘type’ MINGW

Analog for TagView in flutter