Fandom

CHDK Wiki

GPL:stubs2dis.pl

599pages on
this wiki
Add New Page
Talk0 Share
#!/usr/bin/perl
 
# scan chdk's stub_entry*.S for
# NSTUB(CreateController, 0xFF86A6E4)
# and add this information to a disassemble file
#
# (c) 2008 chr
# GPL V3+
#
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
 
if (@ARGV != 1) {
	print("Usage e.g.:\n cat stubs_entry.S stubs_entry_2.S | $0 dump.bin.dis > outfile\n\n");
	exit;
}
 
$dissfile = $ARGV[0];
#$stubfile = $ARGV[1];
 
#####
print STDERR "scan stub file\n";
my %nstub_names; # hash by name to eliminate doubles
 
#open(IN, "<$stubfile") or die "cannot open $stubfile: $!";
while (<STDIN>) {
	if (/^NH?STUB\((.*),.*0x([[:xdigit:]]*)/i) {
		my $addr = sprintf("%08x", hex($2));
		#$nstub{$addr} = $1;
		$nstub_names{$1} = $addr;
	}
}
close IN;
# hash by address
my %nstub = reverse %nstub_names;
 
$nstub{ff81000c} = "TEST start";
print Dumper(\%nstub);
#exit;
 
#####
print STDERR "scan diss file\n";
 
open(IN, "<$dissfile") or die "cannot read $dissfile: $!";
 
while (<IN>) {
	if ($_ eq "	...\n") { print $_; next;}
# print $_;
	my ($addr, $op, $line) = $_ =~ /^([[:xdigit:]]*): \t([[:xdigit:]]*) \t(.*)/;
	unless ($addr) {
		print $_;
		next;
	}
 
	$op_n = hex($op);
	if ( ($op_n & 0x0e000000) == 0x0a000000) {
	# any branch op
	# ff8771c4: 	ebfe91c5 	bl	ff81b8e0 <_binary_dump_bin_start+0xb8e0>
		my ($goto) = $line =~ /\t([[:xdigit:]]*)/;
		if (my $func = $nstub{$goto}) {
			$line =~ s/<.*>/<$func>/;
		}
		my $rel = hex($goto)-hex($addr);
		$rel = "+$rel" if ($rel>0);
		$line =~ s/<(.*)>/<$1 $rel>/;
	}
 
	$line = "$op \t$line";
##
## TODO: handle DEF() from stub_min.S
##
##	if (
##		($line =~ /^(.*\tldr.*\[pc, #([-\d]+).*; )/) ||
##		($line =~ /^(.*\tadd.*pc, #([-\d]+).*; )/)
##	) {
##		$line = $1;
##		my $off = hex($addr) - hex($offset) + $2 + 8;
##		my $point = sprintf("%08x", hex($addr) + $2 + 8);
##		my $value = &get_word($off);
##		$line .= "$point: ($value) ";
##		if (my $str = $nstub{$point}) {
##			$line .= qq| *"$str"|;
##		}
##		elsif (my $str = $nstub{$value}) {
##			$line .= qq| **"$str"|;
##		}
##	} 
##	# ff815e1c:	e24f0090 	sub	r0, pc, #144	; 0x90
##	elsif ($line =~ /^(.*\tsub.*pc, #([-\d]+).*; )/) {
##		$line = $1;
##		my $off = hex($addr) - hex($offset) - $2 + 8;
##		my $point = sprintf("%08x", hex($addr) - $2 + 8);
##		my $value = &get_word($off);
##		$line .= "$point: ($value) ";
##		if (my $str = $nstub{$point}) {
##			$line .= qq| *"$str"|;
##		}
##		elsif (my $str = $nstub{$value}) {
##			$line .= qq| **"$str"|;
##		}
##	}
 
	if (my $str = $nstub{$addr}) {
		print qq|\nNSTUB($str, 0x$addr):\n|;
	}
	print "$addr: \t$line\n"; 
	# progress
	print STDERR "\r0x$addr  ";
}
close IN;

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Also on Fandom

Random Wiki