Эх сурвалжийг харах

gcov: use original libgcov.a with redefined symbols

Alexey Lapshin 3 жил өмнө
parent
commit
21d7fd9b03

+ 51 - 7
components/app_trace/CMakeLists.txt

@@ -1,8 +1,16 @@
 set(srcs
     "app_trace.c"
     "app_trace_util.c"
-    "host_file_io.c"
-    "gcov/gcov_rtio.c")
+    "host_file_io.c")
+
+if(CONFIG_APPTRACE_GCOV_ENABLE)
+    if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
+        list(APPEND srcs
+            "gcov/gcov_rtio.c")
+    else()
+        fail_at_build_time(app_trace "Only GNU compiler can link with Gcov library")
+    endif()
+endif()
 
 set(include_dirs "include")
 
@@ -54,13 +62,49 @@ idf_component_register(SRCS "${srcs}"
                        REQUIRES esp_timer
                        LDFRAGMENTS linker.lf)
 
-# disable --coverage for this component, as it is used as transport
-# for gcov
-target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-profile-arcs" "-fno-test-coverage")
-
 # Force app_trace to also appear later than gcov in link line
 idf_component_get_property(app_trace app_trace COMPONENT_LIB)
-target_link_libraries(${COMPONENT_LIB} INTERFACE $<TARGET_FILE:${app_trace}> gcov $<TARGET_FILE:${app_trace}> c)
+
+if(CONFIG_APPTRACE_GCOV_ENABLE)
+    # The original Gcov library from toolchain will be objcopy with symbols redefinitions (see file gcov/io_sym.map).
+    # This needs because ESP has no file-system onboard, and redefined functions solves this problem and transmits
+    # output file to host PC.
+
+    # Set a name for Gcov library
+    set(GCOV_LIB libgcov_rtio)
+
+    # Set include direcrory of Gcov internal headers
+    execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=plugin
+                    OUTPUT_VARIABLE gcc_plugin_dir
+                    OUTPUT_STRIP_TRAILING_WHITESPACE
+                    ERROR_QUIET)
+    set_source_files_properties(gcov/gcov_rtio.c
+                                PROPERTIES COMPILE_FLAGS "-I${gcc_plugin_dir}/include")
+
+    # Copy libgcov.a with symbols redefinition
+    find_library(GCOV_LIBRARY_PATH gcov ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES})
+    add_custom_command(OUTPUT ${GCOV_LIB}.a
+                       COMMAND ${_CMAKE_TOOLCHAIN_PREFIX}objcopy
+                               --redefine-syms ${CMAKE_CURRENT_LIST_DIR}/gcov/io_sym.map
+                               ${GCOV_LIBRARY_PATH} ${GCOV_LIB}.a
+                       MAIN_DEPENDENCY ${GCOV_LIBRARY_PATH}
+                       VERBATIM)
+    add_custom_target(${GCOV_LIB}_target DEPENDS ${GCOV_LIB}.a)
+    add_library(${GCOV_LIB} STATIC IMPORTED)
+    set_target_properties(${GCOV_LIB}
+                          PROPERTIES
+                          IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${GCOV_LIB}.a)
+    add_dependencies(${GCOV_LIB} ${GCOV_LIB}_target)
+    add_dependencies(${COMPONENT_LIB} ${GCOV_LIB})
+
+    # disable --coverage for this component, as it is used as transport for gcov
+    target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-profile-arcs" "-fno-test-coverage")
+    target_link_options(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=__gcov_init")
+
+    target_link_libraries(${COMPONENT_LIB} INTERFACE ${GCOV_LIB} $<TARGET_FILE:${app_trace}> c)
+else()
+    target_link_libraries(${COMPONENT_LIB} INTERFACE $<TARGET_FILE:${app_trace}> c)
+endif()
 
 # This function adds a dependency on the given component if the component is included into the build.
 function(maybe_add_component component_name)

+ 16 - 2
components/app_trace/gcov/gcov_rtio.c

@@ -103,7 +103,7 @@ static int esp_dbg_stub_gcov_entry(void)
     return ESP_OK;
 }
 
-int gcov_rtio_atexit(void (*function)(void) __attribute__ ((unused)))
+void gcov_rtio_init(void)
 {
     uint32_t capabilities = 0;
     ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
@@ -112,7 +112,6 @@ int gcov_rtio_atexit(void (*function)(void) __attribute__ ((unused)))
         esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_CAPABILITIES, capabilities | ESP_DBG_STUB_CAP_GCOV_TASK);
     }
     esp_register_freertos_tick_hook(gcov_create_task_tick_hook);
-    return ESP_OK;
 }
 
 void esp_gcov_dump(void)
@@ -172,4 +171,19 @@ long gcov_rtio_ftell(void *stream)
     ESP_EARLY_LOGV(TAG, "%s(%p) = %ld", __FUNCTION__, stream, ret);
     return ret;
 }
+
+void gcov_rtio_setbuf(void *arg1 __attribute__ ((unused)), void *arg2 __attribute__ ((unused)))
+{
+    return;
+}
+
+/* Wrappers for Gcov functions */
+
+extern void __real___gcov_init(void *info);
+void __wrap___gcov_init(void *info)
+{
+    __real___gcov_init(info);
+    gcov_rtio_init();
+}
+
 #endif

+ 7 - 0
components/app_trace/gcov/io_sym.map

@@ -0,0 +1,7 @@
+fopen          gcov_rtio_fopen
+fclose         gcov_rtio_fclose
+fwrite         gcov_rtio_fwrite
+fread          gcov_rtio_fread
+fseek          gcov_rtio_fseek
+ftell          gcov_rtio_ftell
+setbuf         gcov_rtio_setbuf