Wikia

CHDK Wiki

GPL:dis2gas.pl

Talk0
573pages on
this wiki
Revision as of 21:57, September 24, 2008 by Pixeldoc2000 (Talk | contribs)

#!/usr/bin/perl -w
 
# convert objdump dissassemble to gas
# ARM asm only
#
# (c) 2008 chr
# GPL V3+
 
my @lines;
while (<STDIN>) {
	push @lines, $_;
}
 
$lines[0] =~ /^([[:xdigit:]]*): /;
my $start_addr = hex($1);
$lines[-1] =~ /^([[:xdigit:]]*): /;
my $end_addr = hex($1);
 
printf("%s %s \n", $start_addr, $end_addr);
 
my @gas;
my %loc_jmp;
foreach (@lines) {
	my ($addr, $op, $line) = $_ =~ /^([[:xdigit:]]*): \t([[:xdigit:]]*) \t(.*)/;
 
	$op_n = hex($op);
 
	if ( ($op_n & 0x0e000000) == 0x0a000000) {
# any branch op
# ff8771c4: 	ebfe91c5 	bl	ff81b8e0 <_binary_dump_bin_start+0xb8e0>
# => "BL	sub_FF81B8E0 \n" // <_binary_dump_bin_start+0xb8e0>
		$line =~ s/\t([[:xdigit:]]*)/\tjump_/;
		my $goto = uc $1;
		if ((hex($goto) ge $start_addr) && (hex($goto) le $end_addr)) {
			$loc_jmp{lc $goto} = 1;
			$line =~ s/jump_/loc_$goto/;
		} else {
			$line =~ s/jump_/sub_$goto/;
		}
		$line =~ s/^(.*?\t)/uc $1/e; # uppercase op
		push @gas, "$addr\t$line";
		next;
	}
	if ($line =~ /^(ldr.*)\[pc, #.*?\(([[:xdigit:]]+)\)/) {
# ff825c38: 	e51f42f0 	ldr	r4, [pc, #-752]	; ff825950: (00001cb8) 
# => "ldr	r4,  =0x00001cb8 \n"
		$line = "$1 =0x$2";
		push @gas, "$addr\t$line";
		next;
	}
	if ($line =~ /^[add|sub]+(.*?), pc, #.*?; ([[:xdigit:]]+): (.*)/) {
# ff814db4: 	b28f00fc 	addlt	r0, pc, #252	; ff814eb8: (65536d64)  *"dmSetup"
# => "ldrlt	r0, =0xff814eb8 \n" // ; (65536d64)  *"dmSetup"
		$line = "ldr$1, =0x$2 ; $3";
		push @gas, "$addr\t$line";
		next;
	}
	push @gas, "$addr\t$line";
}
 
#print Dumper(\@gas);
foreach (@gas) {
	my ($addr, $line) = $_ =~ /^(.*?)\t(.*)/;
	if ($loc_jmp{$addr}) {
		print q|"loc_| . uc ($addr) . qq|:\\n"\n|;
		#print "loc_" . uc $addr . ":\n";
	}
	$line .= ' \n"' unless (
		$line =~ s|(<.*>)$|\\n" // $1| or
		$line =~ s|(;.*)$|\\n" // $1|
	);
 
	print qq|\t"$line\n|;
}

Around Wikia's network

Random Wiki