#!/usr/bin/perl -sw #RE tool, decodes hex into bitfield descriptions {pos,len} # supports disjoint bitfields # supports mixed 64bit and 32bit (in envydis's endianness) hex words # modes: and, or, xor (mask, diff) #Examples: # find a diff between two OPs: # ./bftool -op=xor 8540dc00001c0002 8540dc00001c3c02 # or ./bftool -op=xor 8540dc00001c0002 001c3c02 8540dc00 # or ./bftool -op=xor 001c0002 8540dc00 001c3c02 8540dc00 # > x: U8{0x8540dc00001c0002} U4{0x001c0002,0x8540dc00} # y: U8{0x8540dc00001c3c02} U4{0x001c3c02,0x8540dc00} # z: U8{0x0000000000003c00} U4{0x00003c00,0x00000000} # {pos,len} = {10,4} = {0xa,4} # find a match against a mask: # ./bftool -op=and 3fc0000000000000 8540dc00001c0002 # or ./bftool -op=and 3fc0000000000000 001c0002 8540dc00 # ... # U8{0x0540000000000000} U4{0x00000000,0x05400000} # 54,1 # 56,1 # 58,1 use Data::Dumper; no warnings "portable"; my $op = $op || "nop"; sub readhex{ my $A = shift; my $x = shift(@$A); return undef if not defined($x); return hex($x) if(length($x)>8 or scalar(@$A)==0 or length($A->[0])>8); my $y = shift(@$A); return hex($x)|hex($y) << 32; } my $x = readhex(\@ARGV) || undef; my $y = readhex(\@ARGV) || undef; my $z = 0; if($op eq "nop"){ $z = $x; } elsif($op eq "and"){ $z = $x & $y; } elsif($op eq "xor"){ $z = $x ^ $y; } elsif($op eq "or"){ $z = $x | $y; } print sprintf("x: U8{0x%016x} U4{0x%08x,0x%08x}\n",$x,$x&0xFFFFFFFF,($x>>32)&0xFFFFFFFF); print sprintf("y: U8{0x%016x} U4{0x%08x,0x%08x}\n",$y,$y&0xFFFFFFFF,($y>>32)&0xFFFFFFFF); print sprintf("z: U8{0x%016x} U4{0x%08x,0x%08x}\n",$z,$z&0xFFFFFFFF,($z>>32)&0xFFFFFFFF); my $pos=0; while($z!=0){ while(($z&0x1) eq 0){ $pos++; $z = $z >> 1; } my $len=0; while(($z&0x1) eq 1){ $len++; $z = $z >> 1; } print sprintf("{pos,len} = {%d,%d} = {0x%x,%d}\n",$pos,$len,$pos,$len); $pos+=$len; }