#!/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); }