From 32742df1b4d1d85c45e34645984c45941ce3356c Mon Sep 17 00:00:00 2001 From: Dmitri Makarov Date: Sat, 12 Jun 2021 19:54:44 -0700 Subject: [PATCH] Add build script to extract a list of registered syscalls The list is used in cargo-build-bpf to check generated .so modules for undefined symbols that are not known run-time syscalls. --- Cargo.lock | 1 + programs/bpf/Cargo.lock | 1 + programs/bpf_loader/Cargo.toml | 3 +++ programs/bpf_loader/build.rs | 34 ++++++++++++++++++++++++++++++ sdk/bpf/.gitignore | 1 + sdk/cargo-build-bpf/src/main.rs | 37 ++++++++++----------------------- 6 files changed, 51 insertions(+), 26 deletions(-) create mode 100644 programs/bpf_loader/build.rs diff --git a/Cargo.lock b/Cargo.lock index 2f74809d2..c6d4ba767 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4314,6 +4314,7 @@ dependencies = [ "num-traits", "rand 0.7.3", "rand_core 0.6.2", + "regex", "rustversion", "sha3", "solana-measure", diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index cfe47b368..1971f2485 100644 --- a/programs/bpf/Cargo.lock +++ b/programs/bpf/Cargo.lock @@ -2792,6 +2792,7 @@ dependencies = [ "num-derive", "num-traits", "rand_core 0.6.2", + "regex", "sha3", "solana-measure", "solana-runtime", diff --git a/programs/bpf_loader/Cargo.toml b/programs/bpf_loader/Cargo.toml index a72ff6d2a..c22063dd8 100644 --- a/programs/bpf_loader/Cargo.toml +++ b/programs/bpf_loader/Cargo.toml @@ -9,6 +9,9 @@ homepage = "https://solana.com/" documentation = "https://docs.rs/solana-bpf-loader-program" edition = "2018" +[build-dependencies] +regex = "1.5.4" + [dependencies] bincode = "1.3.1" byteorder = "1.3.4" diff --git a/programs/bpf_loader/build.rs b/programs/bpf_loader/build.rs new file mode 100644 index 000000000..38d5e942a --- /dev/null +++ b/programs/bpf_loader/build.rs @@ -0,0 +1,34 @@ +use regex::Regex; +use std::{ + fs::File, + io::{prelude::*, BufWriter, Read}, + path::PathBuf, + process::exit, + str, +}; + +/** + * Extract a list of registered syscall names and save it in a file + * for distribution with the SDK. This file is read by cargo-build-bpf + * to verify undefined symbols in a .so module that cargo-build-bpf has built. + */ +fn main() { + let path = PathBuf::from("src/syscalls.rs"); + let mut file = match File::open(&path) { + Ok(x) => x, + _ => exit(1), + }; + let mut text = vec![]; + file.read_to_end(&mut text).unwrap(); + let text = str::from_utf8(&text).unwrap(); + let path = PathBuf::from("../../sdk/bpf/syscalls.txt"); + let file = match File::create(&path) { + Ok(x) => x, + _ => exit(1), + }; + let mut out = BufWriter::new(file); + let sysc_re = Regex::new(r#"register_syscall_by_name\([[:space:]]*b"([^"]+)","#).unwrap(); + for caps in sysc_re.captures_iter(&text) { + writeln!(out, "{}", caps[1].to_string()).unwrap(); + } +} diff --git a/sdk/bpf/.gitignore b/sdk/bpf/.gitignore index beaddb4ca..469fb6c5c 100644 --- a/sdk/bpf/.gitignore +++ b/sdk/bpf/.gitignore @@ -7,3 +7,4 @@ /dependencies/bin* /dependencies/.crates.toml /dependencies/.crates2.json +/syscalls.txt diff --git a/sdk/cargo-build-bpf/src/main.rs b/sdk/cargo-build-bpf/src/main.rs index 9d8918562..974b3a740 100644 --- a/sdk/cargo-build-bpf/src/main.rs +++ b/sdk/cargo-build-bpf/src/main.rs @@ -250,32 +250,17 @@ fn postprocess_dump(program_dump: &Path) { // Check whether the built .so file contains undefined symbols that are // not known to the runtime and warn about them if any. fn check_undefined_symbols(config: &Config, program: &Path) { - let syscalls: HashSet = [ - "abort", - "sol_panic_", - "sol_log_", - "sol_log_64_", - "sol_log_compute_units_", - "sol_log_pubkey", - "sol_create_program_address", - "sol_try_find_program_address", - "sol_sha256", - "sol_keccak256", - "sol_get_clock_sysvar", - "sol_get_epoch_schedule_sysvar", - "sol_get_fees_sysvar", - "sol_get_rent_sysvar", - "sol_memcpy_", - "sol_memmove_", - "sol_memcmp_", - "sol_memset_", - "sol_invoke_signed_c", - "sol_invoke_signed_rust", - "sol_alloc_free_", - ] - .iter() - .map(|&symbol| symbol.to_owned()) - .collect(); + let syscalls_txt = config.bpf_sdk.join("syscalls.txt"); + let file = match File::open(syscalls_txt) { + Ok(x) => x, + _ => return, + }; + let mut syscalls = HashSet::new(); + for line_result in BufReader::new(file).lines() { + let line = line_result.unwrap(); + let line = line.trim_end(); + syscalls.insert(line.to_string()); + } let entry = Regex::new(r"^ *[0-9]+: [0-9a-f]{16} +[0-9a-f]+ +NOTYPE +GLOBAL +DEFAULT +UND +(.+)") .unwrap();