PR c++/60417
[official-gcc.git] / libgcc / libgcov-interface.c
blobd4a7f50c22fa0e49e3611d7ac8130eb5387ea0e2
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 */
115 #ifdef L_gcov_fork
116 /* A wrapper for the fork function. Flushes the accumulated profiling data, so
117 that they are not counted twice. */
119 pid_t
120 __gcov_fork (void)
122 pid_t pid;
123 extern __gthread_mutex_t __gcov_flush_mx;
124 __gcov_flush ();
125 pid = fork ();
126 if (pid == 0)
127 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
128 return pid;
130 #endif
132 #ifdef L_gcov_execl
133 /* A wrapper for the execl function. Flushes the accumulated profiling data, so
134 that they are not lost. */
137 __gcov_execl (const char *path, char *arg, ...)
139 va_list ap, aq;
140 unsigned i, length;
141 char **args;
143 __gcov_flush ();
145 va_start (ap, arg);
146 va_copy (aq, ap);
148 length = 2;
149 while (va_arg (ap, char *))
150 length++;
151 va_end (ap);
153 args = (char **) alloca (length * sizeof (void *));
154 args[0] = arg;
155 for (i = 1; i < length; i++)
156 args[i] = va_arg (aq, char *);
157 va_end (aq);
159 return execv (path, args);
161 #endif
163 #ifdef L_gcov_execlp
164 /* A wrapper for the execlp function. Flushes the accumulated
165 profiling data, so that they are not lost. */
168 __gcov_execlp (const char *path, char *arg, ...)
170 va_list ap, aq;
171 unsigned i, length;
172 char **args;
174 __gcov_flush ();
176 va_start (ap, arg);
177 va_copy (aq, ap);
179 length = 2;
180 while (va_arg (ap, char *))
181 length++;
182 va_end (ap);
184 args = (char **) alloca (length * sizeof (void *));
185 args[0] = arg;
186 for (i = 1; i < length; i++)
187 args[i] = va_arg (aq, char *);
188 va_end (aq);
190 return execvp (path, args);
192 #endif
194 #ifdef L_gcov_execle
195 /* A wrapper for the execle function. Flushes the accumulated
196 profiling data, so that they are not lost. */
199 __gcov_execle (const char *path, char *arg, ...)
201 va_list ap, aq;
202 unsigned i, length;
203 char **args;
204 char **envp;
206 __gcov_flush ();
208 va_start (ap, arg);
209 va_copy (aq, ap);
211 length = 2;
212 while (va_arg (ap, char *))
213 length++;
214 va_end (ap);
216 args = (char **) alloca (length * sizeof (void *));
217 args[0] = arg;
218 for (i = 1; i < length; i++)
219 args[i] = va_arg (aq, char *);
220 envp = va_arg (aq, char **);
221 va_end (aq);
223 return execve (path, args, envp);
225 #endif
227 #ifdef L_gcov_execv
228 /* A wrapper for the execv function. Flushes the accumulated
229 profiling data, so that they are not lost. */
232 __gcov_execv (const char *path, char *const argv[])
234 __gcov_flush ();
235 return execv (path, argv);
237 #endif
239 #ifdef L_gcov_execvp
240 /* A wrapper for the execvp function. Flushes the accumulated
241 profiling data, so that they are not lost. */
244 __gcov_execvp (const char *path, char *const argv[])
246 __gcov_flush ();
247 return execvp (path, argv);
249 #endif
251 #ifdef L_gcov_execve
252 /* A wrapper for the execve function. Flushes the accumulated
253 profiling data, so that they are not lost. */
256 __gcov_execve (const char *path, char *const argv[], char *const envp[])
258 __gcov_flush ();
259 return execve (path, argv, envp);
261 #endif
262 #endif /* inhibit_libc */