]> 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 20070b371bf33c1d1cc91481e6bf01c86c98356f..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 *tcp, const long addr, unsigned int size)
+bpf_map_create(struct tcb *const tcp, const kernel_ulong_t addr,
+              unsigned int size)
 {
        struct {
                uint32_t map_type, key_size, value_size, max_entries;
@@ -61,7 +65,8 @@ bpf_map_create(struct tcb *tcp, const long addr, unsigned int size)
 }
 
 static void
-bpf_map_update_elem(struct tcb *tcp, const long addr, unsigned int size)
+bpf_map_update_elem(struct tcb *const tcp, const kernel_ulong_t addr,
+                   unsigned int size)
 {
        struct {
                uint32_t map_fd;
@@ -88,7 +93,8 @@ bpf_map_update_elem(struct tcb *tcp, const long addr, unsigned int size)
 }
 
 static void
-bpf_map_delete_elem(struct tcb *tcp, const long addr, unsigned int size)
+bpf_map_delete_elem(struct tcb *const tcp, const kernel_ulong_t addr,
+                   unsigned int size)
 {
        struct {
                uint32_t map_fd;
@@ -110,7 +116,8 @@ bpf_map_delete_elem(struct tcb *tcp, const long addr, unsigned int size)
 }
 
 static int
-bpf_map_io(struct tcb *tcp, const long addr, unsigned int size, const char *text)
+bpf_map_io(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int size,
+          const char *const text)
 {
        struct bpf_io_elem_struct {
                uint32_t map_fd;
@@ -142,7 +149,8 @@ bpf_map_io(struct tcb *tcp, const long addr, unsigned int size, const char *text
 }
 
 static int
-bpf_prog_load(struct tcb *tcp, const long addr, unsigned int size)
+bpf_prog_load(struct tcb *const tcp, const kernel_ulong_t addr,
+             unsigned int size)
 {
        struct {
                uint32_t prog_type, insn_cnt;
@@ -165,17 +173,92 @@ bpf_prog_load(struct tcb *tcp, const long addr, unsigned int size)
        printxval(bpf_prog_types, attr.prog_type, "BPF_PROG_TYPE_???");
        tprintf(", insn_cnt=%u, insns=%#" PRIx64 ", license=",
                attr.insn_cnt, attr.insns);
-       printstr(tcp, attr.license, -1);
+       printstr(tcp, attr.license);
        tprintf(", log_level=%u, log_size=%u, log_buf=%#" PRIx64 ", kern_version=%u}",
                attr.log_level, attr.log_size, attr.log_buf, attr.kern_version);
 
        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 int cmd = tcp->u_arg[0];
-       const long addr = tcp->u_arg[1];
+       const unsigned int cmd = tcp->u_arg[0];
+       const kernel_ulong_t addr = tcp->u_arg[1];
        const unsigned int size = tcp->u_arg[2];
        int rc = RVAL_DECODED;
 
@@ -203,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;