1 /* Header file for libgcov-*.c. 2 Copyright (C) 1996-2014 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 3, or (at your option) any later 9 version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 for more details. 15 16 Under Section 7 of GPL version 3, you are granted additional 17 permissions described in the GCC Runtime Library Exception, version 18 3.1, as published by the Free Software Foundation. 19 20 You should have received a copy of the GNU General Public License and 21 a copy of the GCC Runtime Library Exception along with this program; 22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 <http://www.gnu.org/licenses/>. */ 24 25 #ifndef GCC_LIBGCOV_H 26 #define GCC_LIBGCOV_H 27 28 #ifndef __KERNEL__ 29 /* work around the poisoned malloc/calloc in system.h. */ 30 #ifndef xmalloc 31 #define xmalloc malloc 32 #endif 33 #ifndef xcalloc 34 #define xcalloc calloc 35 #endif 36 #ifndef xrealloc 37 #define xrealloc realloc 38 #endif 39 #ifndef xfree 40 #define xfree free 41 #endif 42 #else /* __KERNEL__ */ 43 #include "libgcov-kernel.h" 44 #endif /* __KERNEL__ */ 45 46 #ifndef IN_GCOV_TOOL 47 /* About the target. */ 48 /* This path will be used by libgcov runtime. */ 49 50 #ifndef __KERNEL__ 51 #include "tconfig.h" 52 #include "tsystem.h" 53 #include "coretypes.h" 54 #include "tm.h" 55 #include "libgcc_tm.h" 56 #endif /* __KERNEL__ */ 57 58 #undef FUNC_ID_WIDTH 59 #undef FUNC_ID_MASK 60 61 #if BITS_PER_UNIT == 8 62 typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI))); 63 typedef unsigned gcov_position_t __attribute__ ((mode (SI))); 64 #if LONG_LONG_TYPE_SIZE > 32 65 typedef signed gcov_type __attribute__ ((mode (DI))); 66 typedef unsigned gcov_type_unsigned __attribute__ ((mode (DI))); 67 #define FUNC_ID_WIDTH 32 68 #define FUNC_ID_MASK ((1ll << FUNC_ID_WIDTH) - 1) 69 #else 70 typedef signed gcov_type __attribute__ ((mode (SI))); 71 typedef unsigned gcov_type_unsigned __attribute__ ((mode (SI))); 72 #define FUNC_ID_WIDTH 16 73 #define FUNC_ID_MASK ((1 << FUNC_ID_WIDTH) - 1) 74 #endif 75 #else /* BITS_PER_UNIT != 8 */ 76 #if BITS_PER_UNIT == 16 77 typedef unsigned gcov_unsigned_t __attribute__ ((mode (HI))); 78 typedef unsigned gcov_position_t __attribute__ ((mode (HI))); 79 #if LONG_LONG_TYPE_SIZE > 32 80 typedef signed gcov_type __attribute__ ((mode (SI))); 81 typedef unsigned gcov_type_unsigned __attribute__ ((mode (SI))); 82 #define FUNC_ID_WIDTH 32 83 #define FUNC_ID_MASK ((1ll << FUNC_ID_WIDTH) - 1) 84 #else 85 typedef signed gcov_type __attribute__ ((mode (HI))); 86 typedef unsigned gcov_type_unsigned __attribute__ ((mode (HI))); 87 #define FUNC_ID_WIDTH 16 88 #define FUNC_ID_MASK ((1 << FUNC_ID_WIDTH) - 1) 89 #endif 90 #else /* BITS_PER_UNIT != 16 */ 91 typedef unsigned gcov_unsigned_t __attribute__ ((mode (QI))); 92 typedef unsigned gcov_position_t __attribute__ ((mode (QI))); 93 #if LONG_LONG_TYPE_SIZE > 32 94 typedef signed gcov_type __attribute__ ((mode (HI))); 95 typedef unsigned gcov_type_unsigned __attribute__ ((mode (HI))); 96 #define FUNC_ID_WIDTH 32 97 #define FUNC_ID_MASK ((1ll << FUNC_ID_WIDTH) - 1) 98 #else 99 typedef signed gcov_type __attribute__ ((mode (QI))); 100 typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI))); 101 #define FUNC_ID_WIDTH 16 102 #define FUNC_ID_MASK ((1 << FUNC_ID_WIDTH) - 1) 103 #endif 104 #endif /* BITS_PER_UNIT == 16 */ 105 #endif /* BITS_PER_UNIT == 8 */ 106 107 #if LONG_LONG_TYPE_SIZE > 32 108 #define GCOV_TYPE_ATOMIC_FETCH_ADD_FN __atomic_fetch_add_8 109 #define GCOV_TYPE_ATOMIC_FETCH_ADD BUILT_IN_ATOMIC_FETCH_ADD_8 110 #else 111 #define GCOV_TYPE_ATOMIC_FETCH_ADD_FN __atomic_fetch_add_4 112 #define GCOV_TYPE_ATOMIC_FETCH_ADD BUILT_IN_ATOMIC_FETCH_ADD_4 113 #endif 114 115 #if defined (TARGET_POSIX_IO) 116 #define GCOV_LOCKED 1 117 #else 118 #define GCOV_LOCKED 0 119 #endif 120 121 #else /* IN_GCOV_TOOL */ 122 /* About the host. */ 123 /* This path will be compiled for the host and linked into 124 gcov-tool binary. */ 125 126 #include "config.h" 127 #include "system.h" 128 #include "coretypes.h" 129 #include "tm.h" 130 131 typedef unsigned gcov_unsigned_t; 132 typedef unsigned gcov_position_t; 133 /* gcov_type is typedef'd elsewhere for the compiler */ 134 #if defined (HOST_HAS_F_SETLKW) 135 #define GCOV_LOCKED 1 136 #else 137 #define GCOV_LOCKED 0 138 #endif 139 140 #define FUNC_ID_WIDTH 32 141 #define FUNC_ID_MASK ((1ll << FUNC_ID_WIDTH) - 1) 142 143 /* Some Macros specific to gcov-tool. */ 144 145 #define L_gcov 1 146 #define L_gcov_merge_add 1 147 #define L_gcov_merge_single 1 148 #define L_gcov_merge_delta 1 149 #define L_gcov_merge_ior 1 150 #define L_gcov_merge_time_profile 1 151 #define L_gcov_merge_icall_topn 1 152 #define L_gcov_merge_dc 1 153 154 /* Make certian internal functions/variables in libgcov available for 155 gcov-tool access. */ 156 #define GCOV_TOOL_LINKAGE 157 158 extern gcov_type gcov_read_counter_mem (); 159 extern unsigned gcov_get_merge_weight (); 160 161 #endif /* !IN_GCOV_TOOL */ 162 163 #undef EXTRACT_MODULE_ID_FROM_GLOBAL_ID 164 #undef EXTRACT_FUNC_ID_FROM_GLOBAL_ID 165 #undef GEN_FUNC_GLOBAL_ID 166 #define EXTRACT_MODULE_ID_FROM_GLOBAL_ID(gid) \ 167 (gcov_unsigned_t)(((gid) >> FUNC_ID_WIDTH) & FUNC_ID_MASK) 168 #define EXTRACT_FUNC_ID_FROM_GLOBAL_ID(gid) \ 169 (gcov_unsigned_t)((gid) & FUNC_ID_MASK) 170 #define GEN_FUNC_GLOBAL_ID(m,f) ((((gcov_type) (m)) << FUNC_ID_WIDTH) | (f)) 171 172 #if defined(inhibit_libc) 173 #define IN_LIBGCOV (-1) 174 #else 175 #define IN_LIBGCOV 1 176 #if defined(L_gcov) 177 #define GCOV_LINKAGE /* nothing */ 178 #endif 179 #endif 180 181 /* In libgcov we need these functions to be extern, so prefix them with 182 __gcov. In libgcov they must also be hidden so that the instance in 183 the executable is not also used in a DSO. */ 184 #define gcov_var __gcov_var 185 #define gcov_open __gcov_open 186 #define gcov_close __gcov_close 187 #define gcov_write_tag_length __gcov_write_tag_length 188 #define gcov_position __gcov_position 189 #define gcov_seek __gcov_seek 190 #define gcov_rewrite __gcov_rewrite 191 #define gcov_truncate __gcov_truncate 192 #define gcov_is_error __gcov_is_error 193 #define gcov_write_unsigned __gcov_write_unsigned 194 #define gcov_write_counter __gcov_write_counter 195 #define gcov_write_summary __gcov_write_summary 196 #define gcov_write_module_info __gcov_write_module_info 197 #define gcov_read_unsigned __gcov_read_unsigned 198 #define gcov_read_counter __gcov_read_counter 199 #define gcov_read_summary __gcov_read_summary 200 #define gcov_read_buildinfo __gcov_read_buildinfo 201 #define gcov_read_module_info __gcov_read_module_info 202 #define gcov_sort_n_vals __gcov_sort_n_vals 203 204 /* Poison these, so they don't accidentally slip in. */ 205 #pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length 206 #pragma GCC poison gcov_time gcov_magic 207 208 #ifdef HAVE_GAS_HIDDEN 209 #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden"))) 210 #else 211 #define ATTRIBUTE_HIDDEN 212 #endif 213 214 #include "gcov-io.h" 215 216 /* Structures embedded in coveraged program. The structures generated 217 by write_profile must match these. */ 218 /* Information about counters for a single function. */ 219 struct gcov_ctr_info 220 { 221 gcov_unsigned_t num; /* number of counters. */ 222 gcov_type *values; /* their values. */ 223 }; 224 225 /* Information about a single function. This uses the trailing array 226 idiom. The number of counters is determined from the merge pointer 227 array in gcov_info. The key is used to detect which of a set of 228 comdat functions was selected -- it points to the gcov_info object 229 of the object file containing the selected comdat function. */ 230 231 struct gcov_fn_info 232 { 233 const struct gcov_info *key; /* comdat key */ 234 gcov_unsigned_t ident; /* unique ident of function */ 235 gcov_unsigned_t lineno_checksum; /* function lineo_checksum */ 236 gcov_unsigned_t cfg_checksum; /* function cfg checksum */ 237 struct gcov_ctr_info ctrs[1]; /* instrumented counters */ 238 }; 239 240 /* Type of function used to merge counters. */ 241 typedef void (*gcov_merge_fn) (gcov_type *, gcov_unsigned_t); 242 243 /* Information about a single object file. */ 244 struct gcov_info 245 { 246 gcov_unsigned_t version; /* expected version number */ 247 struct gcov_module_info *mod_info; /* addtional module info. */ 248 struct gcov_info *next; /* link to next, used by libgcov */ 249 250 gcov_unsigned_t stamp; /* uniquifying time stamp */ 251 const char *filename; /* output file name */ 252 gcov_unsigned_t eof_pos; /* end position of profile data */ 253 gcov_merge_fn merge[GCOV_COUNTERS]; /* merge functions (null for 254 unused) */ 255 256 unsigned n_functions; /* number of functions */ 257 258 #if !defined (IN_GCOV_TOOL) && !defined (__KERNEL__) 259 const struct gcov_fn_info *const *functions; /* pointer to pointers 260 to function information */ 261 #elif defined (IN_GCOV_TOOL) 262 const struct gcov_fn_info **functions; 263 #else 264 struct gcov_fn_info **functions; 265 #endif /* !IN_GCOV_TOOL */ 266 char **build_info; /* strings to include in BUILD_INFO 267 section of gcda file. */ 268 }; 269 270 /* Information about a single imported module. */ 271 struct dyn_imp_mod 272 { 273 const struct gcov_info *imp_mod; 274 double weight; 275 }; 276 277 /* Register a new object file module. */ 278 extern void __gcov_init (struct gcov_info *) ATTRIBUTE_HIDDEN; 279 280 /* Set sampling rate to RATE. */ 281 extern void __gcov_set_sampling_rate (unsigned int rate); 282 283 /* Called before fork, to avoid double counting. */ 284 extern void __gcov_flush (void) ATTRIBUTE_HIDDEN; 285 286 /* Function to reset all counters to 0. */ 287 extern void __gcov_reset (void); 288 /* Function to enable early write of profile information so far. 289 __gcov_dump is also used by __gcov_dump_all. The latter 290 depends on __GCOV_DUMP to have hidden or protected visibility 291 so that each library has its own copy of the registered dumper. */ 292 extern void __gcov_dump (void) ATTRIBUTE_HIDDEN; 293 294 /* Call __gcov_dump registered from each shared library. 295 This function must have default visibility. */ 296 void __gcov_dump_all (void); 297 298 /* The merge function that just sums the counters. */ 299 extern void __gcov_merge_add (gcov_type *, unsigned) ATTRIBUTE_HIDDEN; 300 301 /* The merge function to choose the most common value. */ 302 extern void __gcov_merge_single (gcov_type *, unsigned) ATTRIBUTE_HIDDEN; 303 304 /* The merge function to choose the most common difference between 305 consecutive values. */ 306 extern void __gcov_merge_delta (gcov_type *, unsigned) ATTRIBUTE_HIDDEN; 307 308 /* The merge function that just ors the counters together. */ 309 extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN; 310 311 /* The merge function used for direct call counters. */ 312 extern void __gcov_merge_dc (gcov_type *, unsigned) ATTRIBUTE_HIDDEN; 313 314 /* The merge function used for indirect call counters. */ 315 extern void __gcov_merge_icall_topn (gcov_type *, unsigned) ATTRIBUTE_HIDDEN; 316 317 extern void __gcov_merge_time_profile (gcov_type *, unsigned) ATTRIBUTE_HIDDEN; 318 319 /* The profiler functions. */ 320 extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned); 321 extern void __gcov_pow2_profiler (gcov_type *, gcov_type); 322 extern void __gcov_one_value_profiler (gcov_type *, gcov_type); 323 extern void __gcov_indirect_call_profiler (gcov_type*, gcov_type, 324 void*, void*); 325 extern void __gcov_indirect_call_profiler_v2 (gcov_type, void *); 326 extern void __gcov_indirect_call_topn_profiler (void *, void *, gcov_unsigned_t) ATTRIBUTE_HIDDEN; 327 extern void __gcov_direct_call_profiler (void *, void *, gcov_unsigned_t) ATTRIBUTE_HIDDEN; 328 extern void __gcov_average_profiler (gcov_type *, gcov_type); 329 extern void __gcov_ior_profiler (gcov_type *, gcov_type); 330 extern void __gcov_sort_n_vals (gcov_type *value_array, int n); 331 extern void __gcov_time_profiler (gcov_type *); 332 333 #ifndef inhibit_libc 334 /* The wrappers around some library functions.. */ 335 extern pid_t __gcov_fork (void) ATTRIBUTE_HIDDEN; 336 extern int __gcov_execl (const char *, char *, ...) ATTRIBUTE_HIDDEN; 337 extern int __gcov_execlp (const char *, char *, ...) ATTRIBUTE_HIDDEN; 338 extern int __gcov_execle (const char *, char *, ...) ATTRIBUTE_HIDDEN; 339 extern int __gcov_execv (const char *, char *const []) ATTRIBUTE_HIDDEN; 340 extern int __gcov_execvp (const char *, char *const []) ATTRIBUTE_HIDDEN; 341 extern int __gcov_execve (const char *, char *const [], char *const []) 342 ATTRIBUTE_HIDDEN; 343 344 345 /* Functions that only available in libgcov. */ 346 GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN; 347 GCOV_LINKAGE void gcov_write_counter (gcov_type) ATTRIBUTE_HIDDEN; 348 GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t) 349 ATTRIBUTE_HIDDEN; 350 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/, 351 const struct gcov_summary *) 352 ATTRIBUTE_HIDDEN; 353 GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN; 354 GCOV_LINKAGE void gcov_truncate (void) ATTRIBUTE_HIDDEN; 355 void gcov_write_module_info (const struct gcov_info *, unsigned) 356 ATTRIBUTE_HIDDEN; 357 GCOV_LINKAGE void gcov_write_module_infos (struct gcov_info *mod_info) 358 ATTRIBUTE_HIDDEN; 359 GCOV_LINKAGE const struct dyn_imp_mod ** 360 gcov_get_sorted_import_module_array (struct gcov_info *mod_info, unsigned *len) 361 ATTRIBUTE_HIDDEN; 362 GCOV_LINKAGE inline void gcov_rewrite (void); 363 364 extern void set_gcov_fn_fixed_up (int fixed_up); 365 extern int get_gcov_fn_fixed_up (void); 366 367 /* "Counts" stored in gcda files can be a real counter value, or 368 an target address. When differentiate these two types because 369 when manipulating counts, we should only change real counter values, 370 rather target addresses. */ 371 372 static inline gcov_type 373 gcov_get_counter (void) 374 { 375 #ifndef IN_GCOV_TOOL 376 /* This version is for reading count values in libgcov runtime: 377 we read from gcda files. */ 378 379 if (get_gcov_fn_fixed_up ()) 380 { 381 gcov_read_counter (); 382 return 0; 383 } 384 else 385 return gcov_read_counter (); 386 #else 387 /* This version is for gcov-tool. We read the value from memory and 388 multiply it by the merge weight. */ 389 390 return gcov_read_counter_mem () * gcov_get_merge_weight (); 391 #endif 392 } 393 394 /* Similar function as gcov_get_counter(), but handles target address 395 counters. */ 396 397 static inline gcov_type 398 gcov_get_counter_target (void) 399 { 400 #ifndef IN_GCOV_TOOL 401 /* This version is for reading count target values in libgcov runtime: 402 we read from gcda files. */ 403 404 if (get_gcov_fn_fixed_up ()) 405 { 406 gcov_read_counter (); 407 return 0; 408 } 409 else 410 return gcov_read_counter (); 411 #else 412 /* This version is for gcov-tool. We read the value from memory and we do NOT 413 multiply it by the merge weight. */ 414 415 return gcov_read_counter_mem (); 416 #endif 417 } 418 419 #endif /* !inhibit_libc */ 420 421 #endif /* GCC_LIBGCOV_H */ 422