blob: dd249e1d5346de9e18d213fd9aa1abe964c6108e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
// IBM_PROLOG_BEGIN_TAG
// This is an automatically generated prolog.
//
// $Source: src/include/usr/gcov.h $
//
// IBM CONFIDENTIAL
//
// COPYRIGHT International Business Machines Corp. 2012
//
// p1
//
// Object Code Only (OCO) source materials
// Licensed Internal Code Source Materials
// IBM HostBoot Licensed Internal Code
//
// The source code for this program is not published or other-
// wise divested of its trade secrets, irrespective of what has
// been deposited with the U.S. Copyright Office.
//
// Origin: 30
//
// IBM_PROLOG_END
#ifndef __USR_GCOV_H
#define __USR_GCOV_H
/** @file gcov.h
* @brief Header file to generate gcov_info chain for each module.
*
* Each gcov-instrumented module needs to have its own gcov_info chain
* and associated linking function. Each .o file will have its own
* gcov_info object which is added to the chain when the module is loaded
* (static initializers) by calling the __gcov_init function.
*
* We make the gcov_info chain unique per-module, instead of a single
* global chain, so that we don't have bad pointers if a module was
* loaded and then unloaded.
*/
#include <stddef.h>
/** @struct gcov_info
* @brief Structure generated by gcc. Do not use.
*
* This structure is automatically generated and instances of it created by
* gcc when the --coverage compile option is used. We don't need to
* manipulate this structure from code except to fix up the chains as objects
* are added to the chain. The rest of this structure is parsed by the
* Gcov.pm debug tool.
*/
struct gcov_info
{
unsigned int version; // Purposefully chose 'unsigned int' to match gcc.
gcov_info* next;
// Really there is more after here in the structure, but this is all
// we care about from an in-memory perspective.
};
// Preprocessor magic to create a variable name based off the module name.
// GCOV_INFO_OBJ() will create a post-processed name like
// 'foobar_gcov_info_head' or 'core_gcov_info_head'.
#ifdef __HOSTBOOT_MODULE
#define __GCOV_PREFIX __HOSTBOOT_MODULE
#else
#define __GCOV_PREFIX core
#endif
#define __GCOV_INFO_OBJ(X,Y) X ## Y
#define _GCOV_INFO_OBJ(X,Y) __GCOV_INFO_OBJ(X,Y)
#define GCOV_INFO_OBJ() _GCOV_INFO_OBJ(__GCOV_PREFIX, _gcov_info_head)
/** Pointer to the beginning of the gcov_info chain for this module. */
gcov_info* GCOV_INFO_OBJ() = NULL;
/** Function called by module loading to add the object gcov_info instance
* to the chain.
*/
extern "C"
void __gcov_init(gcov_info* i_info)
{
// Atomically push i_info onto the gcov_info_head stack.
do
{
i_info->next = GCOV_INFO_OBJ();
} while (!__sync_bool_compare_and_swap(&GCOV_INFO_OBJ(),
i_info->next, i_info));
}
/** Unneeded function but must be defined to compile.
*
* This function appears to be typically used by libgcov.so when instrumented
* on a real linux-based system. It can be used to merge counters across
* multiple runs or when a 'fork' occurs. It doesn't appear that this
* function ever gets called for us but the unresolved symbol is added to
* the module (by gcc) so we've created a stub here to pass compile.
*/
extern "C"
void __gcov_merge_add()
{
while(1);
}
#endif
|