Skip to content

yumosx/voyant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

voyant

voyant is domain specific language based on the eBPF instruction set (insn) and system calls;

ulike other eBPF tools, it is designed to be lightweight and easy extendable,There are three aspectes that can account for my option;

  1. Ligtht tool First of all, no LLVM, indeed LLVM is an exceptional tool for building complier backends, but LLVM is counted in ten millions, the light weight is one of my goals and the rules out LLVM.

  2. Easy: Due to its lightweight design, our DSL is easier to install and can perform effectively even in resource-constrained environments.

  3. Clear: The third, our dsl will offer the similarly level of expressivity as general-purpose programming language, also extending the semantics in certain aspectes;

install

git clone
cd lang
make
sudo ./voyant main.vy

syntax

attach target

Currently, our DSL supports two types of mounting targets: one is kernel functions, and the other is tracepoints. I recommend using tracepoints whenever possible, as they are more stable.

tracepoint

#[syscalls];  //<-----event name

probe [tracepoint] {
    ....
}

kprobe

#kprobe;    //<-----kprobe string

probe [kprobe] {
    ...
}

Hello, world

The out function is similar to the printf function in C. It is typically used to send data from the runtime of our program back to user space.

#syscalls;

probe sys_enter_execve {
    out("%s", "Hello, World!");
}

variable

The := symbol is used to declare a variable in the current scope. currently, we do not support reassigning values to variables.

#syscalls;

probe sys_enter_execve {
    a := 1;
    out("%d\n", a);
}

operator

#syscalls;

probe sys_enter_execve{
    a := 4 * 2;
    b := 4 + 2;
    c := 4 - 2;
    d := 4 / 2;

    out("a:%d b:%d c:%d d:%d\n", a, b, c, d);
}

helper function

Our DSL supports several common helper functions, which are essentially the same as those found in eBPF.

#syscalls;

probe sys_enter_open {
    out("%-18d %-16s %-6d\n", pid(), comm(), cpu());
}

bpf map

  1. Map: Using the map[comm()] statement, we can create a map where the keys are generated by the comm() function.
#syscalls;

probe sys_enter_open{
    map[comm()] := pid();
}
  1. Method Call Operator: The |> operator is a special operator that indicates method call semantics. in this case, map's value init zero
#syscalls;

probe sys_enter_execve {
    enter[comm()] |> count();
}

probe sys_exit_execve {
    exit[comm()] |> count();
}
  1. map in muti probes
#syscalls;

probe sys_enter_open {
    enter[pid()] := args->filename;
}

probe sys_exit_open {
    ret := args->ret;
    out("%-18d %-16s %-6d %s\n", pid(), comm(), ret, enter[pid()]);
}

BEGIN

Begin is a special probe used to perform tasks before program compilation, such as outputting some prompt messages.

#syscalls;

BEGIN {
    out("%-18s %-16s %-6s\n", "PID", "COMM", "FILE");
}

probe sys_enter_open {
    out("%-18d %-16s %-6d\n", pid(), comm(), cpu());
}

probe function args

In our DSL, we can get trace point parameter information using args->filename, and the compiler will automatically infer the corresponding parameter type. For example, args->filename is of type string."

#syscalls;

probe sys_enter_open{
   arg := arg->filename;
   out("%-18d %-16s %-6s\n", pid(), comm(), arg);
}

if stmts

Our DSL also supports simple if statements, and it will later support corresponding boolean expressions.

#syscalls;

probe sys_enter_execve {
    if (cpu() >= 0) {
        out("on cpu %d", cpu());
    }
}

struct fileds

#kprobe;

probe dev_queue_xmit {
	sk := (sk_buff*) arg0;
	out("%d\n", sk->len);
}

About

[refactor] eBPF trace language

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published