aboutsummaryrefslogtreecommitdiff
path: root/core/gcov-profiling.c
blob: c94438ec5e33a3f1cbd58fc783bdd6ab593ea8a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// SPDX-License-Identifier: Apache-2.0
/*
 * 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)
{
}