Skip to content

Commit

Permalink
Check for undefined symbols in .so and warn about run-time errors (so…
Browse files Browse the repository at this point in the history
…lana-labs#17850) (solana-labs#17880)

(cherry picked from commit c684e2b)

Co-authored-by: Dmitri Makarov <dmakarov@users.noreply.github.com>
  • Loading branch information
mergify[bot] and dmakarov authored Jun 11, 2021
1 parent 120a7e4 commit af2a610
Showing 1 changed file with 68 additions and 1 deletion.
69 changes: 68 additions & 1 deletion sdk/cargo-build-bpf/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use {
solana_download_utils::download_file,
solana_sdk::signature::{write_keypair_file, Keypair},
std::{
collections::HashMap,
collections::{HashMap, HashSet},
env,
ffi::OsStr,
fs::{self, File},
Expand Down Expand Up @@ -250,6 +250,71 @@ fn postprocess_dump(program_dump: &Path) {
fs::rename(postprocessed_dump, program_dump).unwrap();
}

// 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<String> = [
"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 entry =
Regex::new(r"^ *[0-9]+: [0-9a-f]{16} +[0-9a-f]+ +NOTYPE +GLOBAL +DEFAULT +UND +(.+)")
.unwrap();
let readelf = config
.bpf_sdk
.join("dependencies")
.join("bpf-tools")
.join("llvm")
.join("bin")
.join("llvm-readelf");
let mut readelf_args = vec!["--dyn-symbols"];
readelf_args.push(program.to_str().unwrap());
let output = spawn(&readelf, &readelf_args);
if config.verbose {
println!("{}", output);
}
let mut unresolved_symbols: Vec<String> = Vec::new();
for line in output.lines() {
let line = line.trim_end();
if entry.is_match(line) {
let captures = entry.captures(line).unwrap();
let symbol = captures[1].to_string();
if !syscalls.contains(&symbol) {
unresolved_symbols.push(symbol);
}
}
}
if !unresolved_symbols.is_empty() {
println!(
"Warning: the following functions are undefined and not known syscalls {:?}.",
unresolved_symbols
);
println!(" Calling them will trigger a run-time error.");
}
}

// check whether custom BPF toolchain is linked, and link it if it is not.
fn link_bpf_toolchain(config: &Config) {
let toolchain_path = config
Expand Down Expand Up @@ -457,6 +522,8 @@ fn build_bpf_package(config: &Config, target_directory: &Path, package: &cargo_m
postprocess_dump(&program_dump);
}

check_undefined_symbols(&config, &program_so);

println!();
println!("To deploy this program:");
println!(" $ solana program deploy {}", program_so.display());
Expand Down

0 comments on commit af2a610

Please sign in to comment.