xref: /aosp_15_r20/external/libtracefs/src/tracefs-uprobes.c (revision 287e80b3a36113050663245e7f2c00d274188f18)
1*287e80b3SSadaf Ebrahimi // SPDX-License-Identifier: LGPL-2.1
2*287e80b3SSadaf Ebrahimi /*
3*287e80b3SSadaf Ebrahimi  * Copyright (C) 2022, VMware, Tzvetomir Stoyanov <[email protected]>
4*287e80b3SSadaf Ebrahimi  *
5*287e80b3SSadaf Ebrahimi  */
6*287e80b3SSadaf Ebrahimi #include <stdlib.h>
7*287e80b3SSadaf Ebrahimi #include <errno.h>
8*287e80b3SSadaf Ebrahimi 
9*287e80b3SSadaf Ebrahimi #include "tracefs.h"
10*287e80b3SSadaf Ebrahimi #include "tracefs-local.h"
11*287e80b3SSadaf Ebrahimi 
12*287e80b3SSadaf Ebrahimi #define UPROBE_DEFAULT_GROUP "uprobes"
13*287e80b3SSadaf Ebrahimi 
14*287e80b3SSadaf Ebrahimi static struct tracefs_dynevent *
uprobe_alloc(enum tracefs_dynevent_type type,const char * system,const char * event,const char * file,unsigned long long offset,const char * fetchargs)15*287e80b3SSadaf Ebrahimi uprobe_alloc(enum tracefs_dynevent_type type, const char *system, const char *event,
16*287e80b3SSadaf Ebrahimi 	     const char *file, unsigned long long offset, const char *fetchargs)
17*287e80b3SSadaf Ebrahimi {
18*287e80b3SSadaf Ebrahimi 	struct tracefs_dynevent *kp;
19*287e80b3SSadaf Ebrahimi 	char *target;
20*287e80b3SSadaf Ebrahimi 
21*287e80b3SSadaf Ebrahimi 	if (!event || !file) {
22*287e80b3SSadaf Ebrahimi 		errno = EINVAL;
23*287e80b3SSadaf Ebrahimi 		return NULL;
24*287e80b3SSadaf Ebrahimi 	}
25*287e80b3SSadaf Ebrahimi 
26*287e80b3SSadaf Ebrahimi 	if (!system)
27*287e80b3SSadaf Ebrahimi 		system = UPROBE_DEFAULT_GROUP;
28*287e80b3SSadaf Ebrahimi 
29*287e80b3SSadaf Ebrahimi 	if (asprintf(&target, "%s:0x%0*llx", file, (int)(sizeof(void *) * 2), offset) < 0)
30*287e80b3SSadaf Ebrahimi 		return NULL;
31*287e80b3SSadaf Ebrahimi 
32*287e80b3SSadaf Ebrahimi 	kp = dynevent_alloc(type, system, event, target, fetchargs);
33*287e80b3SSadaf Ebrahimi 	free(target);
34*287e80b3SSadaf Ebrahimi 
35*287e80b3SSadaf Ebrahimi 	return kp;
36*287e80b3SSadaf Ebrahimi }
37*287e80b3SSadaf Ebrahimi 
38*287e80b3SSadaf Ebrahimi /**
39*287e80b3SSadaf Ebrahimi  * tracefs_uprobe_alloc - Allocate new user probe (uprobe)
40*287e80b3SSadaf Ebrahimi  * @system: The system name (NULL for the default uprobes)
41*287e80b3SSadaf Ebrahimi  * @event: The name of the event to create
42*287e80b3SSadaf Ebrahimi  * @file: The full path to the binary file, where the uprobe will be set
43*287e80b3SSadaf Ebrahimi  * @offset: Offset within the @file
44*287e80b3SSadaf Ebrahimi  * @fetchargs: String with arguments, that will be fetched with the uprobe
45*287e80b3SSadaf Ebrahimi  *
46*287e80b3SSadaf Ebrahimi  * Allocate new uprobe context that will be in the @system group
47*287e80b3SSadaf Ebrahimi  * (or uprobes if @system is NULL) and with @event name. The new uprobe will be
48*287e80b3SSadaf Ebrahimi  * attached to @offset within the @file. The arguments described in @fetchargs
49*287e80b3SSadaf Ebrahimi  * will fetched with the uprobe. See linux/Documentation/trace/uprobetracer.rst
50*287e80b3SSadaf Ebrahimi  * for more details.
51*287e80b3SSadaf Ebrahimi  *
52*287e80b3SSadaf Ebrahimi  * The uprobe is not created in the system.
53*287e80b3SSadaf Ebrahimi  *
54*287e80b3SSadaf Ebrahimi  * Return a pointer to a uprobe context on success, or NULL on error.
55*287e80b3SSadaf Ebrahimi  * The returned pointer must be freed with tracefs_dynevent_free()
56*287e80b3SSadaf Ebrahimi  *
57*287e80b3SSadaf Ebrahimi  */
58*287e80b3SSadaf Ebrahimi struct tracefs_dynevent *
tracefs_uprobe_alloc(const char * system,const char * event,const char * file,unsigned long long offset,const char * fetchargs)59*287e80b3SSadaf Ebrahimi tracefs_uprobe_alloc(const char *system, const char *event,
60*287e80b3SSadaf Ebrahimi 		     const char *file, unsigned long long offset, const char *fetchargs)
61*287e80b3SSadaf Ebrahimi {
62*287e80b3SSadaf Ebrahimi 	return uprobe_alloc(TRACEFS_DYNEVENT_UPROBE, system, event, file, offset, fetchargs);
63*287e80b3SSadaf Ebrahimi }
64*287e80b3SSadaf Ebrahimi 
65*287e80b3SSadaf Ebrahimi /**
66*287e80b3SSadaf Ebrahimi  * tracefs_uretprobe_alloc - Allocate new user return probe (uretprobe)
67*287e80b3SSadaf Ebrahimi  * @system: The system name (NULL for the default uprobes)
68*287e80b3SSadaf Ebrahimi  * @event: The name of the event to create
69*287e80b3SSadaf Ebrahimi  * @file: The full path to the binary file, where the uretprobe will be set
70*287e80b3SSadaf Ebrahimi  * @offset: Offset within the @file
71*287e80b3SSadaf Ebrahimi  * @fetchargs: String with arguments, that will be fetched with the uretprobe
72*287e80b3SSadaf Ebrahimi  *
73*287e80b3SSadaf Ebrahimi  * Allocate mew uretprobe context that will be in the @system group
74*287e80b3SSadaf Ebrahimi  * (or uprobes if @system is NULL) and with @event name. The new uretprobe will
75*287e80b3SSadaf Ebrahimi  * be attached to @offset within the @file. The arguments described in @fetchargs
76*287e80b3SSadaf Ebrahimi  * will fetched with the uprobe. See linux/Documentation/trace/uprobetracer.rst
77*287e80b3SSadaf Ebrahimi  * for more details.
78*287e80b3SSadaf Ebrahimi  *
79*287e80b3SSadaf Ebrahimi  * The uretprobe is not created in the system.
80*287e80b3SSadaf Ebrahimi  *
81*287e80b3SSadaf Ebrahimi  * Return a pointer to a uretprobe context on success, or NULL on error.
82*287e80b3SSadaf Ebrahimi  * The returned pointer must be freed with tracefs_dynevent_free()
83*287e80b3SSadaf Ebrahimi  *
84*287e80b3SSadaf Ebrahimi  */
85*287e80b3SSadaf Ebrahimi struct tracefs_dynevent *
tracefs_uretprobe_alloc(const char * system,const char * event,const char * file,unsigned long long offset,const char * fetchargs)86*287e80b3SSadaf Ebrahimi tracefs_uretprobe_alloc(const char *system, const char *event,
87*287e80b3SSadaf Ebrahimi 			const char *file, unsigned long long offset, const char *fetchargs)
88*287e80b3SSadaf Ebrahimi {
89*287e80b3SSadaf Ebrahimi 	return uprobe_alloc(TRACEFS_DYNEVENT_URETPROBE, system, event, file, offset, fetchargs);
90*287e80b3SSadaf Ebrahimi }
91