aya.rs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. use anyhow::anyhow;
  2. use std::path::PathBuf;
  3. use aya_tool::{bindgen, write_to_file};
  4. use crate::codegen::{Architecture, Options};
  5. pub fn codegen(opts: &Options) -> Result<(), anyhow::Error> {
  6. codegen_internal_btf_bindings(opts)?;
  7. codegen_bindings(opts)
  8. }
  9. fn codegen_internal_btf_bindings(opts: &Options) -> Result<(), anyhow::Error> {
  10. let dir = PathBuf::from("aya");
  11. let generated = dir.join("src/generated");
  12. let mut bindgen = bindgen::user_builder()
  13. .clang_arg(format!(
  14. "-I{}",
  15. opts.libbpf_dir
  16. .join("include/uapi")
  17. .canonicalize()
  18. .unwrap()
  19. .to_string_lossy()
  20. ))
  21. .clang_arg(format!(
  22. "-I{}",
  23. opts.libbpf_dir
  24. .join("include")
  25. .canonicalize()
  26. .unwrap()
  27. .to_string_lossy()
  28. ))
  29. .header(
  30. opts.libbpf_dir
  31. .join("src/libbpf_internal.h")
  32. .to_string_lossy(),
  33. )
  34. .constified_enum_module("bpf_core_relo_kind");
  35. let types = ["bpf_core_relo", "btf_ext_header"];
  36. for x in &types {
  37. bindgen = bindgen.allowlist_type(x);
  38. }
  39. let bindings = bindgen
  40. .generate()
  41. .map_err(|_| anyhow!("bindgen failed"))?
  42. .to_string();
  43. // write the bindings, with the original helpers removed
  44. write_to_file(&generated.join("btf_internal_bindings.rs"), &bindings)?;
  45. Ok(())
  46. }
  47. fn codegen_bindings(opts: &Options) -> Result<(), anyhow::Error> {
  48. let types = [
  49. // BPF
  50. "BPF_TYPES",
  51. "bpf_cmd",
  52. "bpf_insn",
  53. "bpf_attr",
  54. "bpf_map_type",
  55. "bpf_prog_type",
  56. "bpf_attach_type",
  57. "bpf_prog_info",
  58. "bpf_map_info",
  59. "bpf_link_info",
  60. "bpf_btf_info",
  61. "bpf_func_info",
  62. "bpf_line_info",
  63. "bpf_lpm_trie_key",
  64. // BTF
  65. "btf_header",
  66. "btf_ext_info",
  67. "btf_ext_info_sec",
  68. "btf_type",
  69. "btf_enum",
  70. "btf_array",
  71. "btf_member",
  72. "btf_param",
  73. "btf_var",
  74. "btf_var_secinfo",
  75. "btf_func_linkage",
  76. "btf_decl_tag",
  77. // PERF
  78. "perf_event_attr",
  79. "perf_sw_ids",
  80. "perf_hw_id",
  81. "perf_hw_cache_id",
  82. "perf_hw_cache_op_id",
  83. "perf_hw_cache_op_result_id",
  84. "perf_event_sample_format",
  85. "perf_event_mmap_page",
  86. "perf_event_header",
  87. "perf_type_id",
  88. "perf_event_type",
  89. // NETLINK
  90. "ifinfomsg",
  91. "tcmsg",
  92. ];
  93. let vars = [
  94. // BPF
  95. "BPF_PSEUDO_.*",
  96. "BPF_ALU",
  97. "BPF_ALU64",
  98. "BPF_LDX",
  99. "BPF_ST",
  100. "BPF_STX",
  101. "BPF_LD",
  102. "BPF_K",
  103. "BPF_DW",
  104. "BPF_W",
  105. "BPF_H",
  106. "BPF_B",
  107. "BPF_F_.*",
  108. "BPF_JMP",
  109. "BPF_CALL",
  110. "SO_ATTACH_BPF",
  111. "SO_DETACH_BPF",
  112. // BTF
  113. "BTF_INT_.*",
  114. "BTF_KIND_.*",
  115. "BTF_VAR_.*",
  116. // PERF
  117. "PERF_FLAG_.*",
  118. "PERF_EVENT_.*",
  119. "PERF_MAX_.*",
  120. // see linux_wrapper.h, these are to workaround the IOC macros
  121. "AYA_PERF_EVENT_.*",
  122. // NETLINK
  123. "NLMSG_ALIGNTO",
  124. "IFLA_XDP_FD",
  125. "TCA_KIND",
  126. "TCA_OPTIONS",
  127. "TCA_BPF_FD",
  128. "TCA_BPF_NAME",
  129. "TCA_BPF_FLAGS",
  130. "TCA_BPF_FLAG_ACT_DIRECT",
  131. "XDP_FLAGS_.*",
  132. "TC_H_MAJ_MASK",
  133. "TC_H_MIN_MASK",
  134. "TC_H_UNSPEC",
  135. "TC_H_ROOT",
  136. "TC_H_INGRESS",
  137. "TC_H_CLSACT",
  138. "TC_H_MIN_PRIORITY",
  139. "TC_H_MIN_INGRESS",
  140. "TC_H_MIN_EGRESS",
  141. // Ringbuf
  142. "BPF_RINGBUF_.*",
  143. ];
  144. let dir = PathBuf::from("aya");
  145. let generated = dir.join("src/generated");
  146. let builder = || {
  147. bindgen::user_builder()
  148. .header(dir.join("include/linux_wrapper.h").to_string_lossy())
  149. .clang_args(&[
  150. "-I",
  151. &*opts.libbpf_dir.join("include/uapi").to_string_lossy(),
  152. ])
  153. .clang_args(&["-I", &*opts.libbpf_dir.join("include").to_string_lossy()])
  154. };
  155. for arch in Architecture::supported() {
  156. let mut bindgen = builder();
  157. // Set target triple. This will set the right flags (which you can see
  158. // running clang -target=X -E - -dM </dev/null)
  159. let target = match arch {
  160. Architecture::X86_64 => "x86_64-unknown-linux-gnu",
  161. Architecture::ARMv7 => "armv7-unknown-linux-gnu",
  162. Architecture::AArch64 => "aarch64-unknown-linux-gnu",
  163. Architecture::RISCV64 => "riscv64-unknown-linux-gnu",
  164. };
  165. bindgen = bindgen.clang_args(&["-target", target]);
  166. // Set the sysroot. This is needed to ensure that the correct arch
  167. // specific headers are imported.
  168. let sysroot = match arch {
  169. Architecture::X86_64 => &opts.x86_64_sysroot,
  170. Architecture::ARMv7 => &opts.armv7_sysroot,
  171. Architecture::AArch64 => &opts.aarch64_sysroot,
  172. Architecture::RISCV64 => &opts.riscv64_sysroot,
  173. };
  174. bindgen = bindgen.clang_args(&["-I", &*sysroot.to_string_lossy()]);
  175. for x in &types {
  176. bindgen = bindgen.allowlist_type(x);
  177. }
  178. for x in &vars {
  179. bindgen = bindgen
  180. .allowlist_var(x)
  181. .constified_enum("BPF_F_.*")
  182. .constified_enum("BTF_KIND_.*")
  183. .constified_enum("BTF_VAR_.*")
  184. .constified_enum("IFLA_.*")
  185. .constified_enum("TCA_.*")
  186. .constified_enum("BPF_RINGBUF_.*");
  187. }
  188. for x in &types {
  189. bindgen = bindgen.allowlist_type(x);
  190. }
  191. for x in &vars {
  192. bindgen = bindgen.allowlist_var(x);
  193. }
  194. let bindings = bindgen
  195. .generate()
  196. .map_err(|_| anyhow!("bindgen failed"))?
  197. .to_string();
  198. // write the bindings, with the original helpers removed
  199. write_to_file(
  200. &generated.join(format!("linux_bindings_{}.rs", arch)),
  201. &bindings.to_string(),
  202. )?;
  203. }
  204. Ok(())
  205. }