From e8f75ede181858c30a7b1d3955d545899e1548be Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Sun, 28 Jun 2009 18:51:38 +0000 Subject: Add an utility to easily find the assembled instructions at a specific memory location in a Rockbox binary git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21548 a1c6a512-1295-4272-9138-f99709370657 --- utils/analysis/find_addr.pl | 176 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100755 utils/analysis/find_addr.pl (limited to 'utils/analysis') diff --git a/utils/analysis/find_addr.pl b/utils/analysis/find_addr.pl new file mode 100755 index 0000000000..2dcc84ab8a --- /dev/null +++ b/utils/analysis/find_addr.pl @@ -0,0 +1,176 @@ +#!/usr/bin/env perl +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# +# Copyright (C) 2009 by Maurus Cuelenaere +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +use String::Scanf; + +sub check_boundaries +{ + my $fits = 0, $start = $_[0], $end = $_[0] + $_[1]; + foreach my $boundary (@ram_boundaries) + { + if(defined(@$boundary{'name'}) && $start >= @$boundary{'start'} && $end <= @$boundary{'end'}) + { + return 1; + } + } + + return 0; +} + +($lookaddr) = sscanf("0x%lx", $ARGV[0]); +($context_size) = $#ARGV > 0 ? $ARGV[1] : 5; + +if($lookaddr != 0) +{ + # Determine the used objdump utility + + open MAKEFILE, ") + { + chomp($_); + + if(/^export OC=(.+)$/) + { + $objdump = $1; + $objdump =~ s/objcopy/objdump/; + } + } + close MAKEFILE; + + open MAPFILE, ") + { + chomp($_); + + if(/^\s*\.text\.([^\s]+)$/) + { + $prev_function = $1; + } + + if(/^.*?\s*(0x[0-9a-fA-F]+)\s*(0x[0-9a-fA-F]+)\s(.+)$/) + { + ($addr) = sscanf("0x%lx", $1); + ($size) = sscanf("0x%lx", $2); + $library = $3; + + if(check_boundaries($addr, $size) != 0 + && $lookaddr >= $addr && $lookaddr <= ($addr + $size)) + { + #printf "0x%x 0x%x %s %s\n", $addr, $size, $prev_function, $library; + + my $diff = abs($lookaddr - $addr); + if(!defined($match{'diff'}) || $diff <= $match{'diff'}) + { + $match{'diff'} = $diff; + $match{'library'} = $library; + $match{'function'} = $prev_function; + } + } + } + elsif(/^\s*(0x[0-9a-fA-F]+)\s*([^\s]+)$/) + { + ($addr) = sscanf("0x%lx", $1); + my $function = $2; + + if(check_boundaries($addr, 0) != 0 && $lookaddr >= $addr) + { + #printf "0x%x %s\n", $addr, $function; + + my $diff = abs($lookaddr - $addr); + if(!defined($match{'diff'}) || $diff <= $match{'diff'}) + { + $match{'diff'} = $diff; + $match{'library'} = $library; + $match{'function'} = $function; + } + } + } + elsif(/^(.RAM) *(0x[0-9a-fA-F]+) (0x[0-9a-fA-F]+)/) + { + (my $start_addr) = sscanf("0x%lx", $2); + (my $addr_length) = sscanf("0x%lx", $3); + push(@ram_boundaries, {"name", $1, + "start", $start_addr, + "end", $start_addr + $addr_length + }); + } + } + close MAPFILE; + + printf "%s -> %s\n\n", $match{'library'}, $match{'function'}; + + # Replace path/libfoo.a(bar.o) with path/libfoo.a + $match{'library'} =~ s/\(.+\)//; + + open OBJDUMP, "$objdump -S $match{'library'} 2>&1 |" or die "Can't open pipe: $!"; + my $found = 0, $addr; + while() + { + chomp($_); + + if(/^[0-9]+ \<(.+)\>:$/) + { + $found = ($1 eq $match{'function'}); + } + elsif(/Disassembly of section/) + { + $found = 0; + } + elsif($found == 1) + { + if(/^\s*([0-9a-fA-F]+):\s*[0-9a-fA-F]+\s*.+$/) + { + ($addr) = sscanf("%lx", $1); + + if(abs($match{'diff'} - $addr) <= $context_size * 4) + { + printf "%s%s\n", ($addr == $match{'diff'} ? ">": " "), $_; + } + } + else + { + # TODO: be able to also show source code (within context_size) + # printf " %s\n", $_; + } + } + } + close OBJDUMP; +} +else +{ + print "find_addr.pl 0xABCDEF [CONTEXT_SIZE]\n\n"; + print < id3_get_info + + 23c: 00601021 move v0,v1 + > 240: 80620000 lb v0,0(v1) + 244: 0002180a movz v1,zero,v0 + + +Don't forget to build with -g ! +EOF +; +} \ No newline at end of file -- cgit