2014-08-20 Steve Ellcey <sellcey@mips.com>
[official-gcc.git] / libgcc / libgcov-interface.c
blobf73666c136729ebc58364313110ea6c2e26184d2
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 __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
46 extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
48 #ifdef L_gcov_flush
49 #ifdef __GTHREAD_MUTEX_INIT
50 __gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
51 #define init_mx_once()
52 #else
53 __gthread_mutex_t __gcov_flush_mx;
55 static void
56 init_mx (void)
58 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
61 static void
62 init_mx_once (void)
64 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
65 __gthread_once (&once, init_mx);
67 #endif
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. */
73 void
74 __gcov_flush (void)
76 init_mx_once ();
77 __gthread_mutex_lock (&__gcov_flush_mx);
79 __gcov_dump_one (&__gcov_root);
80 __gcov_reset ();
82 __gthread_mutex_unlock (&__gcov_flush_mx);
85 #endif /* L_gcov_flush */
87 #ifdef L_gcov_reset
89 /* Reset all counters to zero. */
91 static void
92 gcov_clear (const struct gcov_info *list)
94 const struct gcov_info *gi_ptr;
96 for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
98 unsigned f_ix;
100 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
102 unsigned t_ix;
103 const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
105 if (!gfi_ptr || gfi_ptr->key != gi_ptr)
106 continue;
107 const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
108 for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
110 if (!gi_ptr->merge[t_ix])
111 continue;
113 memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
114 ci_ptr++;
120 /* Function that can be called from application to reset counters to zero,
121 in order to collect profile in region of interest. */
123 void
124 __gcov_reset (void)
126 gcov_clear (__gcov_root.list);
127 __gcov_root.dumped = 0;
130 #endif /* L_gcov_reset */
132 #ifdef L_gcov_dump
133 /* Function that can be called from application to write profile collected
134 so far, in order to collect profile in region of interest. */
136 void
137 __gcov_dump (void)
139 __gcov_dump_one (&__gcov_root);
142 #endif /* L_gcov_dump */
144 #ifdef L_gcov_fork
145 /* A wrapper for the fork function. Flushes the accumulated profiling data, so
146 that they are not counted twice. */
148 pid_t
149 __gcov_fork (void)
151 pid_t pid;
152 __gcov_flush ();
153 pid = fork ();
154 if (pid == 0)
155 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
156 return pid;
158 #endif
160 #ifdef L_gcov_execl
161 /* A wrapper for the execl function. Flushes the accumulated profiling data, so
162 that they are not lost. */
165 __gcov_execl (const char *path, char *arg, ...)
167 va_list ap, aq;
168 unsigned i, length;
169 char **args;
171 __gcov_flush ();
173 va_start (ap, arg);
174 va_copy (aq, ap);
176 length = 2;
177 while (va_arg (ap, char *))
178 length++;
179 va_end (ap);
181 args = (char **) alloca (length * sizeof (void *));
182 args[0] = arg;
183 for (i = 1; i < length; i++)
184 args[i] = va_arg (aq, char *);
185 va_end (aq);
187 return execv (path, args);
189 #endif
191 #ifdef L_gcov_execlp
192 /* A wrapper for the execlp function. Flushes the accumulated
193 profiling data, so that they are not lost. */
196 __gcov_execlp (const char *path, char *arg, ...)
198 va_list ap, aq;
199 unsigned i, length;
200 char **args;
202 __gcov_flush ();
204 va_start (ap, arg);
205 va_copy (aq, ap);
207 length = 2;
208 while (va_arg (ap, char *))
209 length++;
210 va_end (ap);
212 args = (char **) alloca (length * sizeof (void *));
213 args[0] = arg;
214 for (i = 1; i < length; i++)
215 args[i] = va_arg (aq, char *);
216 va_end (aq);
218 return execvp (path, args);
220 #endif
222 #ifdef L_gcov_execle
223 /* A wrapper for the execle function. Flushes the accumulated
224 profiling data, so that they are not lost. */
227 __gcov_execle (const char *path, char *arg, ...)
229 va_list ap, aq;
230 unsigned i, length;
231 char **args;
232 char **envp;
234 __gcov_flush ();
236 va_start (ap, arg);
237 va_copy (aq, ap);
239 length = 2;
240 while (va_arg (ap, char *))
241 length++;
242 va_end (ap);
244 args = (char **) alloca (length * sizeof (void *));
245 args[0] = arg;
246 for (i = 1; i < length; i++)
247 args[i] = va_arg (aq, char *);
248 envp = va_arg (aq, char **);
249 va_end (aq);
251 return execve (path, args, envp);
253 #endif
255 #ifdef L_gcov_execv
256 /* A wrapper for the execv function. Flushes the accumulated
257 profiling data, so that they are not lost. */
260 __gcov_execv (const char *path, char *const argv[])
262 __gcov_flush ();
263 return execv (path, argv);
265 #endif
267 #ifdef L_gcov_execvp
268 /* A wrapper for the execvp function. Flushes the accumulated
269 profiling data, so that they are not lost. */
272 __gcov_execvp (const char *path, char *const argv[])
274 __gcov_flush ();
275 return execvp (path, argv);
277 #endif
279 #ifdef L_gcov_execve
280 /* A wrapper for the execve function. Flushes the accumulated
281 profiling data, so that they are not lost. */
284 __gcov_execve (const char *path, char *const argv[], char *const envp[])
286 __gcov_flush ();
287 return execve (path, argv, envp);
289 #endif
290 #endif /* inhibit_libc */