Skip to content

Commit

Permalink
clang/gcov: Supports saving data by dumping it directly into memory
Browse files Browse the repository at this point in the history
Supports data storage for code coverage detection without a file system
Compile "boards/arm/mps/mps3-an547/configs/gcov", find the module that needs code coverage analysis, add the parameter "-fprofile-instr-generate -fcoverage-mapping", run qemu-system-arm -M mps3-an547 -nographic -kernel ./nuttx/nuttx, execute the app that calls __llvm_profile_dump, if you set the dump to memory, read the memory in your own way, such as gdb. If you use the default dump to file, please dump the file to the host, and finally use the following command to run:
"llvm-profdata merge -sparse default.profraw -o result.profdata"
"llvm-cov show -format=html ./nuttx/nuttx -instr-profile=result.profdata -output-dir=./coverage/"

Signed-off-by: wangmingrong1 <wangmingrong1@xiaomi.com>
  • Loading branch information
W-M-R committed Nov 20, 2024
1 parent 6d629b3 commit abbea93
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 9 deletions.
11 changes: 11 additions & 0 deletions libs/libbuiltin/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,17 @@ config COVERAGE_ALL
-fcoverage-mapping' parameter to all module.
The data can then be printed nsh run "gcov dump -d /xxx/xxx"

config COVERAGE_DUMP_MEMORY
bool "Dump code coverage data directly to memory"
depends on COVERAGE_MINI
default n

if COVERAGE_DUMP_MEMORY

config COVERAGE_DUMP_MEMORY_ADDR
hex "Dump code coverage data memory address"

endif

config PROFILE_ALL
bool "Enable gprof call graph for all modules"
Expand Down
47 changes: 38 additions & 9 deletions libs/libbuiltin/compiler-rt/coverage.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,15 +225,8 @@ 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)
size_t __llvm_profile_dump(const char *path)
{
int fd;
int ret;

/* Header: __llvm_profile_header from InstrProfData.inc */

const char *filename = path;

/* Calculate size of sections. */

const __llvm_profile_data *data_begin = __llvm_profile_begin_data();
Expand Down Expand Up @@ -266,11 +259,18 @@ void __llvm_profile_dump(const char *path)
hdr.names_delta = (uintptr_t)names_begin;
hdr.value_kind_last = IPVK_LAST;

#ifndef CONFIG_COVERAGE_DUMP_MEMORY

int fd;
int ret;

const char *filename = path;

fd = _NX_OPEN(filename, O_WRONLY | O_CREAT);
if (fd < 0)
{
_NX_SETERRNO(fd);
return;
return -ENOENT;
}

/* Header */
Expand Down Expand Up @@ -323,4 +323,33 @@ void __llvm_profile_dump(const char *path)

exit:
_NX_CLOSE(fd);

return ret;
#else

UNUSED(path);
char *p = (char *)CONFIG_COVERAGE_DUMP_MEMORY_ADDR;

memcpy(p, &hdr, sizeof(hdr));
p += sizeof(hdr);

memcpy(p, data_begin, sizeof(__llvm_profile_data) * num_data);
p += sizeof(__llvm_profile_data) * num_data;

memcpy(p, counters_begin, sizeof(uint64_t) * num_counters);
p += sizeof(uint64_t) * num_counters;

memcpy(p, names_begin, names_size);
p += names_size;

/* Padding */

for (; padding_bytes_after_names != 0; --padding_bytes_after_names)
{
*p++ = '\0';
}

return (uintptr_t)p - CONFIG_COVERAGE_DUMP_MEMORY_ADDR;

#endif
}

0 comments on commit abbea93

Please sign in to comment.