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 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
|
/*
* Oracle Linux DTrace; USDT definitions parser interface.
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
#ifndef _USDT_PARSER_H
#define _USDT_PARSER_H
#include <inttypes.h>
#include <stddef.h>
#include <libelf.h>
#include <dtrace/dof.h>
#include <dtrace/helpers.h>
/*
* Data transfer unit for the DOF parser.
*/
typedef struct usdt_data usdt_data_t;
struct usdt_data {
size_t base; /* base address of section */
size_t size; /* data size */
void *buf; /* data content */
usdt_data_t *next; /* next buffer */
};
/*
* Result of USDT definitions parsing. The order of elements in the parsed
* stream is:
*
* DIT_PROVIDER (at least 1, which contains...)
* DIT_PROBE (at least 1, each of which has...)
* DIT_ARGS_NATIVE (1, optional)
* DIT_ARGS_XLAT (1, optional)
* DIT_ARGS_MAP (1, optional)
* DIT_TRACEPOINT (any number >= 1)
* DIT_EOF (no more providers, last record)
*
* The dof_parsed.provider.flags word indicates the presence of the
* various optional args records in the following stream (you can rely on
* them if it simplifies things, but you don't have to).
*
* On error, a DIT_ERR structure is returned with an error message.
*/
typedef enum dof_parsed_info {
DIT_PROVIDER = 0,
DIT_PROBE = 1,
DIT_TRACEPOINT = 2,
DIT_ERR = 3,
DIT_EOF = 4,
DIT_ARGS_NATIVE = 5,
DIT_ARGS_XLAT = 6,
DIT_ARGS_MAP = 7,
} dof_parsed_info_t;
/*
* Bump this whenever dof_parsed changes.
*
* Files consisting of arrays of dof_parsed have a single 64-bit word at the
* start which is the version of the dof_parseds within it. The data flowing
* over the stream from the seccomped parser has no such prefix.
*/
#define DOF_PARSED_VERSION 3
typedef struct dof_parsed {
/*
* Size of this instance of this structure.
*/
size_t size;
dof_parsed_info_t type;
__extension__ union {
struct dpi_provider_info {
/*
* Number of probes that follow.
*/
size_t nprobes;
/*
* Provider name.
*/
char name[1];
} provider;
struct dpi_probe_info {
/*
* Number of tracepoints that follow.
*/
size_t ntp;
/*
* Number of native arguments that follow (if > 0, a
* DIT_ARGS_NATIVE will be received).
*/
size_t nargc;
/*
* Number of xlated arguments that follow (if > 0, a
* DIT_ARGS_XLAT and DIT_ARGS_MAP will be received).
*/
size_t xargc;
/*
* Probe module, function, and name (\0-separated).
*/
char name[1];
} probe;
/* V2+ only. */
struct dpi_probe_args_native_info {
/*
* Array of native args. nargc in length.
*/
char args[1];
} nargs;
/* V2+ only. */
struct dpi_probe_args_xlat_info {
/*
* Array of translated args. xargc in length.
*/
char args[1];
} xargs;
/*
* V2+ only.
*/
struct dpi_probe_args_map_info {
/*
* Mapping from native arg index to xlated arg index.
* xargc in length.
*/
int8_t argmap[1];
} argmap;
struct dpi_tracepoint_info {
/*
* Offset of this tracepoint.
*/
uint64_t addr;
/*
* True if this is an is-enabled probe.
*/
uint32_t is_enabled;
/* V3+ only. */
/*
* Array of arg source strings. nargc in length.
*/
char args[1];
} tracepoint;
struct dpi_err {
/*
* An errno value.
*/
int err_no;
/*
* A \0-terminated string.
*/
char err[1];
} err;
};
} dof_parsed_t;
/*
* Host-side: in usdt_parser_host.c.
* The host is the non-jailed process that talks to the jailed parser.
*/
/*
* Write the USDT definitions data to the parser pipe OUT.
*
* Returns 0 on success or a positive errno value on error.
*/
int usdt_parser_host_write(int out, const dof_helper_t *dh,
const usdt_data_t *data);
/*
* Read a single dof_parsed_t structure from a parser pipe. Wait at most
* TIMEOUT seconds to do so.
*
* Returns NULL and sets errno on error.
*/
dof_parsed_t *usdt_parser_host_read(int in, int timeout);
/* Parser-side: in usdt_parser.c. */
/*
* Report a parser error.
*/
void usdt_error(int out, int err_no, const char *fmt, ...);
/*
* Get a dof_helper_t from the input fd.
*
* Returns NULL on failure - no further processing is possible in that case.
*/
dof_helper_t *usdt_copyin_helper(int in);
/*
* Get a USDT data block from the input fd.
*
* Set OK to zero if no further parsing is possible.
*/
usdt_data_t *usdt_copyin_data(int in, int out, int *ok);
/*
* Parse probe info out of the passed-in dof_helper_t and USDT definitions data
* block and emit it to OUT in the form of a stream of dof_parser_info_t.
*/
void usdt_parse(int out, dof_helper_t *dhp, usdt_data_t *data);
/*
* Parse probe info out of the passed-in dof_helper_t and DOF section data and
* emit it to OUT in the form of a stream of dof_parser_info_t.
*
* Returns 0 on success or a positive errno value on error.
*/
int usdt_parse_dof(int out, dof_helper_t *dhp, dof_hdr_t *dof);
/*
* Parse probe info out of the passed-in dof_helper_t and ELF notes section
* data and emit it to OUT in the form of a stream of dof_parser_info_t.
*
* Returns 0 on success or a positive errno value on error.
*/
int usdt_parse_notes(int out, dof_helper_t *dhp, usdt_data_t *data);
/*
* Shared host and parser-side.
*/
/*
* Write something to the parser pipe OUT.
*
* Returns 0 on success or a positive errno value on error.
*/
int usdt_parser_write_one(int out, const void *buf, size_t size);
#endif /* _USDT_PARSER_H */
|