use super::super::cast_analysis::AddrSpace;
use super::*;
fn test_btf() -> Option<Btf> {
let path = crate::monitor::find_test_vmlinux()?;
crate::monitor::btf_offsets::load_btf_from_path(&path).ok()
}
fn enum_v(bits: u32, value: i64, variant: Option<&str>, is_signed: bool) -> RenderedValue {
RenderedValue::Enum {
bits,
value,
variant: variant.map(String::from),
is_signed,
}
}
pub(crate) use crate::test_support::btf_blob::{
CastSynBitMember, CastSynMember, CastSynType, cast_build_btf,
};
fn cast_strings_for_t_q() -> (Vec<u8>, u32, u32, u32, u32, u32) {
let mut strings: Vec<u8> = vec![0];
let push = |s: &mut Vec<u8>, name: &str| -> u32 {
let off = s.len() as u32;
s.extend_from_slice(name.as_bytes());
s.push(0);
off
};
let n_int = push(&mut strings, "u64");
let n_t = push(&mut strings, "T");
let n_q = push(&mut strings, "Q");
let n_f = push(&mut strings, "f");
let n_x = push(&mut strings, "x");
(strings, n_int, n_t, n_q, n_f, n_x)
}
fn cast_btf_t_and_q() -> (Vec<u8>, u32, u32) {
let (strings, n_int, n_t, n_q, n_f, n_x) = cast_strings_for_t_q();
let types = vec![
CastSynType::Int {
name_off: n_int,
size: 8,
encoding: 0,
offset: 0,
bits: 64,
},
CastSynType::Struct {
name_off: n_t,
size: 8,
members: vec![CastSynMember {
name_off: n_f,
type_id: 1,
byte_offset: 0,
}],
},
CastSynType::Struct {
name_off: n_q,
size: 8,
members: vec![CastSynMember {
name_off: n_x,
type_id: 1,
byte_offset: 0,
}],
},
];
(cast_build_btf(&types, &strings), 2, 3)
}
#[derive(Default)]
struct CastStubReader {
hit: Option<CastHit>,
cast_map: Option<crate::monitor::cast_analysis::CastMap>,
arena_window: Option<(u64, u64)>,
arena_bytes_at: std::collections::HashMap<u64, Vec<u8>>,
kva_bytes_at: std::collections::HashMap<u64, Vec<u8>>,
arena_type_at: std::collections::HashMap<u64, ArenaResolveHit>,
cross_btf_btfs: Vec<std::sync::Arc<Btf>>,
cross_btf_index: std::collections::HashMap<String, (usize, u32, bool)>,
rendered_slot_addrs: std::collections::HashSet<u32>,
}
impl MemReader for CastStubReader {
fn read_kva(&self, kva: u64, len: usize) -> Option<Vec<u8>> {
let bytes = self.kva_bytes_at.get(&kva)?;
if bytes.len() < len {
return None;
}
Some(bytes[..len].to_vec())
}
fn is_arena_addr(&self, addr: u64) -> bool {
match self.arena_window {
Some((lo, hi)) => addr >= lo && addr < hi,
None => false,
}
}
fn read_arena(&self, addr: u64, len: usize) -> Option<Vec<u8>> {
let bytes = self.arena_bytes_at.get(&addr)?;
if bytes.len() < len {
return None;
}
Some(bytes[..len].to_vec())
}
fn cast_lookup(&self, parent_type_id: u32, member_byte_offset: u32) -> Option<CastHit> {
if let Some(map) = &self.cast_map {
return map.get(&(parent_type_id, member_byte_offset)).copied();
}
self.hit
}
fn resolve_arena_type(&self, addr: u64) -> Option<ArenaResolveHit> {
self.arena_type_at.get(&addr).copied()
}
fn cross_btf_resolve_fwd(
&self,
name: &str,
kind: super::FwdKind,
) -> Option<super::CrossBtfRef<'_>> {
let &(idx, type_id, idx_is_struct) = self.cross_btf_index.get(name)?;
let idx_kind = super::FwdKind::from_is_struct(idx_is_struct);
if idx_kind != kind {
return None;
}
let btf = self.cross_btf_btfs.get(idx)?;
Some(super::CrossBtfRef {
btf: btf.as_ref(),
type_id,
})
}
fn is_already_rendered(&self, addr: u64) -> bool {
self.rendered_slot_addrs.contains(&(addr as u32))
}
}
fn uint(value: u64) -> RenderedValue {
RenderedValue::Uint { bits: 64, value }
}
fn struct_with(members: Vec<(&str, RenderedValue)>) -> RenderedValue {
RenderedValue::Struct {
type_name: None,
members: members
.into_iter()
.map(|(n, v)| RenderedMember {
name: n.to_string(),
value: v,
})
.collect(),
}
}
fn sole_member_value(v: &RenderedValue) -> &RenderedValue {
match v {
RenderedValue::Struct { members, .. } => {
assert_eq!(members.len(), 1, "expected exactly one member");
&members[0].value
}
RenderedValue::Truncated { partial, .. } => sole_member_value(partial),
other => panic!("expected Struct/Truncated, got {other:?}"),
}
}
mod cast_intercept;
mod cast_kernel_arm;
mod cast_pipeline;
mod chase_edge_cases;
mod cpumask_render;
mod datasec_cpumask;
mod display_basics;
mod fwd_sibling;
mod predicates;
mod render_value_coverage;
mod rendered_value_accessors;
mod sdt_bridge;
mod templates_arrays_cycles;
mod typed_arrays_dedup;