From 77986382df4942bbee87a254355832515073de78 Mon Sep 17 00:00:00 2001 From: Enjia Mai Date: Wed, 21 Sep 2022 17:26:25 +0800 Subject: [PATCH] tests: framework: fix code coverage report on zephyr-sdk-0.15 The GCC/GCOV version over 12 has slight format change of the gcno and gcda. Make some adaption in the gcov dump function to fix the code coverage report. Mainly two places change: 1. Added the checksum in the struct gcov_info. This fix the crash in qemu_x86, and mps2_an385 when run with --coverage. 2. Adjust the GCOV_TAG_FUNCTION_LENGTH accroding to gcov-io.h. It's length unit is caculated by bytes now. Fixes #50255. Fixes #50257. Signed-off-by: Enjia Mai --- subsys/testsuite/coverage/coverage.c | 22 +++++++++++++++++++++- subsys/testsuite/coverage/coverage.h | 22 +++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/subsys/testsuite/coverage/coverage.c b/subsys/testsuite/coverage/coverage.c index 739251bc9bc..652500097d5 100644 --- a/subsys/testsuite/coverage/coverage.c +++ b/subsys/testsuite/coverage/coverage.c @@ -73,8 +73,15 @@ size_t calculate_buff_size(struct gcov_info *info) uint32_t iter; uint32_t iter_1; uint32_t iter_2; - /* few Fixed values at the start version, stamp and magic number. */ + + /* Few fixed values at the start: magic number, + * version, stamp, and checksum. + */ +#ifdef GCOV_12_FORMAT + uint32_t size = sizeof(uint32_t) * 4; +#else uint32_t size = sizeof(uint32_t) * 3; +#endif for (iter = 0U; iter < info->n_functions; iter++) { /* space for TAG_FUNCTION and FUNCTION_LENGTH @@ -137,6 +144,12 @@ size_t populate_buffer(uint8_t *buffer, struct gcov_info *info) &buffer_write_position, info->stamp); +#ifdef GCOV_12_FORMAT + buff_write_u32(buffer, + &buffer_write_position, + info->checksum); +#endif + for (iter_functions = 0U; iter_functions < info->n_functions; iter_functions++) { @@ -178,9 +191,16 @@ size_t populate_buffer(uint8_t *buffer, struct gcov_info *info) &buffer_write_position, GCOV_TAG_FOR_COUNTER(iter_counts)); +#ifdef GCOV_12_FORMAT + /* GCOV 12 counts the length by bytes */ + buff_write_u32(buffer, + &buffer_write_position, + counters_per_func->num * 2U * 4); +#else buff_write_u32(buffer, &buffer_write_position, counters_per_func->num * 2U); +#endif for (iter_counter_values = 0U; iter_counter_values < counters_per_func->num; diff --git a/subsys/testsuite/coverage/coverage.h b/subsys/testsuite/coverage/coverage.h index af4a125b0b3..395d03075ca 100644 --- a/subsys/testsuite/coverage/coverage.h +++ b/subsys/testsuite/coverage/coverage.h @@ -38,9 +38,26 @@ #define GCOV_COUNTERS 10U #endif +/* The GCOV 12 gcno/gcda format has slight change, + * Please refer to gcov-io.h in the GCC 12 for + * more details. + * + * Following GCC commits introduced these changes: + * gcc-mirror/gcc@23eb66d + * gcc-mirror/gcc@72e0c74 + */ +#if (__GNUC__ >= 12) +#define GCOV_12_FORMAT +#endif + typedef uint64_t gcov_type; +#ifdef GCOV_12_FORMAT +#define GCOV_TAG_FUNCTION_LENGTH 12 +#else #define GCOV_TAG_FUNCTION_LENGTH 3 +#endif + #define GCOV_DATA_MAGIC (0x67636461) #define GCOV_TAG_FUNCTION (0x01000000) #define GCOV_TAG_COUNTER_BASE (0x01a10000) @@ -77,7 +94,7 @@ struct gcov_fn_info { unsigned int ident; /* unique ident of function */ unsigned int lineno_checksum; /* function lineno_checksum */ unsigned int cfg_checksum; /* function cfg checksum */ - struct gcov_ctr_info ctrs[0]; /* instrumented counters */ + struct gcov_ctr_info ctrs[1]; /* instrumented counters */ }; /** Profiling data per object file @@ -89,6 +106,9 @@ struct gcov_info { unsigned int version; /* Gcov version (same as GCC version) */ struct gcov_info *next; /* List head for a singly-linked list */ unsigned int stamp; /* Uniquifying time stamp */ +#ifdef GCOV_12_FORMAT + unsigned int checksum; /* unique object checksum */ +#endif const char *filename; /* Name of the associated gcda data file */ /* merge functions, null for unused*/ void (*merge[GCOV_COUNTERS])(gcov_type *, unsigned int);