re PR c++/54891 ([C++11] lambda-expression and explicit type conversion (cast notation))
[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 extern void set_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
48 extern void reset_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
49
50 #ifdef L_gcov_flush
51
52 #ifdef __GTHREAD_MUTEX_INIT
53 ATTRIBUTE_HIDDEN __gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
54 #define init_mx_once()
55 #else
56 __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
57
58 static void
59 init_mx (void)
60 {
61 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
62 }
63 static void
64 init_mx_once (void)
65 {
66 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
67 __gthread_once (&once, init_mx);
68 }
69 #endif
70
71 /* Called before fork or exec - write out profile information gathered so
72 far and reset it to zero. This avoids duplication or loss of the
73 profile information gathered so far. */
74
75 void
76 __gcov_flush (void)
77 {
78 init_mx_once ();
79 __gthread_mutex_lock (&__gcov_flush_mx);
80
81 gcov_exit ();
82 gcov_clear ();
83
84 __gthread_mutex_unlock (&__gcov_flush_mx);
85 }
86
87 #endif /* L_gcov_flush */
88
89 #ifdef L_gcov_reset
90
91 /* Function that can be called from application to reset counters to zero,
92 in order to collect profile in region of interest. */
93
94 void
95 __gcov_reset (void)
96 {
97 gcov_clear ();
98 /* Re-enable dumping to support collecting profile in multiple regions
99 of interest. */
100 reset_gcov_dump_complete ();
101 }
102
103 #endif /* L_gcov_reset */
104
105 #ifdef L_gcov_dump
106
107 /* Function that can be called from application to write profile collected
108 so far, in order to collect profile in region of interest. */
109
110 void
111 __gcov_dump (void)
112 {
113 gcov_exit ();
114 /* Prevent profile from being dumped a second time on application exit. */
115 set_gcov_dump_complete ();
116 }
117
118 #endif /* L_gcov_dump */
119
120
121 #ifdef L_gcov_fork
122 /* A wrapper for the fork function. Flushes the accumulated profiling data, so
123 that they are not counted twice. */
124
125 pid_t
126 __gcov_fork (void)
127 {
128 pid_t pid;
129 extern __gthread_mutex_t __gcov_flush_mx;
130 __gcov_flush ();
131 pid = fork ();
132 if (pid == 0)
133 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
134 return pid;
135 }
136 #endif
137
138 #ifdef L_gcov_execl
139 /* A wrapper for the execl function. Flushes the accumulated profiling data, so
140 that they are not lost. */
141
142 int
143 __gcov_execl (const char *path, char *arg, ...)
144 {
145 va_list ap, aq;
146 unsigned i, length;
147 char **args;
148
149 __gcov_flush ();
150
151 va_start (ap, arg);
152 va_copy (aq, ap);
153
154 length = 2;
155 while (va_arg (ap, char *))
156 length++;
157 va_end (ap);
158
159 args = (char **) alloca (length * sizeof (void *));
160 args[0] = arg;
161 for (i = 1; i < length; i++)
162 args[i] = va_arg (aq, char *);
163 va_end (aq);
164
165 return execv (path, args);
166 }
167 #endif
168
169 #ifdef L_gcov_execlp
170 /* A wrapper for the execlp function. Flushes the accumulated profiling data, so
171 that they are not lost. */
172
173 int
174 __gcov_execlp (const char *path, char *arg, ...)
175 {
176 va_list ap, aq;
177 unsigned i, length;
178 char **args;
179
180 __gcov_flush ();
181
182 va_start (ap, arg);
183 va_copy (aq, ap);
184
185 length = 2;
186 while (va_arg (ap, char *))
187 length++;
188 va_end (ap);
189
190 args = (char **) alloca (length * sizeof (void *));
191 args[0] = arg;
192 for (i = 1; i < length; i++)
193 args[i] = va_arg (aq, char *);
194 va_end (aq);
195
196 return execvp (path, args);
197 }
198 #endif
199
200 #ifdef L_gcov_execle
201 /* A wrapper for the execle function. Flushes the accumulated profiling data, so
202 that they are not lost. */
203
204 int
205 __gcov_execle (const char *path, char *arg, ...)
206 {
207 va_list ap, aq;
208 unsigned i, length;
209 char **args;
210 char **envp;
211
212 __gcov_flush ();
213
214 va_start (ap, arg);
215 va_copy (aq, ap);
216
217 length = 2;
218 while (va_arg (ap, char *))
219 length++;
220 va_end (ap);
221
222 args = (char **) alloca (length * sizeof (void *));
223 args[0] = arg;
224 for (i = 1; i < length; i++)
225 args[i] = va_arg (aq, char *);
226 envp = va_arg (aq, char **);
227 va_end (aq);
228
229 return execve (path, args, envp);
230 }
231 #endif
232
233 #ifdef L_gcov_execv
234 /* A wrapper for the execv function. Flushes the accumulated profiling data, so
235 that they are not lost. */
236
237 int
238 __gcov_execv (const char *path, char *const argv[])
239 {
240 __gcov_flush ();
241 return execv (path, argv);
242 }
243 #endif
244
245 #ifdef L_gcov_execvp
246 /* A wrapper for the execvp function. Flushes the accumulated profiling data, so
247 that they are not lost. */
248
249 int
250 __gcov_execvp (const char *path, char *const argv[])
251 {
252 __gcov_flush ();
253 return execvp (path, argv);
254 }
255 #endif
256
257 #ifdef L_gcov_execve
258 /* A wrapper for the execve function. Flushes the accumulated profiling data, so
259 that they are not lost. */
260
261 int
262 __gcov_execve (const char *path, char *const argv[], char *const envp[])
263 {
264 __gcov_flush ();
265 return execve (path, argv, envp);
266 }
267 #endif
268 #endif /* inhibit_libc */