Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v5.3-rc6 120 lines 2.6 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2 3#include <stdio.h> 4#include <unistd.h> 5#include <stdlib.h> 6#include <errno.h> 7#include <sys/types.h> 8#include <sys/stat.h> 9#include <fcntl.h> 10#include <linux/kernel.h> 11#include <linux/err.h> 12#include <traceevent/event-parse.h> 13#include <api/fs/tracing_path.h> 14#include <api/fs/fs.h> 15#include "trace-event.h" 16#include "machine.h" 17#include "util.h" 18 19/* 20 * global trace_event object used by trace_event__tp_format 21 * 22 * TODO There's no cleanup call for this. Add some sort of 23 * __exit function support and call trace_event__cleanup 24 * there. 25 */ 26static struct trace_event tevent; 27static bool tevent_initialized; 28 29int trace_event__init(struct trace_event *t) 30{ 31 struct tep_handle *pevent = tep_alloc(); 32 33 if (pevent) { 34 t->plugin_list = tep_load_plugins(pevent); 35 t->pevent = pevent; 36 } 37 38 return pevent ? 0 : -1; 39} 40 41static int trace_event__init2(void) 42{ 43 int be = tep_is_bigendian(); 44 struct tep_handle *pevent; 45 46 if (trace_event__init(&tevent)) 47 return -1; 48 49 pevent = tevent.pevent; 50 tep_set_flag(pevent, TEP_NSEC_OUTPUT); 51 tep_set_file_bigendian(pevent, be); 52 tep_set_local_bigendian(pevent, be); 53 tevent_initialized = true; 54 return 0; 55} 56 57int trace_event__register_resolver(struct machine *machine, 58 tep_func_resolver_t *func) 59{ 60 if (!tevent_initialized && trace_event__init2()) 61 return -1; 62 63 return tep_set_function_resolver(tevent.pevent, func, machine); 64} 65 66void trace_event__cleanup(struct trace_event *t) 67{ 68 tep_unload_plugins(t->plugin_list, t->pevent); 69 tep_free(t->pevent); 70} 71 72/* 73 * Returns pointer with encoded error via <linux/err.h> interface. 74 */ 75static struct tep_event* 76tp_format(const char *sys, const char *name) 77{ 78 char *tp_dir = get_events_file(sys); 79 struct tep_handle *pevent = tevent.pevent; 80 struct tep_event *event = NULL; 81 char path[PATH_MAX]; 82 size_t size; 83 char *data; 84 int err; 85 86 if (!tp_dir) 87 return ERR_PTR(-errno); 88 89 scnprintf(path, PATH_MAX, "%s/%s/format", tp_dir, name); 90 put_events_file(tp_dir); 91 92 err = filename__read_str(path, &data, &size); 93 if (err) 94 return ERR_PTR(err); 95 96 tep_parse_format(pevent, &event, data, size, sys); 97 98 free(data); 99 return event; 100} 101 102/* 103 * Returns pointer with encoded error via <linux/err.h> interface. 104 */ 105struct tep_event* 106trace_event__tp_format(const char *sys, const char *name) 107{ 108 if (!tevent_initialized && trace_event__init2()) 109 return ERR_PTR(-ENOMEM); 110 111 return tp_format(sys, name); 112} 113 114struct tep_event *trace_event__tp_format_id(int id) 115{ 116 if (!tevent_initialized && trace_event__init2()) 117 return ERR_PTR(-ENOMEM); 118 119 return tep_find_event(tevent.pevent, id); 120}