diff mbox

gcov: Add gcov data struct to sysfs

Message ID 20170504002352.4683-1-matthew.brown.dev@gmail.com
State Accepted
Headers show

Commit Message

Matt Brown May 4, 2017, 12:23 a.m. UTC
Extracting the skiboot gcov data is currently a tedious process which
involves taking a mem dump of skiboot and searching for the gcov_info
struct.
This patch adds the gcov struct to sysfs under /opal/exports. Allowing the
data to be copied directly into userspace and processed.

Signed-off-by: Matt Brown <matthew.brown.dev@gmail.com>
---
 core/gcov-profiling.c | 18 ++++++++++++++++++
 core/opal.c           |  9 +++++++++
 2 files changed, 27 insertions(+)

Comments

Stewart Smith March 13, 2018, 4:34 a.m. UTC | #1
Matt Brown <matthew.brown.dev@gmail.com> writes:
> Extracting the skiboot gcov data is currently a tedious process which
> involves taking a mem dump of skiboot and searching for the gcov_info
> struct.
> This patch adds the gcov struct to sysfs under /opal/exports. Allowing the
> data to be copied directly into userspace and processed.
>
> Signed-off-by: Matt Brown <matthew.brown.dev@gmail.com>
> ---
>  core/gcov-profiling.c | 18 ++++++++++++++++++
>  core/opal.c           |  9 +++++++++
>  2 files changed, 27 insertions(+)

Again, sorry for the huge delay on this.

I've merged a modified version of this to master as of
8d0f41e021b3475a411371cf87b81ae4af763eca.

I've ended up just dumping out the whole chunk of memory to feed
directly into extract-gcov.c code, and I've tested this to work on a
couple of P9 machines. With some work-in-progress op-test-framework
code, this is getting really close to 100% automatable code coverage
gathering!

Thanks heaps for the patch and sorry again it took so long to look at,
test and merge!
diff mbox

Patch

diff --git a/core/gcov-profiling.c b/core/gcov-profiling.c
index cf8b509..2d4b2b2 100644
--- a/core/gcov-profiling.c
+++ b/core/gcov-profiling.c
@@ -51,6 +51,8 @@  struct gcov_info *gcov_info_list;
 
 void __gcov_init(struct gcov_info* f);
 void skiboot_gcov_done(void);
+void *skiboot_gcov_base(void);
+int skiboot_gcov_size(void);
 void __gcov_flush(void) __attrconst;
 void __gcov_merge_add(gcov_type *counters, unsigned int n_counters) __attrconst;
 void __gcov_merge_single(gcov_type *counters, unsigned int n_counters) __attrconst;
@@ -88,6 +90,22 @@  void skiboot_gcov_done(void)
 	printf("GCOV: gcov_info_list at 0x%p\n", gcov_info_list);
 }
 
+void *skiboot_gcov_base(void)
+{
+	return (void *)gcov_info_list;
+}
+
+int skiboot_gcov_size(void)
+{
+	int n = 0;
+	struct gcov_info *i = gcov_info_list;
+
+	while (i->next) {
+		n += sizeof(struct gcov_info);
+		i = i->next;
+	}
+	return n;
+}
 
 void __gcov_merge_add(gcov_type *counters, unsigned int n_counters)
 {
diff --git a/core/opal.c b/core/opal.c
index a719d26..34263a5 100644
--- a/core/opal.c
+++ b/core/opal.c
@@ -51,6 +51,11 @@  static uint64_t opal_dynamic_events;
 extern uint32_t attn_trigger;
 extern uint32_t hir_trigger;
 
+#ifdef SKIBOOT_GCOV
+void *skiboot_gcov_base(void);
+int skiboot_gcov_size(void);
+#endif
+
 void opal_table_init(void)
 {
 	struct opal_table_entry *s = __opal_table_start;
@@ -142,6 +147,10 @@  static void add_opal_firmware_exports_node(struct dt_node *node)
 	dt_add_property_u64s(exports, "symbol_map", sym_start, sym_size);
 	dt_add_property_u64s(exports, "hdat_map", SPIRA_HEAP_BASE,
 				SPIRA_HEAP_SIZE);
+#ifdef SKIBOOT_GCOV
+	dt_add_property_u64s(exports, "gcov", (uint64_t)skiboot_gcov_base(),
+				skiboot_gcov_size());
+#endif
 }
 
 static void add_opal_firmware_node(void)