Commit | Line | Data |
---|---|---|
d42e7319 JB |
1 | # Copyright (c) 2013 Adrian Negreanu <groleo@gmail.com> |
2 | ||
3 | # This program is free software; you can redistribute it and/or modify | |
4 | # it under the terms of the GNU General Public License as published by | |
5 | # the Free Software Foundation; either version 3 of the License, or | |
6 | # (at your option) any later version. | |
7 | # | |
8 | # This program is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
13 | # You should have received a copy of the GNU General Public License | |
14 | # along with this program. If not, see <http://www.gnu.org/licenses/> | |
15 | ||
16 | import os | |
17 | import re | |
18 | import subprocess | |
19 | ||
20 | class LoadSymFiles(gdb.Command): | |
21 | """Add symbol files for files in /proc/pid/maps: load-sym-file [symbols-directory] [lib-directory]""" | |
22 | """Usage example: | |
23 | start # breakpoint 1 | |
24 | set confirm off | |
25 | b dlfcn.c:56 # breakpoint 2, android_dlopen | |
26 | commands 2 # commands to run when breakpoint 2 is hit | |
27 | source ../utils/load_sym_files.py | |
28 | load-sym-files | |
29 | continue | |
30 | end # end of commands for bkpt 2 | |
31 | """ | |
32 | def __init__(self): | |
33 | gdb.Command.__init__(self, "load-sym-files", gdb.COMMAND_FILES, gdb.COMPLETE_FILENAME, True) | |
34 | ||
35 | def invoke(self, arg, from_tty): | |
36 | arg_list = gdb.string_to_argv(arg) | |
37 | symdir = "/system/symbols" | |
38 | libdir = "/system/lib" | |
39 | ||
40 | if len(arg_list) == 1: | |
41 | symdir = arg_list[0] | |
42 | if not os.path.isdir(symdir): | |
43 | print "error: invalid symbol directory(%s)"%symdir | |
44 | print "usage: load-sym-files [symbols-dir] [lib-dir]" | |
45 | return | |
46 | ||
47 | if len(arg_list) == 2: | |
48 | libdir = arg_list[1] | |
49 | if not os.path.isdir(libdir): | |
50 | print "error: invalid library directory(%s)"%libdir | |
51 | print "usage: load-sym-files [symbols-dir] [lib-dir]" | |
52 | return | |
53 | try: | |
54 | pid = gdb.selected_inferior().pid | |
55 | except AttributeError: | |
56 | # in case gdb-version < 7.4 | |
57 | # the array can have more than one element, | |
58 | # but it's good enough when debugging test_egl | |
59 | if len(gdb.inferiors()) == 1: | |
60 | pid = gdb.inferiors()[0].pid | |
61 | else: | |
62 | print "error: no gdb support for more than 1 inferior" | |
63 | return | |
64 | ||
65 | if pid == 0: | |
66 | print "error: debugee not started yet" | |
67 | return | |
68 | ||
69 | maps = open("/proc/%d/maps"%pid,"rb") | |
70 | for line in maps: | |
71 | # b7fc9000-b7fcf000 r-xp 00000000 08:01 1311443 /system/lib/liblog.so | |
72 | m = re.match("([0-9A-Fa-f]+)-[0-9A-Fa-f]+\s+r-xp.*(%s.*)"%libdir,line) | |
73 | if not m: | |
74 | continue | |
75 | ||
76 | start_addr = int(m.group(1),16) | |
77 | lib = m.group(2) | |
78 | text_addr = 0 | |
79 | ||
80 | p = subprocess.Popen("objdump -h "+lib , shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) | |
81 | for header in p.stdout.read().split("\n"): | |
82 | #6 .text 00044ef7 00017f80 00017f80 00017f80 2**4 | |
83 | t = re.match("\s*[0-9]+\s+\.text\s+([0-9A-Fa-f]+\s+){3}([0-9A-Fa-f]+)",header) | |
84 | if t: | |
85 | text_addr = int(t.group(2),16) | |
86 | break | |
87 | symfile = symdir + lib | |
88 | if os.path.isfile(symfile): | |
89 | gdb.execute("add-symbol-file %s 0x%X" % (symfile, start_addr+text_addr)) | |
90 | ||
91 | ||
92 | LoadSymFiles() |