Skip to content

Commit

Permalink
clang/gcov: Normalized output
Browse files Browse the repository at this point in the history
1. clang/gcov: Supports data storage for code coverage detection without a file system
2. clang/gcov: supports compatibility with gcc standard gcov
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 or nsh run "gcov -d /tmp/xxx ", 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 21, 2024
1 parent feb38c4 commit 99b51f3
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 57 deletions.
35 changes: 35 additions & 0 deletions libs/libbuiltin/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,41 @@ 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
bool "Dump code coverage data directly to 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"
Expand Down
94 changes: 37 additions & 57 deletions libs/libbuiltin/compiler-rt/coverage.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@

#include <fcntl.h>
#include <nuttx/fs/fs.h>
#include <nuttx/streams.h>

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

#define INSTR_PROF_RAW_VERSION 8
#define INSTR_PROF_RAW_VERSION_VAR __llvm_profile_raw_version
#define INSTR_PROF_PROFILE_RUNTIME_VAR __llvm_profile_runtime

/* Magic number to detect file format and endianness.
Expand Down Expand Up @@ -98,12 +98,6 @@ typedef struct __llvm_profile_header
enum value_kind value_kind_last;
}__llvm_profile_header;

/****************************************************************************
* Private Data
****************************************************************************/

static uint64_t INSTR_PROF_RAW_VERSION_VAR = INSTR_PROF_RAW_VERSION;

/****************************************************************************
* Public Data
****************************************************************************/
Expand Down Expand Up @@ -138,7 +132,7 @@ static uint64_t __llvm_profile_get_magic(void)

static uint64_t __llvm_profile_get_version(void)
{
return __llvm_profile_raw_version;
return INSTR_PROF_RAW_VERSION;
}

static uint64_t __llvm_profile_get_num_counters(const char *begin,
Expand Down Expand Up @@ -225,14 +219,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, FAR void *stream)
{
int fd;
int ret;

/* Header: __llvm_profile_header from InstrProfData.inc */

const char *filename = path;
const char c = '\0';

/* Calculate size of sections. */

Expand Down Expand Up @@ -266,61 +255,52 @@ 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)
{
_NX_SETERRNO(fd);
return;
}

/* Header */
puts(stream, &hdr, sizeof(hdr));
puts(stream, data_begin, sizeof(__llvm_profile_data) * num_data);
puts(stream, counters_begin, sizeof(uint64_t) * num_counters);
puts(stream, names_begin, names_size);

ret = _NX_WRITE(fd, &hdr, sizeof(hdr));
if (ret != sizeof(hdr))
for (; padding_bytes_after_names != 0; --padding_bytes_after_names)
{
_NX_SETERRNO(ret);
goto exit;
puts(stream, &c, 1);
}
}

void __gcov_dump(void)
{
#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,
(FAR char *)CONFIG_COVERAGE_DUMP_MEMORY_ADDR,
CONFIG_COVERAGE_DUMP_MEMORY_SIZE);

/* Counters */
__llvm_profile_dump(stream.common.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)
{
}

0 comments on commit 99b51f3

Please sign in to comment.