Merge from trunk:
[official-gcc.git] / main / libgcc / libgcov-interface.c
bloba0f3f0d8bad3e996a6e541210e06fbe38475e59e
1 /* Routines required for instrumenting a program. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989-2014 Free Software Foundation, Inc.
5 This file is part of GCC.
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.
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.
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.
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/>. */
26 #include "libgcov.h"
27 #include "gthr.h"
29 #if defined(inhibit_libc)
31 #ifdef L_gcov_flush
32 void __gcov_flush (void) {}
33 #endif
35 #ifdef L_gcov_reset
36 void __gcov_reset (void) {}
37 #endif
39 #ifdef L_gcov_dump
40 void __gcov_dump (void) {}
41 #endif
43 #else
45 extern void gcov_clear (void) ATTRIBUTE_HIDDEN;
46 extern void gcov_exit (void) ATTRIBUTE_HIDDEN;
47 extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
49 #ifdef L_gcov_flush
50 #ifdef __GTHREAD_MUTEX_INIT
51 __gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
52 #define init_mx_once()
53 #else
54 __gthread_mutex_t __gcov_flush_mx;
56 static void
57 init_mx (void)
59 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
62 static void
63 init_mx_once (void)
65 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
66 __gthread_once (&once, init_mx);
68 #endif
70 /* Called before fork or exec - write out profile information gathered so
71 far and reset it to zero. This avoids duplication or loss of the
72 profile information gathered so far. */
74 void
75 __gcov_flush (void)
77 init_mx_once ();
78 __gthread_mutex_lock (&__gcov_flush_mx);
80 gcov_exit ();
81 gcov_clear ();
83 __gthread_mutex_unlock (&__gcov_flush_mx);
86 #endif /* L_gcov_flush */
88 #ifdef L_gcov_reset
90 /* Function that can be called from application to reset counters to zero,
91 in order to collect profile in region of interest. */
93 void
94 __gcov_reset (void)
96 gcov_clear ();
99 #endif /* L_gcov_reset */
101 #ifdef L_gcov_dump
103 /* Function that can be called from application to write profile collected
104 so far, in order to collect profile in region of interest. */
106 void
107 __gcov_dump (void)
109 gcov_exit ();
112 #endif /* L_gcov_dump */
114 #ifdef L_gcov_sampling
116 /* Emitted in coverage.c. */
118 /* Sampling period. */
119 extern gcov_unsigned_t __gcov_sampling_period;
120 extern gcov_unsigned_t __gcov_has_sampling;
121 void __gcov_set_sampling_period (unsigned int period);
122 unsigned int __gcov_sampling_enabled ();
123 /* Per thread sample counter. */
124 __thread gcov_unsigned_t __gcov_sample_counter = 0;
126 /* Set sampling period to PERIOD. */
128 void __gcov_set_sampling_period (unsigned int period)
130 gcc_assert (__gcov_has_sampling);
131 __gcov_sampling_period = period;
134 unsigned int __gcov_sampling_enabled ()
136 return __gcov_has_sampling;
139 #endif
141 #ifdef L_gcov_prefix
143 /* Profile directory prefix specified to -fprofile-generate=. */
144 extern char * __gcov_profile_prefix;
146 char *__gcov_get_profile_prefix ()
148 return __gcov_profile_prefix;
151 #endif
154 #ifdef L_gcov_fork
155 /* A wrapper for the fork function. Flushes the accumulated profiling data, so
156 that they are not counted twice. */
158 pid_t
159 __gcov_fork (void)
161 pid_t pid;
162 extern __gthread_mutex_t __gcov_flush_mx;
163 __gcov_flush ();
164 pid = fork ();
165 if (pid == 0)
166 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
167 return pid;
169 #endif
171 #ifdef L_gcov_execl
172 /* A wrapper for the execl function. Flushes the accumulated profiling data, so
173 that they are not lost. */
176 __gcov_execl (const char *path, char *arg, ...)
178 va_list ap, aq;
179 unsigned i, length;
180 char **args;
182 __gcov_flush ();
184 va_start (ap, arg);
185 va_copy (aq, ap);
187 length = 2;
188 while (va_arg (ap, char *))
189 length++;
190 va_end (ap);
192 args = (char **) alloca (length * sizeof (void *));
193 args[0] = arg;
194 for (i = 1; i < length; i++)
195 args[i] = va_arg (aq, char *);
196 va_end (aq);
198 return execv (path, args);
200 #endif
202 #ifdef L_gcov_execlp
203 /* A wrapper for the execlp function. Flushes the accumulated
204 profiling data, so that they are not lost. */
207 __gcov_execlp (const char *path, char *arg, ...)
209 va_list ap, aq;
210 unsigned i, length;
211 char **args;
213 __gcov_flush ();
215 va_start (ap, arg);
216 va_copy (aq, ap);
218 length = 2;
219 while (va_arg (ap, char *))
220 length++;
221 va_end (ap);
223 args = (char **) alloca (length * sizeof (void *));
224 args[0] = arg;
225 for (i = 1; i < length; i++)
226 args[i] = va_arg (aq, char *);
227 va_end (aq);
229 return execvp (path, args);
231 #endif
233 #ifdef L_gcov_execle
234 /* A wrapper for the execle function. Flushes the accumulated
235 profiling data, so that they are not lost. */
238 __gcov_execle (const char *path, char *arg, ...)
240 va_list ap, aq;
241 unsigned i, length;
242 char **args;
243 char **envp;
245 __gcov_flush ();
247 va_start (ap, arg);
248 va_copy (aq, ap);
250 length = 2;
251 while (va_arg (ap, char *))
252 length++;
253 va_end (ap);
255 args = (char **) alloca (length * sizeof (void *));
256 args[0] = arg;
257 for (i = 1; i < length; i++)
258 args[i] = va_arg (aq, char *);
259 envp = va_arg (aq, char **);
260 va_end (aq);
262 return execve (path, args, envp);
264 #endif
266 #ifdef L_gcov_execv
267 /* A wrapper for the execv function. Flushes the accumulated
268 profiling data, so that they are not lost. */
271 __gcov_execv (const char *path, char *const argv[])
273 __gcov_flush ();
274 return execv (path, argv);
276 #endif
278 #ifdef L_gcov_execvp
279 /* A wrapper for the execvp function. Flushes the accumulated
280 profiling data, so that they are not lost. */
283 __gcov_execvp (const char *path, char *const argv[])
285 __gcov_flush ();
286 return execvp (path, argv);
288 #endif
290 #ifdef L_gcov_execve
291 /* A wrapper for the execve function. Flushes the accumulated
292 profiling data, so that they are not lost. */
295 __gcov_execve (const char *path, char *const argv[], char *const envp[])
297 __gcov_flush ();
298 return execve (path, argv, envp);
300 #endif
301 #endif /* inhibit_libc */