]> granicus.if.org Git - strace/blobdiff - bpf.c
travis: add build environment information to the travis log
[strace] / bpf.c
diff --git a/bpf.c b/bpf.c
index df076e5784dac5d7e1866a5b09aba846971b129e..de909d300c1ac27619a4f830ce0a92a3970962b9 100644 (file)
--- a/bpf.c
+++ b/bpf.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
+ * Copyright (c) 2017 Quentin Monnet <quentin.monnet@6wind.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include "xlat/bpf_map_types.h"
 #include "xlat/bpf_prog_types.h"
 #include "xlat/bpf_map_update_elem_flags.h"
+#include "xlat/bpf_attach_type.h"
+#include "xlat/bpf_attach_flags.h"
 
 static int
-bpf_map_create(struct tcb *const tcp, const kernel_ureg_t addr,
+bpf_map_create(struct tcb *const tcp, const kernel_ulong_t addr,
               unsigned int size)
 {
        struct {
@@ -62,7 +65,7 @@ bpf_map_create(struct tcb *const tcp, const kernel_ureg_t addr,
 }
 
 static void
-bpf_map_update_elem(struct tcb *const tcp, const kernel_ureg_t addr,
+bpf_map_update_elem(struct tcb *const tcp, const kernel_ulong_t addr,
                    unsigned int size)
 {
        struct {
@@ -90,7 +93,7 @@ bpf_map_update_elem(struct tcb *const tcp, const kernel_ureg_t addr,
 }
 
 static void
-bpf_map_delete_elem(struct tcb *const tcp, const kernel_ureg_t addr,
+bpf_map_delete_elem(struct tcb *const tcp, const kernel_ulong_t addr,
                    unsigned int size)
 {
        struct {
@@ -113,7 +116,7 @@ bpf_map_delete_elem(struct tcb *const tcp, const kernel_ureg_t addr,
 }
 
 static int
-bpf_map_io(struct tcb *const tcp, const kernel_ureg_t addr, unsigned int size,
+bpf_map_io(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int size,
           const char *const text)
 {
        struct bpf_io_elem_struct {
@@ -146,7 +149,7 @@ bpf_map_io(struct tcb *const tcp, const kernel_ureg_t addr, unsigned int size,
 }
 
 static int
-bpf_prog_load(struct tcb *const tcp, const kernel_ureg_t addr,
+bpf_prog_load(struct tcb *const tcp, const kernel_ulong_t addr,
              unsigned int size)
 {
        struct {
@@ -177,10 +180,85 @@ bpf_prog_load(struct tcb *const tcp, const kernel_ureg_t addr,
        return RVAL_DECODED | RVAL_FD;
 }
 
+static int
+bpf_obj_manage(struct tcb *const tcp, const kernel_ulong_t addr,
+              unsigned int size)
+{
+       struct {
+               uint64_t ATTRIBUTE_ALIGNED(8) pathname;
+               uint32_t bpf_fd;
+       } attr = {};
+
+       if (!size) {
+               printaddr(addr);
+               return RVAL_DECODED | RVAL_FD;
+       }
+       if (size > sizeof(attr))
+               size = sizeof(attr);
+       if (umoven_or_printaddr(tcp, addr, size, &attr))
+               return RVAL_DECODED | RVAL_FD;
+
+       tprints("{pathname=");
+       printpath(tcp, attr.pathname);
+       tprints(", bpf_fd=");
+       printfd(tcp, attr.bpf_fd);
+       tprints("}");
+
+       return RVAL_DECODED | RVAL_FD;
+}
+
+static int
+bpf_prog_attach_detach(struct tcb *const tcp, const kernel_ulong_t addr,
+                      unsigned int size, bool print_attach)
+{
+       struct {
+               uint32_t target_fd, attach_bpf_fd, attach_type, attach_flags;
+       } attr = {};
+
+       if (!size) {
+               printaddr(addr);
+               return RVAL_DECODED;
+       }
+       if (size > sizeof(attr))
+               size = sizeof(attr);
+       if (umoven_or_printaddr(tcp, addr, size, &attr))
+               return RVAL_DECODED;
+
+       tprints("{target_fd=");
+       printfd(tcp, attr.target_fd);
+       if (print_attach) {
+               tprints(", attach_bpf_fd=");
+               printfd(tcp, attr.attach_bpf_fd);
+       }
+       tprints(", attach_type=");
+       printxval(bpf_attach_type, attr.attach_type, "BPF_???");
+       if (print_attach) {
+               tprints(", attach_flags=");
+               printflags(bpf_attach_flags, attr.attach_flags, "BPF_F_???");
+       }
+       tprints("}");
+
+       return RVAL_DECODED;
+}
+
+static int
+bpf_prog_attach(struct tcb *const tcp, const kernel_ulong_t addr,
+               unsigned int size)
+{
+       return bpf_prog_attach_detach(tcp, addr, size, true);
+}
+
+static int
+bpf_prog_detach(struct tcb *const tcp, const kernel_ulong_t addr,
+               unsigned int size)
+{
+       return bpf_prog_attach_detach(tcp, addr, size, false);
+}
+
 SYS_FUNC(bpf)
 {
        const unsigned int cmd = tcp->u_arg[0];
-       const kernel_ureg_t addr = tcp->u_arg[1];
+       const kernel_ulong_t addr = tcp->u_arg[1];
        const unsigned int size = tcp->u_arg[2];
        int rc = RVAL_DECODED;
 
@@ -208,6 +286,18 @@ SYS_FUNC(bpf)
        case BPF_PROG_LOAD:
                rc = bpf_prog_load(tcp, addr, size);
                break;
+       case BPF_OBJ_PIN:
+               rc = bpf_obj_manage(tcp, addr, size);
+               break;
+       case BPF_OBJ_GET:
+               rc = bpf_obj_manage(tcp, addr, size);
+               break;
+       case BPF_PROG_ATTACH:
+               rc = bpf_prog_attach(tcp, addr, size);
+               break;
+       case BPF_PROG_DETACH:
+               rc = bpf_prog_detach(tcp, addr, size);
+               break;
        default:
                printaddr(addr);
                break;