genode/repos/libports/src/app/gcov/patches/gcov.patch
Christian Prochaska 720919bc14 gcov: update to version 8.3.0
Issue #3307
2019-05-27 14:52:52 +02:00

275 lines
7.4 KiB
Diff

gcov.patch
From: Christian Prochaska <christian.prochaska@genode-labs.com>
---
gcc/gcov.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 132 insertions(+), 7 deletions(-)
diff --git a/gcc/gcov.c b/gcc/gcov.c
index c7c52ce..e039ef0 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -47,6 +47,8 @@ along with Gcov; see the file COPYING3. If not see
#include <getopt.h>
+#include <dirent.h>
+
#include "md5.h"
using namespace std;
@@ -55,6 +57,7 @@ using namespace std;
#include "gcov-io.h"
#include "gcov-io.c"
+
/* 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. */
@@ -436,6 +439,11 @@ static unsigned bbg_supports_has_unexecuted_blocks;
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;
@@ -504,6 +512,16 @@ static int flag_human_readable_numbers = 0;
static int flag_function_summary = 0;
+/*
+ * Genode autopilot mode
+ *
+ * - scans for gcov data files
+ * - strips the Genode depot path from source paths
+ * - writes results to stdout
+ */
+
+static int flag_genode_autopilot = 0;
+
/* Object directory file prefix. This is the directory/file where the
graph and data files are looked for, if nonzero. */
@@ -750,6 +768,43 @@ get_cycles_count (line_info &linfo, bool handle_negative_cycles = true)
return count;
}
+void process_files(const char *dir_path)
+{
+ char new_path[strlen(dir_path) + sizeof('/') + NAME_MAX];
+
+ DIR *dir = opendir(dir_path);
+
+ if (!dir)
+ return;
+
+ struct dirent *dirent;
+
+ while((dirent = readdir(dir)) != NULL) {
+
+ snprintf(new_path, sizeof(new_path), "%s/%s", dir_path, dirent->d_name);
+
+ struct stat stat_buf;
+
+ if (stat(new_path, &stat_buf) != 0)
+ continue;
+
+ if (S_ISDIR(stat_buf.st_mode)) {
+ process_files(new_path);
+ continue;
+ }
+
+ if (!S_ISREG(stat_buf.st_mode))
+ continue;
+
+ if (!strstr(dirent->d_name, ".gcda"))
+ continue;
+
+ process_file(new_path);
+ }
+
+ closedir(dir);
+}
+
int
main (int argc, char **argv)
{
@@ -775,13 +830,25 @@ main (int argc, char **argv)
expandargv (&argc, &argv);
argno = process_args (argc, argv);
- if (optind == argc)
+ if ((optind == argc) && !flag_genode_autopilot)
print_usage (true);
if (argc - argno > 1)
multiple_files = 1;
first_arg = argno;
+
+ if (flag_genode_autopilot) {
+
+ /* search .gcda files and process each one */
+ process_files("/");
+
+ process_all_functions();
+ generate_results(NULL);
+ release_structures();
+
+ return 0;
+ }
for (; argno != argc; argno++)
{
@@ -833,7 +900,8 @@ print_usage (int error_p)
fnotice (file, " -u, --unconditional-branches Show unconditional branch counts too\n");
fnotice (file, " -v, --version Print version number, then exit\n");
fnotice (file, " -w, --verbose Print verbose informations\n");
- fnotice (file, " -x, --hash-filenames Hash long pathnames\n");
+ fnotice (file, " -x, --hash-filenames Hash long pathnames\n\n");
+ fnotice (file, " -g, --genode-autopilot Genode autopilot mode\n");
fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
bug_report_url);
exit (status);
@@ -877,6 +945,7 @@ static const struct option options[] =
{ "display-progress", no_argument, NULL, 'd' },
{ "hash-filenames", no_argument, NULL, 'x' },
{ "use-colors", no_argument, NULL, 'k' },
+ { "genode-autopilot", no_argument, NULL, 'g' },
{ 0, 0, 0, 0 }
};
@@ -887,7 +956,7 @@ process_args (int argc, char **argv)
{
int opt;
- const char *opts = "abcdfhijklmno:prs:uvwx";
+ const char *opts = "abcdfghijklmno:prs:uvwx";
while ((opt = getopt_long (argc, argv, opts, options, NULL)) != -1)
{
switch (opt)
@@ -904,6 +973,9 @@ process_args (int argc, char **argv)
case 'f':
flag_function_summary = 1;
break;
+ case 'g':
+ flag_genode_autopilot = 1;
+ break;
case 'h':
print_usage (false);
/* print_usage will exit. */
@@ -1234,11 +1306,43 @@ process_all_functions (void)
static void
output_gcov_file (const char *file_name, source_info *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)
{
- FILE *gcov_file = fopen (gcov_file_name, "w");
+ FILE *gcov_file = flag_genode_autopilot ?
+ stdout :
+ fopen (gcov_file_name, "w");
if (gcov_file)
{
fnotice (stdout, "Creating '%s'\n", gcov_file_name);
@@ -1246,7 +1350,8 @@ output_gcov_file (const char *file_name, source_info *src)
if (ferror (gcov_file))
fnotice (stderr, "Error writing output file '%s'\n",
gcov_file_name);
- fclose (gcov_file);
+ if (!flag_genode_autopilot)
+ fclose (gcov_file);
}
else
fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name);
@@ -1329,7 +1434,10 @@ generate_results (const char *file_name)
function_summary (&src->coverage, "File");
total_lines += src->coverage.lines;
total_executed += src->coverage.lines_executed;
- if (flag_gcov_file)
+
+ if (flag_gcov_file &&
+ !(flag_genode_autopilot &&
+ (src->coverage.lines_executed == src->coverage.lines)))
{
if (flag_intermediate_format)
/* Output the intermediate format without requiring source
@@ -1384,7 +1492,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;
@@ -1430,6 +1539,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;
}
@@ -1486,6 +1599,18 @@ find_source (const char *file_name)
#endif
&& IS_DIR_SEPARATOR (src->coverage.name[source_length]))
src->coverage.name += source_length + 1;
+
+ if (flag_genode_autopilot) {
+
+ /* strip path of the Genode depot */
+
+ char *depot_relative_path = strstr(src->name, "/depot/");
+ if (depot_relative_path) {
+ src->name = depot_relative_path + strlen("/depot");
+ src->coverage.name = src->name;
+ }
+ }
+
if (!stat (src->name, &status))
src->file_time = status.st_mtime;
}