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
|
/*
* Oracle Linux DTrace.
* Copyright (c) 2020, 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 _DT_DCTX_H
#define _DT_DCTX_H
#include <stdint.h>
#include <linux/bpf.h>
#include <bpf_asm.h>
#include <dt_pt_regs.h>
#include <dt_state.h>
/*
* Static probe IDs for the dtrace provider.
*/
#define DTRACE_BEGIN_ID 1
#define DTRACE_END_ID 2
#define DTRACE_ERROR_ID 3
/*
* The DTrace machine state.
*/
typedef struct dt_mstate {
uint32_t prid; /* Probe ID */
uint32_t stid; /* Statement ID */
uint32_t tag; /* Tag (for future use) */
uint32_t scratch_top; /* Current top of scratch space */
int32_t syscall_errno; /* syscall errno */
uint64_t specsize; /* speculation size */
uint64_t scalarizer; /* used to scalarize pointers */
uint64_t fault; /* DTrace fault flags */
uint64_t tstamp; /* cached timestamp value */
dt_pt_regs regs; /* CPU registers */
uint64_t argv[10]; /* Probe arguments */
uint64_t orig_argv[10]; /* Original (underlying) probe args */
uint64_t saved_argv[6]; /* Saved arguments */
} dt_mstate_t;
#define DMST_PRID offsetof(dt_mstate_t, prid)
#define DMST_STID offsetof(dt_mstate_t, stid)
#define DMST_TAG offsetof(dt_mstate_t, tag)
#define DMST_SCRATCH_TOP offsetof(dt_mstate_t, scratch_top)
#define DMST_ERRNO offsetof(dt_mstate_t, syscall_errno)
#define DMST_SPECSIZE offsetof(dt_mstate_t, specsize)
#define DMST_SCALARIZER offsetof(dt_mstate_t, scalarizer)
#define DMST_FAULT offsetof(dt_mstate_t, fault)
#define DMST_TSTAMP offsetof(dt_mstate_t, tstamp)
#define DMST_REGS offsetof(dt_mstate_t, regs)
#define DMST_ARG(n) offsetof(dt_mstate_t, argv[n])
#define DMST_ORIG_ARG(n) offsetof(dt_mstate_t, orig_argv[n])
/*
* The DTrace context.
*/
typedef struct dt_dctx {
void *ctx; /* BPF context */
dt_activity_t *act; /* pointer to activity state */
dt_mstate_t *mst; /* DTrace machine state */
char *buf; /* Output buffer scratch memory */
char *mem; /* General scratch memory */
char *scratchmem; /* Scratch space for alloca, etc */
char *strtab; /* String constant table */
char *rodata; /* Read-only data */
char *agg; /* Aggregation data */
char *gvars; /* Global variables */
char *lvars; /* Local variables */
} dt_dctx_t;
#define DCTX_CTX offsetof(dt_dctx_t, ctx)
#define DCTX_ACT offsetof(dt_dctx_t, act)
#define DCTX_MST offsetof(dt_dctx_t, mst)
#define DCTX_BUF offsetof(dt_dctx_t, buf)
#define DCTX_MEM offsetof(dt_dctx_t, mem)
#define DCTX_SCRATCHMEM offsetof(dt_dctx_t, scratchmem)
#define DCTX_STRTAB offsetof(dt_dctx_t, strtab)
#define DCTX_RODATA offsetof(dt_dctx_t, rodata)
#define DCTX_AGG offsetof(dt_dctx_t, agg)
#define DCTX_GVARS offsetof(dt_dctx_t, gvars)
#define DCTX_LVARS offsetof(dt_dctx_t, lvars)
#define DCTX_SIZE ((int16_t)sizeof(dt_dctx_t))
/*
* The dctx->buf pointer references a block of memory that contains:
*
* +----------------+
* 0 -> | size |
* +----------------+
* 4 -> | Speculation ID |
* +----------------+
* 8 -> | PRID |
* +----------------+
* 12 -> | STID |
* +----------------+
* 16 -> | Trace Data |
* | ... |
* +----------------+
*/
#define DBUF_SIZE 0
#define DBUF_SPECID 4
#define DBUF_PRID 8
#define DBUF_STID 12
#define DBUF_DATA 16
/*
* The dctx->mem pointer references a block of memory that contains:
*
* +----------------+----------------+
* 0 -> | tstring storage | \
* +----------------+----------------+ |
* DMEM_STRTOK -> | strtok() internal state | |
* +---------------------------------+ > DMEM_SIZE
* DMEM_STACK -> | stack storage | |
* +---------------------------------+ |
* DMEM_TUPLE -> | tuple assembly area | /
* +---------------------------------+
*/
/*
* Macros for the sizes of the components of dctx->mem.
*
* CAUTION: DMEM_TUPLE_SZ(dtp) depends on data collected during code generation
* and therefore cannot be used until all code generation has
* completed.
*/
#define DMEM_STACK_SZ(dtp) \
(4 * sizeof(uint32_t) + \
(dtp)->dt_options[DTRACEOPT_MAXFRAMES] * sizeof(uint64_t))
#define DMEM_TSTR_SZ(dtp) \
(DT_TSTRING_SLOTS * DT_TSTRING_SIZE(dtp))
#define DMEM_STRTOK_SZ(dtp) \
(sizeof(uint64_t) + (dtp)->dt_options[DTRACEOPT_STRSIZE] + 1)
#define DMEM_TUPLE_SZ(dtp) \
((dtp)->dt_maxtuplesize)
/*
* Macros to determine the offset of the components of dctx->mem.
*/
#define DMEM_STRTOK(dtp) \
DMEM_TSTR_SZ(dtp)
#define DMEM_STACK(dtp) \
(DMEM_STRTOK(dtp) + DMEM_STRTOK_SZ(dtp))
#define DMEM_TUPLE(dtp) \
(DMEM_STACK(dtp) + DMEM_STACK_SZ(dtp))
/*
* Macro to determine the total size of the mem area.
*
* CAUTION: DMEM_SIZE(dtp) depends on data collected during code generation
* and therefore cannot be used until all code generation has
* completed.
*/
#define DMEM_SIZE(dtp) (DMEM_TUPLE(dtp) + DMEM_TUPLE_SZ(dtp))
/*
* The stack layout for BPF programs that are generated as trampolines for
* D clauses.
*
* Note: The BPF frame pointer points to the address of the first byte past the
* end of the stack. 8-byte values are properly aligned at offsets -8,
* -16, -24, -32, etc. -- that is, negative multiples of sizeof(uint64_t).
*
* +----------------+
* SP_SLOT(n) | |
* +----------------+
* | ... |
* +----------------+
* SP_SLOT(1) | |
* +----------------+
* SP_BASE = SP_SLOT(0) | |
* +----------------+
* DCTX | DTrace Context |
* +----------------+
*/
#define DT_STK_BASE ((int16_t)0)
#define DT_STK_SLOT_SZ ((int16_t)sizeof(uint64_t))
#define DT_TRAMP_SP_BASE (DT_STK_BASE - DCTX_SIZE - DT_STK_SLOT_SZ)
#define DT_TRAMP_SP_SLOT(n) (DT_TRAMP_SP_BASE - (n) * DT_STK_SLOT_SZ)
/*
* DTrace clause functions can use all BPF registers except for the %fp (frame
* pointer) register and the highest numbered register (currently %r9) that is
* used to store the base pointer for the trace output record.
*/
#define DT_STK_NREGS (MAX_BPF_REG - 2)
/*
* The stack layout for functions that implement a D clause is encoded with the
* following constants.
*
* Note: The BPF frame pointer points to the address of the first byte past the
* end of the stack. 8-byte values are properly aligned at offsets -8,
* -16, -24, -32, etc. -- that is, negative multiples of sizeof(uint64_t).
*
* +----------------+
* | ... |
* +----------------+
* SP_BASE = SP_SLOT(0) | |<--+
* +----------------+ |
* SPILL(n) | %r8 | (n = DT_STK_NREGS - 1 = 8)
* +----------------+ |
* | ... | |
* +----------------+ |
* SPILL(1) | %r1 | |
* +----------------+ |
* SPILL_BASE = SPILL(0) | %r0 | |
* +----------------+ |
* SP | o------------+ (initial value)
* +----------------+
* DCTX | Ptr to dctx |
* +----------------+
*/
#define DT_STK_DCTX (DT_STK_BASE - DT_STK_SLOT_SZ)
#define DT_STK_SP (DT_STK_DCTX - DT_STK_SLOT_SZ)
#define DT_STK_SPILL_BASE (DT_STK_SP - DT_STK_SLOT_SZ)
#define DT_STK_SPILL(n) (DT_STK_SPILL_BASE - (n) * DT_STK_SLOT_SZ)
#define DT_STK_SP_BASE DT_STK_SPILL(DT_STK_NREGS)
#define DT_STK_SP_SLOT(n) (DT_STK_SP_BASE - (n) * DT_STK_SLOT_SZ)
#endif /* _DT_DCTX_H */
|