diff --git a/libs/libbuiltin/Kconfig b/libs/libbuiltin/Kconfig index 4d8c581ce4fbe..6a0ad983ffa76 100644 --- a/libs/libbuiltin/Kconfig +++ b/libs/libbuiltin/Kconfig @@ -101,6 +101,40 @@ config COVERAGE_ALL -fcoverage-mapping' parameter to all module. The data can then be printed nsh run "gcov dump -d /xxx/xxx" +choice + prompt "Code coverage data output" + default COVERAGE_DUMP_FILE + ---help--- + Select the code coverage data output method + +config COVERAGE_DUMP_FILE + ---help--- + Save the code coverage results by writing them to a file + +config COVERAGE_DUMP_MEMORY + bool "Dump code coverage data directly to memory" + depends on COVERAGE_MINI + ---help--- + The data output of code coverage detection is written directly + to the memory instead of writing to the file in the standard way. + +endchoice + +if COVERAGE_DUMP_MEMORY + +config COVERAGE_DUMP_MEMORY_ADDR + hex "Dump code coverage data memory address" + ---help--- + The address set will be used to store code coverage data. + Please ensure that the size is large enough. + +config COVERAGE_DUMP_MEMORY_SIZE + int "Dump code coverage data memory size" + ---help--- + The size set will be used to store code coverage data. + Please ensure that the size is large enough. + +endif config PROFILE_ALL bool "Enable gprof call graph for all modules" diff --git a/libs/libbuiltin/compiler-rt/coverage.c b/libs/libbuiltin/compiler-rt/coverage.c index df85b49a0edec..d9e2ae6488622 100644 --- a/libs/libbuiltin/compiler-rt/coverage.c +++ b/libs/libbuiltin/compiler-rt/coverage.c @@ -33,6 +33,7 @@ #include #include +#include /**************************************************************************** * Pre-processor Definitions @@ -225,14 +226,9 @@ void __llvm_profile_register_names_function(void *names_start, * llvm-prof. See the clang profiling documentation for details. */ -void __llvm_profile_dump(const char *path) +void __llvm_profile_dump(lib_puts_t puts, void *handle) { - int fd; - int ret; - - /* Header: __llvm_profile_header from InstrProfData.inc */ - - const char *filename = path; + const char c = '\0'; /* Calculate size of sections. */ @@ -266,61 +262,55 @@ void __llvm_profile_dump(const char *path) hdr.names_delta = (uintptr_t)names_begin; hdr.value_kind_last = IPVK_LAST; - fd = _NX_OPEN(filename, O_WRONLY | O_CREAT); - if (fd < 0) + puts(handle, &hdr, sizeof(hdr)); + puts(handle, data_begin, sizeof(__llvm_profile_data) * num_data); + puts(handle, counters_begin, sizeof(uint64_t) * num_counters); + puts(handle, names_begin, names_size); + + for (; padding_bytes_after_names != 0; --padding_bytes_after_names) { - _NX_SETERRNO(fd); - return; + puts(handle, &c, 1); } +} - /* Header */ +void __gcov_dump(void) +{ - ret = _NX_WRITE(fd, &hdr, sizeof(hdr)); - if (ret != sizeof(hdr)) - { - _NX_SETERRNO(ret); - goto exit; - } +#ifdef CONFIG_COVERAGE_DUMP_MEMORY - /* Data */ + struct lib_memoutstream_s stream; - ret = _NX_WRITE(fd, data_begin, sizeof(__llvm_profile_data) * num_data); - if (ret != sizeof(__llvm_profile_data) * num_data) - { - _NX_SETERRNO(ret); - goto exit; - } + lib_memoutstream(&stream, + CONFIG_COVERAGE_DUMP_MEMORY_ADDR, + CONFIG_COVERAGE_DUMP_MEMORY_SIZE); - /* Counters */ + __llvm_profile_dump(stream.puts, &stream); - ret = _NX_WRITE(fd, counters_begin, sizeof(uint64_t) * num_counters); - if (ret != sizeof(uint64_t) * num_counters) - { - _NX_SETERRNO(ret); - goto exit; - } +#elif defined (CONFIG_COVERAGE_DUMP_FILE) - /* Names */ + struct lib_rawoutstream_s stream; + char *path; + int fd; - ret = _NX_WRITE(fd, names_begin, names_size); - if (ret != names_size) + path = getenv("GCOV_PREFIX"); + fd = _NX_OPEN(path, O_WRONLY | O_CREAT); + if (fd < 0) { - _NX_SETERRNO(ret); - goto exit; + _NX_SETERRNO(fd); + return; } - /* Padding */ + lib_rawoutstream(&stream, fd); - for (; padding_bytes_after_names != 0; --padding_bytes_after_names) - { - ret = _NX_WRITE(fd, "\0", 1); - if (ret != 1) - { - _NX_SETERRNO(ret); - break; - } - } + __llvm_profile_dump(stream.common.puts, &stream); -exit: _NX_CLOSE(fd); + +#endif + +} + +void __gcov_reset(void) +{ + }