11//! Handles dynamic library loading for proc macro
22
33use crate :: { proc_macro:: bridge, rustc_server:: TokenStream } ;
4- use std:: fs:: File ;
5- use std:: io:: Read ;
64use std:: path:: Path ;
75
86use goblin:: { mach:: Mach , Object } ;
97use libloading:: Library ;
108use ra_proc_macro:: ProcMacroKind ;
119
12- static NEW_REGISTRAR_SYMBOL : & str = "__rustc_proc_macro_decls_" ;
13- static _OLD_REGISTRAR_SYMBOL: & str = "__rustc_derive_registrar_" ;
14-
15- fn read_bytes ( file : & Path ) -> Option < Vec < u8 > > {
16- let mut fd = File :: open ( file) . ok ( ) ?;
17- let mut buffer = Vec :: new ( ) ;
18- fd. read_to_end ( & mut buffer) . ok ( ) ?;
19-
20- Some ( buffer)
21- }
10+ static NEW_REGISTRAR_SYMBOL : & str = "_rustc_proc_macro_decls_" ;
2211
2312fn get_symbols_from_lib ( file : & Path ) -> Option < Vec < String > > {
24- let buffer = read_bytes ( file) ?;
13+ let buffer = std :: fs :: read ( file) . ok ( ) ?;
2514 let object = Object :: parse ( & buffer) . ok ( ) ?;
2615
2716 return match object {
2817 Object :: Elf ( elf) => {
2918 let symbols = elf. dynstrtab . to_vec ( ) . ok ( ) ?;
3019 let names = symbols. iter ( ) . map ( |s| s. to_string ( ) ) . collect ( ) ;
31-
3220 Some ( names)
3321 }
34-
3522 Object :: PE ( pe) => {
3623 let symbol_names =
3724 pe. exports . iter ( ) . flat_map ( |s| s. name ) . map ( |n| n. to_string ( ) ) . collect ( ) ;
3825 Some ( symbol_names)
3926 }
40-
4127 Object :: Mach ( mach) => match mach {
4228 Mach :: Binary ( binary) => {
4329 let exports = binary. exports ( ) . ok ( ) ?;
44- let names = exports. iter ( ) . map ( |s| s. name . clone ( ) ) . collect ( ) ;
45-
30+ let names = exports
31+ . iter ( )
32+ . map ( |s| {
33+ // In macos doc:
34+ // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
35+ // Unlike other dyld API's, the symbol name passed to dlsym() must NOT be
36+ // prepended with an underscore.
37+ if s. name . starts_with ( "_" ) {
38+ s. name [ 1 ..] . to_string ( )
39+ } else {
40+ s. name . to_string ( )
41+ }
42+ } )
43+ . collect ( ) ;
4644 Some ( names)
4745 }
48-
4946 Mach :: Fat ( _) => None ,
5047 } ,
51-
5248 Object :: Archive ( _) | Object :: Unknown ( _) => None ,
5349 } ;
5450}
@@ -57,28 +53,10 @@ fn is_derive_registrar_symbol(symbol: &str) -> bool {
5753 symbol. contains ( NEW_REGISTRAR_SYMBOL )
5854}
5955
60- #[ cfg( not( target_os = "macos" ) ) ]
61- fn adjust_symbol_name ( name : & str ) -> String {
62- name. to_string ( )
63- }
64-
65- #[ cfg( target_os = "macos" ) ]
66- fn adjust_symbol_name ( s : & str ) -> String {
67- // In macos doc:
68- // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
69- // Unlike other dyld API's, the symbol name passed to dlsym() must NOT be
70- // prepended with an underscore.
71- if s. starts_with ( "_" ) {
72- s[ 1 ..s. len ( ) ] . to_string ( )
73- } else {
74- s. to_string ( )
75- }
76- }
77-
7856fn find_registrar_symbol ( file : & Path ) -> Option < String > {
7957 let symbols = get_symbols_from_lib ( file) ?;
8058
81- symbols. iter ( ) . find ( |s| is_derive_registrar_symbol ( s) ) . map ( |s| adjust_symbol_name ( & s ) )
59+ symbols. iter ( ) . find ( |s| is_derive_registrar_symbol ( s) ) . map ( |s| s . clone ( ) )
8260}
8361
8462/// Loads dynamic library in platform dependent manner.
@@ -119,11 +97,9 @@ impl ProcMacroLibraryLibloading {
11997 . ok_or ( format ! ( "Cannot find registrar symbol in file {:?}" , file) ) ?;
12098
12199 let lib = load_library ( file) . map_err ( |e| e. to_string ( ) ) ?;
122-
123100 let exported_macros = {
124101 let macros: libloading:: Symbol < & & [ bridge:: client:: ProcMacro ] > =
125102 unsafe { lib. get ( symbol_name. as_bytes ( ) ) } . map_err ( |e| e. to_string ( ) ) ?;
126-
127103 macros. to_vec ( )
128104 } ;
129105
@@ -140,7 +116,6 @@ pub struct Expander {
140116impl Expander {
141117 pub fn new < P : AsRef < Path > > ( lib : & P ) -> Result < Expander , String > {
142118 let mut libs = vec ! [ ] ;
143-
144119 /* Some libraries for dynamic loading require canonicalized path (even when it is
145120 already absolute
146121 */
@@ -177,20 +152,16 @@ impl Expander {
177152 crate :: rustc_server:: Rustc :: default ( ) ,
178153 parsed_body,
179154 ) ;
180-
181155 return res. map ( |it| it. subtree ) ;
182156 }
183-
184157 bridge:: client:: ProcMacro :: Bang { name, client } if * name == macro_name => {
185158 let res = client. run (
186159 & crate :: proc_macro:: bridge:: server:: SameThread ,
187160 crate :: rustc_server:: Rustc :: default ( ) ,
188161 parsed_body,
189162 ) ;
190-
191163 return res. map ( |it| it. subtree ) ;
192164 }
193-
194165 bridge:: client:: ProcMacro :: Attr { name, client } if * name == macro_name => {
195166 let res = client. run (
196167 & crate :: proc_macro:: bridge:: server:: SameThread ,
@@ -201,10 +172,7 @@ impl Expander {
201172
202173 return res. map ( |it| it. subtree ) ;
203174 }
204-
205- _ => {
206- continue ;
207- }
175+ _ => continue ,
208176 }
209177 }
210178 }
0 commit comments