Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions include/ply/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define _PLY_BUFFER_H

#include <stdint.h>
#include <poll.h>

#include <linux/perf_event.h>

Expand All @@ -34,8 +35,10 @@ void buffer_evh_register(struct buffer_evh *evh);

struct buffer;

struct buffer *buffer_new(int mapfd);
struct ply_return buffer_service(struct buffer *buf, int ready, struct pollfd *fds);
void buffer_fill_pollset(struct buffer *buf, struct pollfd *fds);
nfds_t buffer_get_nfds(struct buffer *buf);

struct ply_return buffer_loop(struct buffer *buf, int timeout);
struct buffer *buffer_new(int mapfd);

#endif /* _PLY_BUFFER_H */
3 changes: 2 additions & 1 deletion include/ply/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ struct irstate {
int dot:1;
int lval:1;
int stack:1;
int user:1;
} hint;
};

Expand Down Expand Up @@ -177,7 +178,7 @@ void ir_emit_sym_to_reg (struct ir *ir, uint16_t dst, struct sym *src);
void ir_emit_reg_to_sym (struct ir *ir, struct sym *dst, uint16_t src);
void ir_emit_sym_to_stack(struct ir *ir, ssize_t offset, struct sym *src);
void ir_emit_sym_to_sym (struct ir *ir, struct sym *dst, struct sym *src);
void ir_emit_read_to_sym (struct ir *ir, struct sym *dst, uint16_t src);
void ir_emit_read_to_sym (struct ir *ir, struct sym *dst, uint16_t src, int user);

void ir_emit_data (struct ir *ir, ssize_t dst, const char *src, size_t size);
void ir_emit_memcpy(struct ir *ir, ssize_t dst, ssize_t src, size_t size);
Expand Down
21 changes: 20 additions & 1 deletion include/ply/ply.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define _PLY_H

#include <stdio.h>
#include <poll.h>

#include "sym.h"
#include "utils.h"
Expand All @@ -23,6 +24,22 @@ struct ply_return {
unsigned exit:1;
};

static inline void ply_return_fold(struct ply_return *ret, struct ply_return new)
{
if (ret->err)
return;

if (new.err) {
*ret = new;
return;
}

if (ret->exit)
return;

*ret = new;
}

/* api */
struct ply_probe {
struct ply_probe *next, *prev;
Expand Down Expand Up @@ -83,7 +100,9 @@ void ply_maps_print(struct ply *ply);
void ply_map_print(struct ply *ply, struct sym *sym, FILE *fp);
void ply_map_clear(struct ply *ply, struct sym *sym);

struct ply_return ply_loop(struct ply *ply);
struct ply_return ply_service(struct ply *ply, int ready, struct pollfd *fds);
nfds_t ply_get_nfds(struct ply *ply);
void ply_fill_pollset(struct ply *ply, struct pollfd *fds);

int ply_start(struct ply *ply);
int ply_stop(struct ply *ply);
Expand Down
2 changes: 2 additions & 0 deletions include/ply/provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ struct provider {
int (*ir_pre) (struct ply_probe *);
int (*ir_post) (struct ply_probe *);
int (*attach) (struct ply_probe *);
int (*start) (struct ply_probe *);
int (*stop) (struct ply_probe *);
int (*detach) (struct ply_probe *);
};

Expand Down
66 changes: 29 additions & 37 deletions src/libply/built-in/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,43 +153,7 @@ struct ply_return buffer_q_drain(struct buffer_q *q)
return ret;
}

struct ply_return buffer_loop(struct buffer *buf, int timeout)
{
struct ply_return ret;
uint32_t cpu;
int ready;

for (;;) {
ready = poll(buf->poll, buf->ncpus, timeout);
if (ready < 0) {
ret.err = 1;
ret.val = errno;
return ret;
}

if (timeout == -1) {
assert(ready);
} else if (ready == 0) {
ret.err = 0;
return ret;
}

for (cpu = 0; ready && (cpu < buf->ncpus); cpu++) {
if (!(buf->poll[cpu].revents & POLLIN))
continue;

ret = buffer_q_drain(&buf->q[cpu]);
if (ret.err | ret.exit)
return ret;

ready--;
}
}

return ret;
}

int buffer_q_init(struct buffer *buf, uint32_t cpu)
static int buffer_q_init(struct buffer *buf, uint32_t cpu)
{
struct perf_event_attr attr = { 0 };
struct buffer_q *q = &buf->q[cpu];
Expand Down Expand Up @@ -225,6 +189,34 @@ int buffer_q_init(struct buffer *buf, uint32_t cpu)
return 0;
}

struct ply_return buffer_service(struct buffer *buf, int ready, struct pollfd *fds)
{
struct ply_return ret = {};
uint32_t cpu;

for (cpu = 0; ready && (cpu < buf->ncpus); cpu++) {
if (!(fds[cpu].revents & POLLIN))
continue;

ret = buffer_q_drain(&buf->q[cpu]);
ready--;
if (ret.err || ret.exit)
break;
}

return ret;
}

void buffer_fill_pollset(struct buffer *buf, struct pollfd *fds)
{
memcpy(fds, buf->poll, buf->ncpus * sizeof(*fds));
}

nfds_t buffer_get_nfds(struct buffer *buf)
{
return buf->ncpus;
}

