tests: move tests/coverage to subsys/testsuite
This part of tests was forgotten when we move to subsys/ Fixes #13729 Signed-off-by: Wentong Wu <wentong.wu@intel.com> Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
dc96f16bcd
commit
0ef2408e26
3 changed files with 0 additions and 0 deletions
269
subsys/testsuite/coverage/coverage.c
Normal file
269
subsys/testsuite/coverage/coverage.c
Normal file
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include "coverage.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#define MALLOC_MAX_HEAP_SIZE 32768
|
||||
#define MALLOC_MIN_BLOCK_SIZE 128
|
||||
#else
|
||||
#define MALLOC_MAX_HEAP_SIZE 16384
|
||||
#define MALLOC_MIN_BLOCK_SIZE 64
|
||||
#endif
|
||||
|
||||
|
||||
K_MEM_POOL_DEFINE(gcov_heap_mem_pool,
|
||||
MALLOC_MIN_BLOCK_SIZE,
|
||||
MALLOC_MAX_HEAP_SIZE, 1, 4);
|
||||
|
||||
|
||||
static struct gcov_info *gcov_info_head;
|
||||
|
||||
/**
|
||||
* Is called by gcc-generated constructor code for each object file compiled
|
||||
* with -fprofile-arcs.
|
||||
*/
|
||||
void __gcov_init(struct gcov_info *info)
|
||||
{
|
||||
info->next = gcov_info_head;
|
||||
gcov_info_head = info;
|
||||
}
|
||||
|
||||
void __gcov_merge_add(gcov_type *counters, unsigned int n_counters)
|
||||
{
|
||||
/* Unused. */
|
||||
}
|
||||
|
||||
/**
|
||||
* buff_write_u64 - Store 64 bit data on a buffer and return the size
|
||||
*/
|
||||
|
||||
#define MASK_32BIT (0xffffffffUL)
|
||||
static inline void buff_write_u64(void *buffer, size_t *off, uint64_t v)
|
||||
{
|
||||
*((u32_t *)((u8_t *)buffer + *off) + 0) = (u32_t)(v & MASK_32BIT);
|
||||
*((u32_t *)((u8_t *)buffer + *off) + 1) = (u32_t)((v >> 32) &
|
||||
MASK_32BIT);
|
||||
*off = *off + sizeof(u64_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* buff_write_u32 - Store 32 bit data on a buffer and return the size
|
||||
*/
|
||||
static inline void buff_write_u32(void *buffer, size_t *off, u32_t v)
|
||||
{
|
||||
*((u32_t *)((u8_t *)buffer + *off)) = v;
|
||||
*off = *off + sizeof(u32_t);
|
||||
}
|
||||
|
||||
|
||||
size_t calculate_buff_size(struct gcov_info *info)
|
||||
{
|
||||
u32_t iter;
|
||||
u32_t iter_1;
|
||||
u32_t iter_2;
|
||||
/* few Fixed values at the start version, stamp and magic number. */
|
||||
u32_t size = sizeof(u32_t) * 3;
|
||||
|
||||
for (iter = 0; iter < info->n_functions; iter++) {
|
||||
/* space for TAG_FUNCTION and FUNCTION_LENGTH
|
||||
* ident
|
||||
* lineno_checksum
|
||||
* cfg_checksum
|
||||
*/
|
||||
size += (sizeof(u32_t) * 5);
|
||||
|
||||
for (iter_1 = 0; iter_1 < GCOV_COUNTERS; iter_1++) {
|
||||
if (!info->merge[iter_1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* for function counter and number of values */
|
||||
size += (sizeof(u32_t) * 2);
|
||||
|
||||
for (iter_2 = 0;
|
||||
iter_2 < info->functions[iter]->ctrs->num;
|
||||
iter_2++) {
|
||||
|
||||
/* Iter for values which is u64_t */
|
||||
size += (sizeof(u64_t));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* populate_buffer - convert from gcov data set (info) to
|
||||
* .gcda file format.
|
||||
* This buffer will now have info similar to a regular gcda
|
||||
* format.
|
||||
*/
|
||||
size_t populate_buffer(u8_t *buffer, struct gcov_info *info)
|
||||
{
|
||||
struct gcov_fn_info *functions;
|
||||
struct gcov_ctr_info *counters_per_func;
|
||||
u32_t iter_functions;
|
||||
u32_t iter_counts;
|
||||
u32_t iter_counter_values;
|
||||
size_t buffer_write_position = 0;
|
||||
|
||||
/* File header. */
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
GCOV_DATA_MAGIC);
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
info->version);
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
info->stamp);
|
||||
|
||||
for (iter_functions = 0;
|
||||
iter_functions < info->n_functions;
|
||||
iter_functions++) {
|
||||
|
||||
functions = info->functions[iter_functions];
|
||||
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
GCOV_TAG_FUNCTION);
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
GCOV_TAG_FUNCTION_LENGTH);
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
functions->ident);
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
functions->lineno_checksum);
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
functions->cfg_checksum);
|
||||
|
||||
counters_per_func = functions->ctrs;
|
||||
|
||||
for (iter_counts = 0;
|
||||
iter_counts < GCOV_COUNTERS;
|
||||
iter_counts++) {
|
||||
|
||||
if (!info->merge[iter_counts]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
GCOV_TAG_FOR_COUNTER(iter_counts));
|
||||
|
||||
buff_write_u32(buffer,
|
||||
&buffer_write_position,
|
||||
counters_per_func->num * 2);
|
||||
|
||||
for (iter_counter_values = 0;
|
||||
iter_counter_values < counters_per_func->num;
|
||||
iter_counter_values++) {
|
||||
|
||||
buff_write_u64(buffer,
|
||||
&buffer_write_position,
|
||||
counters_per_func->\
|
||||
values[iter_counter_values]);
|
||||
}
|
||||
|
||||
counters_per_func++;
|
||||
}
|
||||
}
|
||||
return buffer_write_position;
|
||||
}
|
||||
|
||||
void dump_on_console(const char *filename, char *ptr, size_t len)
|
||||
{
|
||||
u32_t iter;
|
||||
|
||||
printk("\n%c", FILE_START_INDICATOR);
|
||||
while (*filename != '\0') {
|
||||
printk("%c", *filename++);
|
||||
}
|
||||
printk("%c", GCOV_DUMP_SEPARATOR);
|
||||
|
||||
/* Data dump */
|
||||
|
||||
for (iter = 0; iter < len; iter++) {
|
||||
printk(" %02x", (u8_t)*ptr++);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves gcov coverage data and sends it over the given interface.
|
||||
*/
|
||||
void gcov_coverage_dump(void)
|
||||
{
|
||||
u8_t *buffer;
|
||||
size_t size;
|
||||
size_t written_size;
|
||||
struct gcov_info *gcov_list = gcov_info_head;
|
||||
|
||||
k_sched_lock();
|
||||
printk("\nGCOV_COVERAGE_DUMP_START");
|
||||
while (gcov_list) {
|
||||
|
||||
size = calculate_buff_size(gcov_list);
|
||||
|
||||
buffer = (u8_t *) k_mem_pool_malloc(&gcov_heap_mem_pool, size);
|
||||
if (!buffer) {
|
||||
printk("No Mem available to continue dump\n");
|
||||
goto coverage_dump_end;
|
||||
}
|
||||
|
||||
written_size = populate_buffer(buffer, gcov_list);
|
||||
if (written_size != size) {
|
||||
printk("Write Error on buff\n");
|
||||
goto coverage_dump_end;
|
||||
}
|
||||
|
||||
dump_on_console(gcov_list->filename, buffer, size);
|
||||
|
||||
k_free(buffer);
|
||||
gcov_list = gcov_list->next;
|
||||
}
|
||||
coverage_dump_end:
|
||||
printk("\nGCOV_COVERAGE_DUMP_END\n");
|
||||
k_sched_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the gcov by calling the required constructors */
|
||||
void gcov_static_init(void)
|
||||
{
|
||||
extern u32_t __init_array_start, __init_array_end;
|
||||
u32_t func_pointer_start = (u32_t) &__init_array_start;
|
||||
u32_t func_pointer_end = (u32_t) &__init_array_end;
|
||||
|
||||
while (func_pointer_start < func_pointer_end) {
|
||||
void (**p)(void);
|
||||
/* get function pointer */
|
||||
p = (void (**)(void)) func_pointer_start;
|
||||
(*p)();
|
||||
func_pointer_start += sizeof(p);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue