EbpfContext

Struct EbpfContext 

Source
pub struct EbpfContext<'ctx> {
Show 26 fields pub context: &'ctx Context, pub module: Module<'ctx>, pub builder: Builder<'ctx>, pub trace_printk_fn: FunctionValue<'ctx>, pub map_manager: MapManager<'ctx>, pub di_builder: DebugInfoBuilder<'ctx>, pub compile_unit: DICompileUnit<'ctx>, pub register_cache: HashMap<u16, IntValue<'ctx>>, pub variables: HashMap<String, PointerValue<'ctx>>, pub var_types: HashMap<String, VarType>, pub optimized_out_vars: HashMap<String, bool>, pub var_pc_addresses: HashMap<String, u64>, pub variable_context: Option<VariableContext>, pub process_analyzer: Option<*mut DwarfAnalyzer>, pub current_trace_id: Option<u32>, pub current_compile_time_context: Option<CompileTimeContext>, pub trace_context: TraceContext, pub current_resolved_var_module_path: Option<String>, pub pm_key_alloca: Option<PointerValue<'ctx>>, pub event_offset_alloca: Option<PointerValue<'ctx>>, pub offsets_found_flag: Option<PointerValue<'ctx>>, pub compile_options: CompileOptions, pub condition_context_active: bool, pub alias_vars: HashMap<String, Expr>, pub string_vars: HashMap<String, Vec<u8>>, pub scope_stack: Vec<HashSet<String>>,
}
Expand description

eBPF LLVM code generation context

Fields§

§context: &'ctx Context§module: Module<'ctx>§builder: Builder<'ctx>§trace_printk_fn: FunctionValue<'ctx>§map_manager: MapManager<'ctx>§di_builder: DebugInfoBuilder<'ctx>§compile_unit: DICompileUnit<'ctx>§register_cache: HashMap<u16, IntValue<'ctx>>§variables: HashMap<String, PointerValue<'ctx>>§var_types: HashMap<String, VarType>§optimized_out_vars: HashMap<String, bool>§var_pc_addresses: HashMap<String, u64>§variable_context: Option<VariableContext>§process_analyzer: Option<*mut DwarfAnalyzer>§current_trace_id: Option<u32>§current_compile_time_context: Option<CompileTimeContext>§trace_context: TraceContext§current_resolved_var_module_path: Option<String>§pm_key_alloca: Option<PointerValue<'ctx>>§event_offset_alloca: Option<PointerValue<'ctx>>§offsets_found_flag: Option<PointerValue<'ctx>>§compile_options: CompileOptions§condition_context_active: bool§alias_vars: HashMap<String, Expr>§string_vars: HashMap<String, Vec<u8>>§scope_stack: Vec<HashSet<String>>

Implementations§

Source§

impl<'ctx> EbpfContext<'ctx>

Source

pub fn compile_program_with_staged_transmission( &mut self, program: &Program, _variable_types: HashMap<String, TypeKind>, ) -> Result<TraceContext>

Main entry point: compile program with staged transmission system

Source

pub fn compile_statement(&mut self, statement: &Statement) -> Result<u16>

Compile a statement and return the number of instructions generated

Source

pub fn compile_print_statement( &mut self, print_stmt: &PrintStatement, ) -> Result<u16>

Compile print statement and generate LLVM IR on-demand

Source

pub fn resolve_variable_with_priority( &mut self, var_name: &str, ) -> Result<(u16, TypeKind)>

Resolve variable with correct priority: script variables first, then DWARF variables This method is copied from protocol.rs to maintain functionality

Source

pub fn generate_print_string_index(&mut self, string_index: u16) -> Result<()>

Generate eBPF code for PrintStringIndex instruction

Source

