summaryrefslogtreecommitdiffstats
path: root/runtime/probes.c
blob: 19539044d1fc379b4f8a8ae2429616512906df11 (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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* -*- linux-c -*- 
 * Functions for Registering and Unregistering Probes
 * Copyright (C) 2005 Red Hat Inc.
 *
 * This file is part of systemtap, and is free software.  You can
 * redistribute it and/or modify it under the terms of the GNU General
 * Public License (GPL); either version 2, or (at your option) any
 * later version.
 */

#ifndef _PROBES_C_
#define _PROBES_C

/** @file probes.c
 * @brief Functions to assist loading and unloading groups of probes.
 */

/** Unregister a group of jprobes.
 * @param probes Pointer to an array of struct jprobe.
 * @param num_probes Number of probes in the array.
 */

void _stp_unregister_jprobes (struct jprobe *probes, int num_probes)
{
	int i;
	for (i = 0; i < num_probes; i++)
		unregister_jprobe(&probes[i]);
	dbug("All jprobes removed\n");
}

/** Register a group of jprobes.
 * @param probes Pointer to an array of struct jprobe.
 * @param num_probes Number of probes in the array.
 * @return 0 on success.
 */

int _stp_register_jprobes (struct jprobe *probes, int num_probes)
{
	int i, ret ;
	unsigned long addr;

	for (i = 0; i < num_probes; i++) {
		addr =kallsyms_lookup_name((char *)probes[i].kp.addr);
		if (addr == 0) {
			_stp_warn("function %s not found!\n", (char *)probes[i].kp.addr);
			ret = -1; /* FIXME */
			goto out;
		}
		dbug("inserting jprobe at %s (%p)\n", probes[i].kp.addr, addr);
		probes[i].kp.addr = (kprobe_opcode_t *)addr;
		ret = register_jprobe(&probes[i]);
		if (ret)
			goto out;
	}
	return 0;
out:
	_stp_warn("probe module initialization failed.  Exiting...\n");
	_stp_unregister_jprobes(probes, i);
	return ret;
}

/** Unregister a group of kprobes.
 * @param probes Pointer to an array of struct kprobe.
 * @param num_probes Number of probes in the array.
 */

void _stp_unregister_kprobes (struct kprobe *probes, int num_probes)
{
	int i;
	for (i = 0; i < num_probes; i++)
		unregister_kprobe(&probes[i]);
	dbug("All kprobes removed\n");
}


#ifdef USE_RET_PROBES
/** Unregister a group of return probes.
 * @param probes Pointer to an array of struct kretprobe.
 * @param num_probes Number of probes in the array.
 */
void _stp_unregister_kretprobes (struct kretprobe *probes, int num_probes)
{
	int i;
	for (i = 0; i < num_probes; i++)
		unregister_kretprobe(&probes[i]);
	dbug("All return probes removed\n");
}
#endif

/** Register a group of kprobes.
 * @param probes Pointer to an array of struct kprobe.
 * @param num_probes Number of probes in the array.
 * @return 0 on success.
 */
int _stp_register_kprobes (struct kprobe *probes, int num_probes)
{
	int i, ret ;
	unsigned long addr;

	for (i = 0; i < num_probes; i++) {
		addr = kallsyms_lookup_name((char *)probes[i].addr);
		if (addr == 0) {
			_stp_warn("function %s not found!\n", (char *)probes[i].addr);
			ret = -1;
			goto out;
		}
		dbug("inserting kprobe at %s (%p)\n", probes[i].addr, addr);
		probes[i].addr = (kprobe_opcode_t *)addr;
		ret = register_kprobe(&probes[i]);
		if (ret)
			goto out;
	}
	return 0;
out:
	_stp_warn("probe module initialization failed.  Exiting...\n");
	_stp_unregister_kprobes(probes, i);
	return ret;
}

#ifdef USE_RET_PROBES
/** Register a group of return probes.
 * @param probes Pointer to an array of struct kretprobe.
 * @param num_probes Number of probes in the array.
 * @return 0 on success.
 */
int _stp_register_kretprobes (struct kretprobe *probes, int num_probes)
{
	int i, ret ;
	unsigned long addr;

	for (i = 0; i < num_probes; i++) {
		addr = kallsyms_lookup_name((char *)probes[i].kp.addr);
		if (addr == 0) {
			_stp_warn("function %s not found!\n", 
				   (char *)probes[i].kp.addr);
			ret = -1; /* FIXME */
			goto out;
		}
		dbug("inserting kretprobe at %s (%p)\n", probes[i].kp.addr, addr);
		probes[i].kp.addr = (kprobe_opcode_t *)addr;
		ret = register_kretprobe(&probes[i]);
		if (ret)
			goto out;
	}
	return 0;
out:
	_stp_warn("probe module initialization failed.  Exiting...\n");
	_stp_unregister_kretprobes(probes, i);
	return ret;
}
#endif
#endif /* _PROBES_C */