@@ -4,22 +4,18 @@ mod proc_macros;
44
55use rustc_codegen_ssa:: back:: metadata:: DefaultMetadataLoader ;
66use rustc_interface:: util:: rustc_version_str;
7- use rustc_metadata:: locator:: MetadataError ;
87use rustc_proc_macro:: bridge;
98use rustc_session:: config:: host_tuple;
109use rustc_target:: spec:: { Target , TargetTuple } ;
1110use std:: path:: Path ;
12- use std:: { fmt , fs, io, time:: SystemTime } ;
11+ use std:: { fs, io, time:: SystemTime } ;
1312use temp_dir:: TempDir ;
1413
15- use libloading:: Library ;
16- use object:: Object ;
1714use paths:: { Utf8Path , Utf8PathBuf } ;
1815
1916use crate :: {
2017 PanicMessage , ProcMacroClientHandle , ProcMacroKind , ProcMacroSrvSpan , TrackedEnv ,
21- dylib:: proc_macros:: { ProcMacroClients , ProcMacros } ,
22- token_stream:: TokenStream ,
18+ dylib:: proc_macros:: ProcMacros , token_stream:: TokenStream ,
2319} ;
2420
2521pub ( crate ) struct Expander {
@@ -28,10 +24,7 @@ pub(crate) struct Expander {
2824}
2925
3026impl Expander {
31- pub ( crate ) fn new (
32- temp_dir : & TempDir ,
33- lib : & Utf8Path ,
34- ) -> Result < Expander , LoadProcMacroDylibError > {
27+ pub ( crate ) fn new ( temp_dir : & TempDir , lib : & Utf8Path ) -> io:: Result < Expander > {
3528 // Some libraries for dynamic loading require canonicalized path even when it is
3629 // already absolute
3730 let lib = lib. canonicalize_utf8 ( ) ?;
@@ -78,125 +71,28 @@ impl Expander {
7871 }
7972}
8073
81- #[ derive( Debug ) ]
82- pub enum LoadProcMacroDylibError {
83- Io ( io:: Error ) ,
84- LibLoading ( libloading:: Error ) ,
85- MetadataError ( MetadataError < ' static > ) ,
86- }
87-
88- impl fmt:: Display for LoadProcMacroDylibError {
89- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
90- match self {
91- Self :: Io ( e) => e. fmt ( f) ,
92- Self :: LibLoading ( e) => e. fmt ( f) ,
93- Self :: MetadataError ( e) => e. fmt ( f) ,
94- }
95- }
96- }
97-
98- impl From < io:: Error > for LoadProcMacroDylibError {
99- fn from ( e : io:: Error ) -> Self {
100- LoadProcMacroDylibError :: Io ( e)
101- }
102- }
103-
104- impl From < libloading:: Error > for LoadProcMacroDylibError {
105- fn from ( e : libloading:: Error ) -> Self {
106- LoadProcMacroDylibError :: LibLoading ( e)
107- }
108- }
109-
110- impl From < MetadataError < ' _ > > for LoadProcMacroDylibError {
111- fn from ( e : MetadataError < ' _ > ) -> Self {
112- LoadProcMacroDylibError :: MetadataError ( match e {
113- MetadataError :: NotPresent ( path) => MetadataError :: NotPresent ( path. into_owned ( ) . into ( ) ) ,
114- MetadataError :: LoadFailure ( err) => MetadataError :: LoadFailure ( err) ,
115- MetadataError :: VersionMismatch { expected_version, found_version } => {
116- MetadataError :: VersionMismatch { expected_version, found_version }
117- }
118- } )
119- }
120- }
121-
12274struct ProcMacroLibrary {
123- // this contains references to the library, so make sure this drops before _lib
12475 proc_macros : ProcMacros ,
125- // Hold on to the library so it doesn't unload
126- _lib : Library ,
12776}
12877
12978impl ProcMacroLibrary {
130- fn open ( path : & Utf8Path ) -> Result < Self , LoadProcMacroDylibError > {
131- let proc_macro_kinds = rustc_span:: create_default_session_globals_then ( || {
79+ fn open ( path : & Utf8Path ) -> io :: Result < Self > {
80+ let proc_macros = rustc_span:: create_default_session_globals_then ( || {
13281 let ( target, _) =
13382 Target :: search ( & TargetTuple :: from_tuple ( host_tuple ( ) ) , Path :: new ( "" ) , false )
13483 . unwrap ( ) ;
135- rustc_metadata:: locator:: get_proc_macro_info (
84+ rustc_metadata:: locator:: get_proc_macros (
13685 & target,
13786 path. as_ref ( ) ,
13887 & DefaultMetadataLoader ,
13988 rustc_version_str ( ) . unwrap_or ( "unknown" ) ,
14089 )
14190 } ) ?;
14291
143- let file = fs:: File :: open ( path) ?;
144- #[ allow( clippy:: undocumented_unsafe_blocks) ] // FIXME
145- let file = unsafe { memmap2:: Mmap :: map ( & file) } ?;
146- let obj = object:: File :: parse ( & * file)
147- . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: InvalidData , e) ) ?;
148- let symbol_name =
149- find_registrar_symbol ( & obj) . map_err ( invalid_data_err) ?. ok_or_else ( || {
150- invalid_data_err ( format ! ( "Cannot find registrar symbol in file {path}" ) )
151- } ) ?;
152-
153- // SAFETY: We have verified the validity of the dylib as a proc-macro library
154- let lib = unsafe { load_library ( path) } . map_err ( invalid_data_err) ?;
155- // SAFETY: We have verified the validity of the dylib as a proc-macro library
156- // The 'static lifetime is a lie, it's actually the lifetime of the library but unavoidable
157- // due to self-referentiality
158- // But we make sure that we do not drop it before the symbol is dropped
159- let proc_macros =
160- unsafe { lib. get :: < & ' static & ' static ProcMacroClients > ( symbol_name. as_bytes ( ) ) } ;
161- match proc_macros {
162- Ok ( proc_macros) => Ok ( ProcMacroLibrary {
163- proc_macros : ProcMacros :: new ( * proc_macros, proc_macro_kinds) ,
164- _lib : lib,
165- } ) ,
166- Err ( e) => Err ( e. into ( ) ) ,
167- }
92+ Ok ( ProcMacroLibrary { proc_macros : ProcMacros :: new ( proc_macros) } )
16893 }
16994}
17095
171- fn invalid_data_err ( e : impl Into < Box < dyn std:: error:: Error + Send + Sync > > ) -> io:: Error {
172- io:: Error :: new ( io:: ErrorKind :: InvalidData , e)
173- }
174-
175- fn is_derive_registrar_symbol ( symbol : & str ) -> bool {
176- const NEW_REGISTRAR_SYMBOL : & str = "_rustc_proc_macro_decls_" ;
177- symbol. contains ( NEW_REGISTRAR_SYMBOL )
178- }
179-
180- fn find_registrar_symbol ( obj : & object:: File < ' _ > ) -> object:: Result < Option < String > > {
181- Ok ( obj
182- . exports ( ) ?
183- . into_iter ( )
184- . map ( |export| export. name ( ) )
185- . filter_map ( |sym| String :: from_utf8 ( sym. into ( ) ) . ok ( ) )
186- . find ( |sym| is_derive_registrar_symbol ( sym) )
187- . map ( |sym| {
188- // From MacOS docs:
189- // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
190- // Unlike other dyld API's, the symbol name passed to dlsym() must NOT be
191- // prepended with an underscore.
192- if cfg ! ( target_os = "macos" ) && sym. starts_with ( '_' ) {
193- sym[ 1 ..] . to_owned ( )
194- } else {
195- sym
196- }
197- } ) )
198- }
199-
20096/// Copy the dylib to temp directory to prevent locking in Windows
20197#[ cfg( windows) ]
20298fn ensure_file_with_lock_free_access (
@@ -233,54 +129,3 @@ fn ensure_file_with_lock_free_access(
233129) -> io:: Result < Utf8PathBuf > {
234130 Ok ( path. to_owned ( ) )
235131}
236-
237- /// Loads dynamic library in platform dependent manner.
238- ///
239- /// For unix, you have to use RTLD_DEEPBIND flag to escape problems described
240- /// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample)
241- /// and [here](https://github.com/rust-lang/rust/issues/60593).
242- ///
243- /// Usage of RTLD_DEEPBIND
244- /// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1)
245- ///
246- /// It seems that on Windows that behaviour is default, so we do nothing in that case.
247- ///
248- /// # Safety
249- ///
250- /// The caller is responsible for ensuring that the path is valid proc-macro library
251- #[ cfg( windows) ]
252- unsafe fn load_library ( file : & Utf8Path ) -> Result < Library , libloading:: Error > {
253- // SAFETY: The caller is responsible for ensuring that the path is valid proc-macro library
254- unsafe { Library :: new ( file) }
255- }
256-
257- /// Loads dynamic library in platform dependent manner.
258- ///
259- /// For unix, you have to use RTLD_DEEPBIND flag to escape problems described
260- /// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample)
261- /// and [here](https://github.com/rust-lang/rust/issues/60593).
262- ///
263- /// Usage of RTLD_DEEPBIND
264- /// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1)
265- ///
266- /// It seems that on Windows that behaviour is default, so we do nothing in that case.
267- ///
268- /// # Safety
269- ///
270- /// The caller is responsible for ensuring that the path is valid proc-macro library
271- #[ cfg( unix) ]
272- unsafe fn load_library ( file : & Utf8Path ) -> Result < Library , libloading:: Error > {
273- // not defined by POSIX, different values on mips vs other targets
274- #[ cfg( target_env = "gnu" ) ]
275- use libc:: RTLD_DEEPBIND ;
276- use libloading:: os:: unix:: Library as UnixLibrary ;
277- // defined by POSIX
278- use libloading:: os:: unix:: RTLD_NOW ;
279-
280- // MUSL and bionic don't have it..
281- #[ cfg( not( target_env = "gnu" ) ) ]
282- const RTLD_DEEPBIND : std:: os:: raw:: c_int = 0x0 ;
283-
284- // SAFETY: The caller is responsible for ensuring that the path is valid proc-macro library
285- unsafe { UnixLibrary :: open ( Some ( file) , RTLD_NOW | RTLD_DEEPBIND ) . map ( |lib| lib. into ( ) ) }
286- }
0 commit comments