@@ -785,6 +785,70 @@ fn link_natively(
785785 should_archive. then ( || tmpdir. join ( out_filename. file_name ( ) . unwrap ( ) ) . with_extension ( "so" ) ) ;
786786 let temp_filename = archive_member. as_deref ( ) . unwrap_or ( out_filename) ;
787787
788+ // Gather library search paths (-L)
789+ let mut library_search_dirs = vec ! [ ] ;
790+ walk_native_lib_search_dirs ( sess, self_contained_components, None , |dir, is_framework| {
791+ if !is_framework {
792+ library_search_dirs. push ( dir. to_path_buf ( ) ) ;
793+ }
794+ ControlFlow :: < ( ) > :: Continue ( ( ) )
795+ } ) ;
796+
797+ // Find candidate objects to link
798+ let mut obj_candidates = vec ! [ ] ;
799+
800+ // Rust objects
801+ for module in & codegen_results. modules {
802+ if let Some ( ref path) = module. object {
803+ obj_candidates. push ( path. clone ( ) ) ;
804+ }
805+ }
806+
807+ // eprintln!("Library dirs: {:?}", library_search_dirs);
808+ // Native libraries
809+ for native_lib in codegen_results. crate_info . native_libraries . values ( ) . flatten ( ) {
810+ // eprintln!("native lib {}", native_lib.name);
811+ if let Some ( ref path) = native_lib. filename {
812+ // eprintln!(" located at {path:?}");
813+ obj_candidates. push ( PathBuf :: from ( path. to_string ( ) ) ) ;
814+ } else {
815+ // Try to find the library
816+ let name = native_lib. name . to_string ( ) ;
817+ let candidates = & [ format ! ( "lib{name}.a" ) , format ! ( "lib{name}.so" ) ] ;
818+ for candidate in candidates {
819+ // eprintln!("Finding candidate {candidate}");
820+ for lib_dir in & library_search_dirs {
821+ let candidate_path = lib_dir. join ( candidate) ;
822+ if candidate_path. is_file ( ) {
823+ eprintln ! ( "Found native library at {candidate_path:?}" ) ;
824+ obj_candidates. push ( candidate_path) ;
825+ }
826+ }
827+ }
828+ }
829+ }
830+
831+ use object:: read:: Object ;
832+
833+ // Scan native libraries, sources of .ctors/.dtors
834+ let mut problematic_objects = vec ! [ ] ;
835+ let sections = & [ ".ctors" , ".dtors" ] ;
836+ for path in obj_candidates {
837+ match std:: process:: Command :: new ( "readelf" ) . arg ( "-S" ) . arg ( & path) . output ( ) {
838+ Ok ( output) => {
839+ let stdout = String :: from_utf8_lossy ( & output. stdout ) ;
840+ for section in sections {
841+ if stdout. lines ( ) . any ( |line| line. contains ( section) ) {
842+ problematic_objects. push ( ( path. clone ( ) , section. to_string ( ) ) ) ;
843+ }
844+ }
845+ }
846+ Err ( error) => {
847+ eprintln ! ( "Cannot run readelf -S: {error:?}" )
848+ }
849+ }
850+ }
851+
788852 let mut cmd = linker_with_args (
789853 & linker_path,
790854 flavor,
@@ -990,6 +1054,22 @@ fn link_natively(
9901054 }
9911055 }
9921056
1057+ // Scan the built artifact, lld might keep .ctors/.dtors in it
1058+ if let Ok ( data) = std:: fs:: read ( & temp_filename) {
1059+ if let Ok ( file) = object:: read:: File :: parse ( data. as_slice ( ) ) {
1060+ for section_name in sections {
1061+ if let Some ( _section) = file. section_by_name ( section_name) {
1062+ problematic_objects
1063+ . push ( ( temp_filename. to_path_buf ( ) , section_name. to_string ( ) ) ) ;
1064+ }
1065+ }
1066+ }
1067+ }
1068+ if !problematic_objects. is_empty ( ) {
1069+ eprintln ! ( "PROBLEMATIC OBJECtS\n {problematic_objects:?}" ) ;
1070+ panic ! ( "{problematic_objects:?}" ) ;
1071+ }
1072+
9931073 match prog {
9941074 Ok ( prog) => {
9951075 let is_msvc_link_exe = sess. target . is_like_msvc
0 commit comments