diff --git a/repos/base/recipes/pkg/test-xml_generator/runtime b/repos/base/recipes/pkg/test-xml_generator/runtime index b264189d7d..cfb2746cdd 100644 --- a/repos/base/recipes/pkg/test-xml_generator/runtime +++ b/repos/base/recipes/pkg/test-xml_generator/runtime @@ -80,6 +80,11 @@ + + + + + diff --git a/repos/libports/ports/gcov.hash b/repos/libports/ports/gcov.hash index a9a3085fc4..a32fd4e691 100644 --- a/repos/libports/ports/gcov.hash +++ b/repos/libports/ports/gcov.hash @@ -1 +1 @@ -f0518e32e26d8286b84789e661c4999e01d8b569 +f08ebbb6104c2ac722fc5222939bfd9bcdef3d1f diff --git a/repos/libports/src/app/gcov/patches/gcov.patch b/repos/libports/src/app/gcov/patches/gcov.patch index 68fcfe1085..9faabefe4d 100644 --- a/repos/libports/src/app/gcov/patches/gcov.patch +++ b/repos/libports/src/app/gcov/patches/gcov.patch @@ -4,11 +4,11 @@ From: Christian Prochaska --- - gcc/gcov.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 84 insertions(+), 5 deletions(-) + gcc/gcov.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 128 insertions(+), 6 deletions(-) diff --git a/gcc/gcov.c b/gcc/gcov.c -index 50061c7..eead285 100644 +index 50061c7..b9ddccb 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -41,10 +41,13 @@ along with Gcov; see the file COPYING3. If not see @@ -25,7 +25,19 @@ index 50061c7..eead285 100644 /* The gcno file is generated by -ftest-coverage option. The gcda file is generated by a program compiled with -fprofile-arcs. Their formats are documented in gcov-io.h. */ -@@ -350,6 +353,16 @@ static int flag_all_blocks = 0; +@@ -299,6 +302,11 @@ static unsigned bbg_stamp; + + static char *da_file_name; + ++/* Name and file pointer of the input file for the annotation source list (gcan). */ ++ ++#define GCOV_ANNOTATE_SUFFIX ".gcan" ++static char *an_file_name; ++ + /* Data file is missing. */ + + static int no_data_file; +@@ -350,6 +358,16 @@ static int flag_all_blocks = 0; static int flag_function_summary = 0; @@ -42,7 +54,7 @@ index 50061c7..eead285 100644 /* Object directory file prefix. This is the directory/file where the graph and data files are looked for, if nonzero. */ -@@ -407,6 +420,43 @@ static void release_structures (void); +@@ -407,6 +425,43 @@ static void release_structures (void); static void release_function (function_t *); extern int main (int, char **); @@ -86,7 +98,7 @@ index 50061c7..eead285 100644 int main (int argc, char **argv) { -@@ -437,7 +487,7 @@ main (int argc, char **argv) +@@ -437,7 +492,7 @@ main (int argc, char **argv) sources = XNEWVEC (source_t, a_sources); argno = process_args (argc, argv); @@ -95,7 +107,7 @@ index 50061c7..eead285 100644 print_usage (true); if (argc - argno > 1) -@@ -445,6 +495,15 @@ main (int argc, char **argv) +@@ -445,6 +500,18 @@ main (int argc, char **argv) first_arg = argno; @@ -104,14 +116,17 @@ index 50061c7..eead285 100644 + /* search .gcda files and process each one */ + process_files("/"); + -+ /* finish processing arguments */ -+ argno = argc; ++ generate_results(NULL); ++ ++ release_structures(); ++ ++ return 0; + } + for (; argno != argc; argno++) { if (flag_display_progress) -@@ -488,7 +547,8 @@ print_usage (int error_p) +@@ -488,7 +555,8 @@ print_usage (int error_p) fnotice (file, " -r, --relative-only Only show data for relative sources\n"); fnotice (file, " -s, --source-prefix DIR Source prefix to elide\n"); fnotice (file, " -u, --unconditional-branches Show unconditional branch counts too\n"); @@ -121,7 +136,7 @@ index 50061c7..eead285 100644 fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n", bug_report_url); exit (status); -@@ -528,6 +588,7 @@ static const struct option options[] = +@@ -528,6 +596,7 @@ static const struct option options[] = { "source-prefix", required_argument, NULL, 's' }, { "unconditional-branches", no_argument, NULL, 'u' }, { "display-progress", no_argument, NULL, 'd' }, @@ -129,7 +144,7 @@ index 50061c7..eead285 100644 { 0, 0, 0, 0 } }; -@@ -538,7 +599,7 @@ process_args (int argc, char **argv) +@@ -538,7 +607,7 @@ process_args (int argc, char **argv) { int opt; @@ -138,7 +153,7 @@ index 50061c7..eead285 100644 -1) { switch (opt) -@@ -555,6 +616,9 @@ process_args (int argc, char **argv) +@@ -555,6 +624,9 @@ process_args (int argc, char **argv) case 'f': flag_function_summary = 1; break; @@ -148,7 +163,41 @@ index 50061c7..eead285 100644 case 'h': print_usage (false); /* print_usage will exit. */ -@@ -788,14 +852,17 @@ output_gcov_file (const char *file_name, source_t *src) +@@ -784,18 +856,51 @@ process_file (const char *file_name) + static void + output_gcov_file (const char *file_name, source_t *src) + { ++ if (flag_genode_autopilot) { ++ ++ /* output only if the file name appears in the .gcan file */ ++ ++ FILE *annotate_file = fopen(an_file_name, "r"); ++ ++ if (!annotate_file) ++ return; ++ ++ char *source_file = NULL; ++ size_t len = 0; ++ bool annotate = false; ++ ++ while (getline(&source_file, &len, annotate_file) != -1) { ++ ++ /* remove '\n' */ ++ source_file[strlen(source_file) - 1] = 0; ++ ++ if (strstr(src->coverage.name, source_file) != NULL) { ++ annotate = true; ++ break; ++ } ++ } ++ ++ fclose(annotate_file); ++ ++ if (!annotate) ++ return; ++ } ++ + char *gcov_file_name = make_gcov_file_name (file_name, src->coverage.name); if (src->coverage.lines) { @@ -168,7 +217,28 @@ index 50061c7..eead285 100644 } else fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name); -@@ -1114,6 +1181,18 @@ find_source (const char *file_name) +@@ -968,7 +1073,8 @@ create_file_names (const char *file_name) + /* Free previous file names. */ + free (bbg_file_name); + free (da_file_name); +- da_file_name = bbg_file_name = NULL; ++ free (an_file_name); ++ da_file_name = bbg_file_name = an_file_name = NULL; + bbg_file_time = 0; + bbg_stamp = 0; + +@@ -1014,6 +1120,10 @@ create_file_names (const char *file_name) + strcpy (da_file_name, name); + strcpy (da_file_name + length, GCOV_DATA_SUFFIX); + ++ an_file_name = XNEWVEC (char, length + strlen (GCOV_ANNOTATE_SUFFIX) + 1); ++ strcpy (an_file_name, name); ++ strcpy (an_file_name + length, GCOV_ANNOTATE_SUFFIX); ++ + free (name); + return; + } +@@ -1114,6 +1224,18 @@ find_source (const char *file_name) #endif && IS_DIR_SEPARATOR (src->coverage.name[source_length])) src->coverage.name += source_length + 1; diff --git a/repos/libports/src/lib/gcov/libc/libc.cc b/repos/libports/src/lib/gcov/libc/libc.cc index 266f14cdc1..145f0fe725 100644 --- a/repos/libports/src/lib/gcov/libc/libc.cc +++ b/repos/libports/src/lib/gcov/libc/libc.cc @@ -12,6 +12,7 @@ * under the terms of the GNU Affero General Public License version 3. */ +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include extern "C" { #include "stdio.h" @@ -35,11 +37,12 @@ FILE *stderr = &stderr_file; struct Gcov_env { - Genode::Env &env; - Genode::Heap heap { env.ram(), env.rm() }; - Genode::Allocator_avl fs_alloc { &heap }; - File_system::Connection fs { env, fs_alloc, "gcov_data" }; - unsigned long seek_offset { 0 }; + Genode::Env &env; + Genode::Attached_rom_dataspace config { env, "config" }; + Genode::Heap heap { env.ram(), env.rm() }; + Genode::Allocator_avl fs_alloc { &heap }; + File_system::Connection fs { env, fs_alloc, "gcov_data" }; + unsigned long seek_offset { 0 }; /* only one file is open at a time */ Genode::Constructible file_handle; @@ -118,6 +121,55 @@ extern "C" FILE *fopen(const char *path, const char *mode) gcov_env->seek_offset = 0; + /* + * Write the list of source files to be annotated by gcov into a '.gcan' + * file in the same directory as the '.gcda' file. + */ + + try { + + Genode::Xml_node config(gcov_env->config.local_addr(), + gcov_env->config.size()); + + Genode::Xml_node libgcov_node = config.sub_node("libgcov"); + + Absolute_path annotate_file_name { file_name }; + annotate_file_name.remove_trailing('a'); + annotate_file_name.remove_trailing('d'); + annotate_file_name.append("an"); + + File_system::File_handle annotate_file_handle { + gcov_env->fs.file(dir, annotate_file_name.base() + 1, + File_system::WRITE_ONLY, true) }; + + File_system::seek_off_t seek_offset = 0; + + libgcov_node.for_each_sub_node("annotate", + [&] (Genode::Xml_node annotate_node) { + + Absolute_path source_path; + + annotate_node.attribute("source").value(source_path.base(), + source_path.capacity()); + + seek_offset += File_system::write(gcov_env->fs, + annotate_file_handle, + source_path.base(), + Genode::strlen(source_path.base()), + seek_offset); + + seek_offset += File_system::write(gcov_env->fs, + annotate_file_handle, + "\n", + 1, + seek_offset); + }); + + gcov_env->fs.close(annotate_file_handle); + } + catch (Genode::Xml_node::Nonexistent_sub_node) { } + catch (Genode::Xml_attribute::Nonexistent_attribute) { } + return &gcov_env->file; }