|
From: Peter O. <obe...@us...> - 2012-07-04 16:06:12
|
Update of /cvsroot/ltp/utils/analysis/lcov/bin
In directory vz-cvs-4.sog:/tmp/cvs-serv25641
Modified Files:
geninfo
Log Message:
geninfo: enable auto-detection of gcc-4.7 function record format
gcc-4.7 introduced a modified function record format. This format
is in use by android toolchains and has also been ported to some
pre-4.7 versions of gcc. Introduce a heuristic-based auto-detection
to correctly handle .gcno files in these cases.
Index: geninfo
===================================================================
RCS file: /cvsroot/ltp/utils/analysis/lcov/bin/geninfo,v
retrieving revision 1.97
retrieving revision 1.98
diff -C2 -d -r1.97 -r1.98
*** geninfo 8 Jun 2012 14:19:49 -0000 1.97
--- geninfo 4 Jul 2012 16:06:10 -0000 1.98
***************
*** 117,121 ****
$COMPAT_FLAG_LIBTOOL => $COMPAT_VALUE_ON,
$COMPAT_FLAG_HAMMER => $COMPAT_VALUE_OFF,
! $COMPAT_FLAG_ANDROID_4_4_0 => $COMPAT_VALUE_OFF,
);
--- 117,121 ----
$COMPAT_FLAG_LIBTOOL => $COMPAT_VALUE_ON,
$COMPAT_FLAG_HAMMER => $COMPAT_VALUE_OFF,
! $COMPAT_FLAG_ANDROID_4_4_0 => $COMPAT_VALUE_AUTO,
);
***************
*** 124,127 ****
--- 124,128 ----
our %COMPAT_FLAG_AUTO = (
$COMPAT_FLAG_HAMMER => \&compat_hammer_autodetect,
+ $COMPAT_FLAG_ANDROID_4_4_0 => 1,
);
***************
*** 158,162 ****
sub graph_error($$);
sub graph_expect($);
! sub graph_read(*$;$);
sub graph_skip(*$;$);
sub sort_uniq(@);
--- 159,163 ----
sub graph_error($$);
sub graph_expect($);
! sub graph_read(*$;$$);
sub graph_skip(*$;$);
sub sort_uniq(@);
***************
*** 175,183 ****
sub read_bbg_lines_record(*$$$$$$);
sub read_bbg($$);
! sub read_gcno_word(*;$);
! sub read_gcno_value(*$;$);
sub read_gcno_string(*$);
sub read_gcno_lines_record(*$$$$$$$);
! sub read_gcno_function_record(*$$$$);
sub read_gcno($$);
sub get_gcov_capabilities();
--- 176,184 ----
sub read_bbg_lines_record(*$$$$$$);
sub read_bbg($$);
! sub read_gcno_word(*;$$);
! sub read_gcno_value(*$;$$);
sub read_gcno_string(*$);
sub read_gcno_lines_record(*$$$$$$$);
! sub read_gcno_function_record(*$$$$$);
sub read_gcno($$);
sub get_gcov_capabilities();
***************
*** 193,196 ****
--- 194,198 ----
sub parse_compat_flags($);
sub is_compat($);
+ sub is_compat_auto($);
***************
*** 2316,2339 ****
#
! # graph_read(handle, bytes[, description])
#
# Read and return the specified number of bytes from handle. Return undef
! # if the number of bytes could not be read.
#
! sub graph_read(*$;$)
{
! my ($handle, $length, $desc) = @_;
my $data;
my $result;
graph_expect($desc);
$result = read($handle, $data, $length);
if ($debug) {
my $ascii = "";
my $hex = "";
my $i;
! print(STDERR "DEBUG: read($length)=$result: ");
for ($i = 0; $i < length($data); $i++) {
my $c = substr($data, $i, 1);;
--- 2318,2351 ----
#
! # graph_read(handle, bytes[, description, peek])
#
# Read and return the specified number of bytes from handle. Return undef
! # if the number of bytes could not be read. If PEEK is non-zero, reset
! # file position after read.
#
! sub graph_read(*$;$$)
{
! my ($handle, $length, $desc, $peek) = @_;
my $data;
my $result;
+ my $pos;
graph_expect($desc);
+ if ($peek) {
+ $pos = tell($handle);
+ if ($pos == -1) {
+ warn("Could not get current file position: $!\n");
+ return undef;
+ }
+ }
$result = read($handle, $data, $length);
if ($debug) {
+ my $op = $peek ? "peek" : "read";
my $ascii = "";
my $hex = "";
my $i;
! print(STDERR "DEBUG: $op($length)=$result: ");
for ($i = 0; $i < length($data); $i++) {
my $c = substr($data, $i, 1);;
***************
*** 2350,2353 ****
--- 2362,2371 ----
print(STDERR "\n");
}
+ if ($peek) {
+ if (!seek($handle, $pos, 0)) {
+ warn("Could not set file position: $!\n");
+ return undef;
+ }
+ }
if ($result != $length) {
return undef;
***************
*** 2900,2928 ****
#
! # read_gcno_word(handle[, description])
#
# Read and return a word in .gcno format.
#
! sub read_gcno_word(*;$)
{
! my ($handle, $desc) = @_;
! return graph_read($handle, 4, $desc);
}
#
! # read_gcno_value(handle, big_endian[, description])
#
# Read a word in .gcno format from handle and return its integer value
! # according to the specified endianness.
#
! sub read_gcno_value(*$;$)
{
! my ($handle, $big_endian, $desc) = @_;
my $word;
! $word = read_gcno_word($handle, $desc);
return undef if (!defined($word));
if ($big_endian) {
--- 2918,2948 ----
#
! # read_gcno_word(handle[, description, peek])
#
# Read and return a word in .gcno format.
#
! sub read_gcno_word(*;$$)
{
! my ($handle, $desc, $peek) = @_;
! return graph_read($handle, 4, $desc, $peek);
}
#
! # read_gcno_value(handle, big_endian[, description, peek])
#
# Read a word in .gcno format from handle and return its integer value
! # according to the specified endianness. If PEEK is non-zero, reset file
! # position after read.
#
! sub read_gcno_value(*$;$$)
{
! my ($handle, $big_endian, $desc, $peek) = @_;
my $word;
+ my $pos;
! $word = read_gcno_word($handle, $desc, $peek);
return undef if (!defined($word));
if ($big_endian) {
***************
*** 3008,3012 ****
#
! # read_gcno_function_record(handle, graph, base, big_endian)
#
# Read a gcno format function record from handle and add the relevant data
--- 3028,3032 ----
#
! # read_gcno_function_record(handle, graph, base, big_endian, rec_length)
#
# Read a gcno format function record from handle and add the relevant data
***************
*** 3014,3033 ****
#
! sub read_gcno_function_record(*$$$$)
{
! my ($handle, $bb, $fileorder, $base, $big_endian) = @_;
my $filename;
my $function;
my $lineno;
my $lines;
graph_expect("function record");
# Skip ident and checksum
graph_skip($handle, 8, "function ident and checksum") or return undef;
! if (is_compat($COMPAT_FLAG_ANDROID_4_4_0) ||
! ($gcov_version >= $GCOV_VERSION_4_7_0)) {
! # Skip extra checksum added by android 4.4.0 / gcc >= 4.7
! # toolchains.
! graph_skip($handle, 4, "function extra checksum");
}
# Read function name
--- 3034,3080 ----
#
! sub read_gcno_function_record(*$$$$$)
{
! my ($handle, $bb, $fileorder, $base, $big_endian, $rec_length) = @_;
my $filename;
my $function;
my $lineno;
my $lines;
+ my $is_4_7;
graph_expect("function record");
# Skip ident and checksum
graph_skip($handle, 8, "function ident and checksum") or return undef;
! # Determine if this is a gcc 4.7 format function record
! if ($gcov_version >= $GCOV_VERSION_4_7_0) {
! $is_4_7 = 1;
! } elsif (is_compat($COMPAT_FLAG_ANDROID_4_4_0)) {
! $is_4_7 = 1;
! } elsif (is_compat_auto($COMPAT_FLAG_ANDROID_4_4_0)) {
! my $strlen = read_gcno_value($handle, $big_endian, undef, 1);
!
! return undef if (!defined($strlen));
!
! # Heuristic:
! # - pre-gcc 4.7
! # This is the function name length / 4 which should be
! # less than the remaining record length
! # - gcc 4.7
! # This is a checksum, likely with high-order bits set,
! # resulting in a large number
! if ($strlen * 4 > $rec_length - 12) {
! if ($debug) {
! print(STDERR "DEBUG: found overlong string ".
! "length - assuming gcc 4.7 format\n");
! }
! $is_4_7 = 1;
! } elsif ($debug) {
! print(STDERR "DEBUG: found strlen=".($strlen * 4).
! " and rec_length=".($rec_length - 12)."\n");
! }
! }
! # Skip cfg checksum word in case of gcc 4.7 format function record
! if ($is_4_7) {
! graph_skip($handle, 4, "function cfg checksum");
}
# Read function name
***************
*** 3117,3121 ****
if ($tag == $tag_function) {
($filename, $function) = read_gcno_function_record(
! *HANDLE, $bb, $fileorder, $base, $big_endian);
goto incomplete if (!defined($function));
} elsif ($tag == $tag_lines) {
--- 3164,3169 ----
if ($tag == $tag_function) {
($filename, $function) = read_gcno_function_record(
! *HANDLE, $bb, $fileorder, $base, $big_endian,
! $length);
goto incomplete if (!defined($function));
} elsif ($tag == $tag_lines) {
***************
*** 3331,3345 ****
"setting '$name' available!\n");
}
! $value = &$autodetect();
! $compat_value{$flag} = $value;
! $is_autodetect = " (autodetected)";
}
if ($specified{$flag}) {
if ($value == $COMPAT_VALUE_ON) {
info("Enabling compatibility setting ".
"'$name'$is_autodetect\n");
! } else {
info("Disabling compatibility setting ".
"'$name'$is_autodetect\n");
}
}
--- 3379,3401 ----
"setting '$name' available!\n");
}
!
! if (ref($autodetect) eq "CODE") {
! $value = &$autodetect();
! $compat_value{$flag} = $value;
! $is_autodetect = " (auto-detected)";
! }
}
+
if ($specified{$flag}) {
if ($value == $COMPAT_VALUE_ON) {
info("Enabling compatibility setting ".
"'$name'$is_autodetect\n");
! } elsif ($value == $COMPAT_VALUE_OFF) {
info("Disabling compatibility setting ".
"'$name'$is_autodetect\n");
+ } else {
+ info("Using delayed auto-detection for ".
+ "compatibility setting ".
+ "'$name'\n");
}
}
***************
*** 3352,3356 ****
$gcov_version_string =~ /mandrake/i && $gcov_version == 0x30302)
{
! info("Autodetected compatibility mode for GCC 3.3 (hammer)\n");
return $COMPAT_VALUE_ON;
}
--- 3408,3412 ----
$gcov_version_string =~ /mandrake/i && $gcov_version == 0x30302)
{
! info("Auto-detected compatibility mode for GCC 3.3 (hammer)\n");
return $COMPAT_VALUE_ON;
}
***************
*** 3371,3372 ****
--- 3427,3442 ----
return 0;
}
+
+ #
+ # is_compat_auto(flag)
+ #
+ # Return non-zero if compatibility setting for FLAG is set to auto-detect.
+ #
+
+ sub is_compat_auto($)
+ {
+ my ($flag) = @_;
+
+ return 1 if ($compat_value{$flag} == $COMPAT_VALUE_AUTO);
+ return 0;
+ }
|