struct buffer *buffer_new(int mapfd)
{
struct buffer *buf;
Expand Down
42 changes: 38 additions & 4 deletions src/libply/built-in/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ static int str_ir_post(const struct func *func, struct node *n,
ir_emit_ldbp(pb->ir, BPF_REG_1, n->sym->irs.stack);
ir_emit_insn(ir, MOV_IMM((int32_t)type_sizeof(n->sym->type)), BPF_REG_2, 0);
ir_emit_sym_to_reg(ir, BPF_REG_3, ptr->sym);
ir_emit_insn(ir, CALL(BPF_FUNC_probe_read_kernel_str), 0, 0);
if (ptr->sym->irs.hint.user)
ir_emit_insn(ir, CALL(BPF_FUNC_probe_read_user_str), 0, 0);
else
ir_emit_insn(ir, CALL(BPF_FUNC_probe_read_kernel_str), 0, 0);
return 0;
}

Expand All @@ -153,7 +156,7 @@ static int mem_ir_post(const struct func *func, struct node *n,
ir_init_sym(pb->ir, n->sym);

ir_emit_sym_to_reg(pb->ir, BPF_REG_3, ptr->sym);
ir_emit_read_to_sym(pb->ir, n->sym, BPF_REG_3);
ir_emit_read_to_sym(pb->ir, n->sym, BPF_REG_3, ptr->sym->irs.hint.user);
return 0;
}

Expand Down Expand Up @@ -222,6 +225,36 @@ static struct func str_func = {
.ir_post = str_ir_post,
};

struct type t_uptr_func = {
.ttype = T_FUNC,
.func = { .type = &t_void, .args = f_1arg },
};

static int uptr_ir_post(const struct func *func, struct node *n,
struct ply_probe *pb)
{
struct node *child = n->expr.args;

ir_init_sym(pb->ir, n->sym);
ir_emit_sym_to_sym(pb->ir, n->sym, child->sym);
n->sym->irs.hint.user = 1;
return 0;
}

static int uptr_type_infer(const struct func *func, struct node *n)
{
struct node *arg = n->expr.args;

n->sym->type = arg->sym->type;
return 0;
}

static struct func uptr_func = {
.name = "uptr",
.type = &t_uptr_func,
.type_infer = uptr_type_infer,
.ir_post = uptr_ir_post,
};

static int struct_deref_rewrite(const struct func *func, struct node *n,
struct ply_probe *pb)
Expand Down Expand Up @@ -424,7 +457,7 @@ static int deref_ir_post(const struct func *func, struct node *n,
return 0;

ir_emit_sym_to_reg(pb->ir, BPF_REG_0, ptr->sym);
ir_emit_read_to_sym(pb->ir, n->sym, BPF_REG_0);
ir_emit_read_to_sym(pb->ir, n->sym, BPF_REG_0, ptr->sym->irs.hint.user);
return 0;
}

Expand Down Expand Up @@ -603,7 +636,7 @@ static int map_ir_post(const struct func *func, struct node *n,
lhit = ir_alloc_label(pb->ir);

ir_emit_insn(pb->ir, JMP_IMM(BPF_JEQ, 0, lmiss), BPF_REG_0, 0);
ir_emit_read_to_sym(pb->ir, n->sym, BPF_REG_0);
ir_emit_read_to_sym(pb->ir, n->sym, BPF_REG_0, 0);
ir_emit_insn(pb->ir, JMP_IMM(BPF_JA, 0, lhit), 0, 0);

ir_emit_label(pb->ir, lmiss);
Expand Down Expand Up @@ -948,6 +981,7 @@ void memory_init(void)
built_in_register(&strcmp_func);
built_in_register(&str_func);
built_in_register(&mem_func);
built_in_register(&uptr_func);
built_in_register(&struct_deref_func);
built_in_register(&struct_dot_func);
built_in_register(&deref_func);
Expand Down
4 changes: 2 additions & 2 deletions src/libply/grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ probes
;

probe
: PSPEC stmt { __ply_probe_alloc(ply, $1, $2); }
| PSPEC predicate { __ply_probe_alloc(ply, $1, $2); }
: PSPEC stmt { if (__ply_probe_alloc(ply, $1, $2)) YYABORT; }
| PSPEC predicate { if (__ply_probe_alloc(ply, $1, $2)) YYABORT; }
;

/* Support dtrace-style predicates as well as normal if guards. I.e.
Expand Down
11 changes: 9 additions & 2 deletions src/libply/ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ static const char *bpf_func_name(enum bpf_func_id id)
return "probe_read_kernel";
case BPF_FUNC_probe_read_kernel_str:
return "probe_read_kernel_str";
case BPF_FUNC_probe_read_user:
return "probe_read_user";
case BPF_FUNC_probe_read_user_str:
return "probe_read_user_str";
case BPF_FUNC_trace_printk:
return "trace_printk";
default:
Expand Down Expand Up @@ -405,7 +409,7 @@ void ir_emit_sym_to_sym(struct ir *ir, struct sym *dst, struct sym *src)
}
}

void ir_emit_read_to_sym(struct ir *ir, struct sym *dst, uint16_t src)
void ir_emit_read_to_sym(struct ir *ir, struct sym *dst, uint16_t src, int user)
{
struct irstate *irs = &dst->irs;

Expand All @@ -416,7 +420,10 @@ void ir_emit_read_to_sym(struct ir *ir, struct sym *dst, uint16_t src)
if (src != BPF_REG_3)
ir_emit_insn(ir, MOV, BPF_REG_3, src);

ir_emit_insn(ir, CALL(BPF_FUNC_probe_read_kernel), 0, 0);
if (user)
ir_emit_insn(ir, CALL(BPF_FUNC_probe_read_user), 0, 0);
else
ir_emit_insn(ir, CALL(BPF_FUNC_probe_read_kernel), 0, 0);
/* TODO if (r0) exit(r0); */
}

Expand Down
Loading