Skip to content

Commit e918e86

Browse files
committed
tests: Test attach uprobe to specific offset
Add a new test case test_object_uprobe_with_func_offset() to exercise the new functionality. Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
1 parent e8087b0 commit e918e86

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libbpf-rs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ libbpf-sys = { version = "1.4.1", default-features = false, optional = true }
4545
tempfile = { version = "3.3", optional = true }
4646

4747
[dev-dependencies]
48+
goblin = "0.9.3"
4849
libbpf-rs = {path = ".", features = ["generate-test-files"]}
4950
libbpf-rs-dev = {path = "dev", features = ["generate-test-files"]}
5051
log = "0.4.4"

libbpf-rs/tests/common/mod.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
use std::error::Error;
2+
use std::fs;
3+
use std::path::Path;
14
use std::path::PathBuf;
25

6+
use goblin::elf::sym;
7+
use goblin::elf::Elf;
38
use libbpf_rs::Map;
49
use libbpf_rs::MapCore;
510
use libbpf_rs::MapMut;
@@ -85,3 +90,42 @@ where
8590

8691
value
8792
}
93+
94+
pub fn get_symbol_offset(binary_path: &Path, symbol_name: &str) -> Result<usize, Box<dyn Error>> {
95+
let buffer = fs::read(binary_path)?;
96+
let elf = Elf::parse(&buffer)?;
97+
98+
// Check dynamic symbols
99+
for sym in elf.dynsyms.iter() {
100+
if sym.st_type() != sym::STT_FUNC {
101+
continue;
102+
}
103+
if let Some(name) = elf.dynstrtab.get_at(sym.st_name) {
104+
if name == symbol_name {
105+
let sec = &elf.section_headers[sym.st_shndx];
106+
let offset = sym.st_value - sec.sh_addr + sec.sh_offset;
107+
return Ok(offset as usize);
108+
}
109+
}
110+
}
111+
112+
// Check regular symbols
113+
for sym in elf.syms.iter() {
114+
if sym.st_type() != sym::STT_FUNC {
115+
continue;
116+
}
117+
if let Some(name) = elf.strtab.get_at(sym.st_name) {
118+
if name == symbol_name {
119+
let sec = &elf.section_headers[sym.st_shndx];
120+
let offset = sym.st_value - sec.sh_addr + sec.sh_offset;
121+
return Ok(offset as usize);
122+
}
123+
}
124+
}
125+
126+
Err(format!(
127+
"Symbol `{}` not found in binary {:?}",
128+
symbol_name, binary_path
129+
)
130+
.into())
131+
}

libbpf-rs/tests/test.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ use test_tag::tag;
5353
use crate::common::get_map;
5454
use crate::common::get_map_mut;
5555
use crate::common::get_prog_mut;
56+
use crate::common::get_symbol_offset;
5657
use crate::common::get_test_object;
5758
use crate::common::get_test_object_path;
5859
use crate::common::open_test_object;
@@ -1700,6 +1701,28 @@ fn test_object_uprobe_with_opts() {
17001701
assert_eq!(result, 1);
17011702
}
17021703

1704+
#[tag(root)]
1705+
#[test]
1706+
fn test_object_uprobe_with_func_offset() {
1707+
let mut obj = get_test_object("uprobe.bpf.o");
1708+
let prog = get_prog_mut(&mut obj, "handle__uprobe");
1709+
1710+
let pid = unsafe { libc::getpid() };
1711+
let path = current_exe().expect("failed to find executable name");
1712+
let func_offset = get_symbol_offset(&path, "uprobe_target").unwrap();
1713+
let _link = prog
1714+
.attach_uprobe_with_opts(pid, path, func_offset, Default::default())
1715+
.expect("failed to attach prog");
1716+
1717+
let map = get_map_mut(&mut obj, "ringbuf");
1718+
let action = || {
1719+
let _ = uprobe_target();
1720+
};
1721+
let result = with_ringbuffer(&map, action);
1722+
1723+
assert_eq!(result, 1);
1724+
}
1725+
17031726
/// Check that we can attach a BPF program to a uprobe and access the cookie
17041727
/// provided during attach.
17051728
#[tag(root)]

0 commit comments

Comments
 (0)