Skip to content

Commit

Permalink
libs: add gcov framework support
Browse files Browse the repository at this point in the history
In devices without storage media, you can export data to the
command line and then generate the corresponding gcda file

It can save the result output by calling __gcov_info_to_gcda
The usage is similar to:
https://gcc.gnu.org/onlinedocs/gcc/Freestanding-Environments.html#Profiling-and-Test-Coverage-in-Freestanding-Environments

Usage:
 ./tools/configure.sh qemu-armv7a:nsh
Modify the configuration
+CONFIG_COVERAGE_ALL=y
+CONFIG_COVERAGE_MINI=y
+CONFIG_SYSTEM_GCOV=y
Run:
qemu-system-arm -cpu cortex-a7 -nographic -smp 4 \
     -machine virt,virtualization=off,gic-version=2 \
     -net none -chardev stdio,id=con,mux=on -serial chardev:con \
     -mon chardev=con,mode=readline -kernel ./nuttx/nuttx -semihosting -s | tee gcov.txt
./nuttx/tools/gcov_convert.py -i ./gcov.txt
./nuttx/tools/gcov.sh -t arm-none-eabi-gcov

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
  • Loading branch information
Gary-Hobson committed Nov 21, 2024
1 parent 18e8fff commit f1e81ed
Show file tree
Hide file tree
Showing 7 changed files with 548 additions and 7 deletions.
169 changes: 169 additions & 0 deletions include/gcov.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/****************************************************************************
* include/gcov.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/

#ifndef __INCLUDE_GCOV_H
#define __INCLUDE_GCOV_H

/****************************************************************************
* Included Files
****************************************************************************/

#include <sys/types.h>

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

/* The GCOV 12 gcno/gcda format has slight change,
* Please refer to gcov-io.h in the GCC 12 for
* more details.
*/

#if __GNUC__ >= 12
# define GCOV_12_FORMAT
#endif

#if __GNUC__ >= 14
# define GCOV_COUNTERS 9u
#elif __GNUC__ >= 10
# define GCOV_COUNTERS 8u
#elif __GNUC__ >= 8
# define GCOV_COUNTERS 9u
#else
# define GCOV_COUNTERS 10u
#endif

/****************************************************************************
* Public Types
****************************************************************************/

struct gcov_fn_info;
typedef uint64_t gcov_type;

/** Profiling data per object file
*
* This data is generated by gcc during compilation and doesn't change
* at run-time with the exception of the next pointer.
*/

struct gcov_info
{
unsigned int version; /* Gcov version (same as GCC version) */
FAR struct gcov_info *next; /* List head for a singly-linked list */
unsigned int stamp; /* Uniquifying time stamp */
#ifdef GCOV_12_FORMAT
unsigned int checksum; /* unique object checksum */
#endif
FAR const char *filename; /* Name of the associated gcda data file */
void (*merge[GCOV_COUNTERS])(FAR gcov_type *, unsigned int);
unsigned int n_functions; /* number of instrumented functions */
FAR struct gcov_fn_info **functions; /* function information */
};

/****************************************************************************
* Public Data
****************************************************************************/

extern FAR struct gcov_info *__gcov_info_start;
extern FAR struct gcov_info *__gcov_info_end;

/****************************************************************************
* Public Function Prototypes
****************************************************************************/

#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif

/****************************************************************************
* Name: __gcov_reset
*
* Description:
* Set all counters to zero.
*
****************************************************************************/

extern void __gcov_reset(void);

/****************************************************************************
* Name: __gcov_dump
*
* Description:
* Write profile information to a file.
*
****************************************************************************/

extern void __gcov_dump(void);

/****************************************************************************
* Name: __gcov_info_to_gcda
*
* Description:
* Convert the gcov information referenced by INFO to a gcda data stream.
*
* Parameters:
* info - Pointer to the gcov information.
* filename - Callback function to get the filename.
* dump - Callback function to write the gcda data.
* allocate - Callback function to allocate memory.
* arg - User-provided argument.
*
****************************************************************************/

extern void __gcov_info_to_gcda(FAR const struct gcov_info *info,
FAR void (*filename)(FAR const char *,
FAR void *),
FAR void (*dump)(FAR const void *,
unsigned int, FAR void *),
FAR void *(*allocate)(unsigned int,
FAR void *),
FAR void *arg);

/****************************************************************************
* Name: __gcov_filename_to_gcfn
*
* Description:
* Convert the filename to a gcfn data stream.
*
* Parameters:
* filename - Pointer to the filename.
* dump - Callback function to write the gcfn data.
* arg - User-provided argument.
*
****************************************************************************/

extern void __gcov_filename_to_gcfn(FAR const char *filename,
FAR void (*dump)(FAR const void *,
unsigned int,
FAR void *),
FAR void *arg);

#undef EXTERN
#ifdef __cplusplus
}
#endif

#endif /* __INCLUDE_GCOV_H */
2 changes: 1 addition & 1 deletion libs/libbuiltin/compiler-rt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ if(CONFIG_COVERAGE_COMPILER_RT)

target_sources(rt.profile PRIVATE ${RT_PROFILE_SRCS})

elseif(CONFIG_COVERAGE_MINI)
elseif(CONFIG_COVERAGE_MINI AND CONFIG_ARCH_TOOLCHAIN_CLANG)
nuttx_add_system_library(rt.miniprofile)

target_compile_options(rt.miniprofile -fno-profile-instr-generate
Expand Down
2 changes: 1 addition & 1 deletion libs/libbuiltin/compiler-rt/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ CSRCS += $(wildcard compiler-rt/compiler-rt/lib/profile/*.c)
CPPSRCS += $(wildcard compiler-rt/compiler-rt/lib/profile/*.cpp)
CSRCS += InstrProfilingPlatform.c

else ifeq ($(CONFIG_COVERAGE_MINI),y)
else ifeq ($(CONFIG_COVERAGE_MINI)$(CONFIG_ARCH_TOOLCHAIN_CLANG),yy)

FLAGS += -fno-profile-instr-generate -fno-coverage-mapping

Expand Down
9 changes: 7 additions & 2 deletions libs/libbuiltin/libgcc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
# ##############################################################################

if(CONFIG_PROFILE_MINI)
nuttx_add_system_library(libgprof)
target_sources(libgprof PRIVATE profile.c)
nuttx_add_system_library(libprofile)
target_sources(libprofile PRIVATE profile.c)
endif()

if(CONFIG_COVERAGE_MINI AND CONFIG_ARCH_TOOLCHAIN_GCC)
nuttx_add_system_library(libcoverage)
target_sources(libcoverage PRIVATE gcov.c)
endif()
8 changes: 5 additions & 3 deletions libs/libbuiltin/libgcc/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
############################################################################

ifeq ($(CONFIG_PROFILE_MINI),y)

CSRCS += profile.c
endif

ifeq ($(CONFIG_COVERAGE_MINI)$(CONFIG_ARCH_TOOLCHAIN_GCC),yy)
CSRCS += gcov.c
endif

DEPPATH += --dep-path libgcc
VPATH += :libgcc

endif
Loading

0 comments on commit f1e81ed

Please sign in to comment.