Skip to content

Commit

Permalink
Add feature check for uprobe_multi
Browse files Browse the repository at this point in the history
Signed-off-by: Jiri Olsa <[email protected]>
  • Loading branch information
olsajiri committed Oct 22, 2023
1 parent 713f170 commit ff11848
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
71 changes: 71 additions & 0 deletions src/bpffeature.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include "bpffeature.h"

#include <bcc/bcc_syms.h>
#include <bcc/libbpf.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include <cstddef>
#include <cstdio>
#include <fcntl.h>
Expand Down Expand Up @@ -401,6 +403,74 @@ bool BPFfeature::has_kprobe_multi()
return *has_kprobe_multi_;
}

extern "C" __attribute__((noinline)) __attribute__((unused)) void uprobe_multi_test_func(
void)
{
}

bool BPFfeature::has_uprobe_multi()
{
if (has_uprobe_multi_.has_value())
return *has_uprobe_multi_;

LIBBPF_OPTS(bpf_prog_load_opts,
load_opts,
.expected_attach_type = static_cast<enum ::bpf_attach_type>(
libbpf::BPF_TRACE_UPROBE_MULTI), );

const char* sym = "uprobe_multi_test_func";
const char* path = "/proc/self/exe";
int err, progfd, linkfd = -1;
struct bcc_symbol bsym;

err = bcc_resolve_symname(path, sym, 0, -1, NULL, &bsym);
if (err)
{
has_uprobe_multi_ = false;
return *has_uprobe_multi_;
}

struct bpf_insn insns[] = {
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
};

progfd = bpf_prog_load(::BPF_PROG_TYPE_KPROBE,
"uprobe_multi",
"GPL",
reinterpret_cast<struct bpf_insn*>(insns),
ARRAY_SIZE(insns),
&load_opts);

if (progfd >= 0)
{
LIBBPF_OPTS(bpf_link_create_opts, link_opts);
const unsigned long offset = (unsigned long)bsym.offset;

link_opts.uprobe_multi.path = path;
link_opts.uprobe_multi.offsets = &offset;
link_opts.uprobe_multi.cnt = 1;

linkfd = bpf_link_create(progfd,
0,
static_cast<enum ::bpf_attach_type>(
libbpf::BPF_TRACE_UPROBE_MULTI),
&link_opts);
}

has_uprobe_multi_ = linkfd >= 0;

if (linkfd >= 0)
{
close(linkfd);
}
if (progfd >= 0)
{
close(progfd);
}
return *has_uprobe_multi_;
}

bool BPFfeature::has_skb_output(void)
{
if (!has_kfunc())
Expand Down Expand Up @@ -530,6 +600,7 @@ std::string BPFfeature::report(void)
<< " perf_event: " << to_str(has_prog_perf_event())
<< " kfunc: " << to_str(has_kfunc())
<< " kprobe_multi: " << to_str(has_kprobe_multi())
<< " uprobe_multi: " << to_str(has_uprobe_multi())
<< " raw_tp_special: " << to_str(has_raw_tp_special())
<< " iter: " << to_str(has_iter("task")) << std::endl;

Expand Down
2 changes: 2 additions & 0 deletions src/bpffeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class BPFfeature
bool has_d_path();
bool has_uprobe_refcnt();
bool has_kprobe_multi();
bool has_uprobe_multi();
bool has_kfunc();
bool has_skb_output();
bool has_raw_tp_special();
Expand Down Expand Up @@ -117,6 +118,7 @@ class BPFfeature
std::optional<bool> has_map_batch_;
std::optional<bool> has_uprobe_refcnt_;
std::optional<bool> has_kprobe_multi_;
std::optional<bool> has_uprobe_multi_;
std::optional<bool> has_skb_output_;
std::optional<bool> has_raw_tp_special_;
std::optional<bool> has_prog_kfunc_;
Expand Down
10 changes: 10 additions & 0 deletions src/libbpf/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
#define BPF_F_KPROBE_MULTI_RETURN (1U << 0)
#endif

#ifndef BPF_F_UPROBE_MULTI_RETURN
#define BPF_F_UPROBE_MULTI_RETURN (1U << 0)
#endif

// clang-format off
enum bpf_map_type {
BPF_MAP_TYPE_UNSPEC,
Expand Down Expand Up @@ -126,6 +130,12 @@ enum bpf_attach_type {
BPF_SK_REUSEPORT_SELECT_OR_MIGRATE,
BPF_PERF_EVENT,
BPF_TRACE_KPROBE_MULTI,
BPF_LSM_CGROUP,
BPF_STRUCT_OPS,
BPF_NETFILTER,
BPF_TCX_INGRESS,
BPF_TCX_EGRESS,
BPF_TRACE_UPROBE_MULTI,
};

#ifdef __BPF_FUNC_MAPPER
Expand Down

0 comments on commit ff11848

Please sign in to comment.