| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- #include <assert.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <string.h>
- #include <linux/ptrace.h>
- #include "func.h"
- #include "node.h"
- #include "ply.h"
- #include "sym.h"
- #include "type.h"
- struct kprobe {
- };
- /* static int kprobe_ir_prologue(prog_t *prog) */
- /* { */
- /* sym_t *ctx = sym_get(prog->locals, "ctx"); */
- /* if (!ctx) */
- /* return 0; */
- /* irs_alloc_reg(&ctx->irs, prog->ir); */
- /* /\* kernel sets r1 to the address of the context *\/ */
- /* ir_emit_insn(prog->ir, MOV(0, 0), ctx->irs.reg, BPF_REG_1); */
- /* return 0; */
- /* } */
- static inline int is_arg(const char *name)
- {
- return (strstr(name, "arg") == name)
- && (strlen(name) == 4)
- && (name[3] >= '0' && name[3] <= '9');
- }
- /* static int kprobe_rewrite_arg(prog_t *prog, node_t *n) */
- /* { */
- /* const char *reg; */
- /* int arg = n->ident[3] - '0'; */
- /* node_t *new, *ctx; */
- /* reg = arch_register_argument(arg); */
- /* if (!reg) { */
- /* node_print(n, stderr); */
- /* fputs(": the location of this argument is unknown\n", stderr); */
- /* /\* TODO: add ABI mappings for specifying arguments */
- /* * passed on the stack. *\/ */
- /* return -EINVAL; */
- /* } */
- /* ctx = node_ident("ctx"); */
- /* /\* argN => (*ctx).REG *\/ */
- /* new = node_vlist(node_keyword('.', 0), */
- /* node_vlist(node_keyword('*', 0), */
- /* ctx, */
- /* NULL), */
- /* node_string(reg), */
- /* NULL); */
- /* ctx->type = type_ptr_of(&t_pt_regs); */
- /* new->type = n->type; */
- /* new->list->type = &t_void; */
- /* new->list->next->type = &t_pt_regs; */
- /* new->list->next->list->type = &t_void; */
- /* node_replace(n, new); */
- /* return sym_add(prog->locals, ctx->ident, ctx->type, &ctx->sym); */
- /* } */
- /* static int kprobe_rewrite_node(prog_t *prog, node_t *n) */
- /* { */
- /* if ((n->ntype == N_IDENT) && is_arg(n->ident)) */
- /* return kprobe_rewrite_arg(prog, n); */
- /* return 0; */
- /* } */
- /* static int kprobe_resolve(prog_t *prog, node_t *n) */
- /* { */
- /* type_t *t; */
- /* if (is_arg(n->ident)) */
- /* t = &t_ulong; */
- /* else if (!strcmp(n->ident, "ctx")) */
- /* t = type_ptr_of(&t_pt_regs); */
- /* else */
- /* return -ENOENT; */
- /* n->type = t; */
- /* return sym_add(prog->locals, n->ident, t, &n->sym); */
- /* } */
- static const struct func kprobe_arg_func = {
- .name = "argN",
- /* for now, in the future we could read dwarf symbols to
- * figure out the real type. */
- .type = &t_ulong,
- .static_ret = 1,
- };
- static int kprobe_sym_alloc(struct prog *prog, struct node *n)
- {
- const struct func *func = NULL;
- int err;
- switch (n->ntype) {
- case N_EXPR:
- break;
- case N_IDENT:
- if (is_arg(n->ident.name))
- func = &kprobe_arg_func;
- break;
- default:
- break;
- }
- if (!func)
- return -ENOENT;
- err = func_static_validate(func, n);
- if (err)
- return err;
- n->sym = sym_alloc(prog->locals, n, func);
- if (func->static_ret)
- n->sym->type = func_return_type(func);
- return 0;
- }
- static int kprobe_probe(struct prog *prog)
- {
- struct kprobe *kp;
- kp = calloc(1, sizeof(*kp));
- assert(kp);
- prog->provider_data = kp;
- return 0;
- }
- struct provider kprobe = {
- .name = "kprobe",
- /* .ir_prologue = kprobe_ir_prologue, */
- /* .rewrite_node = kprobe_rewrite_node, */
- /* .resolve = kprobe_resolve, */
- .sym_alloc = kprobe_sym_alloc,
- .probe = kprobe_probe,
- };
- __attribute__((constructor))
- static void kprobe_init(void)
- {
- provider_register(&kprobe);
- }
|