@@ -954,19 +954,39 @@ fn codegen_msvc_try(
954954 let cs = catchswitch. catch_switch ( None , None , 1 ) ;
955955 catchswitch. add_handler ( cs, catchpad. llbb ( ) ) ;
956956
957+ // We can't use the TypeDescriptor defined in libpanic_unwind because it
958+ // might be in another DLL and the SEH encoding only supports specifying
959+ // a TypeDescriptor from the current module.
960+ //
961+ // However this isn't an issue since the MSVC runtime uses string
962+ // comparison on the type name to match TypeDescriptors rather than
963+ // pointer equality.
964+ //
965+ // So instead we generate a new TypeDescriptor in each module that uses
966+ // `try` and let the linker merge duplicate definitions in the same
967+ // module.
968+ //
969+ // When modifying, make sure that the type_name string exactly matches
970+ // the one used in src/libpanic_unwind/seh.rs.
971+ let type_info_vtable = bx. declare_global ( "??_7type_info@@6B@" , bx. type_i8p ( ) ) ;
972+ let type_name = bx. const_bytes ( b"rust_panic\0 " ) ;
973+ let type_info =
974+ bx. const_struct ( & [ type_info_vtable, bx. const_null ( bx. type_i8p ( ) ) , type_name] , false ) ;
975+ let tydesc = bx. declare_global ( "__rust_panic_type_info" , bx. val_ty ( type_info) ) ;
976+ unsafe {
977+ llvm:: LLVMRustSetLinkage ( tydesc, llvm:: Linkage :: LinkOnceODRLinkage ) ;
978+ llvm:: SetUniqueComdat ( bx. llmod , tydesc) ;
979+ llvm:: LLVMSetInitializer ( tydesc, type_info) ;
980+ }
981+
957982 // The flag value of 8 indicates that we are catching the exception by
958983 // reference instead of by value. We can't use catch by value because
959984 // that requires copying the exception object, which we don't support
960985 // since our exception object effectively contains a Box.
961986 //
962987 // Source: MicrosoftCXXABI::getAddrOfCXXCatchHandlerType in clang
963988 let flags = bx. const_i32 ( 8 ) ;
964- let tydesc = match bx. tcx ( ) . lang_items ( ) . eh_catch_typeinfo ( ) {
965- Some ( did) => bx. get_static ( did) ,
966- None => bug ! ( "eh_catch_typeinfo not defined, but needed for SEH unwinding" ) ,
967- } ;
968989 let funclet = catchpad. catch_pad ( cs, & [ tydesc, flags, slot] ) ;
969-
970990 let i64_align = bx. tcx ( ) . data_layout . i64_align . abi ;
971991 let payload_ptr = catchpad. load ( slot, ptr_align) ;
972992 let payload = catchpad. load ( payload_ptr, i64_align) ;
0 commit comments