diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_proc_macro_srv/src/dylib.rs | 72 |
1 files changed, 35 insertions, 37 deletions
diff --git a/crates/ra_proc_macro_srv/src/dylib.rs b/crates/ra_proc_macro_srv/src/dylib.rs index ec63d587b..7d6e5d323 100644 --- a/crates/ra_proc_macro_srv/src/dylib.rs +++ b/crates/ra_proc_macro_srv/src/dylib.rs | |||
@@ -16,55 +16,53 @@ fn invalid_data_err(e: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> I | |||
16 | IoError::new(IoErrorKind::InvalidData, e) | 16 | IoError::new(IoErrorKind::InvalidData, e) |
17 | } | 17 | } |
18 | 18 | ||
19 | fn get_symbols_from_lib(file: &Path) -> Result<Vec<String>, IoError> { | 19 | fn is_derive_registrar_symbol(symbol: &str) -> bool { |
20 | symbol.contains(NEW_REGISTRAR_SYMBOL) | ||
21 | } | ||
22 | |||
23 | fn find_registrar_symbol(file: &Path) -> Result<Option<String>, IoError> { | ||
20 | let buffer = std::fs::read(file)?; | 24 | let buffer = std::fs::read(file)?; |
21 | let object = Object::parse(&buffer).map_err(invalid_data_err)?; | 25 | let object = Object::parse(&buffer).map_err(invalid_data_err)?; |
22 | 26 | ||
23 | match object { | 27 | match object { |
24 | Object::Elf(elf) => { | 28 | Object::Elf(elf) => { |
25 | let symbols = elf.dynstrtab.to_vec().map_err(invalid_data_err)?; | 29 | let symbols = elf.dynstrtab.to_vec().map_err(invalid_data_err)?; |
26 | let names = symbols.iter().map(|s| s.to_string()).collect(); | 30 | let name = |
27 | Ok(names) | 31 | symbols.iter().find(|s| is_derive_registrar_symbol(s)).map(|s| s.to_string()); |
32 | Ok(name) | ||
28 | } | 33 | } |
29 | Object::PE(pe) => { | 34 | Object::PE(pe) => { |
30 | let symbol_names = | 35 | let name = pe |
31 | pe.exports.iter().flat_map(|s| s.name).map(|n| n.to_string()).collect(); | 36 | .exports |
32 | Ok(symbol_names) | 37 | .iter() |
38 | .flat_map(|s| s.name) | ||
39 | .find(|s| is_derive_registrar_symbol(s)) | ||
40 | .map(|s| s.to_string()); | ||
41 | Ok(name) | ||
33 | } | 42 | } |
34 | Object::Mach(mach) => match mach { | 43 | Object::Mach(Mach::Binary(binary)) => { |
35 | Mach::Binary(binary) => { | 44 | let exports = binary.exports().map_err(invalid_data_err)?; |
36 | let exports = binary.exports().map_err(invalid_data_err)?; | 45 | let name = exports |
37 | let names = exports | 46 | .iter() |
38 | .into_iter() | 47 | .map(|s| { |
39 | .map(|s| { | 48 | // In macos doc: |
40 | // In macos doc: | 49 | // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html |
41 | // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html | 50 | // Unlike other dyld API's, the symbol name passed to dlsym() must NOT be |
42 | // Unlike other dyld API's, the symbol name passed to dlsym() must NOT be | 51 | // prepended with an underscore. |
43 | // prepended with an underscore. | 52 | if s.name.starts_with("_") { |
44 | if s.name.starts_with("_") { | 53 | &s.name[1..] |
45 | s.name[1..].to_string() | 54 | } else { |
46 | } else { | 55 | &s.name |
47 | s.name | 56 | } |
48 | } | 57 | }) |
49 | }) | 58 | .find(|s| is_derive_registrar_symbol(&s)) |
50 | .collect(); | 59 | .map(|s| s.to_string()); |
51 | Ok(names) | 60 | Ok(name) |
52 | } | 61 | } |
53 | Mach::Fat(_) => Ok(vec![]), | 62 | _ => Ok(None), |
54 | }, | ||
55 | Object::Archive(_) | Object::Unknown(_) => Ok(vec![]), | ||
56 | } | 63 | } |
57 | } | 64 | } |
58 | 65 | ||
59 | fn is_derive_registrar_symbol(symbol: &str) -> bool { | ||
60 | symbol.contains(NEW_REGISTRAR_SYMBOL) | ||
61 | } | ||
62 | |||
63 | fn find_registrar_symbol(file: &Path) -> Result<Option<String>, IoError> { | ||
64 | let symbols = get_symbols_from_lib(file)?; | ||
65 | Ok(symbols.into_iter().find(|s| is_derive_registrar_symbol(s))) | ||
66 | } | ||
67 | |||
68 | /// Loads dynamic library in platform dependent manner. | 66 | /// Loads dynamic library in platform dependent manner. |
69 | /// | 67 | /// |
70 | /// For unix, you have to use RTLD_DEEPBIND flag to escape problems described | 68 | /// For unix, you have to use RTLD_DEEPBIND flag to escape problems described |