|
| 1 | +use std::collections::HashSet; |
1 | 2 | use std::env;
|
2 | 3 | use std::fmt::Write;
|
3 | 4 | use std::path::{Path, PathBuf};
|
@@ -41,21 +42,40 @@ impl Archive {
|
41 | 42 | Ok(symbols)
|
42 | 43 | }
|
43 | 44 |
|
44 |
| - pub fn retain_symbols<'a>(&self, symbols: impl Iterator<Item = &'a str>) -> Result<()> { |
| 45 | + pub fn retain_symbols(&self, mut exported_symbols: HashSet<&str>) -> Result<()> { |
45 | 46 | let sh = crate::sh()?;
|
46 | 47 | let archive = self.as_ref();
|
47 |
| - let prefix = archive.file_stem().unwrap().to_str().unwrap(); |
48 |
| - |
49 |
| - let symbol_renames = symbols.fold(String::new(), |mut output, symbol| { |
50 |
| - let _ = writeln!(output, "{prefix}_{symbol} {symbol}"); |
51 |
| - output |
52 |
| - }); |
| 48 | + let prefix = { |
| 49 | + let file_stem = archive.file_stem().unwrap().to_str().unwrap(); |
| 50 | + file_stem.strip_prefix("lib").unwrap_or(file_stem) |
| 51 | + }; |
| 52 | + |
| 53 | + let all_symbols = { |
| 54 | + let nm = binutil("nm")?; |
| 55 | + let stdout = cmd!(sh, "{nm} --export-symbols {archive}").output()?.stdout; |
| 56 | + String::from_utf8(stdout)? |
| 57 | + }; |
| 58 | + |
| 59 | + let symbol_renames = all_symbols |
| 60 | + .lines() |
| 61 | + .fold(String::new(), |mut output, symbol| { |
| 62 | + if exported_symbols.remove(symbol) { |
| 63 | + return output; |
| 64 | + } |
| 65 | + |
| 66 | + if let Some(symbol) = symbol.strip_prefix("_ZN") { |
| 67 | + let prefix_len = prefix.len(); |
| 68 | + let _ = writeln!(output, "_ZN{symbol} _ZN{prefix_len}{prefix}{symbol}",); |
| 69 | + } else { |
| 70 | + let _ = writeln!(output, "{symbol} {prefix}_{symbol}"); |
| 71 | + } |
| 72 | + output |
| 73 | + }); |
53 | 74 |
|
54 | 75 | let rename_path = archive.with_extension("redefine-syms");
|
55 | 76 | sh.write_file(&rename_path, symbol_renames)?;
|
56 | 77 |
|
57 | 78 | let objcopy = binutil("objcopy")?;
|
58 |
| - cmd!(sh, "{objcopy} --prefix-symbols={prefix}_ {archive}").run()?; |
59 | 79 | cmd!(sh, "{objcopy} --redefine-syms={rename_path} {archive}").run()?;
|
60 | 80 |
|
61 | 81 | sh.remove_path(&rename_path)?;
|
|
0 commit comments