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);