1*287e80b3SSadaf Ebrahimi // SPDX-License-Identifier: LGPL-2.1
2*287e80b3SSadaf Ebrahimi /*
3*287e80b3SSadaf Ebrahimi * Copyright (C) 2021 VMware Inc, Steven Rostedt <[email protected]>
4*287e80b3SSadaf Ebrahimi *
5*287e80b3SSadaf Ebrahimi * Updates:
6*287e80b3SSadaf Ebrahimi * Copyright (C) 2021, VMware, Tzvetomir Stoyanov <[email protected]>
7*287e80b3SSadaf Ebrahimi *
8*287e80b3SSadaf Ebrahimi */
9*287e80b3SSadaf Ebrahimi #include <stdio.h>
10*287e80b3SSadaf Ebrahimi #include <stdlib.h>
11*287e80b3SSadaf Ebrahimi #include <dirent.h>
12*287e80b3SSadaf Ebrahimi #include <unistd.h>
13*287e80b3SSadaf Ebrahimi #include <errno.h>
14*287e80b3SSadaf Ebrahimi #include <fcntl.h>
15*287e80b3SSadaf Ebrahimi #include <limits.h>
16*287e80b3SSadaf Ebrahimi
17*287e80b3SSadaf Ebrahimi #include "tracefs.h"
18*287e80b3SSadaf Ebrahimi #include "tracefs-local.h"
19*287e80b3SSadaf Ebrahimi
20*287e80b3SSadaf Ebrahimi #define KPROBE_EVENTS "kprobe_events"
21*287e80b3SSadaf Ebrahimi #define KPROBE_DEFAULT_GROUP "kprobes"
22*287e80b3SSadaf Ebrahimi
23*287e80b3SSadaf Ebrahimi static struct tracefs_dynevent *
kprobe_alloc(enum tracefs_dynevent_type type,const char * system,const char * event,const char * addr,const char * format)24*287e80b3SSadaf Ebrahimi kprobe_alloc(enum tracefs_dynevent_type type, const char *system, const char *event,
25*287e80b3SSadaf Ebrahimi const char *addr, const char *format)
26*287e80b3SSadaf Ebrahimi {
27*287e80b3SSadaf Ebrahimi struct tracefs_dynevent *kp;
28*287e80b3SSadaf Ebrahimi const char *sys = system;
29*287e80b3SSadaf Ebrahimi const char *ename = event;
30*287e80b3SSadaf Ebrahimi char *tmp;
31*287e80b3SSadaf Ebrahimi
32*287e80b3SSadaf Ebrahimi if (!addr) {
33*287e80b3SSadaf Ebrahimi errno = EBADMSG;
34*287e80b3SSadaf Ebrahimi return NULL;
35*287e80b3SSadaf Ebrahimi }
36*287e80b3SSadaf Ebrahimi if (!sys)
37*287e80b3SSadaf Ebrahimi sys = KPROBE_DEFAULT_GROUP;
38*287e80b3SSadaf Ebrahimi
39*287e80b3SSadaf Ebrahimi if (!event) {
40*287e80b3SSadaf Ebrahimi ename = strdup(addr);
41*287e80b3SSadaf Ebrahimi if (!ename)
42*287e80b3SSadaf Ebrahimi return NULL;
43*287e80b3SSadaf Ebrahimi tmp = strchr(ename, ':');
44*287e80b3SSadaf Ebrahimi if (tmp)
45*287e80b3SSadaf Ebrahimi *tmp = '\0';
46*287e80b3SSadaf Ebrahimi }
47*287e80b3SSadaf Ebrahimi
48*287e80b3SSadaf Ebrahimi kp = dynevent_alloc(type, sys, ename, addr, format);
49*287e80b3SSadaf Ebrahimi if (!event)
50*287e80b3SSadaf Ebrahimi free((char *)ename);
51*287e80b3SSadaf Ebrahimi
52*287e80b3SSadaf Ebrahimi return kp;
53*287e80b3SSadaf Ebrahimi }
54*287e80b3SSadaf Ebrahimi
55*287e80b3SSadaf Ebrahimi /**
56*287e80b3SSadaf Ebrahimi * tracefs_kprobe_alloc - Allocate new kprobe
57*287e80b3SSadaf Ebrahimi * @system: The system name (NULL for the default kprobes)
58*287e80b3SSadaf Ebrahimi * @event: The event to create (NULL to use @addr for the event)
59*287e80b3SSadaf Ebrahimi * @addr: The function and offset (or address) to insert the probe
60*287e80b3SSadaf Ebrahimi * @format: The format string to define the probe.
61*287e80b3SSadaf Ebrahimi *
62*287e80b3SSadaf Ebrahimi * Allocate a kprobe context that will be in the @system group (or kprobes if
63*287e80b3SSadaf Ebrahimi * @system is NULL). Have the name of @event (or @addr if @event is NULL). Will
64*287e80b3SSadaf Ebrahimi * be inserted to @addr (function name, with or without offset, or a address).
65*287e80b3SSadaf Ebrahimi * And the @format will define the format of the kprobe.
66*287e80b3SSadaf Ebrahimi *
67*287e80b3SSadaf Ebrahimi * See the Linux documentation file under:
68*287e80b3SSadaf Ebrahimi * Documentation/trace/kprobetrace.rst
69*287e80b3SSadaf Ebrahimi *
70*287e80b3SSadaf Ebrahimi * The kprobe is not created in the system.
71*287e80b3SSadaf Ebrahimi *
72*287e80b3SSadaf Ebrahimi * Return a pointer to a kprobe context on success, or NULL on error.
73*287e80b3SSadaf Ebrahimi * The returned pointer must be freed with tracefs_dynevent_free()
74*287e80b3SSadaf Ebrahimi *
75*287e80b3SSadaf Ebrahimi * errno will be set to EBADMSG if addr is NULL.
76*287e80b3SSadaf Ebrahimi */
77*287e80b3SSadaf Ebrahimi struct tracefs_dynevent *
tracefs_kprobe_alloc(const char * system,const char * event,const char * addr,const char * format)78*287e80b3SSadaf Ebrahimi tracefs_kprobe_alloc(const char *system, const char *event, const char *addr, const char *format)
79*287e80b3SSadaf Ebrahimi
80*287e80b3SSadaf Ebrahimi {
81*287e80b3SSadaf Ebrahimi return kprobe_alloc(TRACEFS_DYNEVENT_KPROBE, system, event, addr, format);
82*287e80b3SSadaf Ebrahimi }
83*287e80b3SSadaf Ebrahimi
84*287e80b3SSadaf Ebrahimi /**
85*287e80b3SSadaf Ebrahimi * tracefs_kretprobe_alloc - Allocate new kretprobe
86*287e80b3SSadaf Ebrahimi * @system: The system name (NULL for the default kprobes)
87*287e80b3SSadaf Ebrahimi * @event: The event to create (NULL to use @addr for the event)
88*287e80b3SSadaf Ebrahimi * @addr: The function and offset (or address) to insert the retprobe
89*287e80b3SSadaf Ebrahimi * @format: The format string to define the retprobe.
90*287e80b3SSadaf Ebrahimi * @max: Maximum number of instances of the specified function that
91*287e80b3SSadaf Ebrahimi * can be probed simultaneously, or 0 for the default value.
92*287e80b3SSadaf Ebrahimi *
93*287e80b3SSadaf Ebrahimi * Allocate a kretprobe that will be in the @system group (or kprobes if
94*287e80b3SSadaf Ebrahimi * @system is NULL). Have the name of @event (or @addr if @event is
95*287e80b3SSadaf Ebrahimi * NULL). Will be inserted to @addr (function name, with or without
96*287e80b3SSadaf Ebrahimi * offset, or a address). And the @format will define the raw format
97*287e80b3SSadaf Ebrahimi * of the kprobe. See the Linux documentation file under:
98*287e80b3SSadaf Ebrahimi * Documentation/trace/kprobetrace.rst
99*287e80b3SSadaf Ebrahimi * The kretprobe is not created in the system.
100*287e80b3SSadaf Ebrahimi *
101*287e80b3SSadaf Ebrahimi * Return a pointer to a kprobe context on success, or NULL on error.
102*287e80b3SSadaf Ebrahimi * The returned pointer must be freed with tracefs_dynevent_free()
103*287e80b3SSadaf Ebrahimi *
104*287e80b3SSadaf Ebrahimi * errno will be set to EBADMSG if addr is NULL.
105*287e80b3SSadaf Ebrahimi */
106*287e80b3SSadaf Ebrahimi struct tracefs_dynevent *
tracefs_kretprobe_alloc(const char * system,const char * event,const char * addr,const char * format,unsigned int max)107*287e80b3SSadaf Ebrahimi tracefs_kretprobe_alloc(const char *system, const char *event,
108*287e80b3SSadaf Ebrahimi const char *addr, const char *format, unsigned int max)
109*287e80b3SSadaf Ebrahimi {
110*287e80b3SSadaf Ebrahimi struct tracefs_dynevent *kp;
111*287e80b3SSadaf Ebrahimi int ret;
112*287e80b3SSadaf Ebrahimi
113*287e80b3SSadaf Ebrahimi kp = kprobe_alloc(TRACEFS_DYNEVENT_KRETPROBE, system, event, addr, format);
114*287e80b3SSadaf Ebrahimi if (!kp)
115*287e80b3SSadaf Ebrahimi return NULL;
116*287e80b3SSadaf Ebrahimi
117*287e80b3SSadaf Ebrahimi if (!max)
118*287e80b3SSadaf Ebrahimi return kp;
119*287e80b3SSadaf Ebrahimi
120*287e80b3SSadaf Ebrahimi free(kp->prefix);
121*287e80b3SSadaf Ebrahimi kp->prefix = NULL;
122*287e80b3SSadaf Ebrahimi ret = asprintf(&kp->prefix, "r%d:", max);
123*287e80b3SSadaf Ebrahimi if (ret < 0)
124*287e80b3SSadaf Ebrahimi goto error;
125*287e80b3SSadaf Ebrahimi
126*287e80b3SSadaf Ebrahimi return kp;
127*287e80b3SSadaf Ebrahimi error:
128*287e80b3SSadaf Ebrahimi tracefs_dynevent_free(kp);
129*287e80b3SSadaf Ebrahimi return NULL;
130*287e80b3SSadaf Ebrahimi }
131*287e80b3SSadaf Ebrahimi
kprobe_raw(enum tracefs_dynevent_type type,const char * system,const char * event,const char * addr,const char * format)132*287e80b3SSadaf Ebrahimi static int kprobe_raw(enum tracefs_dynevent_type type, const char *system,
133*287e80b3SSadaf Ebrahimi const char *event, const char *addr, const char *format)
134*287e80b3SSadaf Ebrahimi {
135*287e80b3SSadaf Ebrahimi static struct tracefs_dynevent *kp;
136*287e80b3SSadaf Ebrahimi int ret;
137*287e80b3SSadaf Ebrahimi
138*287e80b3SSadaf Ebrahimi kp = kprobe_alloc(type, system, event, addr, format);
139*287e80b3SSadaf Ebrahimi if (!kp)
140*287e80b3SSadaf Ebrahimi return -1;
141*287e80b3SSadaf Ebrahimi
142*287e80b3SSadaf Ebrahimi ret = tracefs_dynevent_create(kp);
143*287e80b3SSadaf Ebrahimi tracefs_dynevent_free(kp);
144*287e80b3SSadaf Ebrahimi
145*287e80b3SSadaf Ebrahimi return ret;
146*287e80b3SSadaf Ebrahimi }
147*287e80b3SSadaf Ebrahimi
148*287e80b3SSadaf Ebrahimi /**
149*287e80b3SSadaf Ebrahimi * tracefs_kprobe_raw - Create a kprobe using raw format
150*287e80b3SSadaf Ebrahimi * @system: The system name (NULL for the default kprobes)
151*287e80b3SSadaf Ebrahimi * @event: The event to create (NULL to use @addr for the event)
152*287e80b3SSadaf Ebrahimi * @addr: The function and offset (or address) to insert the probe
153*287e80b3SSadaf Ebrahimi * @format: The raw format string to define the probe.
154*287e80b3SSadaf Ebrahimi *
155*287e80b3SSadaf Ebrahimi * Create a kprobe that will be in the @system group (or kprobes if
156*287e80b3SSadaf Ebrahimi * @system is NULL). Have the name of @event (or @addr if @event is
157*287e80b3SSadaf Ebrahimi * NULL). Will be inserted to @addr (function name, with or without
158*287e80b3SSadaf Ebrahimi * offset, or a address). And the @format will define the raw format
159*287e80b3SSadaf Ebrahimi * of the kprobe. See the Linux documentation file under:
160*287e80b3SSadaf Ebrahimi * Documentation/trace/kprobetrace.rst
161*287e80b3SSadaf Ebrahimi *
162*287e80b3SSadaf Ebrahimi * Return 0 on success, or -1 on error.
163*287e80b3SSadaf Ebrahimi * If the syntex of @format was incorrect, running
164*287e80b3SSadaf Ebrahimi * tracefs_error_last(NULL) may show what went wrong.
165*287e80b3SSadaf Ebrahimi *
166*287e80b3SSadaf Ebrahimi * errno will be set to EBADMSG if addr or format is NULL.
167*287e80b3SSadaf Ebrahimi */
tracefs_kprobe_raw(const char * system,const char * event,const char * addr,const char * format)168*287e80b3SSadaf Ebrahimi int tracefs_kprobe_raw(const char *system, const char *event,
169*287e80b3SSadaf Ebrahimi const char *addr, const char *format)
170*287e80b3SSadaf Ebrahimi {
171*287e80b3SSadaf Ebrahimi return kprobe_raw(TRACEFS_DYNEVENT_KPROBE, system, event, addr, format);
172*287e80b3SSadaf Ebrahimi }
173*287e80b3SSadaf Ebrahimi
174*287e80b3SSadaf Ebrahimi /**
175*287e80b3SSadaf Ebrahimi * tracefs_kretprobe_raw - Create a kretprobe using raw format
176*287e80b3SSadaf Ebrahimi * @system: The system name (NULL for the default kprobes)
177*287e80b3SSadaf Ebrahimi * @event: The event to create (NULL to use @addr for the event)
178*287e80b3SSadaf Ebrahimi * @addr: The function and offset (or address) to insert the retprobe
179*287e80b3SSadaf Ebrahimi * @format: The raw format string to define the retprobe.
180*287e80b3SSadaf Ebrahimi *
181*287e80b3SSadaf Ebrahimi * Create a kretprobe that will be in the @system group (or kprobes if
182*287e80b3SSadaf Ebrahimi * @system is NULL). Have the name of @event (or @addr if @event is
183*287e80b3SSadaf Ebrahimi * NULL). Will be inserted to @addr (function name, with or without
184*287e80b3SSadaf Ebrahimi * offset, or a address). And the @format will define the raw format
185*287e80b3SSadaf Ebrahimi * of the kprobe. See the Linux documentation file under:
186*287e80b3SSadaf Ebrahimi * Documentation/trace/kprobetrace.rst
187*287e80b3SSadaf Ebrahimi *
188*287e80b3SSadaf Ebrahimi * Return 0 on success, or -1 on error.
189*287e80b3SSadaf Ebrahimi * If the syntex of @format was incorrect, running
190*287e80b3SSadaf Ebrahimi * tracefs_error_last(NULL) may show what went wrong.
191*287e80b3SSadaf Ebrahimi *
192*287e80b3SSadaf Ebrahimi * errno will be set to EBADMSG if addr or format is NULL.
193*287e80b3SSadaf Ebrahimi */
tracefs_kretprobe_raw(const char * system,const char * event,const char * addr,const char * format)194*287e80b3SSadaf Ebrahimi int tracefs_kretprobe_raw(const char *system, const char *event,
195*287e80b3SSadaf Ebrahimi const char *addr, const char *format)
196*287e80b3SSadaf Ebrahimi {
197*287e80b3SSadaf Ebrahimi return kprobe_raw(TRACEFS_DYNEVENT_KRETPROBE, system, event, addr, format);
198*287e80b3SSadaf Ebrahimi }
199