Skip to content

Commit 4281c45

Browse files
ver-nyand-e-s-o
authored andcommitted
query: add kprobe_multi second info call fields
1 parent ecaf2db commit 4281c45

4 files changed

Lines changed: 89 additions & 5 deletions

File tree

libbpf-rs/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
Unreleased
2+
----------
3+
- Added `KprobeMultiLinkInfo` fields that required a second info call.
4+
5+
16
0.26.2
27
------
38
- Added `ProgramMut::assoc_struct_ops` for associating non-struct_ops programs

libbpf-rs/src/query.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,10 @@ pub struct KprobeMultiLinkInfo {
720720
pub flags: u32,
721721
/// Missed probes count.
722722
pub missed: u64,
723+
/// Addresses of the probe.
724+
pub addrs: Vec<u64>,
725+
/// Cookies corresponding to the attach addresses.
726+
pub cookies: Vec<u64>,
723727
}
724728

725729
/// Information about a multi-uprobe link.
@@ -940,10 +944,27 @@ impl LinkInfo {
940944
map_id: unsafe { s.__bindgen_anon_1.struct_ops.map_id },
941945
}),
942946
libbpf_sys::BPF_LINK_TYPE_KPROBE_MULTI => {
947+
let count = unsafe { s.__bindgen_anon_1.kprobe_multi.count } as usize;
948+
let mut addrs = vec![0; count];
949+
let mut cookies = vec![0; count];
950+
951+
s.__bindgen_anon_1.kprobe_multi.addrs = addrs.as_mut_ptr() as u64;
952+
s.__bindgen_anon_1.kprobe_multi.cookies = cookies.as_mut_ptr() as u64;
953+
let item_ptr: *mut libbpf_sys::bpf_link_info = &mut s;
954+
let mut len = size_of_val(&s) as u32;
955+
let ret = unsafe {
956+
libbpf_sys::bpf_obj_get_info_by_fd(fd.as_raw_fd(), item_ptr.cast(), &mut len)
957+
};
958+
if ret != 0 {
959+
return None;
960+
}
961+
943962
LinkTypeInfo::KprobeMulti(KprobeMultiLinkInfo {
944963
count: unsafe { s.__bindgen_anon_1.kprobe_multi.count },
945964
flags: unsafe { s.__bindgen_anon_1.kprobe_multi.flags },
946965
missed: unsafe { s.__bindgen_anon_1.kprobe_multi.missed },
966+
addrs,
967+
cookies,
947968
})
948969
}
949970
libbpf_sys::BPF_LINK_TYPE_UPROBE_MULTI => {

libbpf-rs/tests/common/mod.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,28 @@ fn check_symbol_offset(elf: &Elf, sym: &sym::Sym) -> Option<usize> {
143143
}
144144
None
145145
}
146+
147+
pub(crate) fn resolve_ksym_addr(sym_name: &str) -> Option<u64> {
148+
let kallsyms = fs::read_to_string("/proc/kallsyms").ok()?;
149+
150+
for line in kallsyms.split('\n') {
151+
let mut parts = line.split_whitespace();
152+
let Some(addr) = parts.next() else {
153+
continue;
154+
};
155+
if parts.next().is_none() {
156+
continue;
157+
}
158+
let Some(sym) = parts.next() else {
159+
continue;
160+
};
161+
162+
if sym_name == sym {
163+
return Some(
164+
u64::from_str_radix(addr, 16).expect("ksym found but could not resolve addr"),
165+
);
166+
}
167+
}
168+
169+
None
170+
}

libbpf-rs/tests/test.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use std::fs;
1919
use std::hint;
2020
use std::io;
2121
use std::io::Read;
22+
use std::iter::zip;
2223
use std::mem::size_of;
2324
use std::mem::size_of_val;
2425
use std::os::unix::io::AsFd;
@@ -37,6 +38,7 @@ use std::sync::mpsc::channel;
3738
use std::time::Duration;
3839

3940
use libbpf_rs::num_possible_cpus;
41+
use libbpf_rs::query::KprobeMultiLinkInfo;
4042
use libbpf_rs::query::LinkTypeInfo;
4143
use libbpf_rs::query::PerfEventType;
4244
use libbpf_rs::query::ProgInfoIter;
@@ -1854,16 +1856,47 @@ fn test_object_kprobe_multi_with_opts() {
18541856
let mut obj = open_obj.load().expect("failed to load object");
18551857
let prog = get_prog_mut(&mut obj, "handle__kprobe");
18561858

1859+
let syms_opt = vec![
1860+
"bpf_fentry_test1".to_string(),
1861+
"bpf_fentry_test2".to_string(),
1862+
];
1863+
let cookies_opt = vec![6, 7];
18571864
let opts = KprobeMultiOpts {
1858-
symbols: vec![
1859-
"bpf_fentry_test1".to_string(),
1860-
"bpf_fentry_test2".to_string(),
1861-
],
1865+
symbols: syms_opt.clone(),
1866+
cookies: cookies_opt.clone(),
18621867
..Default::default()
18631868
};
1864-
let _link = prog
1869+
1870+
let link = prog
18651871
.attach_kprobe_multi_with_opts(opts)
18661872
.expect("failed to attach prog");
1873+
1874+
let link_info = link.info().expect("failed to get kprobe_multi link info");
1875+
let LinkTypeInfo::KprobeMulti(kprobe_multi) = link_info.info else {
1876+
panic!(
1877+
"Expected LinkTypeInfo::KprobeMulti for kprobe_multi, got: {:?}",
1878+
link_info.info
1879+
);
1880+
};
1881+
1882+
let KprobeMultiLinkInfo {
1883+
count,
1884+
addrs,
1885+
cookies,
1886+
..
1887+
} = kprobe_multi;
1888+
assert_eq!(count, syms_opt.len() as u32);
1889+
for (actual, sym) in zip(addrs, syms_opt) {
1890+
let Some(expected) = common::resolve_ksym_addr(&sym) else {
1891+
// requires reading `/proc/kallsyms`
1892+
break;
1893+
};
1894+
1895+
assert_eq!(actual, expected);
1896+
}
1897+
for (actual, expected) in zip(cookies, cookies_opt) {
1898+
assert_eq!(actual, expected);
1899+
}
18671900
}
18681901

18691902
/// Check that we can attach a BPF program to a kernel tracepoint.

0 commit comments

Comments
 (0)