The following GDB Python convenience function (as defined by the script) will search through the output of (gdb) info proc mappings for the library you've specified in the function parameter and return the start address of the .text segment of that library or executable.
Here is an example output of (gdb) info proc mapping with the entry for libc.so highlighted in red. The Start Addr is what we'll have the convenience function fetch:
Start Addr End Addr Size Offset objfile
0x100000 0x103000 0x3000 0x100000
0x8000000 0x8029000 0x29000 0 /home/user/glibc64_power6/elf/ld.so
0x8039000 0x803a000 0x1000 0x29000 /home/user/glibc64_power6/elf/ld.so
0x803a000 0x803e000 0x4000 0x2a000 /home/user/glibc64_power6/elf/ld.so
0x10000000 0x10002000 0x2000 0 /home/user/libdfp64_power6/test-isinf
0x10011000 0x10012000 0x1000 0x1000 /home/user/libdfp64_power6/test-isinf
0x40000000000 0x40000002000 0x2000 0
0x40000002000 0x40000195000 0x193000 0 /home/user/glibc64_power6/libc.so
0x40000195000 0x400001a4000 0xf000 0x193000 /home/user/glibc64_power6/libc.so
0x400001a4000 0x400001a8000 0x4000 0x192000 /home/user/glibc64_power6/libc.so
0x400001a8000 0x400001bf000 0x17000 0x196000 /home/user/glibc64_power6/libc.so
0x400001bf000 0x400001c3000 0x4000 0x1bf000
0x400001c3000 0x4000026b000 0xa8000 0 /home/user/glibc64_power6/math/libm.so
0x4000026b000 0x4000027a000 0xf000 0xa8000 /home/user/glibc64_power6/math/libm.so
0x4000027a000 0x4000027b000 0x1000 0xa7000 /home/user/glibc64_power6/math/libm.so
0x4000027b000 0x40000285000 0xa000 0xa8000 /home/user/glibc64_power6/math/libm.so
0x40000285000 0x40000286000 0x1000 0x285000
0x40000286000 0x400002a3000 0x1d000 0 /home/user/glibc64_power6/nptl/libpthread.so
0x400002a3000 0x400002b2000 0xf000 0x1d000 /home/user/glibc64_power6/nptl/libpthread.so
0x400002b2000 0x400002b3000 0x1000 0x1c000 /home/user/glibc64_power6/nptl/libpthread.so
0x400002b3000 0x400002b5000 0x2000 0x1d000 /home/user/glibc64_power6/nptl/libpthread.so
0x400002b5000 0x400002ba000 0x5000 0x2b5000
0x400002ba000 0x4000031a000 0x60000 0 /home/user/libdfp64_power6/libdfp-1.0.7.so
0x4000031a000 0x40000329000 0xf000 0x60000 /home/user/libdfp64_power6/libdfp-1.0.7.so
0x40000329000 0x40000332000 0x9000 0x5f000 /home/user/libdfp64_power6/libdfp-1.0.7.so
0x40000332000 0x40000334000 0x2000 0x332000
0xffffff9d000 0xffffffb3000 0x16000 0xfff9d000 [stack]
Add the following to your ~.gdbinit file, or source it directly in your .gdb script:
source /path/to/gdb_start_address.pygdb_start_address.py:
# gdb_start_address.py created by Ryan S. Arnold, April 2011. NoThere is currently a bug in GDB which crashes GDB after a direct assignment from this user function, e.g., (gdb) set $foo = $start_address("libc"). To use the function to set a variable do the following:
# attribution required or necessary to use/reuse/copy/modify this
# function/script.
import re
class StartAddress(gdb.Function):
"""Returns the start address of a library or executable from info
proc mappings."""
def __init__(self):
super (StartAddress, self).__init__ ("start_address")
def invoke(self, library):
mappings = gdb.execute("info proc mappings", to_string=True)
lines = mappings.split('\n')
to_mappings = ""
for line in lines:
if (to_mappings != "true"):
if (re.search("Start Addr", line)):
to_mappings = "true"
continue
else:
# The first match is the .text segment. Make sure to
# match on "/libdfp-1.0.7.so" when passed "libdfp" and
# not on "/libdfp" in the following example:
# /home/ryanarn/libdfp/build64_power6/libdfp-1.0.7.so
if (re.search("/" + library.string() + "[^/]*$", line)):
chunks = line.split()
return int(str(chunks[0]),16)
return 0x0
StartAddress ()
(gdb) p $start_address("libc")I created this function to use in the Libdfp Makefile.gdb GNU make script. Libdfp's Make system will automatically generate .gdb scripts for each of the test cases in the test-suite. I use this function to find the load address of the library so that I can programmaticaly load the symbol file in the correct location, as in the following snippet of test-isinf.gdb:
$3 = 4398046760960
(gdb) set $foo = $
(gdb) p $foo
$4 = 4398046760960
source /home/ryanarn/eglibc/eglibc/libdfp/trunk/tests/gdb_start_address.py
...
p/x $start_address("libdfp")
set $libdfp_start = $
set $libdfp_text = 0x0af40
set $libdfp_addr = $libdfp_start + $libdfp_text
add-symbol-file ./libdfp.so.1 $libdfp_addr
This comment has been removed by a blog administrator.
ReplyDelete