pub fn generate_expr_error( &mut self, expr_string_index: u16, error_code_iv: IntValue<'ctx>, flags_iv: IntValue<'ctx>, failing_addr_iv: IntValue<'ctx>, ) -> Result<()>

Generate ExprError instruction with expression string index and error code/flags

Source

pub fn generate_print_variable_index( &mut self, var_name_index: u16, type_encoding: TypeKind, var_name: &str, ) -> Result<()>

Generate eBPF code for PrintVariableIndex instruction

Source

pub fn generate_backtrace_instruction(&mut self, depth: u8) -> Result<()>

Generate Backtrace instruction

Source§

impl<'ctx> EbpfContext<'ctx>

Source

pub fn new( context: &'ctx Context, module_name: &str, trace_id: Option<u32>, compile_options: &CompileOptions, ) -> Result<Self>

Create a new eBPF code generation context

Source

pub fn enter_scope(&mut self)

Enter a new lexical scope

Source

pub fn exit_scope(&mut self)

Exit current lexical scope and drop all names declared within

Source

pub fn is_name_in_any_scope(&self, name: &str) -> bool

Check if a name exists in any active scope

Source

pub fn is_name_in_current_scope(&self, name: &str) -> bool

Check if a name exists in current (top) scope

Source

pub fn declare_name_in_current_scope(&mut self, name: &str) -> Result<()>

Declare a name in the current scope. Disallow same-scope redeclaration and shadowing.

Source

pub fn new_with_process_analyzer( context: &'ctx Context, module_name: &str, process_analyzer: Option<&mut DwarfAnalyzer>, trace_id: Option<u32>, compile_options: &CompileOptions, ) -> Result<Self>

Create a new code generator with DWARF analyzer support

Source

pub fn set_compile_time_context(&mut self, pc_address: u64, module_path: String)

Set compile-time context for DWARF queries

Source

pub fn get_compile_time_context(&self) -> Result<&CompileTimeContext>

Get compile-time context for DWARF queries

Source

pub fn take_module_hint(&mut self) -> Option<String>

Take and clear the current module hint for offsets (if any)

Source

pub fn create_basic_ebpf_function(&mut self, function_name: &str) -> Result<()>

Create basic eBPF function with proper signature

Source

pub fn get_module(&self) -> &Module<'ctx>

Get the LLVM module reference

Source

pub fn get_trace_context(&self) -> TraceContext

Get the string table after compilation

Source

pub fn get_pt_regs_parameter(&self) -> Result<PointerValue<'ctx>>

Get pt_regs parameter from current function

Source

pub fn compile_program( &mut self, _program: &Program, function_name: &str, trace_statements: &[Statement], target_pid: Option<u32>, compile_time_pc: Option<u64>, module_path: Option<&str>, ) -> Result<(FunctionValue<'ctx>, TraceContext)>

Compile a complete program with statements

Source

pub fn get_or_create_flag_global(&mut self, name: &str) -> PointerValue<'ctx>

Get or create a global i8 flag by name, initialized to 0

Source

pub fn store_flag_value(&mut self, name: &str, value: u8) -> Result<()>

Set a flag global to a constant u8 value at runtime

Source

pub fn mark_any_success(&mut self) -> Result<()>

Mark that at least one variable succeeded (status==0)

Source

pub fn mark_any_fail(&mut self) -> Result<()>

Mark that at least one variable failed (status!=0)

Source

pub fn get_or_create_offsets_found_flag(&mut self) -> PointerValue<'ctx>

Get (and create if needed) the global flag tracking the last proc_module_offsets lookup. Stored as i8 where 0 = miss, 1 = found.

Source

pub fn store_offsets_found_flag(&mut self, flag: IntValue<'ctx>) -> Result<()>

Store a boolean into the offsets-found flag (true => found, false => miss).

Source

pub fn store_offsets_found_const(&mut self, value: bool) -> Result<()>

Store a constant boolean value into the offsets-found flag.

Source

pub fn load_offsets_found_flag(&mut self) -> Result<IntValue<'ctx>>

Load the current offsets-found flag as i1 (true => found, false => miss).

Source

pub fn get_or_create_cond_error_global(&mut self) -> PointerValue<'ctx>

Get or create global for condition error code (i8). Name: _gs_cond_error

Source

pub fn reset_condition_error(&mut self) -> Result<()>

Reset condition error to 0 (only meaningful when condition_context_active=true)

Source

pub fn get_or_create_cond_error_addr_global(&mut self) -> PointerValue<'ctx>

Get or create global for condition error address (i64). Name: _gs_cond_error_addr

Source

pub fn set_condition_error_if_unset(&mut self, code: u8) -> Result<()>

If in condition context, set error code when it’s currently 0 (first error wins)

Source

pub fn build_condition_error_predicate(&mut self) -> Result<IntValue<'ctx>>

Read the current condition error as i1 predicate: (error != 0)

Source

pub fn get_or_create_cond_error_flags_global(&mut self) -> PointerValue<'ctx>

Get or create global for condition error flags (i8). Name: _gs_cond_error_flags

Source

pub fn or_condition_error_flags(&mut self, flags: IntValue<'ctx>) -> Result<()>

OR into condition error flags (BV must be i8)

Source

pub fn set_condition_error_addr_if_unset( &mut self, addr: IntValue<'ctx>, ) -> Result<()>

If in condition context, record failing address (first win). addr must be i64

Source§

impl<'ctx> EbpfContext<'ctx>

Source

pub fn evaluate_result_to_llvm_value( &mut self, evaluation_result: &EvaluationResult, dwarf_type: &TypeInfo, var_name: &str, pc_address: u64, ) -> Result<BasicValueEnum<'ctx>>

Convert EvaluationResult to LLVM value

Source

pub fn evaluation_result_to_address_with_hint( &mut self, evaluation_result: &EvaluationResult, status_ptr: Option<PointerValue<'ctx>>, module_hint: Option<&str>, ) -> Result<IntValue<'ctx>>

Variant that allows passing an explicit module hint for offsets lookup

Source

pub fn query_dwarf_for_complex_expr( &mut self, expr: &Expr, ) -> Result<Option<VariableWithEvaluation>>

Query DWARF for complex expression (supports member access, array access, etc.)

Source

pub fn query_dwarf_for_variable( &mut self, var_name: &str, ) -> Result<Option<VariableWithEvaluation>>

Query DWARF for variable information

Source

pub fn get_dwarf_type_size(dwarf_type: &TypeInfo) -> u64

Get DWARF type size in bytes

Source

pub fn query_dwarf_for_member_access( &mut self, obj_expr: &Expr, field_name: &str, ) -> Result<Option<VariableWithEvaluation>>

Query DWARF for member access (obj.field)

Source

pub fn query_dwarf_for_array_access( &mut self, array_expr: &Expr, index_expr: &Expr, ) -> Result<Option<VariableWithEvaluation>>

Query DWARF for array access (arr[index])

Source

pub fn query_dwarf_for_chain_access( &mut self, chain: &[String], ) -> Result<Option<VariableWithEvaluation>>

Query DWARF for chain access (person.name.first)

Source

pub fn query_dwarf_for_pointer_deref( &mut self, expr: &Expr, ) -> Result<Option<VariableWithEvaluation>>

Query DWARF for pointer dereference (*ptr)

Source

pub fn compute_pointed_location_with_index( &mut self, ptr_expr: &Expr, index: i64, ) -> Result<(EvaluationResult, TypeInfo)>

Compute a typed pointed-to location for expressions like ptr +/- K where K is an element index. Returns a computed location EvaluationResult along with the pointed-to DWARF type. The offset is scaled by the element size of the pointer/array target type.

Source§

impl<'ctx> EbpfContext<'ctx>

Source

pub fn compile_expr(&mut self, expr: &Expr) -> Result<BasicValueEnum<'ctx>>

Compile an expression

Source

pub fn handle_special_variable( &mut self, name: &str, ) -> Result<BasicValueEnum<'ctx>>

Handle special variables like $pid, $tid, etc.

Source

pub fn compile_binary_op( &mut self, left: BasicValueEnum<'ctx>, op: BinaryOp, right: BasicValueEnum<'ctx>, ) -> Result<BasicValueEnum<'ctx>>

Compile binary operations

Source

pub fn compile_member_access( &mut self, obj_expr: &Expr, field: &str, ) -> Result<BasicValueEnum<'ctx>>

Compile member access (struct.field)

Source

pub fn compile_pointer_deref( &mut self, expr: &Expr, ) -> Result<BasicValueEnum<'ctx>>

Compile pointer dereference (*ptr)

Source

pub fn compile_array_access( &mut self, array_expr: &Expr, index_expr: &Expr, ) -> Result<BasicValueEnum<'ctx>>

Compile array access (arr[index])

Source

pub fn compile_chain_access( &mut self, chain: &[String], ) -> Result<BasicValueEnum<'ctx>>

Compile chain access (person.name.first)

Source

pub fn compile_dwarf_expression( &mut self, expr: &Expr, ) -> Result<BasicValueEnum<'ctx>>

Unified DWARF expression compilation

Source§

impl<'ctx> EbpfContext<'ctx>

Source

pub fn get_or_create_i8_buffer( &mut self, size: u32, name_prefix: &str, ) -> (ArrayType<'ctx>, PointerValue<'ctx>)

Get or create a static i8 buffer global of a given size, returning its ArrayType and pointer

Source

pub fn read_user_cstr_into_buffer( &mut self, src_addr: IntValue<'ctx>, size: u32, name_prefix: &str, ) -> Result<(PointerValue<'ctx>, IntValue<'ctx>, ArrayType<'ctx>)>

Read a user C-string into a static buffer using bpf_probe_read_user_str. Returns (buffer_ptr, len_including_nul).

Source

pub fn read_user_bytes_into_buffer( &mut self, src_addr: IntValue<'ctx>, size: u32, name_prefix: &str, ) -> Result<(PointerValue<'ctx>, IntValue<'ctx>, ArrayType<'ctx>)>

Read raw user bytes into a static buffer using bpf_probe_read_user. Returns (buffer_ptr, status==0?).

Source

pub fn generate_runtime_address_from_offsets( &mut self, link_addr: IntValue<'ctx>, section_type: u8, module_cookie: u64, ) -> Result<(IntValue<'ctx>, IntValue<'ctx>)>

Compute runtime address from link-time address using proc_module_offsets map section_type: 0=text, 1=rodata, 2=data, 3=bss; other values fallback to data

Source

pub fn load_register_value( &mut self, reg_num: u16, pt_regs_ptr: PointerValue<'ctx>, ) -> Result<BasicValueEnum<'ctx>>

Load a register value from pt_regs

Source

pub fn generate_memory_read( &mut self, addr: IntValue<'ctx>, size: MemoryAccessSize, ) -> Result<BasicValueEnum<'ctx>>

Generate memory read using bpf_probe_read_user

Source

pub fn generate_memory_read_with_status( &mut self, addr: IntValue<'ctx>, size: MemoryAccessSize, ) -> Result<BasicValueEnum<'ctx>>

Generate memory read with runtime status capture (for control-flow conditions). On helper failure, sets condition error code (if active) and returns zero value.

Source

pub fn dwarf_reg_to_pt_regs_offset(&self, dwarf_reg: u16) -> Result<usize>

Map DWARF register number to pt_regs offset (simplified)

Source

pub fn create_bpf_helper_call( &mut self, helper_id: u64, args: &[BasicValueEnum<'ctx>], return_type: BasicTypeEnum<'ctx>, call_name: &str, ) -> Result<BasicValueEnum<'ctx>>

Create eBPF helper call using the correct calling convention This creates an indirect call through the eBPF helper mechanism

Source

pub fn get_current_timestamp(&mut self) -> Result<IntValue<'ctx>>

Get current timestamp using bpf_ktime_get_ns

Source

pub fn get_current_pid_tgid(&mut self) -> Result<IntValue<'ctx>>

Get current PID/TID using bpf_get_current_pid_tgid

Source

pub fn create_event_output( &mut self, data: PointerValue<'ctx>, size: u64, ) -> Result<()>

Create event output using either RingBuf or PerfEventArray based on compile options This is the unified interface that should be used for all event output

Source

pub fn create_ringbuf_output_dynamic( &mut self, data: PointerValue<'ctx>, size: IntValue<'ctx>, ) -> Result<()>

Create ringbuf output with dynamic size (IntValue)

Source

pub fn lookup_percpu_value_ptr( &mut self, map_name: &str, key_const: u32, ) -> Result<PointerValue<'ctx>>

Lookup per-CPU map value pointer for a given map name and u32 key constant

Source

pub fn create_perf_event_output_dynamic( &mut self, data: PointerValue<'ctx>, size: IntValue<'ctx>, ) -> Result<()>

Create perf event output with dynamic size (IntValue)

Source§

impl<'ctx> EbpfContext<'ctx>

Source

pub fn send_trace_event_header(&mut self) -> Result<()>

Send TraceEventHeader as first segment

Source

pub fn send_trace_event_message(&mut self, trace_id: u64) -> Result<()>

Send TraceEventMessage as second segment

Source

pub fn send_end_instruction(&mut self, total_instructions: u16) -> Result<()>

Send EndInstruction as final segment

Source§

impl<'ctx> EbpfContext<'ctx>

Source

pub fn set_alias_variable(&mut self, name: &str, expr: Expr)

Register a DWARF alias variable. The value expression is stored and resolved at use time.

Source

pub fn alias_variable_exists(&self, name: &str) -> bool

Check whether an alias variable exists

Source

pub fn get_alias_variable(&self, name: &str) -> Option<Expr>

Get a clone of the stored alias expression if present

Source

pub fn store_variable( &mut self, name: &str, value: BasicValueEnum<'ctx>, ) -> Result<()>

Store a variable value

Source

pub fn load_variable(&mut self, name: &str) -> Result<BasicValueEnum<'ctx>>

Retrieve a variable value

Source

pub fn variable_exists(&self, name: &str) -> bool

Check if a variable exists in the current scope

Source

pub fn get_variable_type(&self, name: &str) -> Option<&VarType>

Get variable type

Source

pub fn clear_variables(&mut self)

Clear all variables (for new scope)

Source

pub fn set_string_variable_bytes(&mut self, name: &str, bytes: Vec<u8>)

Register a string variable’s bytes (including optional NUL terminator)

Source

pub fn get_string_variable_bytes(&self, name: &str) -> Option<&Vec<u8>>

Get string variable bytes if present

Auto Trait Implementations§

§

impl<'ctx> !Freeze for EbpfContext<'ctx>

§

impl<'ctx> !RefUnwindSafe for EbpfContext<'ctx>

§

impl<'ctx> !Send for EbpfContext<'ctx>

§

impl<'ctx> !Sync for EbpfContext<'ctx>

§

impl<'ctx> Unpin for EbpfContext<'ctx>

§

impl<'ctx> UnwindSafe for EbpfContext<'ctx>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more