/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ #ifndef __USDT_BPF_H__ #define __USDT_BPF_H__
/* Return number of USDT arguments defined for currently traced USDT. */
__weak __hidden int bpf_usdt_arg_cnt(struct pt_regs *ctx)
{ struct __bpf_usdt_spec *spec; int spec_id;
spec_id = __bpf_usdt_spec_id(ctx); if (spec_id < 0) return -ESRCH;
spec = bpf_map_lookup_elem(&__bpf_usdt_specs, &spec_id); if (!spec) return -ESRCH;
return spec->arg_cnt;
}
/* Returns the size in bytes of the #*arg_num* (zero-indexed) USDT argument. *Returnsnegativeerrorifargumentisnotfoundorarg_numisinvalid.
*/ static __always_inline int bpf_usdt_arg_size(struct pt_regs *ctx, __u64 arg_num)
{ struct __bpf_usdt_arg_spec *arg_spec; struct __bpf_usdt_spec *spec; int spec_id;
spec_id = __bpf_usdt_spec_id(ctx); if (spec_id < 0) return -ESRCH;
spec = bpf_map_lookup_elem(&__bpf_usdt_specs, &spec_id); if (!spec) return -ESRCH;
if (arg_num >= BPF_USDT_MAX_ARG_CNT) return -ENOENT;
barrier_var(arg_num); if (arg_num >= spec->arg_cnt) return -ENOENT;
/* Fetch USDT argument #*arg_num* (zero-indexed) and put its value into *res. *Returns0onsuccess;negativeerror,otherwise. *Onerror*resisguaranteedtobesettozero.
*/
__weak __hidden int bpf_usdt_arg(struct pt_regs *ctx, __u64 arg_num, long *res)
{ struct __bpf_usdt_spec *spec; struct __bpf_usdt_arg_spec *arg_spec; unsignedlong val, idx; int err, spec_id;
*res = 0;
spec_id = __bpf_usdt_spec_id(ctx); if (spec_id < 0) return -ESRCH;
spec = bpf_map_lookup_elem(&__bpf_usdt_specs, &spec_id); if (!spec) return -ESRCH;
if (arg_num >= BPF_USDT_MAX_ARG_CNT) return -ENOENT;
barrier_var(arg_num); if (arg_num >= spec->arg_cnt) return -ENOENT;
arg_spec = &spec->args[arg_num]; switch (arg_spec->arg_type) { case BPF_USDT_ARG_CONST: /* Arg is just a constant ("-4@$-9" in USDT arg spec). *valueisrecordedinarg_spec->val_offdirectly.
*/
val = arg_spec->val_off; break; case BPF_USDT_ARG_REG: /* Arg is in a register (e.g, "8@%rax" in USDT arg spec), *sowereadthecontentsofthatregisterdirectlyfrom *structpt_regs.Tokeepthingssimpleuser-spaceparts *recordoffsetof(structpt_regs,<regname>)inarg_spec->reg_off.
*/
err = bpf_probe_read_kernel(&val, sizeof(val), (void *)ctx + arg_spec->reg_off); if (err) return err; break; case BPF_USDT_ARG_REG_DEREF: /* Arg is in memory addressed by register, plus some offset *(e.g.,"-4@-1204(%rbp)"inUSDTargspec).Registeris *identifiedlikewithBPF_USDT_ARG_REGcase,andtheoffset *isinarg_spec->val_off.Wefirstfetchregistercontents *frompt_regs,thendoanotheruser-spaceprobereadto *fetchargumentvalueitself.
*/
err = bpf_probe_read_kernel(&val, sizeof(val), (void *)ctx + arg_spec->reg_off); if (err) return err;
err = bpf_probe_read_user(&val, sizeof(val), (void *)val + arg_spec->val_off); if (err) return err; #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
val >>= arg_spec->arg_bitshift; #endif break; case BPF_USDT_ARG_SIB: /* Arg is in memory addressed by SIB (Scale-Index-Base) mode *(e.g.,"-1@-96(%rbp,%rax,8)"inUSDTargspec).Wefirst *fetchthebaseregistercontentsandtheindexregister *contentsfrompt_regs.Thenwecalculatethefinaladdress *asbase+(index*scale)+offset,anddoauser-space *probereadtofetchtheargumentvalue.
*/
err = bpf_probe_read_kernel(&val, sizeof(val), (void *)ctx + arg_spec->reg_off); if (err) return err;
err = bpf_probe_read_kernel(&idx, sizeof(idx), (void *)ctx + arg_spec->idx_reg_off); if (err) return err;
err = bpf_probe_read_user(&val, sizeof(val), (void *)(val + (idx << arg_spec->scale_bitshift) + arg_spec->val_off)); if (err) return err; #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
val >>= arg_spec->arg_bitshift; #endif break; default: return -EINVAL;
}
/* cast arg from 1, 2, or 4 bytes to final 8 byte size clearing *necessaryupperarg_bitshiftbits,withsignextensionifargument *issigned
*/
val <<= arg_spec->arg_bitshift; if (arg_spec->arg_signed)
val = ((long)val) >> arg_spec->arg_bitshift; else
val = val >> arg_spec->arg_bitshift;
*res = val; return0;
}
/* Retrieve user-specified cookie value provided during attach as *bpf_usdt_opts.usdt_cookie.ThisservesthesamepurposeasBPFcookie *returnedbybpf_get_attach_cookie().Libbpf'ssupportforUSDTisitself *utilizingBPFcookiesinternally,sousercan'tuseBPFcookiedirectly *forUSDTprogramsandhastousebpf_usdt_cookie()APIinstead.
*/
__weak __hidden long bpf_usdt_cookie(struct pt_regs *ctx)
{ struct __bpf_usdt_spec *spec; int spec_id;
spec_id = __bpf_usdt_spec_id(ctx); if (spec_id < 0) return0;
spec = bpf_map_lookup_elem(&__bpf_usdt_specs, &spec_id); if (!spec) return0;
return spec->usdt_cookie;
}
/* we rely on ___bpf_apply() and ___bpf_narg() macros already defined in bpf_tracing.h */ #define ___bpf_usdt_args0() ctx #define ___bpf_usdt_args1(x) ___bpf_usdt_args0(), ({ long _x; bpf_usdt_arg(ctx, 0, &_x); _x; }) #define ___bpf_usdt_args2(x, args...) ___bpf_usdt_args1(args), ({ long _x; bpf_usdt_arg(ctx, 1, &_x); _x; }) #define ___bpf_usdt_args3(x, args...) ___bpf_usdt_args2(args), ({ long _x; bpf_usdt_arg(ctx, 2, &_x); _x; }) #define ___bpf_usdt_args4(x, args...) ___bpf_usdt_args3(args), ({ long _x; bpf_usdt_arg(ctx, 3, &_x); _x; }) #define ___bpf_usdt_args5(x, args...) ___bpf_usdt_args4(args), ({ long _x; bpf_usdt_arg(ctx, 4, &_x); _x; }) #define ___bpf_usdt_args6(x, args...) ___bpf_usdt_args5(args), ({ long _x; bpf_usdt_arg(ctx, 5, &_x); _x; }) #define ___bpf_usdt_args7(x, args...) ___bpf_usdt_args6(args), ({ long _x; bpf_usdt_arg(ctx, 6, &_x); _x; }) #define ___bpf_usdt_args8(x, args...) ___bpf_usdt_args7(args), ({ long _x; bpf_usdt_arg(ctx, 7, &_x); _x; }) #define ___bpf_usdt_args9(x, args...) ___bpf_usdt_args8(args), ({ long _x; bpf_usdt_arg(ctx, 8, &_x); _x; }) #define ___bpf_usdt_args10(x, args...) ___bpf_usdt_args9(args), ({ long _x; bpf_usdt_arg(ctx, 9, &_x); _x; }) #define ___bpf_usdt_args11(x, args...) ___bpf_usdt_args10(args), ({ long _x; bpf_usdt_arg(ctx, 10, &_x); _x; }) #define ___bpf_usdt_args12(x, args...) ___bpf_usdt_args11(args), ({ long _x; bpf_usdt_arg(ctx, 11, &_x); _x; }) #define ___bpf_usdt_args(args...) ___bpf_apply(___bpf_usdt_args, ___bpf_narg(args))(args)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.