libgcov-driver.c (set_gcov_dump_complete, [...]): Remove global functions polluting...
[gcc.git] / libgcc / libgcov-interface.c
1 /* Routines required for instrumenting a program. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989-2014 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
25
26 #include "libgcov.h"
27 #include "gthr.h"
28
29 #if defined(inhibit_libc)
30
31 #ifdef L_gcov_flush
32 void __gcov_flush (void) {}
33 #endif
34
35 #ifdef L_gcov_reset
36 void __gcov_reset (void) {}
37 #endif
38
39 #ifdef L_gcov_dump
40 void __gcov_dump (void) {}
41 #endif
42
43 #else
44
45 extern void gcov_clear (void) ATTRIBUTE_HIDDEN;
46 extern void gcov_exit (void) ATTRIBUTE_HIDDEN;
47
48 #ifdef L_gcov_flush
49
50 #ifdef __GTHREAD_MUTEX_INIT
51 ATTRIBUTE_HIDDEN __gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
52 #define init_mx_once()
53 #else
54 __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
55
56 static void
57 init_mx (void)
58 {
59 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
60 }
61 static void
62 init_mx_once (void)
63 {
64 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
65 __gthread_once (&once, init_mx);
66 }
67 #endif
68
69 /* Called before fork or exec - write out profile information gathered so
70 far and reset it to zero. This avoids duplication or loss of the
71 profile information gathered so far. */
72
73 void
74 __gcov_flush (void)
75 {
76 init_mx_once ();
77 __gthread_mutex_lock (&__gcov_flush_mx);
78
79 gcov_exit ();
80 gcov_clear ();
81
82 __gthread_mutex_unlock (&__gcov_flush_mx);
83 }
84
85 #endif /* L_gcov_flush */
86
87 #ifdef L_gcov_reset
88
89 /* Function that can be called from application to reset counters to zero,
90 in order to collect profile in region of interest. */
91
92 void
93 __gcov_reset (void)
94 {
95 gcov_clear ();
96 }
97
98 #endif /* L_gcov_reset */
99
100 #ifdef L_gcov_dump
101
102 /* Function that can be called from application to write profile collected
103 so far, in order to collect profile in region of interest. */
104
105 void
106 __gcov_dump (void)
107 {
108 gcov_exit ();
109 }
110
111 #endif /* L_gcov_dump */
112
113
114 #ifdef L_gcov_fork
115 /* A wrapper for the fork function. Flushes the accumulated profiling data, so
116 that they are not counted twice. */
117
118 pid_t
119 __gcov_fork (void)
120 {
121 pid_t pid;
122 extern __gthread_mutex_t __gcov_flush_mx;
123 __gcov_flush ();
124 pid = fork ();
125 if (pid == 0)
126 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
127 return pid;
128 }
129 #endif
130
131 #ifdef L_gcov_execl
132 /* A wrapper for the execl function. Flushes the accumulated profiling data, so
133 that they are not lost. */
134
135 int
136 __gcov_execl (const char *path, char *arg, ...)
137 {
138 va_list ap, aq;
139 unsigned i, length;
140 char **args;
141
142 __gcov_flush ();
143
144 va_start (ap, arg);
145 va_copy (aq, ap);
146
147 length = 2;
148 while (va_arg (ap, char *))
149 length++;
150 va_end (ap);
151
152 args = (char **) alloca (length * sizeof (void *));
153 args[0] = arg;
154 for (i = 1; i < length; i++)
155 args[i] = va_arg (aq, char *);
156 va_end (aq);
157
158 return execv (path, args);
159 }
160 #endif
161
162 #ifdef L_gcov_execlp
163 /* A wrapper for the execlp function. Flushes the accumulated profiling data, so
164 that they are not lost. */
165
166 int
167 __gcov_execlp (const char *path, char *arg, ...)
168 {
169 va_list ap, aq;
170 unsigned i, length;
171 char **args;
172
173 __gcov_flush ();
174
175 va_start (ap, arg);
176 va_copy (aq, ap);
177
178 length = 2;
179 while (va_arg (ap, char *))
180 length++;
181 va_end (ap);
182
183 args = (char **) alloca (length * sizeof (void *));
184 args[0] = arg;
185 for (i = 1; i < length; i++)
186 args[i] = va_arg (aq, char *);
187 va_end (aq);
188
189 return execvp (path, args);
190 }
191 #endif
192
193 #ifdef L_gcov_execle
194 /* A wrapper for the execle function. Flushes the accumulated profiling data, so
195 that they are not lost. */
196
197 int
198 __gcov_execle (const char *path, char *arg, ...)
199 {
200 va_list ap, aq;
201 unsigned i, length;
202 char **args;
203 char **envp;
204
205 __gcov_flush ();
206
207 va_start (ap, arg);
208 va_copy (aq, ap);
209
210 length = 2;
211 while (va_arg (ap, char *))
212 length++;
213 va_end (ap);
214
215 args = (char **) alloca (length * sizeof (void *));
216 args[0] = arg;
217 for (i = 1; i < length; i++)
218 args[i] = va_arg (aq, char *);
219 envp = va_arg (aq, char **);
220 va_end (aq);
221
222 return execve (path, args, envp);
223 }
224 #endif
225
226 #ifdef L_gcov_execv
227 /* A wrapper for the execv function. Flushes the accumulated profiling data, so
228 that they are not lost. */
229
230 int
231 __gcov_execv (const char *path, char *const argv[])
232 {
233 __gcov_flush ();
234 return execv (path, argv);
235 }
236 #endif
237
238 #ifdef L_gcov_execvp
239 /* A wrapper for the execvp function. Flushes the accumulated profiling data, so
240 that they are not lost. */
241
242 int
243 __gcov_execvp (const char *path, char *const argv[])
244 {
245 __gcov_flush ();
246 return execvp (path, argv);
247 }
248 #endif
249
250 #ifdef L_gcov_execve
251 /* A wrapper for the execve function. Flushes the accumulated profiling data, so
252 that they are not lost. */
253
254 int
255 __gcov_execve (const char *path, char *const argv[], char *const envp[])
256 {
257 __gcov_flush ();
258 return execve (path, argv, envp);
259 }
260 #endif
261 #endif /* inhibit_libc */