summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2009-07-01 12:25:24 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2009-07-01 12:25:24 +0000
commit1176553a07a0284a8cb5b99fcf1e67a8c7ed994c (patch)
tree408bdc7d7bece9f56cd17c0432e27094dbe95e76
parent7398c2d20dca04e6240536546e09583159d0cc10 (diff)
downloadrockbox-1176553a07a0284a8cb5b99fcf1e67a8c7ed994c.tar.gz
rockbox-1176553a07a0284a8cb5b99fcf1e67a8c7ed994c.zip
utils/analysis/find_addr.pl: also add support for plugins & codecs
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21590 a1c6a512-1295-4272-9138-f99709370657
-rwxr-xr-xutils/analysis/find_addr.pl105
1 files changed, 100 insertions, 5 deletions
diff --git a/utils/analysis/find_addr.pl b/utils/analysis/find_addr.pl
index 2dcc84ab8a..dca85fdbdc 100755
--- a/utils/analysis/find_addr.pl
+++ b/utils/analysis/find_addr.pl
@@ -18,6 +18,7 @@
18# KIND, either express or implied. 18# KIND, either express or implied.
19# 19#
20use String::Scanf; 20use String::Scanf;
21use Cwd;
21 22
22sub check_boundaries 23sub check_boundaries
23{ 24{
@@ -33,15 +34,59 @@ sub check_boundaries
33 return 0; 34 return 0;
34} 35}
35 36
37sub dynamic_space
38{
39 my $space = $_[0], $space_array = $_[1], $ret;
40
41 printf "This address is in %s space, please select the %s which was used with this address:\n", $space, $space;
42 $count = 1;
43 foreach my $el (@$space_array)
44 {
45 printf " [%d]: %s\n", $count++, $el;
46 }
47
48 print "\n";
49 my $sel = -1;
50 do
51 {
52 print "Selection: ";
53 $sel = <STDIN>;
54 } while($sel <= 0 || $sel > $count - 1 || !($sel =~ /^[+-]?\d+$/));
55
56 my $file = sprintf("apps/%ss/%s", $space, @$space_array[$sel - 1]);
57 $ret{'library'} = sprintf("%s/%s", cwd(), $file);
58 open FILE, "$objdump -t $file |" or die "Can't open pipe: $!";
59 while(<FILE>)
60 {
61 chomp($_);
62 if(/^([0-9a-fA-F]+).+\s([0-9a-fA-F]{3,})\s(?:[^\s]+\s)?(.+)$/)
63 {
64 (my $addr) = sscanf("%lx", $1);
65 (my $size) = sscanf("%lx", $2);
66
67 if($lookaddr >= $addr && $lookaddr <= ($addr + $size))
68 {
69 my $diff = abs($lookaddr - $addr);
70 if(!defined($ret{'diff'}) || $diff <= $ret{'diff'})
71 {
72 $ret{'diff'} = $diff;
73 $ret{'function'} = $3;
74 }
75 }
76 }
77 }
78 close FILE;
79
80 return %ret;
81}
82
36($lookaddr) = sscanf("0x%lx", $ARGV[0]); 83($lookaddr) = sscanf("0x%lx", $ARGV[0]);
37($context_size) = $#ARGV > 0 ? $ARGV[1] : 5; 84($context_size) = $#ARGV > 0 ? $ARGV[1] : 5;
38 85
39if($lookaddr != 0) 86if($lookaddr != 0)
40{ 87{
41 # Determine the used objdump utility 88 # Determine the used objdump utility
42
43 open MAKEFILE, "<Makefile" or die "Can't open Makefile: $!"; 89 open MAKEFILE, "<Makefile" or die "Can't open Makefile: $!";
44 my $objdump;
45 while(<MAKEFILE>) 90 while(<MAKEFILE>)
46 { 91 {
47 chomp($_); 92 chomp($_);
@@ -54,8 +99,29 @@ if($lookaddr != 0)
54 } 99 }
55 close MAKEFILE; 100 close MAKEFILE;
56 101
102 # Generate a list of all codecs
103 open FINDCODECS, "find apps/codecs/ -name '*.elf' 2>&1 |" or die "Can't open pipe: $!";
104 my @codecs;
105 while(<FINDCODECS>)
106 {
107 chomp($_);
108 $_ =~ s/apps\/codecs\///;
109 push(@codecs, $_);
110 }
111 close FINDCODECS;
112 # Generate a list of all plugins
113 open FINDPLUGINS, "find apps/plugins/ -name '*.elf' 2>&1 |" or die "Can't open pipe: $!";
114 my @plugins;
115 while(<FINDPLUGINS>)
116 {
117 chomp($_);
118 $_ =~ s/apps\/plugins\///;
119 push(@plugins, $_);
120 }
121 close FINDPLUGINS;
122
57 open MAPFILE, "<rockbox.map" or die "Can't open rockbox.map: $!"; 123 open MAPFILE, "<rockbox.map" or die "Can't open rockbox.map: $!";
58 my $addr, $size, $library, $match, $prev_function; 124 my $addr, $size, $library, $match, $prev_function, $codec_addr, $plugin_addr;
59 while(<MAPFILE>) 125 while(<MAPFILE>)
60 { 126 {
61 chomp($_); 127 chomp($_);
@@ -65,6 +131,20 @@ if($lookaddr != 0)
65 $prev_function = $1; 131 $prev_function = $1;
66 } 132 }
67 133
134 if(/^\.([^\s]+)\s*(0x[0-9a-fA-F]+)/)
135 {
136 ($addr) = sscanf("0x%lx", $2);
137 if($1 eq "plugin" || $1 eq "codec")
138 {
139 $plugin_addr = $addr;
140 }
141 elsif($1 eq "codec")
142 {
143 $codec_addr = $addr;
144 }
145 }
146
147
68 if(/^.*?\s*(0x[0-9a-fA-F]+)\s*(0x[0-9a-fA-F]+)\s(.+)$/) 148 if(/^.*?\s*(0x[0-9a-fA-F]+)\s*(0x[0-9a-fA-F]+)\s(.+)$/)
69 { 149 {
70 ($addr) = sscanf("0x%lx", $1); 150 ($addr) = sscanf("0x%lx", $1);
@@ -115,6 +195,17 @@ if($lookaddr != 0)
115 } 195 }
116 close MAPFILE; 196 close MAPFILE;
117 197
198 if($lookaddr >= $codec_addr && $lookaddr < $plugin_addr)
199 {
200 # look for codec
201 %match = dynamic_space("codec", \@codecs);
202 }
203 elsif($lookaddr >= $plugin_addr)
204 {
205 # look for plugin
206 %match = dynamic_space("plugin", \@plugins);
207 }
208
118 printf "%s -> %s\n\n", $match{'library'}, $match{'function'}; 209 printf "%s -> %s\n\n", $match{'library'}, $match{'function'};
119 210
120 # Replace path/libfoo.a(bar.o) with path/libfoo.a 211 # Replace path/libfoo.a(bar.o) with path/libfoo.a
@@ -126,7 +217,7 @@ if($lookaddr != 0)
126 { 217 {
127 chomp($_); 218 chomp($_);
128 219
129 if(/^[0-9]+ \<(.+)\>:$/) 220 if(/^[0-9a-fA-F]+\s\<(.+)\>:$/)
130 { 221 {
131 $found = ($1 eq $match{'function'}); 222 $found = ($1 eq $match{'function'});
132 } 223 }
@@ -140,6 +231,10 @@ if($lookaddr != 0)
140 { 231 {
141 ($addr) = sscanf("%lx", $1); 232 ($addr) = sscanf("%lx", $1);
142 233
234 if($addr - $lookaddr > 0)
235 {
236 $addr -= $lookaddr;
237 }
143 if(abs($match{'diff'} - $addr) <= $context_size * 4) 238 if(abs($match{'diff'} - $addr) <= $context_size * 4)
144 { 239 {
145 printf "%s%s\n", ($addr == $match{'diff'} ? ">": " "), $_; 240 printf "%s%s\n", ($addr == $match{'diff'} ? ">": " "), $_;
@@ -162,7 +257,7 @@ This makes it possible to find the exact assembly instruction at the specified
162memory location (depends on Makefile, rockbox.map and the object files). 257memory location (depends on Makefile, rockbox.map and the object files).
163 258
164Usage example: 259Usage example:
165 mcuelenaere\@wim2160:~/rockbox/build2\$ ../utils/analysis/find_addr.pl 0x8001a434 3 260 mcuelenaere\@wim2160:~/rockbox/build2\$ ../utils/analysis/find_addr.pl 0x8001a434 1
166 /home/mcuelenaere/rockbox/build2/apps/screens.o -> id3_get_info 261 /home/mcuelenaere/rockbox/build2/apps/screens.o -> id3_get_info
167 262
168 23c: 00601021 move v0,v1 263 23c: 00601021 move v0,v1