@@ -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)
{
@@ -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)
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(+)