|
|
@ -109,7 +109,7 @@ pub struct Object {
|
|
|
|
/// Program license
|
|
|
|
/// Program license
|
|
|
|
pub license: CString,
|
|
|
|
pub license: CString,
|
|
|
|
/// Kernel version
|
|
|
|
/// Kernel version
|
|
|
|
pub kernel_version: KernelVersion,
|
|
|
|
pub kernel_version: Option<u32>,
|
|
|
|
/// Program BTF
|
|
|
|
/// Program BTF
|
|
|
|
pub btf: Option<Btf>,
|
|
|
|
pub btf: Option<Btf>,
|
|
|
|
/// Program BTF.ext
|
|
|
|
/// Program BTF.ext
|
|
|
@ -135,7 +135,7 @@ pub struct Program {
|
|
|
|
/// The license
|
|
|
|
/// The license
|
|
|
|
pub license: CString,
|
|
|
|
pub license: CString,
|
|
|
|
/// The kernel version
|
|
|
|
/// The kernel version
|
|
|
|
pub kernel_version: KernelVersion,
|
|
|
|
pub kernel_version: Option<u32>,
|
|
|
|
/// The section containing the program
|
|
|
|
/// The section containing the program
|
|
|
|
pub section: ProgramSection,
|
|
|
|
pub section: ProgramSection,
|
|
|
|
/// The section index of the program
|
|
|
|
/// The section index of the program
|
|
|
@ -579,7 +579,7 @@ impl Object {
|
|
|
|
let kernel_version = if let Some(section) = obj.section_by_name("version") {
|
|
|
|
let kernel_version = if let Some(section) = obj.section_by_name("version") {
|
|
|
|
parse_version(Section::try_from(§ion)?.data, endianness)?
|
|
|
|
parse_version(Section::try_from(§ion)?.data, endianness)?
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
KernelVersion::Any
|
|
|
|
None
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
let mut bpf_obj = Object::new(endianness, license, kernel_version);
|
|
|
|
let mut bpf_obj = Object::new(endianness, license, kernel_version);
|
|
|
@ -631,7 +631,7 @@ impl Object {
|
|
|
|
Ok(bpf_obj)
|
|
|
|
Ok(bpf_obj)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn new(endianness: Endianness, license: CString, kernel_version: KernelVersion) -> Object {
|
|
|
|
fn new(endianness: Endianness, license: CString, kernel_version: Option<u32>) -> Object {
|
|
|
|
Object {
|
|
|
|
Object {
|
|
|
|
endianness,
|
|
|
|
endianness,
|
|
|
|
license,
|
|
|
|
license,
|
|
|
@ -1256,7 +1256,7 @@ fn parse_license(data: &[u8]) -> Result<CString, ParseError> {
|
|
|
|
.to_owned())
|
|
|
|
.to_owned())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn parse_version(data: &[u8], endianness: object::Endianness) -> Result<KernelVersion, ParseError> {
|
|
|
|
fn parse_version(data: &[u8], endianness: object::Endianness) -> Result<Option<u32>, ParseError> {
|
|
|
|
let data = match data.len() {
|
|
|
|
let data = match data.len() {
|
|
|
|
4 => data.try_into().unwrap(),
|
|
|
|
4 => data.try_into().unwrap(),
|
|
|
|
_ => {
|
|
|
|
_ => {
|
|
|
@ -1271,9 +1271,10 @@ fn parse_version(data: &[u8], endianness: object::Endianness) -> Result<KernelVe
|
|
|
|
object::Endianness::Little => u32::from_le_bytes(data),
|
|
|
|
object::Endianness::Little => u32::from_le_bytes(data),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Ok(match v {
|
|
|
|
Ok(if v == KERNEL_VERSION_ANY {
|
|
|
|
KERNEL_VERSION_ANY => KernelVersion::Any,
|
|
|
|
None
|
|
|
|
v => KernelVersion::Version(v),
|
|
|
|
} else {
|
|
|
|
|
|
|
|
Some(v)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1301,24 +1302,6 @@ fn get_map_field(btf: &Btf, type_id: u32) -> Result<u32, BtfError> {
|
|
|
|
Ok(arr.len)
|
|
|
|
Ok(arr.len)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// The parsed kernel version
|
|
|
|
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
|
|
|
|
|
|
pub enum KernelVersion {
|
|
|
|
|
|
|
|
/// Specified version
|
|
|
|
|
|
|
|
Version(u32),
|
|
|
|
|
|
|
|
/// Any version
|
|
|
|
|
|
|
|
Any,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl From<KernelVersion> for u32 {
|
|
|
|
|
|
|
|
fn from(version: KernelVersion) -> u32 {
|
|
|
|
|
|
|
|
match version {
|
|
|
|
|
|
|
|
KernelVersion::Any => KERNEL_VERSION_ANY,
|
|
|
|
|
|
|
|
KernelVersion::Version(v) => v,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Parsed '.bss' '.data' and '.rodata' sections. These sections are arrays of
|
|
|
|
// Parsed '.bss' '.data' and '.rodata' sections. These sections are arrays of
|
|
|
|
// bytes and are relocated based on their section index.
|
|
|
|
// bytes and are relocated based on their section index.
|
|
|
|
fn parse_data_map_section(section: &Section) -> Result<Map, ParseError> {
|
|
|
|
fn parse_data_map_section(section: &Section) -> Result<Map, ParseError> {
|
|
|
@ -1592,23 +1575,20 @@ mod tests {
|
|
|
|
Err(ParseError::InvalidKernelVersion { .. })
|
|
|
|
Err(ParseError::InvalidKernelVersion { .. })
|
|
|
|
));
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
assert!(matches!(
|
|
|
|
parse_version(&0xFFFF_FFFEu32.to_le_bytes(), Endianness::Little)
|
|
|
|
parse_version(&0xFFFF_FFFEu32.to_le_bytes(), Endianness::Little),
|
|
|
|
.expect("failed to parse magic version"),
|
|
|
|
Ok(None)
|
|
|
|
KernelVersion::Any
|
|
|
|
));
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
assert!(matches!(
|
|
|
|
parse_version(&0xFFFF_FFFEu32.to_be_bytes(), Endianness::Big)
|
|
|
|
parse_version(&0xFFFF_FFFEu32.to_be_bytes(), Endianness::Big),
|
|
|
|
.expect("failed to parse magic version"),
|
|
|
|
Ok(None)
|
|
|
|
KernelVersion::Any
|
|
|
|
));
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
assert!(matches!(
|
|
|
|
parse_version(&1234u32.to_le_bytes(), Endianness::Little)
|
|
|
|
parse_version(&1234u32.to_le_bytes(), Endianness::Little),
|
|
|
|
.expect("failed to parse magic version"),
|
|
|
|
Ok(Some(1234))
|
|
|
|
KernelVersion::Version(1234)
|
|
|
|
));
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
@ -1699,11 +1679,7 @@ mod tests {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn fake_obj() -> Object {
|
|
|
|
fn fake_obj() -> Object {
|
|
|
|
Object::new(
|
|
|
|
Object::new(Endianness::Little, CString::new("GPL").unwrap(), None)
|
|
|
|
Endianness::Little,
|
|
|
|
|
|
|
|
CString::new("GPL").unwrap(),
|
|
|
|
|
|
|
|
KernelVersion::Any,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
@ -1753,7 +1729,7 @@ mod tests {
|
|
|
|
obj.parse_program(&fake_section(BpfSectionKind::Program,"kprobe/foo", bytes_of(&fake_ins()))),
|
|
|
|
obj.parse_program(&fake_section(BpfSectionKind::Program,"kprobe/foo", bytes_of(&fake_ins()))),
|
|
|
|
Ok((Program {
|
|
|
|
Ok((Program {
|
|
|
|
license,
|
|
|
|
license,
|
|
|
|
kernel_version: KernelVersion::Any,
|
|
|
|
kernel_version: None,
|
|
|
|
section: ProgramSection::KProbe { .. },
|
|
|
|
section: ProgramSection::KProbe { .. },
|
|
|
|
.. }, Function {
|
|
|
|
.. }, Function {
|
|
|
|
name,
|
|
|
|
name,
|
|
|
|