Re: [PATCH v2] gcov: Add __gcov_info_to_gdca()
On 23/07/2021 09:16, Martin Liška wrote: On 7/23/21 9:06 AM, Sebastian Huber wrote: On 23/07/2021 08:52, Martin Liška wrote: +#ifdef NEED_L_GCOV_INFO_TO_GCDA +/* Convert the gcov info to a gcda data stream. It is intended for + free-standing environments which do not support the C library file I/O. */ + +void +__gcov_info_to_gcda (const struct gcov_info *gi_ptr, + void (*filename) (const char *, void *), What about begin_finaname_fn? + void (*dump) (const void *, unsigned, void *), + void *(*allocate) (unsigned, void *), + void *arg) +{ + (*filename) (gi_ptr->filename, arg); + write_one_data (gi_ptr, NULL, dump, allocate, arg); +} +#endif /* NEED_L_GCOV_INFO_TO_GCDA */ About gcov_write_summary: it should be also dumped in order to have a complete .gcda file, right? How can I get access to the summary information? Here it is not available: You only need to change gcov_write_summary in gcov-io.c. Sorry, I still don't know how I can get the summary information if I only have a pointer to the gcov_info structure which does not contain a summary member. You're right, sorry! But in your case, it will be simple to re-created it by the script at a host system. gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary) { gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH); gcov_write_unsigned (summary->runs); gcov_write_unsigned (summary->sum_max); } Where summary->runs will be 1 and sum_max is maximum counter during the run. This __gcov_info_to_gcda() is just a low-level piece which is necessary to get the gcda stream from an embedded system to a host without having to know the details of gcov. In follow up patches we could think about a standard format to serialize the gcda stream. For this format we could add support to the host gcov tools. One of the tools could read this stream and output proper *.gcda files. -- embedded brains GmbH Herr Sebastian HUBER Dornierstr. 4 82178 Puchheim Germany email: sebastian.hu...@embedded-brains.de phone: +49-89-18 94 741 - 16 fax: +49-89-18 94 741 - 08 Registergericht: Amtsgericht München Registernummer: HRB 157899 Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler Unsere Datenschutzerklärung finden Sie hier: https://embedded-brains.de/datenschutzerklaerung/
Re: [PATCH v2] gcov: Add __gcov_info_to_gdca()
On 23/07/2021 11:17, Sebastian Huber wrote: On 23/07/2021 08:52, Martin Liška wrote: It would be nice having a test-case that can test your approach. The problem is that you need the linker set to get access to the gcov information. The test program of the commit message works on my Linux machine. I am not sure if it is generic enough for the test suite. Instead of printing the information we could compare it against an expected output so that we have a self-contained test program. Yep, that would be nice. I tried to run the attached test case as "gcc/testsuite/gcc.dg/gcov-info-to-gcda.c". However, I get this error: Invoking the compiler as /tmp/sh/b-gcc-git-linux/gcc/xgcc -B/tmp/sh/b-gcc-git-linux/gcc/ /home/EB/sebastian_h/src/gcc/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c -fdiagnostics-plain-output -fprofile-arcs -fprofile-info-section -lm -o ./gcov-info-to-gcda.exe Setting timeout to 300 Executing on host: /tmp/sh/b-gcc-git-linux/gcc/xgcc -B/tmp/sh/b-gcc-git-linux/gcc/ /home/EB/sebastian_h/src/gcc/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c -fdiagnostics-plain-output -fprofile-arcs -fprofile-info-section -lm -o ./gcov-info-to-gcda.exe (timeout = 300) spawn -ignore SIGHUP /tmp/sh/b-gcc-git-linux/gcc/xgcc -B/tmp/sh/b-gcc-git-linux/gcc/ /home/EB/sebastian_h/src/gcc/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c -fdiagnostics-plain-output -fprofile-arcs -fprofile-info-section -lm -o ./gcov-info-to-gcda.exe pid is 79704 -79704 /home/EB/sebastian_h/src/gcc/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c:5:10: fatal error: gcov.h: No such file or directory compilation terminated. Is it possible to do such kind of tests? I also have to link to -lgcov? Ok, the linking is not the problem. If I declare __gcov_info_to_gcda() locally, the test runs. -- embedded brains GmbH Herr Sebastian HUBER Dornierstr. 4 82178 Puchheim Germany email: sebastian.hu...@embedded-brains.de phone: +49-89-18 94 741 - 16 fax: +49-89-18 94 741 - 08 Registergericht: Amtsgericht München Registernummer: HRB 157899 Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler Unsere Datenschutzerklärung finden Sie hier: https://embedded-brains.de/datenschutzerklaerung/
Re: [PATCH v2] gcov: Add __gcov_info_to_gdca()
On 23/07/2021 08:52, Martin Liška wrote: It would be nice having a test-case that can test your approach. The problem is that you need the linker set to get access to the gcov information. The test program of the commit message works on my Linux machine. I am not sure if it is generic enough for the test suite. Instead of printing the information we could compare it against an expected output so that we have a self-contained test program. Yep, that would be nice. I tried to run the attached test case as "gcc/testsuite/gcc.dg/gcov-info-to-gcda.c". However, I get this error: Invoking the compiler as /tmp/sh/b-gcc-git-linux/gcc/xgcc -B/tmp/sh/b-gcc-git-linux/gcc/ /home/EB/sebastian_h/src/gcc/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c -fdiagnostics-plain-output -fprofile-arcs -fprofile-info-section -lm -o ./gcov-info-to-gcda.exe Setting timeout to 300 Executing on host: /tmp/sh/b-gcc-git-linux/gcc/xgcc -B/tmp/sh/b-gcc-git-linux/gcc/ /home/EB/sebastian_h/src/gcc/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c -fdiagnostics-plain-output -fprofile-arcs -fprofile-info-section -lm -o ./gcov-info-to-gcda.exe(timeout = 300) spawn -ignore SIGHUP /tmp/sh/b-gcc-git-linux/gcc/xgcc -B/tmp/sh/b-gcc-git-linux/gcc/ /home/EB/sebastian_h/src/gcc/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c -fdiagnostics-plain-output -fprofile-arcs -fprofile-info-section -lm -o ./gcov-info-to-gcda.exe pid is 79704 -79704 /home/EB/sebastian_h/src/gcc/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c:5:10: fatal error: gcov.h: No such file or directory compilation terminated. Is it possible to do such kind of tests? I also have to link to -lgcov? -- embedded brains GmbH Herr Sebastian HUBER Dornierstr. 4 82178 Puchheim Germany email: sebastian.hu...@embedded-brains.de phone: +49-89-18 94 741 - 16 fax: +49-89-18 94 741 - 08 Registergericht: Amtsgericht München Registernummer: HRB 157899 Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler Unsere Datenschutzerklärung finden Sie hier: https://embedded-brains.de/datenschutzerklaerung/ /* { dg-do run } */ /* { dg-skip-if "profile-info-section" { powerpc-ibm-aix* } } */ /* { dg-options "-fprofile-arcs -fprofile-info-section" } */ #include extern const struct gcov_info *my_info; static unsigned counter; static void filename (const char *f, void *arg) { if (arg != ) __builtin_abort (); if (__builtin_strcmp (f, __FILE__) != 0) __builtin_abort (); } static void dump (const void *d, unsigned n, void *arg) { unsigned *m = (unsigned *)arg; if (m != ) __builtin_abort (); if (*m == 0) { const unsigned *u = d; if (*u != 0x67636461) __builtin_abort (); } *m += n; } static void * allocate (unsigned length, void *arg) { if (arg != ) __builtin_abort (); return __builtin_malloc (length); } int main() { __asm__ volatile (".set my_info, .LPBX2"); __gcov_info_to_gcda (my_info, filename, dump, allocate, ); return 0; }
Re: [PATCH v2] gcov: Add __gcov_info_to_gdca()
On 7/23/21 9:06 AM, Sebastian Huber wrote: On 23/07/2021 08:52, Martin Liška wrote: +#ifdef NEED_L_GCOV_INFO_TO_GCDA +/* Convert the gcov info to a gcda data stream. It is intended for + free-standing environments which do not support the C library file I/O. */ + +void +__gcov_info_to_gcda (const struct gcov_info *gi_ptr, + void (*filename) (const char *, void *), What about begin_finaname_fn? + void (*dump) (const void *, unsigned, void *), + void *(*allocate) (unsigned, void *), + void *arg) +{ + (*filename) (gi_ptr->filename, arg); + write_one_data (gi_ptr, NULL, dump, allocate, arg); +} +#endif /* NEED_L_GCOV_INFO_TO_GCDA */ About gcov_write_summary: it should be also dumped in order to have a complete .gcda file, right? How can I get access to the summary information? Here it is not available: You only need to change gcov_write_summary in gcov-io.c. Sorry, I still don't know how I can get the summary information if I only have a pointer to the gcov_info structure which does not contain a summary member. You're right, sorry! But in your case, it will be simple to re-created it by the script at a host system. gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary) { gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH); gcov_write_unsigned (summary->runs); gcov_write_unsigned (summary->sum_max); } Where summary->runs will be 1 and sum_max is maximum counter during the run. Cheers, Martin
Re: [PATCH v2] gcov: Add __gcov_info_to_gdca()
On 23/07/2021 08:52, Martin Liška wrote: +#ifdef NEED_L_GCOV_INFO_TO_GCDA +/* Convert the gcov info to a gcda data stream. It is intended for + free-standing environments which do not support the C library file I/O. */ + +void +__gcov_info_to_gcda (const struct gcov_info *gi_ptr, + void (*filename) (const char *, void *), What about begin_finaname_fn? + void (*dump) (const void *, unsigned, void *), + void *(*allocate) (unsigned, void *), + void *arg) +{ + (*filename) (gi_ptr->filename, arg); + write_one_data (gi_ptr, NULL, dump, allocate, arg); +} +#endif /* NEED_L_GCOV_INFO_TO_GCDA */ About gcov_write_summary: it should be also dumped in order to have a complete .gcda file, right? How can I get access to the summary information? Here it is not available: You only need to change gcov_write_summary in gcov-io.c. Sorry, I still don't know how I can get the summary information if I only have a pointer to the gcov_info structure which does not contain a summary member. -- embedded brains GmbH Herr Sebastian HUBER Dornierstr. 4 82178 Puchheim Germany email: sebastian.hu...@embedded-brains.de phone: +49-89-18 94 741 - 16 fax: +49-89-18 94 741 - 08 Registergericht: Amtsgericht München Registernummer: HRB 157899 Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler Unsere Datenschutzerklärung finden Sie hier: https://embedded-brains.de/datenschutzerklaerung/
Re: [PATCH v2] gcov: Add __gcov_info_to_gdca()
On 7/23/21 8:21 AM, Sebastian Huber wrote: On 23/07/2021 07:31, Martin Liška wrote: +static void * +allocate_handler (unsigned size, void *unused) +{ + (void)unused; + return xmalloc (size); +} +#endif /* NEED_L_GCOV */ + +#if defined(NEED_L_GCOV) || defined(NEED_L_GCOV_INFO_TO_GCDA) +static inline void Likewise here. +dump_unsigned (gcov_unsigned_t word, + void (*dump) (const void *, unsigned, void *), + void *arg) +{ + (*dump) (, sizeof (word), arg); +} Likewise here. Adding the gcov_ prefix would make some lines longer than 79 characters. We already have several functions in this file without a gocv_ prefix, for example write_one_data(), write_topn_counters(). All right, I don't insist on that. Cheers, Martin
Re: [PATCH v2] gcov: Add __gcov_info_to_gdca()
On 7/23/21 8:14 AM, Sebastian Huber wrote: On 23/07/2021 07:31, Martin Liška wrote: write_topn_counters (const struct gcov_ctr_info *ci_ptr, unsigned t_ix, - gcov_unsigned_t n_counts) + gcov_unsigned_t n_counts, + void (*dump) (const void *, unsigned, void *), + void *(*allocate)(unsigned, void *), + void *arg) I would likely prefer dump_fn and allocate_fn argumen t names. If I use dump_fn and allocate_fn throughout the code, then several lines would exceed 79 characters. This needs more vertical space. Should I still add the _fn postfix? Yes, please do so. Martin
Re: [PATCH v2] gcov: Add __gcov_info_to_gdca()
On 7/23/21 8:10 AM, Sebastian Huber wrote: Hallo Martin, Hello. thanks for your review. On 23/07/2021 07:31, Martin Liška wrote: On 7/13/21 10:15 PM, Sebastian Huber wrote: Hello. Thanks for working on that, there's my review: Add __gcov_info_to_gcda() to libgcov to get the gcda data for a gcda info in a freestanding environment. It is intended to be used with the -fprofile-info-section option. A crude test program which doesn't use a linker script is (use "gcc -coverage -fprofile-info-section -lgcc test.c" to compile it): [...]>> @@ -365,46 +426,48 @@ write_topn_counters (const struct gcov_ctr_info *ci_ptr, if (list_sizes == NULL || counters > list_size_length) { list_size_length = MAX (LIST_SIZE_MIN_LENGTH, 2 * counters); -#if HAVE_SYS_MMAN_H +#if !defined(inhibit_libc) && HAVE_SYS_MMAN_H list_sizes = (unsigned *)malloc_mmap (list_size_length * sizeof (unsigned)); #endif /* Malloc fallback. */ if (list_sizes == NULL) - list_sizes = (unsigned *)xmalloc (list_size_length * sizeof (unsigned)); + list_sizes = + (unsigned *)(*allocate) (list_size_length * sizeof (unsigned), arg); } - memset (list_sizes, 0, counters * sizeof (unsigned)); Are you sure we don't need this zeroing? The list_sizes array is iterated two times using the same "counters" limit. In the first iteration ... unsigned pair_total = 0; for (unsigned i = 0; i < counters; i++) { gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2]; + unsigned sizes = 0; + ... the sizes is initialized to zero here and ... for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start; node != NULL; node = node->next) - { - ++pair_total; - ++list_sizes[i]; - } + ++sizes; + + pair_total += sizes; + list_sizes[i] = sizes; ... written to the array here. Oh, good then! } unsigned disk_size = GCOV_TOPN_DISK_COUNTERS * counters + 2 * pair_total; - gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix), - GCOV_TAG_COUNTER_LENGTH (disk_size)); + dump_unsigned (GCOV_TAG_FOR_COUNTER (t_ix), dump, arg), + dump_unsigned (GCOV_TAG_COUNTER_LENGTH (disk_size), dump, arg); for (unsigned i = 0; i < counters; i++) { - gcov_write_counter (ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i]); - gcov_write_counter (list_sizes[i]); + dump_counter (ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i], dump, arg); + dump_counter (list_sizes[i], dump, arg); gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2]; unsigned j = 0; for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start; j < list_sizes[i]; node = node->next, j++) { - gcov_write_counter (node->value); - gcov_write_counter (node->count); + dump_counter (node->value, dump, arg); + dump_counter (node->count, dump, arg); } } } [...] +#ifdef NEED_L_GCOV_INFO_TO_GCDA +/* Convert the gcov info to a gcda data stream. It is intended for + free-standing environments which do not support the C library file I/O. */ + +void +__gcov_info_to_gcda (const struct gcov_info *gi_ptr, + void (*filename) (const char *, void *), What about begin_finaname_fn? + void (*dump) (const void *, unsigned, void *), + void *(*allocate) (unsigned, void *), + void *arg) +{ + (*filename) (gi_ptr->filename, arg); + write_one_data (gi_ptr, NULL, dump, allocate, arg); +} +#endif /* NEED_L_GCOV_INFO_TO_GCDA */ About gcov_write_summary: it should be also dumped in order to have a complete .gcda file, right? How can I get access to the summary information? Here it is not available: You only need to change gcov_write_summary in gcov-io.c. /* Information about a single object file. */ struct gcov_info { [...] #ifndef IN_GCOV_TOOL const struct gcov_fn_info *const *functions; /* pointer to pointers to function information */ #else struct gcov_fn_info **functions; struct gcov_summary summary; #endif /* !IN_GCOV_TOOL */ }; Should we dump a memset(, 0, summary) summary? Can we remove gcov_write_counter function? It is no longer used. What is the policy to remove functions? We can remove it if it's unused :) I think it can be handy having a script that creates a .gcda file from your reference dump output, what do you think? I think the dump output from the example is not useful for real applications. In an embedded system you would probably dump the information via a serial interface. The dump could be compressed and base64 encoded with some sort of EDAC. Sure, but a host system needs to take such a stream and reconstruct .gcda files. That's what I mean. Btw. do you use the created .gcda files only for gcov (coverage reports), or do you use it for -fprofile-use (PGO/FDO)? Btw. the generated .gcda files should
Re: [PATCH v2] gcov: Add __gcov_info_to_gdca()
On 23/07/2021 07:31, Martin Liška wrote: +static void * +allocate_handler (unsigned size, void *unused) +{ + (void)unused; + return xmalloc (size); +} +#endif /* NEED_L_GCOV */ + +#if defined(NEED_L_GCOV) || defined(NEED_L_GCOV_INFO_TO_GCDA) +static inline void Likewise here. +dump_unsigned (gcov_unsigned_t word, + void (*dump) (const void *, unsigned, void *), + void *arg) +{ + (*dump) (, sizeof (word), arg); +} Likewise here. Adding the gcov_ prefix would make some lines longer than 79 characters. We already have several functions in this file without a gocv_ prefix, for example write_one_data(), write_topn_counters(). -- embedded brains GmbH Herr Sebastian HUBER Dornierstr. 4 82178 Puchheim Germany email: sebastian.hu...@embedded-brains.de phone: +49-89-18 94 741 - 16 fax: +49-89-18 94 741 - 08 Registergericht: Amtsgericht München Registernummer: HRB 157899 Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler Unsere Datenschutzerklärung finden Sie hier: https://embedded-brains.de/datenschutzerklaerung/
Re: [PATCH v2] gcov: Add __gcov_info_to_gdca()
On 23/07/2021 07:31, Martin Liška wrote: write_topn_counters (const struct gcov_ctr_info *ci_ptr, unsigned t_ix, - gcov_unsigned_t n_counts) + gcov_unsigned_t n_counts, + void (*dump) (const void *, unsigned, void *), + void *(*allocate)(unsigned, void *), + void *arg) I would likely prefer dump_fn and allocate_fn argumen t names. If I use dump_fn and allocate_fn throughout the code, then several lines would exceed 79 characters. This needs more vertical space. Should I still add the _fn postfix? -- embedded brains GmbH Herr Sebastian HUBER Dornierstr. 4 82178 Puchheim Germany email: sebastian.hu...@embedded-brains.de phone: +49-89-18 94 741 - 16 fax: +49-89-18 94 741 - 08 Registergericht: Amtsgericht München Registernummer: HRB 157899 Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler Unsere Datenschutzerklärung finden Sie hier: https://embedded-brains.de/datenschutzerklaerung/
Re: [PATCH v2] gcov: Add __gcov_info_to_gdca()
Hallo Martin, thanks for your review. On 23/07/2021 07:31, Martin Liška wrote: On 7/13/21 10:15 PM, Sebastian Huber wrote: Hello. Thanks for working on that, there's my review: Add __gcov_info_to_gcda() to libgcov to get the gcda data for a gcda info in a freestanding environment. It is intended to be used with the -fprofile-info-section option. A crude test program which doesn't use a linker script is (use "gcc -coverage -fprofile-info-section -lgcc test.c" to compile it): [...]>> @@ -365,46 +426,48 @@ write_topn_counters (const struct gcov_ctr_info *ci_ptr, if (list_sizes == NULL || counters > list_size_length) { list_size_length = MAX (LIST_SIZE_MIN_LENGTH, 2 * counters); -#if HAVE_SYS_MMAN_H +#if !defined(inhibit_libc) && HAVE_SYS_MMAN_H list_sizes = (unsigned *)malloc_mmap (list_size_length * sizeof (unsigned)); #endif /* Malloc fallback. */ if (list_sizes == NULL) - list_sizes = (unsigned *)xmalloc (list_size_length * sizeof (unsigned)); + list_sizes = + (unsigned *)(*allocate) (list_size_length * sizeof (unsigned), arg); } - memset (list_sizes, 0, counters * sizeof (unsigned)); Are you sure we don't need this zeroing? The list_sizes array is iterated two times using the same "counters" limit. In the first iteration ... unsigned pair_total = 0; for (unsigned i = 0; i < counters; i++) { gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2]; + unsigned sizes = 0; + ... the sizes is initialized to zero here and ... for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start; node != NULL; node = node->next) - { - ++pair_total; - ++list_sizes[i]; - } + ++sizes; + + pair_total += sizes; + list_sizes[i] = sizes; ... written to the array here. } unsigned disk_size = GCOV_TOPN_DISK_COUNTERS * counters + 2 * pair_total; - gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix), - GCOV_TAG_COUNTER_LENGTH (disk_size)); + dump_unsigned (GCOV_TAG_FOR_COUNTER (t_ix), dump, arg), + dump_unsigned (GCOV_TAG_COUNTER_LENGTH (disk_size), dump, arg); for (unsigned i = 0; i < counters; i++) { - gcov_write_counter (ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i]); - gcov_write_counter (list_sizes[i]); + dump_counter (ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i], dump, arg); + dump_counter (list_sizes[i], dump, arg); gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2]; unsigned j = 0; for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start; j < list_sizes[i]; node = node->next, j++) { - gcov_write_counter (node->value); - gcov_write_counter (node->count); + dump_counter (node->value, dump, arg); + dump_counter (node->count, dump, arg); } } } [...] +#ifdef NEED_L_GCOV_INFO_TO_GCDA +/* Convert the gcov info to a gcda data stream. It is intended for + free-standing environments which do not support the C library file I/O. */ + +void +__gcov_info_to_gcda (const struct gcov_info *gi_ptr, + void (*filename) (const char *, void *), What about begin_finaname_fn? + void (*dump) (const void *, unsigned, void *), + void *(*allocate) (unsigned, void *), + void *arg) +{ + (*filename) (gi_ptr->filename, arg); + write_one_data (gi_ptr, NULL, dump, allocate, arg); +} +#endif /* NEED_L_GCOV_INFO_TO_GCDA */ About gcov_write_summary: it should be also dumped in order to have a complete .gcda file, right? How can I get access to the summary information? Here it is not available: /* Information about a single object file. */ struct gcov_info { [...] #ifndef IN_GCOV_TOOL const struct gcov_fn_info *const *functions; /* pointer to pointers to function information */ #else struct gcov_fn_info **functions; struct gcov_summary summary; #endif /* !IN_GCOV_TOOL */ }; Should we dump a memset(, 0, summary) summary? Can we remove gcov_write_counter function? It is no longer used. What is the policy to remove functions? I think it can be handy having a script that creates a .gcda file from your reference dump output, what do you think? I think the dump output from the example is not useful for real applications. In an embedded system you would probably dump the information via a serial interface. The dump could be compressed and base64 encoded with some sort of EDAC. It would be nice having a test-case that can test your approach. The problem is that you need the linker set to get access to the gcov information. The test program of the commit message works on my Linux machine. I am not sure if it is generic enough for the test suite. Instead of printing the information we could compare it against an expected output so that we have a self-contained test program. -- embedded
Re: [PATCH v2] gcov: Add __gcov_info_to_gdca()
On 7/13/21 10:15 PM, Sebastian Huber wrote: Hello. Thanks for working on that, there's my review: Add __gcov_info_to_gcda() to libgcov to get the gcda data for a gcda info in a freestanding environment. It is intended to be used with the -fprofile-info-section option. A crude test program which doesn't use a linker script is (use "gcc -coverage -fprofile-info-section -lgcc test.c" to compile it): #include #include #include extern const struct gcov_info *my_info; static void filename (const char *f, void *arg) { printf("filename: %s\n", f); } static void dump (const void *d, unsigned n, void *arg) { const unsigned char *c = d; for (unsigned i = 0; i < n; ++i) printf ("%02x", c[i]); } static void * allocate (unsigned length, void *arg) { return malloc (length); } int main() { __asm__ volatile (".set my_info, .LPBX2"); __gcov_info_to_gcda (my_info, filename, dump, allocate, NULL); return 0; } With this patch, is included in libgcov-driver.c even if inhibit_libc is defined. This header file should be also available for freestanding environments. If this is not the case, then we have to define intptr_t somehow. The patch removes one use of memset() which makes the include superfluous. gcc/ * gcc/gcov-io.h (gcov_write): Declare. * gcc/gcov-io.c (gcov_write): New. * doc/invoke.texi (fprofile-info-section): Mention __gcov_info_to_gdca(). libgcc/ Makefile.in (LIBGCOV_DRIVER): Add _gcov_info_to_gcda. gcov.h (gcov_info): Declare. (__gcov_info_to_gdca): Likewise. libgcov-driver.c (#include ): New. (#include ): Remove. (NEED_L_GCOV): Conditionally define. (NEED_L_GCOV_INFO_TO_GCDA): Likewise. (are_all_counters_zero): New. (dump_handler): Likewise. (allocate_handler): Likewise. (dump_unsigned): Likewise. (dump_counter): Likewise. (write_topn_counters): Add dump, allocate, and arg parameters. Use dump_unsigned() and dump_counter(). (write_one_data): Add dump, allocate, and arg parameters. Use dump_unsigned(), dump_counter(), and are_all_counters_zero(). (__gcov_info_to_gcda): New. --- gcc/doc/invoke.texi | 80 +++--- gcc/gcov-io.c | 10 +++ gcc/gcov-io.h | 1 + libgcc/Makefile.in | 2 +- libgcc/gcov.h | 17 libgcc/libgcov-driver.c | 176 ++-- 6 files changed, 230 insertions(+), 56 deletions(-) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index e67d47af676d..2c514acf2003 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -14782,17 +14782,17 @@ To optimize the program based on the collected profile information, use Register the profile information in the specified section instead of using a constructor/destructor. The section name is @var{name} if it is specified, otherwise the section name defaults to @code{.gcov_info}. A pointer to the -profile information generated by @option{-fprofile-arcs} or -@option{-ftest-coverage} is placed in the specified section for each -translation unit. This option disables the profile information registration -through a constructor and it disables the profile information processing -through a destructor. This option is not intended to be used in hosted -environments such as GNU/Linux. It targets systems with limited resources -which do not support constructors and destructors. The linker could collect -the input sections in a continuous memory block and define start and end -symbols. The runtime support could dump the profiling information registered -in this linker set during program termination to a serial line for example. A -GNU linker script example which defines a linker output section follows: +profile information generated by @option{-fprofile-arcs} is placed in the +specified section for each translation unit. This option disables the profile +information registration through a constructor and it disables the profile +information processing through a destructor. This option is not intended to be +used in hosted environments such as GNU/Linux. It targets free-standing +environments (for example embedded systems) with limited resources which do not +support constructors/destructors or the C library file I/O. + +The linker could collect the input sections in a continuous memory block and +define start and end symbols. A GNU linker script example which defines a +linker output section follows: @smallexample .gcov_info : @@ -14803,6 +14803,64 @@ GNU linker script example which defines a linker output section follows: @} @end smallexample +The program could dump the profiling information registered in this linker set +for example like this: + +@smallexample +#include +#include +#include + +extern const struct gcov_info