Struct Compiler

Source
pub struct Compiler<'a> { /* private fields */ }

Implementations§

Source§

impl<'a> Compiler<'a>

Source

pub fn create(types: &'a TypeDatabase) -> Self

Create a new compiler instance.

§Arguments
  • types - The BTF type library to use when resolving types.
§Example
use bpf_script::compiler::Compiler;
use bpf_script::types::TypeDatabase;

let mut database = TypeDatabase::default();
let mut compiler = Compiler::create(&database);
Examples found in repository?
examples/print-instructions.rs (line 35)
4fn main() {
5    let prog = r#"
6            fn(vec: &iovec)
7              vec_copy: iovec = 0
8              vec_copy.iov_base = vec.iov_base
9              vec_copy.iov_len = vec.iov_len
10              return 50
11        "#;
12
13    let mut database = TypeDatabase::default();
14
15    let u64id = database
16        .add_integer(Some("__u64"), 8, false)
17        .expect("Failed to add type.");
18
19    let iov_base = Field {
20        offset: 0,
21        type_id: u64id,
22    };
23
24    let iov_len = Field {
25        offset: 64,
26        type_id: u64id,
27    };
28
29    database
30        .add_struct(
31            Some("iovec"),
32            &[("iov_base", iov_base), ("iov_len", iov_len)],
33        )
34        .expect("Failed to add type.");
35    let mut compiler = Compiler::create(&database);
36    compiler.compile(prog).unwrap();
37
38    for ins in compiler.get_instructions() {
39        println!("{}", ins);
40    }
41}
Source

pub fn capture(&mut self, name: &str, value: i64)

Used to capture variables from the outer scope into the BPF program being compiled. This is mostly used to capture map identifers to pass to BPF helpers and for other integer values that need to be captured. In the future, this will be extended to capture arbitrary types making sharing between Rust and BPF more seamless.

§Arguments

name - The name of the variable when referenced from the script. value - The value of the variable.

§Example
use bpf_script::compiler::Compiler;
use bpf_script::types::TypeDatabase;

let mut database = TypeDatabase::default();
let mut compiler = Compiler::create(&database);
compiler.capture("outer", 0xdeadbeef);
compiler.compile(r#"
    fn()
        return outer
"#).expect("Failed to compile.");
Source

pub fn compile(&mut self, script_text: &str) -> InternalResult<()>

Compile a given script.

§Arguments
  • script_text - The script to compile, as a string.
§Example
use bpf_script::compiler::Compiler;
use bpf_script::types::TypeDatabase;

let mut database = TypeDatabase::default();
database.add_integer(Some("u32"), 4, false);
let mut compiler = Compiler::create(&database);
compiler.compile(r#"
    fn(a: u32)
        return a
"#).expect("Failed to compile.");
Examples found in repository?
examples/print-instructions.rs (line 36)
4fn main() {
5    let prog = r#"
6            fn(vec: &iovec)
7              vec_copy: iovec = 0
8              vec_copy.iov_base = vec.iov_base
9              vec_copy.iov_len = vec.iov_len
10              return 50
11        "#;
12
13    let mut database = TypeDatabase::default();
14
15    let u64id = database
16        .add_integer(Some("__u64"), 8, false)
17        .expect("Failed to add type.");
18
19    let iov_base = Field {
20        offset: 0,
21        type_id: u64id,
22    };
23
24    let iov_len = Field {
25        offset: 64,
26        type_id: u64id,
27    };
28
29    database
30        .add_struct(
31            Some("iovec"),
32            &[("iov_base", iov_base), ("iov_len", iov_len)],
33        )
34        .expect("Failed to add type.");
35    let mut compiler = Compiler::create(&database);
36    compiler.compile(prog).unwrap();
37
38    for ins in compiler.get_instructions() {
39        println!("{}", ins);
40    }
41}
Source

pub fn get_instructions(&self) -> &[Instruction]

Returns the internally held instructions after compile has been called.

§Example
use bpf_script::compiler::Compiler;
use bpf_script::types::TypeDatabase;

let mut database = TypeDatabase::default();
database.add_integer(Some("u32"), 4, false);
let mut compiler = Compiler::create(&database);
compiler.compile(r#"
    fn(a: u32)
        return a
"#).expect("Failed to compile.");
for ins in compiler.get_instructions() {
    println!("{}", ins);
}
Examples found in repository?
examples/print-instructions.rs (line 38)
4fn main() {
5    let prog = r#"
6            fn(vec: &iovec)
7              vec_copy: iovec = 0
8              vec_copy.iov_base = vec.iov_base
9              vec_copy.iov_len = vec.iov_len
10              return 50
11        "#;
12
13    let mut database = TypeDatabase::default();
14
15    let u64id = database
16        .add_integer(Some("__u64"), 8, false)
17        .expect("Failed to add type.");
18
19    let iov_base = Field {
20        offset: 0,
21        type_id: u64id,
22    };
23
24    let iov_len = Field {
25        offset: 64,
26        type_id: u64id,
27    };
28
29    database
30        .add_struct(
31            Some("iovec"),
32            &[("iov_base", iov_base), ("iov_len", iov_len)],
33        )
34        .expect("Failed to add type.");
35    let mut compiler = Compiler::create(&database);
36    compiler.compile(prog).unwrap();
37
38    for ins in compiler.get_instructions() {
39        println!("{}", ins);
40    }
41}
Source

pub fn get_bytecode(&self) -> Vec<u64>

Returns the bytecode of a program after compile has been called. These are the raw instructions that make up a BPF program that can be passed directly to the kernel.

§Example
use bpf_script::compiler::Compiler;
use bpf_script::types::TypeDatabase;

let mut database = TypeDatabase::default();
database.add_integer(Some("u32"), 4, false);
let mut compiler = Compiler::create(&database);
compiler.compile(r#"
    fn(a: u32)
        return a
"#).expect("Failed to compile.");
for ins in compiler.get_bytecode() {
    println!("{}", ins);
}

Auto Trait Implementations§

§

impl<'a> Freeze for Compiler<'a>

§

impl<'a> RefUnwindSafe for Compiler<'a>

§

impl<'a> Send for Compiler<'a>

§

impl<'a> Sync for Compiler<'a>

§

impl<'a> Unpin for Compiler<'a>

§

impl<'a> UnwindSafe for Compiler<'a>

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, 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> Same for T

Source§

type Output = T

Should always be Self
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.