A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 281 lines 8.0 kB view raw
1#!/usr/bin/env perl 2# __________ __ ___. 3# Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7# \/ \/ \/ \/ \/ 8# $Id$ 9# 10# Copyright (C) 2009 by Maurus Cuelenaere 11# 12# This program is free software; you can redistribute it and/or 13# modify it under the terms of the GNU General Public License 14# as published by the Free Software Foundation; either version 2 15# of the License, or (at your option) any later version. 16# 17# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18# KIND, either express or implied. 19# 20use String::Scanf; 21use Cwd; 22 23sub check_boundaries 24{ 25 my $fits = 0, $start = $_[0], $end = $_[0] + $_[1]; 26 foreach my $boundary (@ram_boundaries) 27 { 28 if(defined(@$boundary{'name'}) && $start >= @$boundary{'start'} && $end <= @$boundary{'end'}) 29 { 30 return 1; 31 } 32 } 33 34 return 0; 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 $prefix; 57 if($space eq 'plugin') 58 { 59 $prefix = 'apps'; 60 } 61 else 62 { 63 $prefix = 'lib/rbcodec'; 64 } 65 my $file = sprintf("%s/%ss/%s", $prefix, $space, @$space_array[$sel - 1]); 66 $ret{'library'} = sprintf("%s/%s", cwd(), $file); 67 open FILE, "$objdump -t $file |" or die "Can't open pipe: $!"; 68 while(<FILE>) 69 { 70 chomp($_); 71 if(/^([0-9a-fA-F]+).+\s([0-9a-fA-F]{3,})\s(?:[^\s]+\s)?(.+)$/) 72 { 73 (my $addr) = sscanf("%lx", $1); 74 (my $size) = sscanf("%lx", $2); 75 76 if($lookaddr >= $addr && $lookaddr <= ($addr + $size)) 77 { 78 my $diff = abs($lookaddr - $addr); 79 if(!defined($ret{'diff'}) || $diff <= $ret{'diff'}) 80 { 81 $ret{'diff'} = $diff; 82 $ret{'function'} = $3; 83 } 84 } 85 } 86 } 87 close FILE; 88 89 return %ret; 90} 91 92($lookaddr) = sscanf("0x%lx", $ARGV[0]); 93($context_size) = $#ARGV > 0 ? $ARGV[1] : 5; 94 95if($lookaddr != 0) 96{ 97 # Determine the used objdump utility 98 open MAKEFILE, "<Makefile" or die "Can't open Makefile: $!"; 99 while(<MAKEFILE>) 100 { 101 chomp($_); 102 103 if(/^export OC=(.+)$/) 104 { 105 $objdump = $1; 106 $objdump =~ s/objcopy/objdump/; 107 } 108 } 109 close MAKEFILE; 110 111 # Generate a list of all codecs 112 open FINDCODECS, "find lib/rbcodec/codecs/ -name '*.elf' 2>&1 |" or die "Can't open pipe: $!"; 113 my @codecs; 114 while(<FINDCODECS>) 115 { 116 chomp($_); 117 $_ =~ s/lib\/rbcodec\/codecs\///; 118 push(@codecs, $_); 119 } 120 close FINDCODECS; 121 # Generate a list of all plugins 122 open FINDPLUGINS, "find apps/plugins/ -name '*.elf' 2>&1 |" or die "Can't open pipe: $!"; 123 my @plugins; 124 while(<FINDPLUGINS>) 125 { 126 chomp($_); 127 $_ =~ s/apps\/plugins\///; 128 push(@plugins, $_); 129 } 130 close FINDPLUGINS; 131 132 open MAPFILE, "<rockbox.map" or die "Can't open rockbox.map: $!"; 133 my $addr, $size, $library, $match, $prev_function, $codec_addr, $plugin_addr; 134 while(<MAPFILE>) 135 { 136 chomp($_); 137 138 if(/^\s*\.text\.([^\s]+)$/) 139 { 140 $prev_function = $1; 141 } 142 143 if(/^\.([^\s]+)\s*(0x[0-9a-fA-F]+)/) 144 { 145 ($addr) = sscanf("0x%lx", $2); 146 if($1 eq "plugin") 147 { 148 $plugin_addr = $addr; 149 } 150 elsif($1 eq "codec") 151 { 152 $codec_addr = $addr; 153 } 154 } 155 156 157 if(/^.*?\s*(0x[0-9a-fA-F]+)\s*(0x[0-9a-fA-F]+)\s(.+)$/) 158 { 159 ($addr) = sscanf("0x%lx", $1); 160 ($size) = sscanf("0x%lx", $2); 161 $library = $3; 162 163 if(check_boundaries($addr, $size) != 0 164 && $lookaddr >= $addr && $lookaddr <= ($addr + $size)) 165 { 166 #printf "0x%x 0x%x %s %s\n", $addr, $size, $prev_function, $library; 167 168 my $diff = abs($lookaddr - $addr); 169 if(!defined($match{'diff'}) || $diff <= $match{'diff'}) 170 { 171 $match{'diff'} = $diff; 172 $match{'library'} = $library; 173 $match{'function'} = $prev_function; 174 } 175 } 176 } 177 elsif(/^\s*(0x[0-9a-fA-F]+)\s*([^\s]+)$/) 178 { 179 ($addr) = sscanf("0x%lx", $1); 180 my $function = $2; 181 182 if(check_boundaries($addr, 0) != 0 && $lookaddr >= $addr) 183 { 184 #printf "0x%x %s\n", $addr, $function; 185 186 my $diff = abs($lookaddr - $addr); 187 if(!defined($match{'diff'}) || $diff <= $match{'diff'}) 188 { 189 $match{'diff'} = $diff; 190 $match{'library'} = $library; 191 $match{'function'} = $function; 192 } 193 } 194 } 195 elsif(/^(.RAM) *(0x[0-9a-fA-F]+) (0x[0-9a-fA-F]+)/) 196 { 197 (my $start_addr) = sscanf("0x%lx", $2); 198 (my $addr_length) = sscanf("0x%lx", $3); 199 push(@ram_boundaries, {"name", $1, 200 "start", $start_addr, 201 "end", $start_addr + $addr_length 202 }); 203 } 204 } 205 close MAPFILE; 206 207 if($lookaddr >= $codec_addr && $lookaddr < $plugin_addr 208 && $codec_addr != 0) 209 { 210 # look for codec 211 %match = dynamic_space("codec", \@codecs); 212 } 213 elsif($lookaddr >= $plugin_addr && $plugin_addr != 0) 214 { 215 # look for plugin 216 %match = dynamic_space("plugin", \@plugins); 217 } 218 219 printf "%s -> %s\n\n", $match{'library'}, $match{'function'}; 220 221 # Replace path/libfoo.a(bar.o) with path/libfoo.a 222 $match{'library'} =~ s/\(.+\)//; 223 224 open OBJDUMP, "$objdump -S $match{'library'} 2>&1 |" or die "Can't open pipe: $!"; 225 my $found = 0, $addr; 226 while(<OBJDUMP>) 227 { 228 chomp($_); 229 230 if(/^[0-9a-fA-F]+\s\<(.+)\>:$/) 231 { 232 $found = ($1 eq $match{'function'}); 233 } 234 elsif(/Disassembly of section/) 235 { 236 $found = 0; 237 } 238 elsif($found == 1) 239 { 240 if(/^\s*([0-9a-fA-F]+):\s*[0-9a-fA-F]+\s*.+$/) 241 { 242 ($addr) = sscanf("%lx", $1); 243 244 if($addr - $lookaddr > 0) 245 { 246 $addr -= $lookaddr; 247 } 248 if(abs($match{'diff'} - $addr) <= $context_size * 4) 249 { 250 printf "%s%s\n", ($addr == $match{'diff'} ? ">": " "), $_; 251 } 252 } 253 else 254 { 255 # TODO: be able to also show source code (within context_size) 256 # printf " %s\n", $_; 257 } 258 } 259 } 260 close OBJDUMP; 261} 262else 263{ 264 print "find_addr.pl 0xABCDEF [CONTEXT_SIZE]\n\n"; 265 print <<EOF 266This makes it possible to find the exact assembly instruction at the specified 267memory location (depends on Makefile, rockbox.map and the object files). 268 269Usage example: 270 mcuelenaere\@wim2160:~/rockbox/build2\$ ../utils/analysis/find_addr.pl 0x8001a434 1 271 /home/mcuelenaere/rockbox/build2/apps/screens.o -> id3_get_info 272 273 23c: 00601021 move v0,v1 274 > 240: 80620000 lb v0,0(v1) 275 244: 0002180a movz v1,zero,v0 276 277 278Don't forget to build with -g ! 279EOF 280; 281}