diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index fa79decf..39725e84 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -18,7 +18,7 @@ jobs: fail-fast: false matrix: rust: - - "1.63.0" + - "stable" - "beta" - "nightly" llvm: ["15", "rustc"] @@ -75,6 +75,15 @@ jobs: sudo apt-get update sudo apt-get install llvm-${{ matrix.llvm }}-dev libclang-${{ matrix.llvm }}-dev + - name: Install LLVM tools + if: matrix.llvm == 'rustc' + shell: bash + run: | + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + echo -e "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main\n" | sudo tee /etc/apt/sources.list.d/llvm.list + sudo apt-get update + sudo apt-get install llvm-15-tools + - name: Build run: cargo build --verbose ${CARGO_ARGS} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e61d7736..e53b86a0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,7 +14,24 @@ env: CARGO_TERM_COLOR: always jobs: - lint: + lint-stable: + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v2 + + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + components: clippy, rust-src + override: true + + - name: Run clippy + run: | + cargo clippy --workspace -- --deny warnings + + lint-nightly: runs-on: ubuntu-20.04 steps: @@ -24,12 +41,9 @@ jobs: with: profile: minimal toolchain: nightly - components: rustfmt, clippy, miri, rust-src + components: rustfmt, rust-src override: true - name: Check formatting run: | cargo fmt --all -- --check - - name: Run clippy - run: | - cargo clippy --workspace -- --deny warnings diff --git a/Cargo.lock b/Cargo.lock index 8c2b3df0..9abb3eea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -153,39 +153,37 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.22" +version = "4.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" +checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", - "indexmap", "once_cell", "strsim", "termcolor", - "textwrap", ] [[package]] name = "clap_derive" -version = "3.2.18" +version = "4.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.38", + "proc-macro2 1.0.49", "quote 1.0.18", "syn 1.0.94", ] [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" dependencies = [ "os_str_bytes", ] @@ -238,9 +236,9 @@ dependencies = [ [[package]] name = "either" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "failure" @@ -258,7 +256,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 1.0.38", + "proc-macro2 1.0.49", "quote 1.0.18", "syn 1.0.94", "synstructure", @@ -302,12 +300,6 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "heck" version = "0.4.0" @@ -323,16 +315,6 @@ dependencies = [ "libc", ] -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "itoa" version = "1.0.2" @@ -454,7 +436,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.38", + "proc-macro2 1.0.49", "quote 1.0.18", "syn 1.0.94", "version_check", @@ -466,7 +448,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.38", + "proc-macro2 1.0.49", "quote 1.0.18", "version_check", ] @@ -482,11 +464,11 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.38" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" dependencies = [ - "unicode-xid 0.2.3", + "unicode-ident", ] [[package]] @@ -504,7 +486,7 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ - "proc-macro2 1.0.38", + "proc-macro2 1.0.49", ] [[package]] @@ -605,7 +587,7 @@ version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ - "proc-macro2 1.0.38", + "proc-macro2 1.0.49", "quote 1.0.18", "syn 1.0.94", ] @@ -655,7 +637,7 @@ version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a" dependencies = [ - "proc-macro2 1.0.38", + "proc-macro2 1.0.49", "quote 1.0.18", "unicode-xid 0.2.3", ] @@ -666,7 +648,7 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.38", + "proc-macro2 1.0.49", "quote 1.0.18", "syn 1.0.94", "unicode-xid 0.2.3", @@ -702,12 +684,6 @@ dependencies = [ "term", ] -[[package]] -name = "textwrap" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" - [[package]] name = "thiserror" version = "1.0.31" @@ -723,7 +699,7 @@ version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ - "proc-macro2 1.0.38", + "proc-macro2 1.0.49", "quote 1.0.18", "syn 1.0.94", ] @@ -738,6 +714,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + [[package]] name = "unicode-width" version = "0.1.9" @@ -770,13 +752,13 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "which" -version = "4.2.5" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" dependencies = [ "either", - "lazy_static", "libc", + "once_cell", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0b0c3e54..3e197c4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ edition = "2021" [dependencies] # cli deps -clap = { version = "3.2", optional = true, features = ["derive"] } +clap = { version = "4.0", optional = true, features = ["derive"] } simplelog = {version = "0.7.6", optional = true} # lib deps diff --git a/src/bin/bpf-linker.rs b/src/bin/bpf-linker.rs index 23e9f527..e9339565 100644 --- a/src/bin/bpf-linker.rs +++ b/src/bin/bpf-linker.rs @@ -6,8 +6,13 @@ extern crate aya_rustc_llvm_proxy; use clap::Parser; use log::*; use simplelog::{Config, LevelFilter, SimpleLogger, TermLogger, TerminalMode, WriteLogger}; -use std::{collections::HashSet, env, fs::File, str::FromStr}; -use std::{fs, path::PathBuf}; +use std::{ + collections::HashSet, + env, + fs::{self, File}, + path::PathBuf, + str::FromStr, +}; use thiserror::Error; use bpf_linker::{Cpu, Linker, LinkerOptions, OptLevel, OutputType}; @@ -86,7 +91,7 @@ struct CommandLine { libs: Vec, /// Optimization level. 0-3, s, or z - #[clap(short = 'O', default_value = "2", multiple = true)] + #[clap(short = 'O', default_value = "2")] optimize: Vec, /// Export the symbols specified in the file `path`. The symbols must be separated by new lines @@ -114,7 +119,7 @@ struct CommandLine { dump_module: Option, /// Extra command line arguments to pass to LLVM - #[clap(long, value_name = "args", use_delimiter = true, multiple = true)] + #[clap(long, value_name = "args", use_value_delimiter = true, action = clap::ArgAction::Append)] llvm_args: Vec, /// Disable passing --bpf-expand-memcpy-in-order to LLVM. @@ -132,30 +137,30 @@ struct CommandLine { // The options below are for wasm-ld compatibility /// Comma separated list of symbols to export. See also `--export-symbols` - #[clap(long, value_name = "symbols", use_delimiter = true, multiple = true)] + #[clap(long, value_name = "symbols", use_value_delimiter = true, action = clap::ArgAction::Append)] export: Vec, #[clap( short = 'l', long = "lib", - use_delimiter = true, - multiple = true, - hidden = true + use_value_delimiter = true, + action = clap::ArgAction::Append, + hide = true )] _lib: Option, - #[clap(long = "debug", hidden = true)] + #[clap(long = "debug", hide = true)] _debug: bool, - #[clap(long = "rsp-quoting", hidden = true)] + #[clap(long = "rsp-quoting", hide = true)] _rsp_quoting: Option, - #[clap(long = "flavor", hidden = true)] + #[clap(long = "flavor", hide = true)] _flavor: Option, - #[clap(long = "no-entry", hidden = true)] + #[clap(long = "no-entry", hide = true)] _no_entry: bool, - #[clap(long = "gc-sections", hidden = true)] + #[clap(long = "gc-sections", hide = true)] _gc_sections: bool, - #[clap(long = "strip-debug", hidden = true)] + #[clap(long = "strip-debug", hide = true)] _strip_debug: bool, - #[clap(long = "strip-all", hidden = true)] + #[clap(long = "strip-all", hide = true)] _strip_all: bool, } @@ -167,10 +172,10 @@ fn main() { arg } }); - let cli = CommandLine::from_iter(args); + let cli = CommandLine::parse_from(args); if cli.inputs.is_empty() { - error("no input files", clap::ErrorKind::TooFewValues); + error("no input files", clap::error::ErrorKind::TooFewValues); } let env_log_level = match env::var("RUST_LOG") { @@ -178,7 +183,7 @@ fn main() { Ok(l) => Some(l), Err(e) => error( &format!("invalid RUST_LOG value: {}", e), - clap::ErrorKind::InvalidValue, + clap::error::ErrorKind::InvalidValue, ), }, _ => None, @@ -190,7 +195,7 @@ fn main() { Err(e) => { error( &format!("failed to open log file: {:?}", e), - clap::ErrorKind::Io, + clap::error::ErrorKind::Io, ); } }; @@ -231,7 +236,7 @@ fn main() { .map(|s| s.to_string()) .collect::>(), Err(e) => { - error(&e.to_string(), clap::ErrorKind::Io); + error(&e.to_string(), clap::error::ErrorKind::Io); } }) .unwrap_or_else(HashSet::new); @@ -256,10 +261,84 @@ fn main() { }; if let Err(e) = Linker::new(options).link() { - error(&e.to_string(), clap::ErrorKind::Io); + error(&e.to_string(), clap::error::ErrorKind::Io); } } -fn error(desc: &str, kind: clap::ErrorKind) -> ! { - clap::Error::with_description(desc.to_string(), kind).exit(); +fn error(desc: &str, kind: clap::error::ErrorKind) -> ! { + clap::Error::raw(kind, desc.to_string()).exit(); +} + +#[cfg(test)] +mod test { + use super::*; + + // Test made to reproduce the following bug: + // https://github.com/aya-rs/bpf-linker/issues/27 + // where --export argument followed by positional arguments resulted in + // parsing the positional args as `export`, not as `inputs`. + // There can be multiple exports, but they always have to be preceded by + // `--export` flag. + #[test] + fn test_export_input_args() { + let args = vec![ + "bpf-linker", + "--export", + "foo", + "--export", + "bar", + "symbols.o", // this should be parsed as `input`, not `export` + "rcgu.o", // this should be parsed as `input`, not `export` + "-L", + "target/debug/deps", + "-L", + "target/debug", + "-L", + "/home/foo/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib", + "-o", + "/tmp/bin.s", + "--target=bpf", + "--emit=asm", + ]; + let cli = CommandLine::parse_from(args); + assert_eq!(cli.export, vec!["foo", "bar"]); + assert_eq!( + cli.inputs, + vec![PathBuf::from("symbols.o"), PathBuf::from("rcgu.o")] + ); + } + + #[test] + fn test_export_delimiter() { + let args = vec![ + "bpf-linker", + "--export", + "foo,bar", + "--export=ayy,lmao", + "symbols.o", // this should be parsed as `input`, not `export` + "--export=lol", + "--export", + "rotfl", + "rcgu.o", // this should be parsed as `input`, not `export` + "-L", + "target/debug/deps", + "-L", + "target/debug", + "-L", + "/home/foo/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib", + "-o", + "/tmp/bin.s", + "--target=bpf", + "--emit=asm", + ]; + let cli = CommandLine::parse_from(args); + assert_eq!( + cli.export, + vec!["foo", "bar", "ayy", "lmao", "lol", "rotfl"] + ); + assert_eq!( + cli.inputs, + vec![PathBuf::from("symbols.o"), PathBuf::from("rcgu.o")] + ); + } } diff --git a/src/llvm/mod.rs b/src/llvm/mod.rs index 79d48bf6..fdc3520e 100644 --- a/src/llvm/mod.rs +++ b/src/llvm/mod.rs @@ -66,7 +66,7 @@ pub unsafe fn find_embedded_bitcode( let buffer_name = CString::new("mem_buffer").unwrap(); let buffer = LLVMCreateMemoryBufferWithMemoryRange( data.as_ptr() as *const libc_char, - data.len() as usize, + data.len(), buffer_name.as_ptr(), 0, ); @@ -109,7 +109,7 @@ pub unsafe fn link_bitcode_buffer( let buffer_name = CString::new("mem_buffer").unwrap(); let buffer = LLVMCreateMemoryBufferWithMemoryRange( buffer.as_ptr() as *const libc_char, - buffer.len() as usize, + buffer.len(), buffer_name.as_ptr(), 0, ); diff --git a/tests/tests.rs b/tests/tests.rs index 9882fa0b..e114ebfa 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -19,7 +19,7 @@ fn run_mode(mode: &'static str) { config.target_rustcflags = Some(rustc_flags); if let Ok(filecheck) = which("FileCheck") { config.llvm_filecheck = Some(filecheck) - } else if let Ok(filecheck) = which("FileCheck-12") { + } else if let Ok(filecheck) = which("FileCheck-15") { config.llvm_filecheck = Some(filecheck) } else { panic!("no FileCheck binary found");