Skip to content

Commit daca8d9

Browse files
committed
geninfo: Fix 'unexpected end of file' error
Use the compiler version as stored in the .gcno file to determine if the file contains function records with split checksums. This fixes the following problem that can occur when lcov is run using a gcov tool of GCC version 4.7 and above on .gcno files compiled with a version below 4.7: # lcov -c -d . -o test.info --initial [...] geninfo: ERROR: test.gcno: reached unexpected end of file Also add missing lcov version to --debug output. Signed-off-by: Peter Oberparleiter <[email protected]>
1 parent a90d50e commit daca8d9

File tree

1 file changed

+48
-13
lines changed

1 file changed

+48
-13
lines changed

bin/geninfo

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ sub read_gcno_word(*;$$);
196196
sub read_gcno_value(*$;$$);
197197
sub read_gcno_string(*$);
198198
sub read_gcno_lines_record(*$$$$$$);
199-
sub determine_gcno_split_crc($$$);
200-
sub read_gcno_function_record(*$$$$);
199+
sub determine_gcno_split_crc($$$$);
200+
sub read_gcno_function_record(*$$$$$);
201201
sub read_gcno($);
202202
sub get_gcov_capabilities();
203203
sub get_overall_line($$$$);
@@ -419,6 +419,8 @@ else
419419

420420
@data_directory = @ARGV;
421421

422+
debug("$lcov_version\n");
423+
422424
# Check for help option
423425
if ($help)
424426
{
@@ -3363,20 +3365,20 @@ sub read_gcno_lines_record(*$$$$$$)
33633365
}
33643366

33653367
#
3366-
# determine_gcno_split_crc(handle, big_endian, rec_length)
3368+
# determine_gcno_split_crc(handle, big_endian, rec_length, version)
33673369
#
33683370
# Determine if HANDLE refers to a .gcno file with a split checksum function
33693371
# record format. Return non-zero in case of split checksum format, zero
33703372
# otherwise, undef in case of read error.
33713373
#
33723374

3373-
sub determine_gcno_split_crc($$$)
3375+
sub determine_gcno_split_crc($$$$)
33743376
{
3375-
my ($handle, $big_endian, $rec_length) = @_;
3377+
my ($handle, $big_endian, $rec_length, $version) = @_;
33763378
my $strlen;
33773379
my $overlong_string;
33783380

3379-
return 1 if ($gcov_version >= $GCOV_VERSION_4_7_0);
3381+
return 1 if ($version >= $GCOV_VERSION_4_7_0);
33803382
return 1 if (is_compat($COMPAT_MODE_SPLIT_CRC));
33813383

33823384
# Heuristic:
@@ -3408,15 +3410,15 @@ sub determine_gcno_split_crc($$$)
34083410
}
34093411

34103412
#
3411-
# read_gcno_function_record(handle, graph, big_endian, rec_length)
3413+
# read_gcno_function_record(handle, graph, big_endian, rec_length, version)
34123414
#
34133415
# Read a gcno format function record from handle and add the relevant data
34143416
# to graph. Return (filename, function) on success, undef on error.
34153417
#
34163418

3417-
sub read_gcno_function_record(*$$$$)
3419+
sub read_gcno_function_record(*$$$$$)
34183420
{
3419-
my ($handle, $bb, $fileorder, $big_endian, $rec_length) = @_;
3421+
my ($handle, $bb, $fileorder, $big_endian, $rec_length, $version) = @_;
34203422
my $filename;
34213423
my $function;
34223424
my $lineno;
@@ -3428,7 +3430,8 @@ sub read_gcno_function_record(*$$$$)
34283430
# Determine if this is a function record with split checksums
34293431
if (!defined($gcno_split_crc)) {
34303432
$gcno_split_crc = determine_gcno_split_crc($handle, $big_endian,
3431-
$rec_length);
3433+
$rec_length,
3434+
$version);
34323435
return undef if (!defined($gcno_split_crc));
34333436
}
34343437
# Skip cfg checksum word in case of split checksums
@@ -3451,6 +3454,33 @@ sub read_gcno_function_record(*$$$$)
34513454
return ($filename, $function);
34523455
}
34533456

3457+
#
3458+
# map_gcno_version
3459+
#
3460+
# Map version number as found in .gcno files to the format used in geninfo.
3461+
#
3462+
3463+
sub map_gcno_version($)
3464+
{
3465+
my ($version) = @_;
3466+
my ($a, $b, $c);
3467+
my ($major, $minor);
3468+
3469+
$a = $version >> 24;
3470+
$b = $version >> 16 & 0xff;
3471+
$c = $version >> 8 & 0xff;
3472+
3473+
if ($a < ord('A')) {
3474+
$major = $a - ord('0');
3475+
$minor = ($b - ord('0')) * 10 + $c - ord('0');
3476+
} else {
3477+
$major = ($a - ord('A')) * 10 + $b - ord('0');
3478+
$minor = $c - ord('0');
3479+
}
3480+
3481+
return $major << 16 | $minor << 8;
3482+
}
3483+
34543484
#
34553485
# read_gcno(filename)
34563486
#
@@ -3481,6 +3511,7 @@ sub read_gcno($)
34813511
my $instr;
34823512
my $graph;
34833513
my $filelength;
3514+
my $version;
34843515
local *HANDLE;
34853516

34863517
open(HANDLE, "<", $gcno_filename) or goto open_error;
@@ -3497,8 +3528,12 @@ sub read_gcno($)
34973528
} else {
34983529
goto magic_error;
34993530
}
3500-
# Skip version and stamp
3501-
graph_skip(*HANDLE, 8, "version and stamp") or goto incomplete;
3531+
# Read version
3532+
$version = read_gcno_value(*HANDLE, $big_endian, "compiler version");
3533+
$version = map_gcno_version($version);
3534+
debug(sprintf("found version 0x%08x\n", $version));
3535+
# Skip stamp
3536+
graph_skip(*HANDLE, 4, "file timestamp") or goto incomplete;
35023537
while (!eof(HANDLE)) {
35033538
my $next_pos;
35043539
my $curr_pos;
@@ -3528,7 +3563,7 @@ sub read_gcno($)
35283563
if ($tag == $tag_function) {
35293564
($filename, $function) = read_gcno_function_record(
35303565
*HANDLE, $bb, $fileorder, $big_endian,
3531-
$length);
3566+
$length, $version);
35323567
goto incomplete if (!defined($function));
35333568
} elsif ($tag == $tag_lines) {
35343569
# Read lines record

0 commit comments

Comments
 (0)