aboutsummaryrefslogtreecommitdiffstats
path: root/roms/skiboot/core/gcov-profiling.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/skiboot/core/gcov-profiling.c')
-rw-r--r--roms/skiboot/core/gcov-profiling.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/roms/skiboot/core/gcov-profiling.c b/roms/skiboot/core/gcov-profiling.c
new file mode 100644
index 000000000..fdad51ed9
--- /dev/null
+++ b/roms/skiboot/core/gcov-profiling.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+/*
+ * libgcov skeleton reimplementation to build skiboot with gcov support
+ *
+ * Copyright 2015-2018 IBM Corp.
+ */
+
+#include <skiboot.h>
+#include <compiler.h>
+#include <stdio.h>
+
+typedef long gcov_type;
+
+/*
+ * This is GCC internal data structure. See GCC libgcc/libgcov.h for
+ * details.
+ *
+ * If gcc changes this, we have to change it.
+ */
+
+typedef unsigned int gcov_unsigned_int;
+
+#if __GNUC__ == 4 && __GNUC_MINOR__ >= 9
+#define GCOV_COUNTERS 9
+#else
+#define GCOV_COUNTERS 8
+#endif
+
+struct gcov_info
+{
+ gcov_unsigned_int version;
+ struct gcov_info *next;
+ gcov_unsigned_int stamp;
+ const char *filename;
+ void (*merge[GCOV_COUNTERS])(gcov_type *, unsigned int);
+ unsigned int n_functions;
+ struct gcov_fn_info **functions;
+};
+
+/* We have a list of all gcov info set up at startup */
+struct gcov_info *gcov_info_list;
+
+void __gcov_init(struct gcov_info* f);
+void skiboot_gcov_done(void);
+void __gcov_flush(void);
+void __gcov_merge_add(gcov_type *counters, unsigned int n_counters);
+void __gcov_merge_single(gcov_type *counters, unsigned int n_counters);
+void __gcov_merge_delta(gcov_type *counters, unsigned int n_counters);
+void __gcov_merge_ior(gcov_type *counters, unsigned int n_counters);
+void __gcov_merge_time_profile(gcov_type *counters, unsigned int n_counters);
+void __gcov_exit(void);
+
+void __gcov_init(struct gcov_info* f)
+{
+ static gcov_unsigned_int version = 0;
+
+ if (version == 0) {
+ printf("GCOV version: %u\n", f->version);
+ version = f->version;
+ }
+
+ if (gcov_info_list)
+ f->next = gcov_info_list;
+
+ gcov_info_list = f;
+ return;
+}
+
+void skiboot_gcov_done(void)
+{
+ struct gcov_info *i = gcov_info_list;
+
+ if (i->filename)
+ printf("GCOV: gcov_info_list looks sane (first file: %s)\n",
+ i->filename);
+ else
+ prlog(PR_WARNING, "GCOV: gcov_info_list doesn't look sane. "
+ "i->filename == NULL.");
+
+ printf("GCOV: gcov_info_list at 0x%p\n", gcov_info_list);
+}
+
+void __gcov_merge_add(gcov_type *counters, unsigned int n_counters)
+{
+ (void)counters;
+ (void)n_counters;
+
+ return;
+}
+
+void __gcov_flush(void)
+{
+ return;
+}
+
+void __gcov_merge_single(gcov_type *counters, unsigned int n_counters)
+{
+ (void)counters;
+ (void)n_counters;
+
+ return;
+}
+
+void __gcov_merge_delta(gcov_type *counters, unsigned int n_counters)
+{
+ (void)counters;
+ (void)n_counters;
+
+ return;
+}
+
+void __gcov_merge_ior(gcov_type *counters, unsigned int n_counters)
+{
+ (void)counters;
+ (void)n_counters;
+ return;
+}
+
+void __gcov_merge_time_profile(gcov_type *counters, unsigned int n_counters)
+{
+ (void)counters;
+ (void)n_counters;
+}
+
+void __gcov_exit(void)
+{
+}