GPL:stubs2dis.pl
Talk0
539pages on
this wiki
this wiki
#!/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;