Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 309c1648 authored by Martin Liska's avatar Martin Liska Committed by Greg Kroah-Hartman
Browse files

gcov: support GCC 12.1 and newer compilers

commit 977ef30a7d888eeb52fb6908f99080f33e5309a8 upstream.

Starting with GCC 12.1, the created .gcda format can't be read by gcov
tool.  There are 2 significant changes to the .gcda file format that
need to be supported:

a) [gcov: Use system IO buffering]
   (23eb66d1d46a34cb28c4acbdf8a1deb80a7c5a05) changed that all sizes in
   the format are in bytes and not in words (4B)

b) [gcov: make profile merging smarter]
   (72e0c742bd01f8e7e6dcca64042b9ad7e75979de) add a new checksum to the
   file header.

Tested with GCC 7.5, 10.4, 12.2 and the current master.

Link: https://lkml.kernel.org/r/624bda92-f307-30e9-9aaa-8cc678b2dfb2@suse.cz


Signed-off-by: default avatarMartin Liska <mliska@suse.cz>
Tested-by: default avatarPeter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: default avatarPeter Oberparleiter <oberpar@linux.ibm.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 012e3679
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -33,6 +33,13 @@

#define GCOV_TAG_FUNCTION_LENGTH	3

/* Since GCC 12.1 sizes are in BYTES and not in WORDS (4B). */
#if (__GNUC__ >= 12)
#define GCOV_UNIT_SIZE				4
#else
#define GCOV_UNIT_SIZE				1
#endif

static struct gcov_info *gcov_info_head;

/**
@@ -439,12 +446,18 @@ static size_t convert_to_gcda(char *buffer, struct gcov_info *info)
	pos += store_gcov_u32(buffer, pos, info->version);
	pos += store_gcov_u32(buffer, pos, info->stamp);

#if (__GNUC__ >= 12)
	/* Use zero as checksum of the compilation unit. */
	pos += store_gcov_u32(buffer, pos, 0);
#endif

	for (fi_idx = 0; fi_idx < info->n_functions; fi_idx++) {
		fi_ptr = info->functions[fi_idx];

		/* Function record. */
		pos += store_gcov_u32(buffer, pos, GCOV_TAG_FUNCTION);
		pos += store_gcov_u32(buffer, pos, GCOV_TAG_FUNCTION_LENGTH);
		pos += store_gcov_u32(buffer, pos,
			GCOV_TAG_FUNCTION_LENGTH * GCOV_UNIT_SIZE);
		pos += store_gcov_u32(buffer, pos, fi_ptr->ident);
		pos += store_gcov_u32(buffer, pos, fi_ptr->lineno_checksum);
		pos += store_gcov_u32(buffer, pos, fi_ptr->cfg_checksum);
@@ -458,7 +471,8 @@ static size_t convert_to_gcda(char *buffer, struct gcov_info *info)
			/* Counter record. */
			pos += store_gcov_u32(buffer, pos,
					      GCOV_TAG_FOR_COUNTER(ct_idx));
			pos += store_gcov_u32(buffer, pos, ci_ptr->num * 2);
			pos += store_gcov_u32(buffer, pos,
				ci_ptr->num * 2 * GCOV_UNIT_SIZE);

			for (cv_idx = 0; cv_idx < ci_ptr->num; cv_idx++) {
				pos += store_gcov_u64(buffer, pos,