1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#! /usr/bin/perl -w
# vim:set ft=perl ai si et ts=4 sts=4 sw=4 tw=0:
# USAGE: dump-tables.pl FILE
use strict;
@ARGV == 1 || die "\nUSAGE: dump-tables.pl FILE\n";
open FD, $ARGV[0] or die "$ARGV[0]: $!";
my ($magic,$hsize) = (read32(),read32());
my $rest = readn($hsize - 8);
my ($ssize,$flags,$version,$name) = unpack 'Nna*', $rest;
($version,$name) = split /\0/, $version;
printf "th_magic: %08X\n", $magic;
print "th_hsize: $hsize\n";
print "th_ssize: $ssize\n";
print "th_flags: $flags\n";
print "th_version: $version\n";
print "th_name: $name\n";
my $bytes = $hsize;
while(!eof FD){
dump_table();
}
sub readn { my $s; read FD, $s, shift; return $s }
sub read32 { my $n; read FD, $n, 4; return unpack 'i', pack 'i', unpack 'N',$n }
sub read16 { my $n; read FD, $n, 2; return unpack 's', pack 's', unpack 'n',$n }
sub read8 { my $n; read FD, $n, 1; return unpack 'c',$n }
sub dump_table {
my ($id,$flags,$hi,$lo) = (read16(),read16(),read32(),read32());
my $max = 40;
print "td_id: $id ($::TID{$id})\n".
"td_flags: $flags (@{[TFLAGS($flags)]})\n".
"td_hilen: $hi\n".
"td_lolen: $lo\n";
my $read = $::TFLAGS{$flags}->[1];
my $tot = $lo * ($hi?$hi:1);
$tot *=2 if $::TID{$id}eq 'YYT_ID_TRANSITION';
my @d;
for(1..$tot){
my $v = $read->();
if($max-- > 0){
push @d, $v;
}
}
print "td_data: ";
print join ', ', @d;
my $pad = pad64(tell FD);
print "\npadding: $pad\n";
while($pad-- > 0){ read8() }
return tell FD;
}
sub TFLAGS {
my @s;
my $f = shift;
foreach(keys %::TFLAGS){
if ($f & $_){
push @s, $::TFLAGS{$_}->[0]
}
}
return join '|', @s;
}
sub pad64{ return ((8-((shift)%8))%8) }
BEGIN {
%::TID = (
0x01 => 'YYT_ID_ACCEPT' ,
0x02 => 'YYT_ID_BASE' ,
0x03 => 'YYT_ID_CHK' ,
0x04 => 'YYT_ID_DEF' ,
0x05 => 'YYT_ID_EC' ,
0x06 => 'YYT_ID_META' ,
0x07 => 'YYT_ID_NUL_TRANS' ,
0x08 => 'YYT_ID_NXT' ,
0x09 => 'YYT_ID_RULE_CAN_MATCH_EOL' ,
0x0A => 'YYT_ID_START_STATE_LIST' ,
0x0B => 'YYT_ID_TRANSITION');
%::TFLAGS = (
0x01 => ['YYT_DATA8',\&read8] ,
0x02 => ['YYT_DATA16',\&read16] ,
0x04 => ['YYT_DATA32',\&read32] ,
0x08 => ['YYT_PTRANS',sub{}]);
}
1
__END__
|