codeblockparser
#!/usr/bin/perl
use Compress::Zlib;
sub decodereloc {
my ($reltype, $relop) = @_;
if($reltype == 2)
{
return "baseaddr + $relop";
}
elsif($reltype == 9)
{
return "$relop";
}
elsif($reltype == 0x80)
{
return "imp_$relop";
}
elsif($reltype == 0x81)
{
return "__alloca_probe - . - 4";
}
elsif($reltype == 0x84)
{
return "__aulldiv - . - 4";
}
elsif($reltype == 0x85)
{
return "_ftol - . - 4";
}
elsif($reltype == 0x86)
{
return "__allmul - . - 4";
}
else
{
return "RELOC($reltype,$relop)";
}
}
undef $/;
$codeblock = <>;
$header = substr($codeblock,0,0x60);
($name, $zip, $ofs1, $initproc, $ofs2, $len2, $relocofs, $reloclen) =
unpack("x12x4x46Z8xCVVVVVV", $header);
if($zip)
{
$codeblock = $header . uncompress(substr($codeblock, 0x60));
}
$relocs = substr($codeblock,$relocofs, $reloclen);
@relocs = ();
while(($reloc = substr($relocs,0,8,"")) ne "")
{
my ($typeofs,$operand) = unpack("VV", $reloc);
push @relocs,[$typeofs >> 8, $typeofs & 0xFF, $operand];
}
@relocs = sort { $a->[0] <=> $b->[0] } @relocs;
($reladdr,$reltype,$relop) = @{shift @relocs};
$skip = 0;
print "# OCM module $name\n.text\nbaseaddr:\n";
for $i (0..(length $codeblock) - 1)
{
if($skip)
{
$skip--;
next;
}
if(defined($reladdr) && $i == $reladdr)
{
$skip = 3;
print "\t.long ".decodereloc($reltype,$relop)."\n";
($reladdr,$reltype,$relop) = @{shift @relocs};
next;
}
if($i == $initproc)
{
print "initproc:\n.global initproc\n";
}
printf "\t.byte 0x%02x\n", unpack("x${i}C",$codeblock);
}
codeblockparser.txt · Last modified: 2009/04/29 10:27 by megadiscman
