Skip to content

Commit 668b208

Browse files
committed
Add symbol prefixing feature for BoringSSL
1 parent 75ef523 commit 668b208

File tree

5 files changed

+113
-0
lines changed

5 files changed

+113
-0
lines changed

boring-sys/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ pq-experimental = []
6868
# those for `pq-experimental` feature apply.
6969
underscore-wildcards = []
7070

71+
# Add a prefix to all symbols in libcrypto and libssl to prevent conflicts
72+
# with other OpenSSL or BoringSSL versions that might be linked in the same process.
73+
prefix-symbols = []
74+
7175
[build-dependencies]
7276
bindgen = { workspace = true }
7377
cmake = { workspace = true }

boring-sys/build/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub(crate) struct Features {
1919
pub(crate) pq_experimental: bool,
2020
pub(crate) rpk: bool,
2121
pub(crate) underscore_wildcards: bool,
22+
pub(crate) prefix_symbols: bool,
2223
}
2324

2425
pub(crate) struct Env {
@@ -109,12 +110,14 @@ impl Features {
109110
let pq_experimental = env::var_os("CARGO_FEATURE_PQ_EXPERIMENTAL").is_some();
110111
let rpk = env::var_os("CARGO_FEATURE_RPK").is_some();
111112
let underscore_wildcards = env::var_os("CARGO_FEATURE_UNDERSCORE_WILDCARDS").is_some();
113+
let prefix_symbols = env::var_os("CARGO_FEATURE_PREFIX_SYMBOLS").is_some();
112114

113115
Self {
114116
fips,
115117
pq_experimental,
116118
rpk,
117119
underscore_wildcards,
120+
prefix_symbols,
118121
}
119122
}
120123

boring-sys/build/main.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ use std::process::{Command, Output};
99
use std::sync::OnceLock;
1010

1111
use crate::config::Config;
12+
use crate::prefix::{prefix_symbols, PrefixCallback};
1213

1314
mod config;
15+
mod prefix;
1416

1517
fn should_use_cmake_cross_compilation(config: &Config) -> bool {
1618
if config.host == config.target {
@@ -547,6 +549,10 @@ fn built_boring_source_path(config: &Config) -> &PathBuf {
547549
.define("FIPS", "1");
548550
}
549551

552+
if config.features.prefix_symbols {
553+
cfg.define("CMAKE_POSITION_INDEPENDENT_CODE", "ON");
554+
}
555+
550556
cfg.build_target("ssl").build();
551557
cfg.build_target("crypto").build()
552558
})
@@ -574,6 +580,9 @@ fn main() {
574580
if !config.env.docs_rs {
575581
emit_link_directives(&config);
576582
}
583+
if config.features.prefix_symbols {
584+
prefix_symbols(&config);
585+
}
577586
generate_bindings(&config);
578587
}
579588

@@ -668,6 +677,10 @@ fn generate_bindings(config: &Config) {
668677
.clang_arg(sysroot.display().to_string());
669678
}
670679

680+
if config.features.prefix_symbols {
681+
builder = builder.parse_callbacks(Box::new(PrefixCallback));
682+
}
683+
671684
let headers = [
672685
"aes.h",
673686
"asn1_mac.h",

boring-sys/build/prefix.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
use crate::{config::Config, pick_best_android_ndk_toolchain, run_command};
2+
use std::{fs, io::Write, path::PathBuf, process::Command};
3+
4+
// The prefix to add to all symbols
5+
// RBSSL = Rust BoringSSL, chosen arbitrarily to avoid collisions with other projects
6+
const PREFIX: &str = "RBSSL";
7+
8+
// Callback to add a `link_name` macro with the prefix to all generated bindings
9+
#[derive(Debug)]
10+
pub struct PrefixCallback;
11+
12+
impl bindgen::callbacks::ParseCallbacks for PrefixCallback {
13+
fn generated_link_name_override(
14+
&self,
15+
item_info: bindgen::callbacks::ItemInfo<'_>,
16+
) -> Option<String> {
17+
Some(format!("{PREFIX}_{}", item_info.name))
18+
}
19+
}
20+
21+
fn android_toolchain(config: &Config) -> PathBuf {
22+
let mut android_bin_path = config
23+
.env
24+
.android_ndk_home
25+
.clone()
26+
.expect("Please set ANDROID_NDK_HOME for Android build");
27+
android_bin_path.extend(["toolchains", "llvm", "prebuilt"]);
28+
android_bin_path.push(pick_best_android_ndk_toolchain(&android_bin_path).unwrap());
29+
android_bin_path.push("bin");
30+
android_bin_path
31+
}
32+
33+
pub fn prefix_symbols(config: &Config) {
34+
// List static libraries to prefix symbols in
35+
let static_libs: Vec<PathBuf> = [
36+
config.out_dir.join("build"),
37+
config.out_dir.join("build").join("ssl"),
38+
config.out_dir.join("build").join("crypto"),
39+
]
40+
.iter()
41+
.flat_map(|dir| {
42+
["libssl.a", "libcrypto.a"]
43+
.into_iter()
44+
.map(move |file| PathBuf::from(dir).join(file))
45+
})
46+
.filter(|p| p.exists())
47+
.collect();
48+
49+
// Use `nm` to list symbols in these static libraries
50+
let nm = match &*config.target_os {
51+
"android" => android_toolchain(config).join("llvm-nm"),
52+
_ => PathBuf::from("nm"),
53+
};
54+
let out = run_command(Command::new(nm).args(&static_libs)).unwrap();
55+
let mut redefine_syms: Vec<String> = String::from_utf8_lossy(&out.stdout)
56+
.lines()
57+
.filter(|l| {
58+
[" T ", " D ", " B ", " C ", " R ", " W "]
59+
.iter()
60+
.any(|s| l.contains(s))
61+
})
62+
.filter_map(|l| l.split_whitespace().nth(2).map(|s| s.to_string()))
63+
.filter(|l| !l.starts_with("_"))
64+
.map(|l| format!("{l} {PREFIX}_{l}"))
65+
.collect();
66+
redefine_syms.sort();
67+
redefine_syms.dedup();
68+
69+
let redefine_syms_path = config.out_dir.join("redefine_syms.txt");
70+
let mut f = fs::File::create(&redefine_syms_path).unwrap();
71+
for sym in &redefine_syms {
72+
writeln!(f, "{sym}").unwrap();
73+
}
74+
f.flush().unwrap();
75+
76+
// Use `objcopy` to prefix symbols in these static libraries
77+
let objcopy = match &*config.target_os {
78+
"android" => android_toolchain(config).join("llvm-objcopy"),
79+
_ => PathBuf::from("objcopy"),
80+
};
81+
for static_lib in &static_libs {
82+
run_command(
83+
Command::new(&objcopy)
84+
.arg(format!("--redefine-syms={}", redefine_syms_path.display()))
85+
.arg(static_lib),
86+
)
87+
.unwrap();
88+
}
89+
}

boring/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ pq-experimental = ["boring-sys/pq-experimental"]
4444
# those for `pq-experimental` feature apply.
4545
underscore-wildcards = ["boring-sys/underscore-wildcards"]
4646

47+
# Add a prefix to all symbols in libcrypto and libssl to prevent conflicts
48+
# with other OpenSSL or BoringSSL versions that might be linked in the same process.
49+
prefix-symbols = ["boring-sys/prefix-symbols"]
50+
4751
[dependencies]
4852
bitflags = { workspace = true }
4953
foreign-types = { workspace = true }

0 commit comments

Comments
 (0)