xtask: add code generator for aya

pull/1/head
Alessandro Decina 4 years ago
parent 08d4b1aeda
commit fb0c8f0bc9

@ -0,0 +1,164 @@
use anyhow::anyhow;
use std::path::PathBuf;
use structopt::StructOpt;
use aya_gen::{bindgen, write_to_file};
use crate::codegen::Architecture;
#[derive(StructOpt)]
pub struct CodegenOptions {
#[structopt(long)]
libbpf_dir: PathBuf,
}
pub fn codegen(opts: CodegenOptions) -> Result<(), anyhow::Error> {
codegen_internal_btf_bindings(&opts)?;
codegen_bindings(&opts)
}
fn codegen_internal_btf_bindings(opts: &CodegenOptions) -> Result<(), anyhow::Error> {
let dir = PathBuf::from("aya");
let generated = dir.join("src/generated");
let mut bindgen = bindgen::user_builder().header(
opts.libbpf_dir
.join("src/libbpf_internal.h")
.to_string_lossy(),
);
let types = ["bpf_core_relo", "btf_ext_header"];
for x in &types {
bindgen = bindgen.whitelist_type(x);
}
let bindings = bindgen
.generate()
.map_err(|_| anyhow!("bindgen failed"))?
.to_string();
// write the bindings, with the original helpers removed
write_to_file(
&generated.join("btf_internal_bindings.rs"),
&bindings.to_string(),
)?;
Ok(())
}
fn codegen_bindings(opts: &CodegenOptions) -> Result<(), anyhow::Error> {
let types = [
// BPF
"BPF_TYPES",
"bpf_cmd",
"bpf_insn",
"bpf_attr",
"bpf_map_type",
"bpf_prog_type",
"bpf_attach_type",
// BTF
"btf_header",
"btf_ext_info",
"btf_ext_info_sec",
"btf_type",
"btf_enum",
"btf_array",
"btf_member",
"btf_param",
"btf_var",
"btf_var_secinfo",
// PERF
"perf_event_attr",
"perf_sw_ids",
"perf_event_sample_format",
"perf_event_mmap_page",
"perf_event_header",
"perf_type_id",
"perf_event_type",
// NETLINK
"ifinfomsg",
];
let vars = [
// BPF
"BPF_PSEUDO_.*",
"BPF_ALU",
"BPF_ALU64",
"BPF_LDX",
"BPF_ST",
"BPF_STX",
"BPF_LD",
"BPF_K",
"BPF_DW",
"BPF_W",
"BPF_H",
"BPF_B",
"SO_ATTACH_BPF",
"SO_DETACH_BPF",
// BTF
"BTF_KIND_.*",
"BTF_INT_.*",
// PERF
"PERF_FLAG_.*",
"PERF_EVENT_.*",
// NETLINK
"NLMSG_ALIGNTO",
"IFLA_XDP_FD",
"XDP_FLAGS_.*",
];
let dir = PathBuf::from("aya");
let generated = dir.join("src/generated");
let builder = || {
bindgen::user_builder()
.header(dir.join("include/linux_wrapper.h").to_string_lossy())
.clang_args(&[
"-I",
&*opts.libbpf_dir.join("include/uapi").to_string_lossy(),
])
.clang_args(&["-I", &*opts.libbpf_dir.join("include").to_string_lossy()])
};
for arch in Architecture::supported() {
let mut bindgen = builder();
for x in &types {
bindgen = bindgen.whitelist_type(x);
}
for x in &vars {
bindgen = bindgen.whitelist_var(x);
}
// FIXME: this stuff is probably debian/ubuntu specific
match arch {
Architecture::X86_64 => {
bindgen = bindgen.clang_args(&["-I", "/usr/include/x86_64-linux-gnu"]);
}
Architecture::AArch64 => {
bindgen = bindgen.clang_args(&["-I", "/usr/aarch64-linux-gnu/include"]);
}
};
for x in &types {
bindgen = bindgen.whitelist_type(x);
}
for x in &vars {
bindgen = bindgen.whitelist_var(x);
}
let bindings = bindgen
.generate()
.map_err(|_| anyhow!("bindgen failed"))?
.to_string();
// write the bindings, with the original helpers removed
write_to_file(
&generated.join(format!("linux_bindings_{}.rs", arch)),
&bindings.to_string(),
)?;
}
Ok(())
}

@ -29,7 +29,7 @@ pub fn codegen(opts: CodegenOptions) -> Result<(), anyhow::Error> {
let dir = PathBuf::from("bpf/aya-bpf-bindings");
let generated = dir.join("src").join(opts.arch.to_string());
let mut bindgen = bindgen::builder()
let mut bindgen = bindgen::bpf_builder()
.header(&*dir.join("include/bindings.h").to_string_lossy())
.clang_args(&["-I", &*opts.libbpf_dir.join("src").to_string_lossy()]);

@ -1,14 +1,23 @@
mod aya;
mod aya_bpf_bindings;
mod helpers;
use structopt::StructOpt;
const SUPPORTED_ARCHS: &'static [Architecture] = &[Architecture::X86_64, Architecture::AArch64];
#[derive(Debug, Copy, Clone)]
pub enum Architecture {
X86_64,
AArch64,
}
impl Architecture {
pub fn supported() -> &'static [Architecture] {
SUPPORTED_ARCHS
}
}
impl std::str::FromStr for Architecture {
type Err = String;
@ -38,6 +47,8 @@ pub struct Options {
#[derive(StructOpt)]
enum Command {
#[structopt(name = "aya")]
Aya(aya::CodegenOptions),
#[structopt(name = "aya-bpf-bindings")]
AyaBpfBindings(aya_bpf_bindings::CodegenOptions),
}
@ -45,6 +56,7 @@ enum Command {
pub fn codegen(opts: Options) -> Result<(), anyhow::Error> {
use Command::*;
match opts.command {
Aya(opts) => aya::codegen(opts),
AyaBpfBindings(opts) => aya_bpf_bindings::codegen(opts),
}
}

Loading…
Cancel
Save