User Tools

Site Tools


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 12:27 by megadiscman