|
|
@ -7,7 +7,7 @@ use structopt::StructOpt;
|
|
|
|
use aya_gen::{
|
|
|
|
use aya_gen::{
|
|
|
|
bindgen,
|
|
|
|
bindgen,
|
|
|
|
getters::{generate_getters_for_items, read_getter},
|
|
|
|
getters::{generate_getters_for_items, read_getter},
|
|
|
|
write_to_file, write_to_file_fmt,
|
|
|
|
write_to_file_fmt,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
use syn::{parse_str, Item};
|
|
|
|
use syn::{parse_str, Item};
|
|
|
|
|
|
|
|
|
|
|
@ -18,68 +18,72 @@ use crate::codegen::{
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(StructOpt)]
|
|
|
|
#[derive(StructOpt)]
|
|
|
|
pub struct CodegenOptions {
|
|
|
|
pub struct CodegenOptions {
|
|
|
|
#[structopt(long)]
|
|
|
|
|
|
|
|
arch: Architecture,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[structopt(long)]
|
|
|
|
#[structopt(long)]
|
|
|
|
libbpf_dir: PathBuf,
|
|
|
|
libbpf_dir: PathBuf,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn codegen(opts: CodegenOptions) -> Result<(), anyhow::Error> {
|
|
|
|
pub fn codegen(opts: CodegenOptions) -> Result<(), anyhow::Error> {
|
|
|
|
let dir = PathBuf::from("bpf/aya-bpf-bindings");
|
|
|
|
let dir = PathBuf::from("bpf/aya-bpf-bindings");
|
|
|
|
let generated = dir.join("src").join(opts.arch.to_string());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut bindgen = bindgen::bpf_builder()
|
|
|
|
let builder = || {
|
|
|
|
.header(&*dir.join("include/bindings.h").to_string_lossy())
|
|
|
|
let mut bindgen = bindgen::bpf_builder()
|
|
|
|
.clang_args(&["-I", &*opts.libbpf_dir.join("src").to_string_lossy()]);
|
|
|
|
.header(&*dir.join("include/bindings.h").to_string_lossy())
|
|
|
|
|
|
|
|
.clang_args(&["-I", &*opts.libbpf_dir.join("src").to_string_lossy()]);
|
|
|
|
|
|
|
|
|
|
|
|
let types = ["bpf_map_.*"];
|
|
|
|
let types = ["bpf_map_.*"];
|
|
|
|
let vars = ["BPF_.*", "bpf_.*"];
|
|
|
|
let vars = ["BPF_.*", "bpf_.*"];
|
|
|
|
|
|
|
|
|
|
|
|
for x in &types {
|
|
|
|
for x in &types {
|
|
|
|
bindgen = bindgen.whitelist_type(x);
|
|
|
|
bindgen = bindgen.whitelist_type(x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for x in &vars {
|
|
|
|
for x in &vars {
|
|
|
|
bindgen = bindgen.whitelist_var(x);
|
|
|
|
bindgen = bindgen.whitelist_var(x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let bindings = bindgen
|
|
|
|
bindgen
|
|
|
|
.generate()
|
|
|
|
};
|
|
|
|
.map_err(|_| anyhow!("bindgen failed"))?
|
|
|
|
|
|
|
|
.to_string();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut tree = parse_str::<syn::File>(&bindings).unwrap();
|
|
|
|
for arch in Architecture::supported() {
|
|
|
|
let (indexes, helpers) = extract_helpers(&tree.items);
|
|
|
|
let generated = dir.join("src").join(arch.to_string());
|
|
|
|
let helpers = expand_helpers(&helpers);
|
|
|
|
|
|
|
|
for index in indexes {
|
|
|
|
|
|
|
|
tree.items[index] = Item::Verbatim(TokenStream::new())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// write the bindings, with the original helpers removed
|
|
|
|
let bindings = builder()
|
|
|
|
write_to_file(
|
|
|
|
.generate()
|
|
|
|
&generated.join("bindings.rs"),
|
|
|
|
.map_err(|_| anyhow!("bindgen failed"))?
|
|
|
|
&tree.to_token_stream().to_string(),
|
|
|
|
.to_string();
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
|
|
let mut tree = parse_str::<syn::File>(&bindings).unwrap();
|
|
|
|
// write the new helpers as expanded by expand_helpers()
|
|
|
|
let (indexes, helpers) = extract_helpers(&tree.items);
|
|
|
|
write_to_file_fmt(
|
|
|
|
let helpers = expand_helpers(&helpers);
|
|
|
|
&generated.join("helpers.rs"),
|
|
|
|
for index in indexes {
|
|
|
|
&format!("use super::bindings::*; {}", helpers.to_string()),
|
|
|
|
tree.items[index] = Item::Verbatim(TokenStream::new())
|
|
|
|
)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// write the bpf_probe_read() getters
|
|
|
|
// write the bindings, with the original helpers removed
|
|
|
|
let bpf_probe_read = syn::parse_str("crate::bpf_probe_read").unwrap();
|
|
|
|
write_to_file_fmt(
|
|
|
|
write_to_file_fmt(
|
|
|
|
&generated.join("bindings.rs"),
|
|
|
|
&generated.join("getters.rs"),
|
|
|
|
&tree.to_token_stream().to_string(),
|
|
|
|
&format!(
|
|
|
|
)?;
|
|
|
|
"use super::bindings::*; {}",
|
|
|
|
|
|
|
|
&generate_getters_for_items(&tree.items, |getter| {
|
|
|
|
// write the new helpers as expanded by expand_helpers()
|
|
|
|
read_getter(getter, &bpf_probe_read)
|
|
|
|
write_to_file_fmt(
|
|
|
|
})
|
|
|
|
&generated.join("helpers.rs"),
|
|
|
|
.to_string()
|
|
|
|
&format!("use super::bindings::*; {}", helpers.to_string()),
|
|
|
|
),
|
|
|
|
)?;
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
|
|
// write the bpf_probe_read() getters
|
|
|
|
|
|
|
|
let bpf_probe_read = syn::parse_str("crate::bpf_probe_read").unwrap();
|
|
|
|
|
|
|
|
write_to_file_fmt(
|
|
|
|
|
|
|
|
&generated.join("getters.rs"),
|
|
|
|
|
|
|
|
&format!(
|
|
|
|
|
|
|
|
"use super::bindings::*; {}",
|
|
|
|
|
|
|
|
&generate_getters_for_items(&tree.items, |getter| {
|
|
|
|
|
|
|
|
read_getter(getter, &bpf_probe_read)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.to_string()
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|