| From: Martin Liska <mliska@suse.cz> |
| Subject: gcov: support GCC 12.1 and newer compilers |
| Date: Thu, 13 Oct 2022 09:40:59 +0200 |
| |
| 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: Martin Liska <mliska@suse.cz> |
| Tested-by: Peter Oberparleiter <oberpar@linux.ibm.com> |
| Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| kernel/gcov/gcc_4_7.c | 18 ++++++++++++++++-- |
| 1 file changed, 16 insertions(+), 2 deletions(-) |
| |
| --- a/kernel/gcov/gcc_4_7.c~gcov-support-gcc-121-and-newer-compilers |
| +++ a/kernel/gcov/gcc_4_7.c |
| @@ -30,6 +30,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; |
| |
| /** |
| @@ -383,12 +390,18 @@ size_t convert_to_gcda(char *buffer, str |
| 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); |
| @@ -402,7 +415,8 @@ size_t convert_to_gcda(char *buffer, str |
| /* 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, |
| _ |