|
@@ -84,8 +84,17 @@ pub struct Program {
|
|
|
pub kernel_version: KernelVersion,
|
|
|
/// The section containing the program
|
|
|
pub section: ProgramSection,
|
|
|
- /// The function
|
|
|
- pub function: Function,
|
|
|
+ /// The section index of the program
|
|
|
+ pub section_index: usize,
|
|
|
+ /// The address of the program
|
|
|
+ pub address: u64,
|
|
|
+}
|
|
|
+
|
|
|
+impl Program {
|
|
|
+ /// The key used by [Object::functions]
|
|
|
+ pub fn function_key(&self) -> (usize, u64) {
|
|
|
+ (self.section_index, self.address)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// An eBPF function
|
|
@@ -646,7 +655,7 @@ impl Object {
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
- fn parse_program(&self, section: &Section) -> Result<Program, ParseError> {
|
|
|
+ fn parse_program(&self, section: &Section) -> Result<(Program, Function), ParseError> {
|
|
|
let prog_sec = ProgramSection::from_str(section.name)?;
|
|
|
let name = prog_sec.name().to_owned();
|
|
|
|
|
@@ -664,22 +673,28 @@ impl Object {
|
|
|
(FuncSecInfo::default(), LineSecInfo::default(), 0, 0)
|
|
|
};
|
|
|
|
|
|
- Ok(Program {
|
|
|
- license: self.license.clone(),
|
|
|
- kernel_version: self.kernel_version,
|
|
|
- section: prog_sec,
|
|
|
- function: Function {
|
|
|
- name,
|
|
|
- address: section.address,
|
|
|
- section_index: section.index,
|
|
|
- section_offset: 0,
|
|
|
- instructions: copy_instructions(section.data)?,
|
|
|
- func_info,
|
|
|
- line_info,
|
|
|
- func_info_rec_size,
|
|
|
- line_info_rec_size,
|
|
|
+ let function = Function {
|
|
|
+ name,
|
|
|
+ address: section.address,
|
|
|
+ section_index: section.index,
|
|
|
+ section_offset: 0,
|
|
|
+ instructions: copy_instructions(section.data)?,
|
|
|
+ func_info,
|
|
|
+ line_info,
|
|
|
+ func_info_rec_size,
|
|
|
+ line_info_rec_size,
|
|
|
+ };
|
|
|
+
|
|
|
+ Ok((
|
|
|
+ Program {
|
|
|
+ license: self.license.clone(),
|
|
|
+ kernel_version: self.kernel_version,
|
|
|
+ section: prog_sec,
|
|
|
+ section_index: function.section_index.0,
|
|
|
+ address: function.address,
|
|
|
},
|
|
|
- })
|
|
|
+ function,
|
|
|
+ ))
|
|
|
}
|
|
|
|
|
|
fn parse_text_section(&mut self, section: Section) -> Result<(), ParseError> {
|
|
@@ -875,7 +890,8 @@ impl Object {
|
|
|
res?
|
|
|
}
|
|
|
BpfSectionKind::Program => {
|
|
|
- let program = self.parse_program(§ion)?;
|
|
|
+ let (program, function) = self.parse_program(§ion)?;
|
|
|
+ self.functions.insert(program.function_key(), function);
|
|
|
self.programs
|
|
|
.insert(program.section.name().to_owned(), program);
|
|
|
if !section.relocations.is_empty() {
|
|
@@ -895,10 +911,10 @@ impl Object {
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
- /// Sanitize BPF programs.
|
|
|
- pub fn sanitize_programs(&mut self, features: &Features) {
|
|
|
- for program in self.programs.values_mut() {
|
|
|
- program.sanitize(features);
|
|
|
+ /// Sanitize BPF functions.
|
|
|
+ pub fn sanitize_functions(&mut self, features: &Features) {
|
|
|
+ for function in self.functions.values_mut() {
|
|
|
+ function.sanitize(features);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -918,9 +934,9 @@ const BPF_FUNC_PROBE_READ_KERNEL: i32 = 113;
|
|
|
const BPF_FUNC_PROBE_READ_USER_STR: i32 = 114;
|
|
|
const BPF_FUNC_PROBE_READ_KERNEL_STR: i32 = 115;
|
|
|
|
|
|
-impl Program {
|
|
|
+impl Function {
|
|
|
fn sanitize(&mut self, features: &Features) {
|
|
|
- for inst in &mut self.function.instructions {
|
|
|
+ for inst in &mut self.instructions {
|
|
|
if !insn_is_helper_call(inst) {
|
|
|
continue;
|
|
|
}
|
|
@@ -1652,17 +1668,17 @@ mod tests {
|
|
|
|
|
|
assert_matches!(
|
|
|
obj.parse_program(&fake_section(BpfSectionKind::Program,"kprobe/foo", bytes_of(&fake_ins()))),
|
|
|
- Ok(Program {
|
|
|
+ Ok((Program {
|
|
|
license,
|
|
|
kernel_version: KernelVersion::Any,
|
|
|
section: ProgramSection::KProbe { .. },
|
|
|
- function: Function {
|
|
|
+ .. }, Function {
|
|
|
name,
|
|
|
address: 0,
|
|
|
section_index: SectionIndex(0),
|
|
|
section_offset: 0,
|
|
|
instructions,
|
|
|
- ..} }) if license.to_string_lossy() == "GPL" && name == "foo" && instructions.len() == 1
|
|
|
+ ..})) if license.to_string_lossy() == "GPL" && name == "foo" && instructions.len() == 1
|
|
|
);
|
|
|
}
|
|
|
|