diff --git a/include/gcov.h b/include/gcov.h index e494fe1e50d67..1faad7a9a87dc 100644 --- a/include/gcov.h +++ b/include/gcov.h @@ -161,6 +161,20 @@ extern void __gcov_filename_to_gcfn(FAR const char *filename, FAR void *), FAR void *arg); +/**************************************************************************** + * Name: __gcov_dump_to_memory + * + * Description: + * Dump gcov data directly to memory + * + * Parameters: + * ptr - Memory Address + * size - Memory block size + * + ****************************************************************************/ + +size_t __gcov_dump_to_memory(FAR void *ptr, size_t size); + #undef EXTERN #ifdef __cplusplus } diff --git a/libs/libbuiltin/compiler-rt/coverage.c b/libs/libbuiltin/compiler-rt/coverage.c index df85b49a0edec..ab24d5f7b2f06 100644 --- a/libs/libbuiltin/compiler-rt/coverage.c +++ b/libs/libbuiltin/compiler-rt/coverage.c @@ -33,13 +33,13 @@ #include #include +#include /**************************************************************************** * 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. @@ -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 ****************************************************************************/ @@ -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, @@ -225,14 +219,10 @@ 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(FAR struct lib_outstream_s *stream) { - int fd; - int ret; - - /* Header: __llvm_profile_header from InstrProfData.inc */ - - const char *filename = path; + const char c = '\0'; + size_t size = 0; /* Calculate size of sections. */ @@ -266,61 +256,83 @@ 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 */ - - ret = _NX_WRITE(fd, &hdr, sizeof(hdr)); - if (ret != sizeof(hdr)) + size += sizeof(hdr); + if (sizeof(hdr) != stream->puts(stream, &hdr, sizeof(hdr))) { - _NX_SETERRNO(ret); goto exit; } - /* Data */ - - ret = _NX_WRITE(fd, data_begin, sizeof(__llvm_profile_data) * num_data); - if (ret != sizeof(__llvm_profile_data) * num_data) + size += sizeof(__llvm_profile_data) * num_data; + if (sizeof(__llvm_profile_data) * num_data != + stream->puts(stream, data_begin, + sizeof(__llvm_profile_data) * num_data)) { - _NX_SETERRNO(ret); goto exit; } - /* Counters */ - - ret = _NX_WRITE(fd, counters_begin, sizeof(uint64_t) * num_counters); - if (ret != sizeof(uint64_t) * num_counters) + size += sizeof(uint64_t) * num_counters; + if (sizeof(uint64_t) * num_counters != + stream->puts(stream, counters_begin, + sizeof(uint64_t) * num_counters)) { - _NX_SETERRNO(ret); goto exit; } - /* Names */ - - ret = _NX_WRITE(fd, names_begin, names_size); - if (ret != names_size) + size += names_size; + if (names_size != stream->puts(stream, names_begin, names_size)) { - _NX_SETERRNO(ret); goto exit; } - /* Padding */ - for (; padding_bytes_after_names != 0; --padding_bytes_after_names) { - ret = _NX_WRITE(fd, "\0", 1); - if (ret != 1) + size += 1; + if (1 != stream->puts(stream, &c, 1)) { - _NX_SETERRNO(ret); break; } } exit: + + return size; +} + +void __gcov_dump(void) +{ + struct lib_rawoutstream_s stream; + FAR char *path; + int fd; + + path = getenv("GCOV_PREFIX"); + if (!path) + { + return; + } + + fd = _NX_OPEN(path, O_WRONLY | O_CREAT); + if (fd < 0) + { + _NX_SETERRNO(fd); + return; + } + + lib_rawoutstream(&stream, fd); + + __llvm_profile_dump(&stream.common); + _NX_CLOSE(fd); } + +size_t __gcov_dump_to_memory(FAR void *ptr, size_t size) +{ + struct lib_memoutstream_s stream; + + lib_memoutstream(&stream, ptr, size); + + return __llvm_profile_dump(&stream.common); +} + +void __gcov_reset(void) +{ +}