1
1
//! Validates all used crates and extern libraries and loads their metadata
2
2
3
3
use std:: error:: Error ;
4
+ use std:: ffi:: OsString ;
4
5
use std:: ops:: Fn ;
5
6
use std:: path:: Path ;
6
7
use std:: str:: FromStr ;
@@ -539,6 +540,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
539
540
Some ( cnum)
540
541
}
541
542
Err ( err) => {
543
+ debug ! ( "failed to resolve crate {} {:?}" , name, dep_kind) ;
542
544
let missing_core =
543
545
self . maybe_resolve_crate ( sym:: core, CrateDepKind :: Explicit , None ) . is_err ( ) ;
544
546
err. report ( self . sess , span, missing_core) ;
@@ -587,6 +589,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
587
589
match self . load ( & mut locator) ? {
588
590
Some ( res) => ( res, None ) ,
589
591
None => {
592
+ info ! ( "falling back to loading proc_macro" ) ;
590
593
dep_kind = CrateDepKind :: MacrosOnly ;
591
594
match self . load_proc_macro ( & mut locator, path_kind, host_hash) ? {
592
595
Some ( res) => res,
@@ -598,6 +601,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
598
601
599
602
match result {
600
603
( LoadResult :: Previous ( cnum) , None ) => {
604
+ info ! ( "library for `{}` was loaded previously" , name) ;
601
605
// When `private_dep` is none, it indicates the directly dependent crate. If it is
602
606
// not specified by `--extern` on command line parameters, it may be
603
607
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
@@ -612,6 +616,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
612
616
Ok ( cnum)
613
617
}
614
618
( LoadResult :: Loaded ( library) , host_library) => {
619
+ info ! ( "register newly loaded library for `{}`" , name) ;
615
620
self . register_crate ( host_library, root, library, dep_kind, name, private_dep)
616
621
}
617
622
_ => panic ! ( ) ,
@@ -695,7 +700,25 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
695
700
stable_crate_id : StableCrateId ,
696
701
) -> Result < & ' static [ ProcMacro ] , CrateError > {
697
702
let sym_name = self . sess . generate_proc_macro_decls_symbol ( stable_crate_id) ;
698
- Ok ( unsafe { * load_symbol_from_dylib :: < * const & [ ProcMacro ] > ( path, & sym_name) ? } )
703
+ debug ! ( "trying to dlsym proc_macros {} for symbol `{}`" , path. display( ) , sym_name) ;
704
+
705
+ unsafe {
706
+ let result = load_symbol_from_dylib :: < * const & [ ProcMacro ] > ( path, & sym_name) ;
707
+ match result {
708
+ Ok ( result) => {
709
+ debug ! ( "loaded dlsym proc_macros {} for symbol `{}`" , path. display( ) , sym_name) ;
710
+ Ok ( * result)
711
+ }
712
+ Err ( err) => {
713
+ debug ! (
714
+ "failed to dlsym proc_macros {} for symbol `{}`" ,
715
+ path. display( ) ,
716
+ sym_name
717
+ ) ;
718
+ Err ( err. into ( ) )
719
+ }
720
+ }
721
+ }
699
722
}
700
723
701
724
fn inject_panic_runtime ( & mut self , krate : & ast:: Crate ) {
@@ -1142,6 +1165,30 @@ fn format_dlopen_err(e: &(dyn std::error::Error + 'static)) -> String {
1142
1165
e. sources ( ) . map ( |e| format ! ( ": {e}" ) ) . collect ( )
1143
1166
}
1144
1167
1168
+ fn attempt_load_dylib ( path : & Path ) -> Result < libloading:: Library , libloading:: Error > {
1169
+ if let Some ( ext) = path. extension ( )
1170
+ && cfg ! ( target_os = "aix" )
1171
+ && ext. eq ( "a" )
1172
+ {
1173
+ // On AIX, we ship all libraries as .a big_af archive
1174
+ // the expected format is lib<name>.a(libname.so) for the actual
1175
+ // dynamic library
1176
+ let library_name = path. file_stem ( ) . expect ( "expect a library name" ) ;
1177
+ let mut archive_member = OsString :: from ( "a(" ) ;
1178
+ archive_member. push ( library_name) ;
1179
+ archive_member. push ( ".so)" ) ;
1180
+ let new_path = path. with_extension ( archive_member) ;
1181
+
1182
+ // On AIX, we need RTLD_MEMBER to dlopen an archived shared
1183
+ // flags = RTLD_LAZY | RTLD_LOCAL | RTLD_MEMBER
1184
+ // these are not yet in libc https://github.com/rust-lang/libc/pull/4044
1185
+ let flags = 0x4 | 0x80000 | 0x40000 ;
1186
+ unsafe { libloading:: os:: unix:: Library :: open ( Some ( & new_path) , flags) } . map ( |lib| lib. into ( ) )
1187
+ } else {
1188
+ unsafe { libloading:: Library :: new ( & path) }
1189
+ }
1190
+ }
1191
+
1145
1192
// On Windows the compiler would sometimes intermittently fail to open the
1146
1193
// proc-macro DLL with `Error::LoadLibraryExW`. It is suspected that something in the
1147
1194
// system still holds a lock on the file, so we retry a few times before calling it
@@ -1152,7 +1199,8 @@ fn load_dylib(path: &Path, max_attempts: usize) -> Result<libloading::Library, S
1152
1199
let mut last_error = None ;
1153
1200
1154
1201
for attempt in 0 ..max_attempts {
1155
- match unsafe { libloading:: Library :: new ( & path) } {
1202
+ debug ! ( "Attempt to load proc-macro `{}`." , path. display( ) ) ;
1203
+ match attempt_load_dylib ( path) {
1156
1204
Ok ( lib) => {
1157
1205
if attempt > 0 {
1158
1206
debug ! (
@@ -1166,6 +1214,7 @@ fn load_dylib(path: &Path, max_attempts: usize) -> Result<libloading::Library, S
1166
1214
Err ( err) => {
1167
1215
// Only try to recover from this specific error.
1168
1216
if !matches ! ( err, libloading:: Error :: LoadLibraryExW { .. } ) {
1217
+ debug ! ( "Failed to load proc-macro `{}`. Not retrying" , path. display( ) ) ;
1169
1218
let err = format_dlopen_err ( & err) ;
1170
1219
// We include the path of the dylib in the error ourselves, so
1171
1220
// if it's in the error, we strip it.
0 commit comments