@@ -0,0 +1,4 | |||||
|
1 | 3236b2a1a6a04bc11754d3f995873876b5046183 3.2.0.17 | |||
|
2 | ad411bb94578a052d1b4aa6b4c8a769fe2711072 3.2.0.18 | |||
|
3 | a9b894b0ab6a8fa48f50ce3dd7200406b83e2a62 3.2.0.19 | |||
|
4 | bd1252670981361939ed2a1c3febc94247019956 3.2.0.20 |
@@ -0,0 +1,17 | |||||
|
1 | cmake_minimum_required(VERSION 3.6) | |||
|
2 | project(libgcov C) | |||
|
3 | include(sparc-rtems) | |||
|
4 | include(cppcheck) | |||
|
5 | ||||
|
6 | set(LIB_GCOV_SOURCES | |||
|
7 | gcov-io.c | |||
|
8 | gcov-io.h | |||
|
9 | gcov-iov.h | |||
|
10 | libgcov.c | |||
|
11 | ) | |||
|
12 | ||||
|
13 | add_library(gcov STATIC ${LIB_GCOV_SOURCES}) | |||
|
14 | ||||
|
15 | add_custom_target(gcovr | |||
|
16 | COMMAND gcovr --exclude='.*gcov.*' --gcov-executable=${rtems_dir}/bin/sparc-rtems-gcov --object-directory ${CMAKE_BINARY_DIR} -r ${CMAKE_SOURCE_DIR} --html --html-details -o ${CMAKE_CURRENT_BINARY_DIR}/gcov.html && xdg-open ${CMAKE_CURRENT_BINARY_DIR}/gcov.html | |||
|
17 | ) |
@@ -0,0 +1,41 | |||||
|
1 | #!/usr/bin/env python3 | |||
|
2 | ||||
|
3 | __author__ = "Alexis Jeandet" | |||
|
4 | __copyright__ = "Copyright 2018, Laboratory of Plasma Physics" | |||
|
5 | __credits__ = [] | |||
|
6 | __license__ = "GPLv2" | |||
|
7 | __version__ = "1.0.0" | |||
|
8 | __maintainer__ = "Alexis Jeandet" | |||
|
9 | __email__ = "alexis.jeandet@member.fsf.org" | |||
|
10 | __status__ = "Development" | |||
|
11 | ||||
|
12 | import time | |||
|
13 | import sys | |||
|
14 | import os | |||
|
15 | import serial | |||
|
16 | import argparse | |||
|
17 | from datetime import datetime | |||
|
18 | ||||
|
19 | parser = argparse.ArgumentParser() | |||
|
20 | parser.add_argument("-f", "--gcov-file", help="Gcov output file generated by record_lfr_console.py") | |||
|
21 | args = parser.parse_args() | |||
|
22 | ||||
|
23 | ||||
|
24 | ||||
|
25 | def main(): | |||
|
26 | with open(args.gcov_file,'r') as gcov: | |||
|
27 | files = [] | |||
|
28 | for line in gcov.readlines(): | |||
|
29 | head,dest_file,data = line.split(',') | |||
|
30 | if dest_file not in files: | |||
|
31 | files.append(dest_file) | |||
|
32 | if head == '_GCOV_': | |||
|
33 | print(f"Writing {dest_file}\n") | |||
|
34 | with open(dest_file,'wb') as gcda_file: | |||
|
35 | gcda_file.write(bytes([int(''.join(value),16) for value in zip(data[::2],data[1::2]) ])) | |||
|
36 | else: | |||
|
37 | raise | |||
|
38 | ||||
|
39 | ||||
|
40 | if __name__ == "__main__": | |||
|
41 | main() |
@@ -0,0 +1,488 | |||||
|
1 | /* Test for GCC >= 3.4.4 && <= 4.4.6 */ | |||
|
2 | //#if ( ( __GNUC__ > 3 ) || \ | |||
|
3 | // ( __GNUC__ == 3 && __GNUC_MINOR__ > 4 )|| \ | |||
|
4 | // ( __GNUC__ == 3 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ >= 4 ) ) && \ | |||
|
5 | // ( ( __GNUC__ < 4 ) || \ | |||
|
6 | // ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 )|| \ | |||
|
7 | // ( __GNUC__ == 4 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ <= 6 ) ) | |||
|
8 | /* | |||
|
9 | * ===================================================================================== | |||
|
10 | * | |||
|
11 | * Filename: gcov-io.c | |||
|
12 | * | |||
|
13 | * Description: This is the I/O file for embedded systems | |||
|
14 | * | |||
|
15 | * Version: 1.0 | |||
|
16 | * Created: 03/04/08 09:51:59 | |||
|
17 | * Revision: none | |||
|
18 | * Compiler: gcc | |||
|
19 | * | |||
|
20 | * Author: Aitor Viana Sanchez (avs), aitor.viana.sanchez@esa.int | |||
|
21 | * Company: European Space Agency (ESA-ESTEC) | |||
|
22 | * | |||
|
23 | * ===================================================================================== | |||
|
24 | */ | |||
|
25 | ||||
|
26 | /* File format for coverage information | |||
|
27 | Copyright (C) 1996, 1997, 1998, 2000, 2002, | |||
|
28 | 2003 Free Software Foundation, Inc. | |||
|
29 | Contributed by Bob Manson <manson@cygnus.com>. | |||
|
30 | Completely remangled by Nathan Sidwell <nathan@codesourcery.com>. | |||
|
31 | ||||
|
32 | This file is part of GCC. | |||
|
33 | ||||
|
34 | GCC is free software; you can redistribute it and/or modify it under | |||
|
35 | the terms of the GNU General Public License as published by the Free | |||
|
36 | Software Foundation; either version 2, or (at your option) any later | |||
|
37 | version. | |||
|
38 | ||||
|
39 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |||
|
40 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
|
41 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
|
42 | for more details. | |||
|
43 | ||||
|
44 | You should have received a copy of the GNU General Public License | |||
|
45 | along with GCC; see the file COPYING. If not, write to the Free | |||
|
46 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |||
|
47 | 02111-1307, USA. */ | |||
|
48 | ||||
|
49 | #include <stdio.h> | |||
|
50 | #include <stdlib.h> /* for atexit() */ | |||
|
51 | #include <string.h> | |||
|
52 | #include "gcov-io.h" | |||
|
53 | ||||
|
54 | /* Routines declared in gcov-io.h. This file should be #included by | |||
|
55 | another source file, after having #included gcov-io.h. */ | |||
|
56 | ||||
|
57 | ||||
|
58 | /* This function shall be defined somewhere else */ | |||
|
59 | //int send_data(unsigned char * buffer, unsigned int size); | |||
|
60 | ||||
|
61 | /*----------------------------------------------------------------------------- | |||
|
62 | * PRIVATE INTERFACE | |||
|
63 | *-----------------------------------------------------------------------------*/ | |||
|
64 | ||||
|
65 | static void gcov_write_block (unsigned); | |||
|
66 | static gcov_unsigned_t *gcov_write_words (unsigned); | |||
|
67 | GCOV_LINKAGE int gcov_send (void); | |||
|
68 | GCOV_LINKAGE int gcov_close(void); | |||
|
69 | ||||
|
70 | extern struct gcov_info * gcov_list; | |||
|
71 | extern gcov_unsigned_t gcov_crc32; | |||
|
72 | ||||
|
73 | int dev_id = 0; | |||
|
74 | ||||
|
75 | /* | |||
|
76 | * === FUNCTION ====================================================================== | |||
|
77 | * Name: from_file | |||
|
78 | * Description: This function just return the given parameter | |||
|
79 | * ===================================================================================== | |||
|
80 | */ | |||
|
81 | static inline gcov_unsigned_t from_file (gcov_unsigned_t value) | |||
|
82 | { | |||
|
83 | return value; | |||
|
84 | } | |||
|
85 | ||||
|
86 | /* | |||
|
87 | * === FUNCTION ====================================================================== | |||
|
88 | * Name: gcov_version | |||
|
89 | * Description: This function returns TRUE (1) if the gcov version is the | |||
|
90 | * version expected. The function returns FALSE (0) in any other case. | |||
|
91 | * ===================================================================================== | |||
|
92 | */ | |||
|
93 | static int gcov_version (struct gcov_info *ptr, gcov_unsigned_t version) | |||
|
94 | { | |||
|
95 | if (version != GCOV_VERSION) | |||
|
96 | { | |||
|
97 | char v[4], e[4]; | |||
|
98 | ||||
|
99 | GCOV_UNSIGNED2STRING (v, version); | |||
|
100 | GCOV_UNSIGNED2STRING (e, GCOV_VERSION); | |||
|
101 | ||||
|
102 | printf ("profiling:%s:Version mismatch - expected %.4s got %.4s\n", | |||
|
103 | ptr->filename, e, v); | |||
|
104 | ||||
|
105 | return 0; | |||
|
106 | } | |||
|
107 | return 1; | |||
|
108 | } | |||
|
109 | ||||
|
110 | ||||
|
111 | /*----------------------------------------------------------------------------- | |||
|
112 | * PUBLIC INTERFACE | |||
|
113 | *-----------------------------------------------------------------------------*/ | |||
|
114 | ||||
|
115 | /* Dump the coverage counts. We merge with existing counts when | |||
|
116 | possible, to avoid growing the .da files ad infinitum. We use this | |||
|
117 | program's checksum to make sure we only accumulate whole program | |||
|
118 | statistics to the correct summary. An object file might be embedded | |||
|
119 | in two separate programs, and we must keep the two program | |||
|
120 | summaries separate. */ | |||
|
121 | ||||
|
122 | /* | |||
|
123 | * === FUNCTION ====================================================================== | |||
|
124 | * Name: gcov_exit | |||
|
125 | * Description: This function dumps the coverage couns. The merging with | |||
|
126 | * existing counts is not done in embedded systems. | |||
|
127 | * ===================================================================================== | |||
|
128 | */ | |||
|
129 | void gcov_exit (void) | |||
|
130 | { | |||
|
131 | struct gcov_info *gi_ptr; | |||
|
132 | struct gcov_summary this_program; | |||
|
133 | struct gcov_summary all; | |||
|
134 | struct gcov_ctr_summary *cs_ptr; | |||
|
135 | const struct gcov_ctr_info *ci_ptr; | |||
|
136 | unsigned t_ix; | |||
|
137 | gcov_unsigned_t c_num; | |||
|
138 | unsigned long coreId = 0; | |||
|
139 | ||||
|
140 | /* retrieve the id of the CPU the program is running on */ | |||
|
141 | #ifdef LEON3 | |||
|
142 | __asm__ __volatile__("rd %%asr17,%0\n\t" | |||
|
143 | "srl %0,28,%0" : | |||
|
144 | "=&r" (coreId) : ); | |||
|
145 | #endif | |||
|
146 | ||||
|
147 | printf("_GCOVEXIT_BEGIN_,core%d\n", coreId); /* see also _GCOVEXIT_END_ */ | |||
|
148 | ||||
|
149 | if(gcov_list == (void*)0x0) | |||
|
150 | printf("%s: gcov_list == NULL\n", __func__); | |||
|
151 | ||||
|
152 | memset (&all, 0, sizeof (all)); | |||
|
153 | /* Find the totals for this execution. */ | |||
|
154 | memset (&this_program, 0, sizeof (this_program)); | |||
|
155 | for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) | |||
|
156 | { | |||
|
157 | ||||
|
158 | ci_ptr = gi_ptr->counts; | |||
|
159 | for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++) | |||
|
160 | { | |||
|
161 | if (!((1 << t_ix) & gi_ptr->ctr_mask)) | |||
|
162 | continue; | |||
|
163 | ||||
|
164 | cs_ptr = &this_program.ctrs[t_ix]; | |||
|
165 | cs_ptr->num += ci_ptr->num; | |||
|
166 | for (c_num = 0; c_num < ci_ptr->num; c_num++) | |||
|
167 | { | |||
|
168 | cs_ptr->sum_all += ci_ptr->values[c_num]; | |||
|
169 | if (cs_ptr->run_max < ci_ptr->values[c_num]) | |||
|
170 | cs_ptr->run_max = ci_ptr->values[c_num]; | |||
|
171 | } | |||
|
172 | ci_ptr++; | |||
|
173 | } | |||
|
174 | } | |||
|
175 | /* Now merge each file. */ | |||
|
176 | for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) | |||
|
177 | { | |||
|
178 | ||||
|
179 | struct gcov_summary program; | |||
|
180 | gcov_type *values[GCOV_COUNTERS]; | |||
|
181 | const struct gcov_fn_info *fi_ptr; | |||
|
182 | unsigned fi_stride; | |||
|
183 | unsigned c_ix, f_ix, n_counts; | |||
|
184 | ||||
|
185 | c_ix = 0; | |||
|
186 | for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++) | |||
|
187 | if ((1 << t_ix) & gi_ptr->ctr_mask) | |||
|
188 | { | |||
|
189 | values[c_ix] = gi_ptr->counts[c_ix].values; | |||
|
190 | c_ix++; | |||
|
191 | } | |||
|
192 | ||||
|
193 | /* Calculate the function_info stride. This depends on the | |||
|
194 | number of counter types being measured. */ | |||
|
195 | fi_stride = sizeof (struct gcov_fn_info) + c_ix * sizeof (unsigned); | |||
|
196 | if (__alignof__ (struct gcov_fn_info) > sizeof (unsigned)) | |||
|
197 | { | |||
|
198 | fi_stride += __alignof__ (struct gcov_fn_info) - 1; | |||
|
199 | fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1); | |||
|
200 | } | |||
|
201 | ||||
|
202 | if (!gcov_open (gi_ptr->filename)) | |||
|
203 | { | |||
|
204 | printf ("profiling:%s:Cannot open\n", gi_ptr->filename); | |||
|
205 | continue; | |||
|
206 | } | |||
|
207 | ||||
|
208 | program.checksum = gcov_crc32; | |||
|
209 | ||||
|
210 | /* Write out the data. */ | |||
|
211 | gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION); | |||
|
212 | gcov_write_unsigned (gi_ptr->stamp); | |||
|
213 | ||||
|
214 | /* Write execution counts for each function. */ | |||
|
215 | for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++) | |||
|
216 | { | |||
|
217 | fi_ptr = (const struct gcov_fn_info *) | |||
|
218 | ((const char *) gi_ptr->functions + f_ix * fi_stride); | |||
|
219 | ||||
|
220 | /* Announce function. */ | |||
|
221 | gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH); | |||
|
222 | gcov_write_unsigned (fi_ptr->ident); | |||
|
223 | gcov_write_unsigned (fi_ptr->checksum); | |||
|
224 | ||||
|
225 | c_ix = 0; | |||
|
226 | for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++) | |||
|
227 | { | |||
|
228 | gcov_type *c_ptr; | |||
|
229 | ||||
|
230 | if (!((1 << t_ix) & gi_ptr->ctr_mask)) | |||
|
231 | continue; | |||
|
232 | ||||
|
233 | n_counts = fi_ptr->n_ctrs[c_ix]; | |||
|
234 | ||||
|
235 | gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix), | |||
|
236 | GCOV_TAG_COUNTER_LENGTH (n_counts)); | |||
|
237 | c_ptr = values[c_ix]; | |||
|
238 | while (n_counts--) | |||
|
239 | gcov_write_counter (*c_ptr++); | |||
|
240 | ||||
|
241 | values[c_ix] = c_ptr; | |||
|
242 | c_ix++; | |||
|
243 | } | |||
|
244 | } | |||
|
245 | ||||
|
246 | gcov_send(); | |||
|
247 | gcov_close(); | |||
|
248 | ||||
|
249 | } | |||
|
250 | ||||
|
251 | printf("_GCOVEXIT_END_,core%d\n", coreId); | |||
|
252 | } | |||
|
253 | ||||
|
254 | ||||
|
255 | /* Called before fork or exec - write out profile information gathered so | |||
|
256 | far and reset it to zero. This avoids duplication or loss of the | |||
|
257 | profile information gathered so far. */ | |||
|
258 | ||||
|
259 | void | |||
|
260 | __gcov_flush (void) | |||
|
261 | { | |||
|
262 | const struct gcov_info *gi_ptr; | |||
|
263 | ||||
|
264 | gcov_exit (); | |||
|
265 | for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) | |||
|
266 | { | |||
|
267 | unsigned t_ix; | |||
|
268 | const struct gcov_ctr_info *ci_ptr; | |||
|
269 | ||||
|
270 | for (t_ix = 0, ci_ptr = gi_ptr->counts; t_ix != GCOV_COUNTERS; t_ix++) | |||
|
271 | if ((1 << t_ix) & gi_ptr->ctr_mask) | |||
|
272 | { | |||
|
273 | memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num); | |||
|
274 | ci_ptr++; | |||
|
275 | } | |||
|
276 | } | |||
|
277 | } | |||
|
278 | ||||
|
279 | ||||
|
280 | ||||
|
281 | /* Open a gcov file. NAME is the name of the file to open and MODE | |||
|
282 | indicates whether a new file should be created, or an existing file | |||
|
283 | opened for modification. If MODE is >= 0 an existing file will be | |||
|
284 | opened, if possible, and if MODE is <= 0, a new file will be | |||
|
285 | created. Use MODE=0 to attempt to reopen an existing file and then | |||
|
286 | fall back on creating a new one. Return zero on failure, >0 on | |||
|
287 | opening an existing file and <0 on creating a new one. */ | |||
|
288 | GCOV_LINKAGE int gcov_open(const char *name) | |||
|
289 | { | |||
|
290 | // gcov_var.start is cleared in the gcov_close function. | |||
|
291 | // If this variable is not cleared...ERROR | |||
|
292 | if( gcov_var.start != 0 ) | |||
|
293 | return 0; | |||
|
294 | ||||
|
295 | // Clear everything | |||
|
296 | gcov_var.start = 0; | |||
|
297 | gcov_var.offset = gcov_var.length = 0; | |||
|
298 | gcov_var.overread = -1u; | |||
|
299 | gcov_var.error = 0; | |||
|
300 | ||||
|
301 | ||||
|
302 | // copy the filename in the gcov_var structure | |||
|
303 | strcpy(gcov_var.filename, name); | |||
|
304 | ||||
|
305 | ||||
|
306 | // return 1 means everything is OK | |||
|
307 | return 1; | |||
|
308 | } | |||
|
309 | ||||
|
310 | /* Close the current gcov file. Flushes data to disk. Returns nonzero | |||
|
311 | on failure or error flag set. */ | |||
|
312 | ||||
|
313 | GCOV_LINKAGE int gcov_send (void) | |||
|
314 | { | |||
|
315 | /*printf("%s: file %s\n", __func__, gcov_var.filename);*/ | |||
|
316 | if (gcov_var.offset) | |||
|
317 | gcov_write_block (gcov_var.offset); | |||
|
318 | ||||
|
319 | gcov_var.length = 0; | |||
|
320 | return gcov_var.error; | |||
|
321 | } | |||
|
322 | ||||
|
323 | GCOV_LINKAGE int gcov_close(void) | |||
|
324 | { | |||
|
325 | memset(gcov_var.filename, 0, strlen(gcov_var.filename)); | |||
|
326 | ||||
|
327 | // Clear the start variable because will be tested in the gcov_open | |||
|
328 | // function | |||
|
329 | gcov_var.start = 0; | |||
|
330 | ||||
|
331 | // Return the error, not sure whether the error is modifed. | |||
|
332 | return gcov_var.error; | |||
|
333 | } | |||
|
334 | ||||
|
335 | ||||
|
336 | static void gcov_write_block (unsigned size) { | |||
|
337 | unsigned char *buffer = (unsigned char*) gcov_var.buffer; | |||
|
338 | unsigned int i; | |||
|
339 | ||||
|
340 | printf("_GCOV_,%s,", gcov_var.filename); | |||
|
341 | /* to speed up the printing process, we display bytes 4 by 4 */ | |||
|
342 | for(i = 0; i < size; i++) { | |||
|
343 | printf("%02X%02X%02X%02X", (unsigned int)(buffer[0]), | |||
|
344 | (unsigned int)(buffer[1]), | |||
|
345 | (unsigned int)(buffer[2]), | |||
|
346 | (unsigned int)(buffer[3])); | |||
|
347 | ||||
|
348 | buffer += sizeof(gcov_unsigned_t); | |||
|
349 | } | |||
|
350 | printf("\n"); | |||
|
351 | ||||
|
352 | gcov_var.start += size; | |||
|
353 | gcov_var.offset -= size; | |||
|
354 | } | |||
|
355 | ||||
|
356 | /* Allocate space to write BYTES bytes to the gcov file. Return a | |||
|
357 | pointer to those bytes, or NULL on failure. */ | |||
|
358 | ||||
|
359 | static gcov_unsigned_t *gcov_write_words (unsigned words) { | |||
|
360 | gcov_unsigned_t *result; | |||
|
361 | ||||
|
362 | GCOV_CHECK_WRITING (); | |||
|
363 | if (gcov_var.offset >= GCOV_BLOCK_SIZE) | |||
|
364 | { | |||
|
365 | gcov_write_block (GCOV_BLOCK_SIZE); | |||
|
366 | if (gcov_var.offset) | |||
|
367 | { | |||
|
368 | GCOV_CHECK (gcov_var.offset == 1); | |||
|
369 | memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4); | |||
|
370 | } | |||
|
371 | } | |||
|
372 | result = &gcov_var.buffer[gcov_var.offset]; | |||
|
373 | gcov_var.offset += words; | |||
|
374 | ||||
|
375 | return result; | |||
|
376 | } | |||
|
377 | ||||
|
378 | /* Write unsigned VALUE to coverage file. Sets error flag | |||
|
379 | appropriately. */ | |||
|
380 | ||||
|
381 | GCOV_LINKAGE void | |||
|
382 | gcov_write_unsigned (gcov_unsigned_t value) | |||
|
383 | { | |||
|
384 | gcov_unsigned_t *buffer = gcov_write_words (1); | |||
|
385 | ||||
|
386 | buffer[0] = value; | |||
|
387 | } | |||
|
388 | ||||
|
389 | /* Write counter VALUE to coverage file. Sets error flag | |||
|
390 | appropriately. */ | |||
|
391 | ||||
|
392 | GCOV_LINKAGE void | |||
|
393 | gcov_write_counter (gcov_type value) | |||
|
394 | { | |||
|
395 | gcov_unsigned_t *buffer = gcov_write_words (2); | |||
|
396 | ||||
|
397 | buffer[0] = (gcov_unsigned_t) value; | |||
|
398 | if (sizeof (value) > sizeof (gcov_unsigned_t)) | |||
|
399 | buffer[1] = (gcov_unsigned_t) (value >> 32); | |||
|
400 | else | |||
|
401 | buffer[1] = 0; | |||
|
402 | ||||
|
403 | } | |||
|
404 | ||||
|
405 | /* Write a tag TAG and length LENGTH. */ | |||
|
406 | ||||
|
407 | GCOV_LINKAGE void | |||
|
408 | gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length) | |||
|
409 | { | |||
|
410 | gcov_unsigned_t *buffer = gcov_write_words (2); | |||
|
411 | ||||
|
412 | buffer[0] = tag; | |||
|
413 | buffer[1] = length; | |||
|
414 | } | |||
|
415 | ||||
|
416 | /* Write a summary structure to the gcov file. Return nonzero on | |||
|
417 | overflow. */ | |||
|
418 | ||||
|
419 | GCOV_LINKAGE void | |||
|
420 | gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary) | |||
|
421 | { | |||
|
422 | unsigned ix; | |||
|
423 | const struct gcov_ctr_summary *csum; | |||
|
424 | ||||
|
425 | gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH); | |||
|
426 | gcov_write_unsigned (summary->checksum); | |||
|
427 | for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) | |||
|
428 | { | |||
|
429 | gcov_write_unsigned (csum->num); | |||
|
430 | gcov_write_unsigned (csum->runs); | |||
|
431 | gcov_write_counter (csum->sum_all); | |||
|
432 | gcov_write_counter (csum->run_max); | |||
|
433 | gcov_write_counter (csum->sum_max); | |||
|
434 | } | |||
|
435 | } | |||
|
436 | ||||
|
437 | GCOV_LINKAGE gcov_type | |||
|
438 | gcov_read_counter (void) | |||
|
439 | { | |||
|
440 | return 0; | |||
|
441 | } | |||
|
442 | ||||
|
443 | /* Add a new object file onto the bb chain. Invoked automatically | |||
|
444 | when running an object file's global ctors. */ | |||
|
445 | ||||
|
446 | void | |||
|
447 | __gcov_init (struct gcov_info *info) | |||
|
448 | { | |||
|
449 | if (!info->version) | |||
|
450 | return; | |||
|
451 | if (gcov_version (info, info->version)) | |||
|
452 | { | |||
|
453 | const char *ptr = info->filename; | |||
|
454 | gcov_unsigned_t crc32 = gcov_crc32; | |||
|
455 | ||||
|
456 | /* Added by LESIA*/ | |||
|
457 | printf("Covered file: %s\n", info->filename); | |||
|
458 | /* End of Added by LESIA*/ | |||
|
459 | ||||
|
460 | do | |||
|
461 | { | |||
|
462 | unsigned ix; | |||
|
463 | gcov_unsigned_t value = *ptr << 24; | |||
|
464 | ||||
|
465 | for (ix = 8; ix--; value <<= 1) | |||
|
466 | { | |||
|
467 | gcov_unsigned_t feedback; | |||
|
468 | ||||
|
469 | feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0; | |||
|
470 | crc32 <<= 1; | |||
|
471 | crc32 ^= feedback; | |||
|
472 | } | |||
|
473 | } | |||
|
474 | while (*ptr++); | |||
|
475 | ||||
|
476 | gcov_crc32 = crc32; | |||
|
477 | ||||
|
478 | if (!gcov_list) | |||
|
479 | atexit (gcov_exit); | |||
|
480 | ||||
|
481 | info->next = gcov_list; | |||
|
482 | gcov_list = info; | |||
|
483 | } | |||
|
484 | else | |||
|
485 | printf("%s: Version mismatch\n", "WARNING"); | |||
|
486 | info->version = 0; | |||
|
487 | } | |||
|
488 | //#endif /* __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ */ |
@@ -0,0 +1,485 | |||||
|
1 | /* Test for GCC >= 3.4.4 && <= 4.4.6 */ | |||
|
2 | //#if ( ( __GNUC__ > 3 ) || \ | |||
|
3 | // ( __GNUC__ == 3 && __GNUC_MINOR__ > 4 )|| \ | |||
|
4 | // ( __GNUC__ == 3 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ >= 4 ) ) && \ | |||
|
5 | // ( ( __GNUC__ < 4 ) || \ | |||
|
6 | // ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 )|| \ | |||
|
7 | // ( __GNUC__ == 4 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ <= 6 ) ) | |||
|
8 | //#include <stdlib.h> | |||
|
9 | //#include <stdio.h> | |||
|
10 | /* File format for coverage information | |||
|
11 | Copyright (C) 1996, 1997, 1998, 2000, 2002, | |||
|
12 | 2003, 2004 Free Software Foundation, Inc. | |||
|
13 | Contributed by Bob Manson <manson@cygnus.com>. | |||
|
14 | Completely remangled by Nathan Sidwell <nathan@codesourcery.com>. | |||
|
15 | ||||
|
16 | This file is part of GCC. | |||
|
17 | ||||
|
18 | GCC is free software; you can redistribute it and/or modify it under | |||
|
19 | the terms of the GNU General Public License as published by the Free | |||
|
20 | Software Foundation; either version 2, or (at your option) any later | |||
|
21 | version. | |||
|
22 | ||||
|
23 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |||
|
24 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
|
25 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
|
26 | for more details. | |||
|
27 | ||||
|
28 | You should have received a copy of the GNU General Public License | |||
|
29 | along with GCC; see the file COPYING. If not, write to the Free | |||
|
30 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |||
|
31 | 02111-1307, USA. */ | |||
|
32 | ||||
|
33 | /* As a special exception, if you link this library with other files, | |||
|
34 | some of which are compiled with GCC, to produce an executable, | |||
|
35 | this library does not by itself cause the resulting executable | |||
|
36 | to be covered by the GNU General Public License. | |||
|
37 | This exception does not however invalidate any other reasons why | |||
|
38 | the executable file might be covered by the GNU General Public License. */ | |||
|
39 | ||||
|
40 | /* Coverage information is held in two files. A notes file, which is | |||
|
41 | generated by the compiler, and a data file, which is generated | |||
|
42 | by the program under test. Both files use a similar structure. We | |||
|
43 | do not attempt to make these files backwards compatible with | |||
|
44 | previous versions, as you only need coverage information when | |||
|
45 | developing a program. We do hold version information, so that | |||
|
46 | mismatches can be detected, and we use a format that allows tools | |||
|
47 | to skip information they do not understand or are not interested | |||
|
48 | in. | |||
|
49 | ||||
|
50 | Numbers are recorded in the 32 bit unsigned binary form of the | |||
|
51 | endianness of the machine generating the file. 64 bit numbers are | |||
|
52 | stored as two 32 bit numbers, the low part first. Strings are | |||
|
53 | padded with 1 to 4 NUL bytes, to bring the length up to a multiple | |||
|
54 | of 4. The number of 4 bytes is stored, followed by the padded | |||
|
55 | string. Zero length and NULL strings are simply stored as | |||
|
56 | a length of zero (they have no trailing NUL or padding). | |||
|
57 | ||||
|
58 | int32: byte3 byte2 byte1 byte0 | byte0 byte1 byte2 byte3 | |||
|
59 | int64: int32:low int32:high | |||
|
60 | string: int32:0 | int32:length char* char:0 padding | |||
|
61 | padding: | char:0 | char:0 char:0 | char:0 char:0 char:0 | |||
|
62 | item: int32 | int64 | string | |||
|
63 | ||||
|
64 | The basic format of the files is | |||
|
65 | ||||
|
66 | file : int32:magic int32:version int32:stamp record* | |||
|
67 | ||||
|
68 | The magic ident is different for the notes and the data files. The | |||
|
69 | magic ident is used to determine the endianness of the file, when | |||
|
70 | reading. The version is the same for both files and is derived | |||
|
71 | from gcc's version number. The stamp value is used to synchronize | |||
|
72 | note and data files and to synchronize merging within a data | |||
|
73 | file. It need not be an absolute time stamp, merely a ticker that | |||
|
74 | increments fast enough and cycles slow enough to distinguish | |||
|
75 | different compile/run/compile cycles. | |||
|
76 | ||||
|
77 | Although the ident and version are formally 32 bit numbers, they | |||
|
78 | are derived from 4 character ASCII strings. The version number | |||
|
79 | consists of the single character major version number, a two | |||
|
80 | character minor version number (leading zero for versions less than | |||
|
81 | 10), and a single character indicating the status of the release. | |||
|
82 | That will be 'e' experimental, 'p' prerelease and 'r' for release. | |||
|
83 | Because, by good fortune, these are in alphabetical order, string | |||
|
84 | collating can be used to compare version strings. Be aware that | |||
|
85 | the 'e' designation will (naturally) be unstable and might be | |||
|
86 | incompatible with itself. For gcc 3.4 experimental, it would be | |||
|
87 | '304e' (0x33303465). When the major version reaches 10, the | |||
|
88 | letters A-Z will be used. Assuming minor increments releases every | |||
|
89 | 6 months, we have to make a major increment every 50 years. | |||
|
90 | Assuming major increments releases every 5 years, we're ok for the | |||
|
91 | next 155 years -- good enough for me. | |||
|
92 | ||||
|
93 | A record has a tag, length and variable amount of data. | |||
|
94 | ||||
|
95 | record: header data | |||
|
96 | header: int32:tag int32:length | |||
|
97 | data: item* | |||
|
98 | ||||
|
99 | Records are not nested, but there is a record hierarchy. Tag | |||
|
100 | numbers reflect this hierarchy. Tags are unique across note and | |||
|
101 | data files. Some record types have a varying amount of data. The | |||
|
102 | LENGTH is the number of 4bytes that follow and is usually used to | |||
|
103 | determine how much data. The tag value is split into 4 8-bit | |||
|
104 | fields, one for each of four possible levels. The most significant | |||
|
105 | is allocated first. Unused levels are zero. Active levels are | |||
|
106 | odd-valued, so that the LSB of the level is one. A sub-level | |||
|
107 | incorporates the values of its superlevels. This formatting allows | |||
|
108 | you to determine the tag hierarchy, without understanding the tags | |||
|
109 | themselves, and is similar to the standard section numbering used | |||
|
110 | in technical documents. Level values [1..3f] are used for common | |||
|
111 | tags, values [41..9f] for the notes file and [a1..ff] for the data | |||
|
112 | file. | |||
|
113 | ||||
|
114 | The basic block graph file contains the following records | |||
|
115 | note: unit function-graph* | |||
|
116 | unit: header int32:checksum string:source | |||
|
117 | function-graph: announce_function basic_blocks {arcs | lines}* | |||
|
118 | announce_function: header int32:ident int32:checksum | |||
|
119 | string:name string:source int32:lineno | |||
|
120 | basic_block: header int32:flags* | |||
|
121 | arcs: header int32:block_no arc* | |||
|
122 | arc: int32:dest_block int32:flags | |||
|
123 | lines: header int32:block_no line* | |||
|
124 | int32:0 string:NULL | |||
|
125 | line: int32:line_no | int32:0 string:filename | |||
|
126 | ||||
|
127 | The BASIC_BLOCK record holds per-bb flags. The number of blocks | |||
|
128 | can be inferred from its data length. There is one ARCS record per | |||
|
129 | basic block. The number of arcs from a bb is implicit from the | |||
|
130 | data length. It enumerates the destination bb and per-arc flags. | |||
|
131 | There is one LINES record per basic block, it enumerates the source | |||
|
132 | lines which belong to that basic block. Source file names are | |||
|
133 | introduced by a line number of 0, following lines are from the new | |||
|
134 | source file. The initial source file for the function is NULL, but | |||
|
135 | the current source file should be remembered from one LINES record | |||
|
136 | to the next. The end of a block is indicated by an empty filename | |||
|
137 | - this does not reset the current source file. Note there is no | |||
|
138 | ordering of the ARCS and LINES records: they may be in any order, | |||
|
139 | interleaved in any manner. The current filename follows the order | |||
|
140 | the LINES records are stored in the file, *not* the ordering of the | |||
|
141 | blocks they are for. | |||
|
142 | ||||
|
143 | The data file contains the following records. | |||
|
144 | data: {unit function-data* summary:object summary:program*}* | |||
|
145 | unit: header int32:checksum | |||
|
146 | function-data: announce_function arc_counts | |||
|
147 | announce_function: header int32:ident int32:checksum | |||
|
148 | arc_counts: header int64:count* | |||
|
149 | summary: int32:checksum {count-summary}GCOV_COUNTERS | |||
|
150 | count-summary: int32:num int32:runs int64:sum | |||
|
151 | int64:max int64:sum_max | |||
|
152 | ||||
|
153 | The ANNOUNCE_FUNCTION record is the same as that in the note file, | |||
|
154 | but without the source location. The ARC_COUNTS gives the counter | |||
|
155 | values for those arcs that are instrumented. The SUMMARY records | |||
|
156 | give information about the whole object file and about the whole | |||
|
157 | program. The checksum is used for whole program summaries, and | |||
|
158 | disambiguates different programs which include the same | |||
|
159 | instrumented object file. There may be several program summaries, | |||
|
160 | each with a unique checksum. The object summary's checksum is zero. | |||
|
161 | Note that the data file might contain information from several runs | |||
|
162 | concatenated, or the data might be merged. | |||
|
163 | ||||
|
164 | This file is included by both the compiler, gcov tools and the | |||
|
165 | runtime support library libgcov. IN_LIBGCOV and IN_GCOV are used to | |||
|
166 | distinguish which case is which. If IN_LIBGCOV is nonzero, | |||
|
167 | libgcov is being built. If IN_GCOV is nonzero, the gcov tools are | |||
|
168 | being built. Otherwise the compiler is being built. IN_GCOV may be | |||
|
169 | positive or negative. If positive, we are compiling a tool that | |||
|
170 | requires additional functions (see the code for knowledge of what | |||
|
171 | those functions are). */ | |||
|
172 | ||||
|
173 | #ifndef GCC_GCOV_IO_H | |||
|
174 | #define GCC_GCOV_IO_H | |||
|
175 | ||||
|
176 | typedef unsigned int gcov_unsigned_t; | |||
|
177 | typedef unsigned int gcov_position_t; | |||
|
178 | ||||
|
179 | typedef unsigned long long gcov_type; | |||
|
180 | ||||
|
181 | /* No tengo ni idea de que es el SETLKW, asi que de momento el target | |||
|
182 | * no tiene de eso */ | |||
|
183 | ||||
|
184 | //#if defined (TARGET_HAS_F_SETLKW) | |||
|
185 | //#define GCOV_LOCKED 1 | |||
|
186 | //#else | |||
|
187 | #define GCOV_LOCKED 0 | |||
|
188 | //#endif | |||
|
189 | //#endif | |||
|
190 | ||||
|
191 | ||||
|
192 | ||||
|
193 | /* In gcov we want function linkage to be static. In the compiler we want | |||
|
194 | it extern, so that they can be accessed from elsewhere. In libgcov we | |||
|
195 | need these functions to be extern, so prefix them with __gcov. In | |||
|
196 | libgcov they must also be hidden so that the instance in the executable | |||
|
197 | is not also used in a DSO. */ | |||
|
198 | ||||
|
199 | #define gcov_var __gcov_var | |||
|
200 | #define gcov_open __gcov_open | |||
|
201 | #define gcov_close __gcov_close | |||
|
202 | #define gcov_write_tag_length __gcov_write_tag_length | |||
|
203 | #define gcov_position __gcov_position | |||
|
204 | #define gcov_seek __gcov_seek | |||
|
205 | #define gcov_rewrite __gcov_rewrite | |||
|
206 | #define gcov_is_error __gcov_is_error | |||
|
207 | #define gcov_is_eof __gcov_is_eof | |||
|
208 | #define gcov_write_unsigned __gcov_write_unsigned | |||
|
209 | #define gcov_write_counter __gcov_write_counter | |||
|
210 | #define gcov_write_summary __gcov_write_summary | |||
|
211 | #define gcov_read_unsigned __gcov_read_unsigned | |||
|
212 | #define gcov_read_counter __gcov_read_counter | |||
|
213 | #define gcov_read_summary __gcov_read_summary | |||
|
214 | ||||
|
215 | /* Esto no tengo ni repajolera idea de para que vale */ | |||
|
216 | ||||
|
217 | /* Poison these, so they don't accidentally slip in. */ | |||
|
218 | //#pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length | |||
|
219 | //#pragma GCC poison gcov_read_string gcov_sync gcov_time gcov_magic | |||
|
220 | ||||
|
221 | #ifdef HAVE_GAS_HIDDEN | |||
|
222 | #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden"))) | |||
|
223 | #else | |||
|
224 | #define ATTRIBUTE_HIDDEN | |||
|
225 | #endif | |||
|
226 | ||||
|
227 | #ifndef GCOV_LINKAGE | |||
|
228 | #define GCOV_LINKAGE extern | |||
|
229 | //#define GCOV_LINKAGE | |||
|
230 | #endif | |||
|
231 | ||||
|
232 | /* File suffixes. */ | |||
|
233 | #define GCOV_DATA_SUFFIX ".gcda" | |||
|
234 |