-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the unstable option to reduce the binary size of dynamic library …
…based on service requirements
- Loading branch information
1 parent
317d14a
commit 32549d4
Showing
6 changed files
with
232 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; | ||
use rustc_hir::def_id::DefId; | ||
use rustc_middle::ty::TyCtxt; | ||
|
||
pub(super) fn process<'tcx>( | ||
tcx: TyCtxt<'tcx>, | ||
symbol: String, | ||
def_id: DefId, | ||
) -> String { | ||
let crate_name = tcx.crate_name(def_id.krate); | ||
let crate_name = crate_name.as_str(); | ||
let symbol_mangling_plugin = &tcx.sess.opts.unstable_opts.symbol_mangling_plugin; | ||
if !symbol_mangling_plugin.hasher_contains(crate_name) { | ||
return symbol; | ||
} | ||
|
||
let (salt, level) = symbol_mangling_plugin.hasher_args(); | ||
|
||
let hash = tcx.with_stable_hashing_context(|mut hcx| { | ||
let mut hasher = StableHasher::new(); | ||
symbol.hash_stable(&mut hcx, &mut hasher); | ||
salt.hash_stable(&mut hcx, &mut hasher); | ||
hasher.finish::<Hash64>().as_u64() | ||
}); | ||
|
||
match level { | ||
1 => encode_1(tcx, crate_name, hash, def_id), | ||
_ => encode_2(tcx, crate_name, hash, def_id), | ||
} | ||
} | ||
|
||
fn encode_1<'tcx>( | ||
tcx: TyCtxt<'tcx>, | ||
crate_name: &str, | ||
hash: u64, | ||
def_id: DefId, | ||
) -> String { | ||
if let Some(item_name) = tcx.opt_item_name(def_id) { | ||
let item_name = item_name.as_str(); | ||
format!("_ZN{}{crate_name}.{item_name}.{:08x}E", crate_name.len() + item_name.len() + 11, hash >> 8) | ||
} else { | ||
encode_2(tcx, crate_name, hash, def_id) | ||
} | ||
} | ||
|
||
fn encode_2<'tcx>( | ||
_tcx: TyCtxt<'tcx>, | ||
crate_name: &str, | ||
hash: u64, | ||
_def_id: DefId, | ||
) -> String { | ||
format!("_ZN{}{crate_name}.{hash:016x}E", crate_name.len() + 18) | ||
} |
20 changes: 20 additions & 0 deletions
20
src/doc/unstable-book/src/compiler-flags/symbol_mangling_plugin.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# `symbol_mangling_plugin` | ||
|
||
Instead of defining a new mangling rule, it provides a plug-in for reprocessing mangling symbol names. | ||
|
||
The average length of symbol names in the rust standard library is about 100 bytes, while the average length of symbol names in the C++ standard library is about 65 bytes. In some embedded environments where dynamic library are widely used, rust dynamic library symbol name space hash become one of the key bottlenecks of application. The plug-in mechanism provided here can help us eliminate this bottlenech. | ||
|
||
The plug-in information is not written into the generated binary file. Therefore, you need to ensure that the plug-in configuration is consistent in multiple build environments. For example, the configuration parameters of the plug-in must be consistent in the build project of the dynamic library and the build project that depends on the dynamic library. Otherwise, an `undefined symbol` or `undefined version` error occurs. | ||
|
||
The value of this parameter is in the format of `-Z symbol_mangling_plugin=<plugin name>:<plugin arguments>`. Currently only one plug-in is available: `hasher`. | ||
|
||
## Hasher plug-in | ||
|
||
The configuration format is `-Z symbol_mangling_plugin=hasher:<crate>[*],...[,excluded=true|false][,level=1|2][,salt=<value>]`. | ||
|
||
In the preceding information, `<crate>` matches the name of the crate. If the name ends with `*`, the prefix is matched. The hasher plug-in only reprocesses the symbol names in (or not in, if `excluded=true`) specified crate. The hasher plug-in uses the hash value to replace the complete symbol names, compressing the symbol name space and avoid symbol conflicts. | ||
|
||
If `level=`, the new symbol name format is `_ZN{length}{crate}.{item}.{hash32}E`. Otherwise, the new symbol name format is `_ZN{length}{crate}.{hash64}E`, which is the default format. | ||
|
||
`salt` can specify a salt value for hash calculation, which reduces security risks caused by malicious replacement of dynamic libraries and increases security. | ||
|