Reverting merge from trunk
[official-gcc.git] / libgcc / libgcov-interface.c
blob5e23178b87e3b3038b007cb54c5fc2021736f291
1 /* Routines required for instrumenting a program. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989-2013 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 "tconfig.h"
27 #include "tsystem.h"
28 #include "coretypes.h"
29 #include "tm.h"
30 #include "libgcc_tm.h"
31 #include "gthr.h"
33 #if defined(inhibit_libc)
34 #define IN_LIBGCOV (-1)
35 #else
36 #define IN_LIBGCOV 1
37 #endif
38 #include "gcov-io.h"
40 #if defined(inhibit_libc)
42 #ifdef L_gcov_flush
43 void __gcov_flush (void) {}
44 #endif
46 #ifdef L_gcov_reset
47 void __gcov_reset (void) {}
48 #endif
50 #ifdef L_gcov_dump
51 void __gcov_dump (void) {}
52 #endif
54 #else
56 extern void gcov_clear (void) ATTRIBUTE_HIDDEN;
57 extern void gcov_exit (void) ATTRIBUTE_HIDDEN;
58 extern void set_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
59 extern void reset_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
61 #ifdef L_gcov_flush
63 #ifdef __GTHREAD_MUTEX_INIT
64 ATTRIBUTE_HIDDEN __gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
65 #define init_mx_once()
66 #else
67 __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
69 static void
70 init_mx (void)
72 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
74 static void
75 init_mx_once (void)
77 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
78 __gthread_once (&once, init_mx);
80 #endif
82 /* Called before fork or exec - write out profile information gathered so
83 far and reset it to zero. This avoids duplication or loss of the
84 profile information gathered so far. */
86 void
87 __gcov_flush (void)
89 init_mx_once ();
90 __gthread_mutex_lock (&__gcov_flush_mx);
92 gcov_exit ();
93 gcov_clear ();
95 __gthread_mutex_unlock (&__gcov_flush_mx);
98 #endif /* L_gcov_flush */
100 #ifdef L_gcov_reset
102 /* Function that can be called from application to reset counters to zero,
103 in order to collect profile in region of interest. */
105 void
106 __gcov_reset (void)
108 gcov_clear ();
109 /* Re-enable dumping to support collecting profile in multiple regions
110 of interest. */
111 reset_gcov_dump_complete ();
114 #endif /* L_gcov_reset */
116 #ifdef L_gcov_dump
118 /* Function that can be called from application to write profile collected
119 so far, in order to collect profile in region of interest. */
121 void
122 __gcov_dump (void)
124 gcov_exit ();
125 /* Prevent profile from being dumped a second time on application exit. */
126 set_gcov_dump_complete ();
129 #endif /* L_gcov_dump */
132 #ifdef L_gcov_fork
133 /* A wrapper for the fork function. Flushes the accumulated profiling data, so
134 that they are not counted twice. */
136 pid_t
137 __gcov_fork (void)
139 pid_t pid;
140 extern __gthread_mutex_t __gcov_flush_mx;
141 __gcov_flush ();
142 pid = fork ();
143 if (pid == 0)
144 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
145 return pid;
147 #endif
149 #ifdef L_gcov_execl
150 /* A wrapper for the execl function. Flushes the accumulated profiling data, so
151 that they are not lost. */
154 __gcov_execl (const char *path, char *arg, ...)
156 va_list ap, aq;
157 unsigned i, length;
158 char **args;
160 __gcov_flush ();
162 va_start (ap, arg);
163 va_copy (aq, ap);
165 length = 2;
166 while (va_arg (ap, char *))
167 length++;
168 va_end (ap);
170 args = (char **) alloca (length * sizeof (void *));
171 args[0] = arg;
172 for (i = 1; i < length; i++)
173 args[i] = va_arg (aq, char *);
174 va_end (aq);
176 return execv (path, args);
178 #endif
180 #ifdef L_gcov_execlp
181 /* A wrapper for the execlp function. Flushes the accumulated profiling data, so
182 that they are not lost. */
185 __gcov_execlp (const char *path, char *arg, ...)
187 va_list ap, aq;
188 unsigned i, length;
189 char **args;
191 __gcov_flush ();
193 va_start (ap, arg);
194 va_copy (aq, ap);
196 length = 2;
197 while (va_arg (ap, char *))
198 length++;
199 va_end (ap);
201 args = (char **) alloca (length * sizeof (void *));
202 args[0] = arg;
203 for (i = 1; i < length; i++)
204 args[i] = va_arg (aq, char *);
205 va_end (aq);
207 return execvp (path, args);
209 #endif
211 #ifdef L_gcov_execle
212 /* A wrapper for the execle function. Flushes the accumulated profiling data, so
213 that they are not lost. */
216 __gcov_execle (const char *path, char *arg, ...)
218 va_list ap, aq;
219 unsigned i, length;
220 char **args;
221 char **envp;
223 __gcov_flush ();
225 va_start (ap, arg);
226 va_copy (aq, ap);
228 length = 2;
229 while (va_arg (ap, char *))
230 length++;
231 va_end (ap);
233 args = (char **) alloca (length * sizeof (void *));
234 args[0] = arg;
235 for (i = 1; i < length; i++)
236 args[i] = va_arg (aq, char *);
237 envp = va_arg (aq, char **);
238 va_end (aq);
240 return execve (path, args, envp);
242 #endif
244 #ifdef L_gcov_execv
245 /* A wrapper for the execv function. Flushes the accumulated profiling data, so
246 that they are not lost. */
249 __gcov_execv (const char *path, char *const argv[])
251 __gcov_flush ();
252 return execv (path, argv);
254 #endif
256 #ifdef L_gcov_execvp
257 /* A wrapper for the execvp function. Flushes the accumulated profiling data, so
258 that they are not lost. */
261 __gcov_execvp (const char *path, char *const argv[])
263 __gcov_flush ();
264 return execvp (path, argv);
266 #endif
268 #ifdef L_gcov_execve
269 /* A wrapper for the execve function. Flushes the accumulated profiling data, so
270 that they are not lost. */
273 __gcov_execve (const char *path, char *const argv[], char *const envp[])
275 __gcov_flush ();
276 return execve (path, argv, envp);
278 #endif
279 #endif /* inhibit_libc */