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
|
#!/usr/bin/perl
#
# checkov.pl
#
# Check NASM map output for overflow
#
# This assumes that a section for which start != vstart, both
# ranges need to be checked for overflow (true for SYSLINUX)
#
($in, $target) = @ARGV;
sub overlap($$$$) {
my($s1,$e1,$s2,$e2) = @_;
return 1 if ( $s2 < $e1 && $e2 > $s1 );
return 1 if ( $s1 < $e2 && $e1 > $s2 );
return 0;
}
open(IN, '<', $in) or die "$0: Cannot open input file: $in\n";
$section = undef;
while ( $line = <IN> ) {
if ( $line =~ /^-/ ) {
if ( $line =~ /^\-\-\-\- Section (\S+) / ) {
$section = $1;
} else {
$section = undef;
}
} elsif ( defined($section) ) {
if ( $line =~ /^length\:\s*(\S+)/ ) {
$length{$section} = hex $1;
} elsif ( $line =~ /^start\:\s*(\S+)/ ) {
$start{$section} = hex $1;
} elsif ( $line =~ /^vstart\:\s*(\S+)/ ) {
$vstart{$section} = hex $1;
}
}
}
close(IN);
$err = 0;
foreach $s ( keys(%start) ) {
$sstart = $start{$s};
$svstart = $vstart{$s};
$send = $sstart + $length{$s};
$svend = $svstart + $length{$s};
if ( $send > 0x10000 || $svend > 0x10000 ) {
print STDERR "$target: 16-bit overflow on section $s\n";
$err++;
}
foreach $o ( keys(%start) ) {
next if ( $s ge $o );
$ostart = $start{$o};
$ovstart = $vstart{$o};
$oend = $ostart + $length{$o};
$ovend = $ovstart + $length{$o};
if ( overlap($sstart, $send, $ostart, $oend) ||
overlap($svstart, $svend, $ostart, $oend) ||
overlap($sstart, $send, $ovstart, $ovend) ||
overlap($svstart, $svend, $ovstart, $ovend) ) {
print STDERR "$target: section $s overlaps section $o\n";
$err++;
}
}
}
if ( $err ) {
unlink($target);
exit(1);
} else {
exit(0);
}
|