Add a bundler module for parsing exported symbols
We can use this to detect which plugin formats are supported by a plugin. Otherwise the bundler would be very awkward to use when supporting multiple formats.
This commit is contained in:
parent
fefc2de9ba
commit
d39ebb5b51
38
Cargo.lock
generated
38
Cargo.lock
generated
|
@ -400,6 +400,17 @@ dependencies = [
|
||||||
"xml-rs",
|
"xml-rs",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "goblin"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c955ab4e0ad8c843ea653a3d143048b87490d9be56bd7132a435c2407846ac8f"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"plain",
|
||||||
|
"scroll",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -665,6 +676,12 @@ version = "0.3.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plain"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.36"
|
version = "1.0.36"
|
||||||
|
@ -728,6 +745,26 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scroll"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da"
|
||||||
|
dependencies = [
|
||||||
|
"scroll_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scroll_derive"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bdbda6ac5cd1321e724fa9cee216f3a61885889b896f073b8f82322789c5250e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.136"
|
version = "1.0.136"
|
||||||
|
@ -1118,6 +1155,7 @@ name = "xtask"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"goblin",
|
||||||
"serde",
|
"serde",
|
||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,5 +7,6 @@ license = "ISC"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
goblin = "0.5"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
|
|
|
@ -5,6 +5,8 @@ use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
|
mod symbols;
|
||||||
|
|
||||||
const USAGE_STRING: &str =
|
const USAGE_STRING: &str =
|
||||||
"Usage: cargo xtask bundle <package> [--release] [--target <triple>] [--bundle-vst3]";
|
"Usage: cargo xtask bundle <package> [--release] [--target <triple>] [--bundle-vst3]";
|
||||||
|
|
||||||
|
|
31
xtask/src/symbols.rs
Normal file
31
xtask/src/symbols.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
use anyhow::{bail, Context, Result};
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
/// Check whether a binary exports the specified symbol. Used to detect the plugin formats supported
|
||||||
|
/// by a plugin library. Returns an error if the binary cuuld not be read. This function will also
|
||||||
|
/// parse non-native binaries.
|
||||||
|
pub fn exported<P: AsRef<Path>>(binary: P, symbol: &str) -> Result<bool> {
|
||||||
|
// Parsing the raw binary instead of relying on nm-like tools makes cross compiling a bit easier
|
||||||
|
let bytes = fs::read(&binary)
|
||||||
|
.with_context(|| format!("Could not read '{}'", binary.as_ref().display()))?;
|
||||||
|
match goblin::Object::parse(&bytes)? {
|
||||||
|
goblin::Object::Elf(obj) => Ok(obj.dynsyms.iter().any(|sym| {
|
||||||
|
!sym.is_import()
|
||||||
|
&& sym.is_function()
|
||||||
|
&& obj.dynstrtab.get_at(sym.st_name) == Some(symbol)
|
||||||
|
})),
|
||||||
|
goblin::Object::Mach(obj) => {
|
||||||
|
let obj = match obj {
|
||||||
|
goblin::mach::Mach::Fat(arches) => arches
|
||||||
|
.get(0)
|
||||||
|
.context("Fat Mach-O binary without any binaries")?,
|
||||||
|
goblin::mach::Mach::Binary(obj) => obj,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(obj.exports()?.into_iter().any(|sym| sym.name == symbol))
|
||||||
|
}
|
||||||
|
goblin::Object::PE(obj) => Ok(obj.exports.iter().any(|sym| sym.name == Some(symbol))),
|
||||||
|
obj => bail!("Unsupported object type: {:?}", obj),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue