GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/gmon/mcount.c Lines: 0 44 0.0 %
Date: 2017-11-07 Branches: 0 18 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: mcount.c,v 1.15 2015/01/16 16:48:51 deraadt Exp $ */
2
/*-
3
 * Copyright (c) 1983, 1992, 1993
4
 *	The Regents of the University of California.  All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of the University nor the names of its contributors
15
 *    may be used to endorse or promote products derived from this software
16
 *    without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 */
30
31
#include <sys/types.h>
32
#include <sys/gmon.h>
33
34
/*
35
 * mcount is called on entry to each function compiled with the profiling
36
 * switch set.  _mcount(), which is declared in a machine-dependent way
37
 * with _MCOUNT_DECL, does the actual work and is either inlined into a
38
 * C routine or called by an assembly stub.  In any case, this magic is
39
 * taken care of by the MCOUNT definition in <machine/profile.h>.
40
 *
41
 * _mcount updates data structures that represent traversals of the
42
 * program's call graph edges.  frompc and selfpc are the return
43
 * address and function address that represents the given call graph edge.
44
 */
45
_MCOUNT_DECL(u_long frompc, u_long selfpc) __used;
46
/* _mcount; may be static, inline, etc */
47
_MCOUNT_DECL(u_long frompc, u_long selfpc)
48
{
49
	u_short *frompcindex;
50
	struct tostruct *top, *prevtop;
51
	struct gmonparam *p;
52
	long toindex;
53
#ifdef _KERNEL
54
	int s;
55
56
	/*
57
	 * Do not profile execution if memory for the current CPU
58
	 * desciptor and profiling buffers has not yet been allocated
59
	 * or if the CPU we are running on has not yet set its trap
60
	 * handler.
61
	 */
62
	if (gmoninit == 0)
63
		return;
64
65
	if ((p = curcpu()->ci_gmon) == NULL)
66
		return;
67
#else
68
	p = &_gmonparam;
69
#endif
70
	/*
71
	 * check that we are profiling
72
	 * and that we aren't recursively invoked.
73
	 */
74
	if (p->state != GMON_PROF_ON)
75
		return;
76
#ifdef _KERNEL
77
	MCOUNT_ENTER;
78
#else
79
	p->state = GMON_PROF_BUSY;
80
#endif
81
	/*
82
	 * check that frompcindex is a reasonable pc value.
83
	 * for example:	signal catchers get called from the stack,
84
	 *		not from text space.  too bad.
85
	 */
86
	frompc -= p->lowpc;
87
	if (frompc > p->textsize)
88
		goto done;
89
90
#if (HASHFRACTION & (HASHFRACTION - 1)) == 0
91
	if (p->hashfraction == HASHFRACTION)
92
		frompcindex =
93
		    &p->froms[frompc / (HASHFRACTION * sizeof(*p->froms))];
94
	else
95
#endif
96
		frompcindex =
97
		    &p->froms[frompc / (p->hashfraction * sizeof(*p->froms))];
98
	toindex = *frompcindex;
99
	if (toindex == 0) {
100
		/*
101
		 *	first time traversing this arc
102
		 */
103
		toindex = ++p->tos[0].link;
104
		if (toindex >= p->tolimit)
105
			/* halt further profiling */
106
			goto overflow;
107
108
		*frompcindex = toindex;
109
		top = &p->tos[toindex];
110
		top->selfpc = selfpc;
111
		top->count = 1;
112
		top->link = 0;
113
		goto done;
114
	}
115
	top = &p->tos[toindex];
116
	if (top->selfpc == selfpc) {
117
		/*
118
		 * arc at front of chain; usual case.
119
		 */
120
		top->count++;
121
		goto done;
122
	}
123
	/*
124
	 * have to go looking down chain for it.
125
	 * top points to what we are looking at,
126
	 * prevtop points to previous top.
127
	 * we know it is not at the head of the chain.
128
	 */
129
	for (; /* goto done */; ) {
130
		if (top->link == 0) {
131
			/*
132
			 * top is end of the chain and none of the chain
133
			 * had top->selfpc == selfpc.
134
			 * so we allocate a new tostruct
135
			 * and link it to the head of the chain.
136
			 */
137
			toindex = ++p->tos[0].link;
138
			if (toindex >= p->tolimit)
139
				goto overflow;
140
141
			top = &p->tos[toindex];
142
			top->selfpc = selfpc;
143
			top->count = 1;
144
			top->link = *frompcindex;
145
			*frompcindex = toindex;
146
			goto done;
147
		}
148
		/*
149
		 * otherwise, check the next arc on the chain.
150
		 */
151
		prevtop = top;
152
		top = &p->tos[top->link];
153
		if (top->selfpc == selfpc) {
154
			/*
155
			 * there it is.
156
			 * increment its count
157
			 * move it to the head of the chain.
158
			 */
159
			top->count++;
160
			toindex = prevtop->link;
161
			prevtop->link = top->link;
162
			top->link = *frompcindex;
163
			*frompcindex = toindex;
164
			goto done;
165
		}
166
	}
167
done:
168
#ifdef _KERNEL
169
	MCOUNT_EXIT;
170
#else
171
	p->state = GMON_PROF_ON;
172
#endif
173
	return;
174
overflow:
175
	p->state = GMON_PROF_ERROR;
176
#ifdef _KERNEL
177
	MCOUNT_EXIT;
178
#endif
179
	return;
180
}
181
182
/*
183
 * Actual definition of mcount function.  Defined in <machine/profile.h>,
184
 * which is included by <sys/gmon.h>.
185
 */
186
MCOUNT