@@ -51,9 +51,7 @@ use alloc::boxed::Box;
5151use core:: any:: Any ;
5252use core:: mem;
5353use core:: raw;
54-
55- use crate :: windows as c;
56- use libc:: { c_int, c_uint} ;
54+ use libc:: { c_int, c_uint, c_void} ;
5755
5856// First up, a whole bunch of type definitions. There's a few platform-specific
5957// oddities here, and a lot that's just blatantly copied from LLVM. The purpose
@@ -76,18 +74,19 @@ use libc::{c_int, c_uint};
7674// sort of operation. For example, if you compile this C++ code on MSVC and emit
7775// the LLVM IR:
7876//
79- // #include <stdin.h>
77+ // #include <stdint.h>
78+ //
79+ // struct rust_panic {
80+ // uint64_t x[2];
81+ // }
8082//
8183// void foo() {
82- // uint64_t a[2] = {0, 1};
84+ // rust_panic a = {0, 1};
8385// throw a;
8486// }
8587//
8688// That's essentially what we're trying to emulate. Most of the constant values
87- // below were just copied from LLVM, I'm at least not 100% sure what's going on
88- // everywhere. For example the `.PA_K\0` and `.PEA_K\0` strings below (stuck in
89- // the names of a few of these) I'm not actually sure what they do, but it seems
90- // to mirror what LLVM does!
89+ // below were just copied from LLVM,
9190//
9291// In any case, these structures are all constructed in a similar manner, and
9392// it's just somewhat verbose for us.
@@ -98,10 +97,9 @@ use libc::{c_int, c_uint};
9897#[ macro_use]
9998mod imp {
10099 pub type ptr_t = * mut u8 ;
101- pub const OFFSET : i32 = 4 ;
102100
101+ #[ cfg( bootstrap) ]
103102 pub const NAME1 : [ u8 ; 7 ] = [ b'.' , b'P' , b'A' , b'_' , b'K' , 0 , 0 ] ;
104- pub const NAME2 : [ u8 ; 7 ] = [ b'.' , b'P' , b'A' , b'X' , 0 , 0 , 0 ] ;
105103
106104 macro_rules! ptr {
107105 ( 0 ) => ( core:: ptr:: null_mut( ) ) ;
@@ -113,10 +111,9 @@ mod imp {
113111#[ macro_use]
114112mod imp {
115113 pub type ptr_t = u32 ;
116- pub const OFFSET : i32 = 8 ;
117114
115+ #[ cfg( bootstrap) ]
118116 pub const NAME1 : [ u8 ; 7 ] = [ b'.' , b'P' , b'E' , b'A' , b'_' , b'K' , 0 ] ;
119- pub const NAME2 : [ u8 ; 7 ] = [ b'.' , b'P' , b'E' , b'A' , b'X' , 0 , 0 ] ;
120117
121118 extern "C" {
122119 pub static __ImageBase: u8 ;
@@ -141,7 +138,7 @@ pub struct _ThrowInfo {
141138#[ repr( C ) ]
142139pub struct _CatchableTypeArray {
143140 pub nCatchableTypes : c_int ,
144- pub arrayOfCatchableTypes : [ imp:: ptr_t ; 2 ] ,
141+ pub arrayOfCatchableTypes : [ imp:: ptr_t ; 1 ] ,
145142}
146143
147144#[ repr( C ) ]
@@ -164,9 +161,19 @@ pub struct _PMD {
164161pub struct _TypeDescriptor {
165162 pub pVFTable : * const u8 ,
166163 pub spare : * mut u8 ,
164+ #[ cfg( bootstrap) ]
167165 pub name : [ u8 ; 7 ] ,
166+ #[ cfg( not( bootstrap) ) ]
167+ pub name : [ u8 ; 11 ] ,
168168}
169169
170+ // Note that we intentionally ignore name mangling rules here: we don't want C++
171+ // to be able to catch Rust panics by simply declaring a `struct rust_panic`.
172+ #[ cfg( bootstrap) ]
173+ use imp:: NAME1 as TYPE_NAME ;
174+ #[ cfg( not( bootstrap) ) ]
175+ const TYPE_NAME : [ u8 ; 11 ] = * b"rust_panic\0 " ;
176+
170177static mut THROW_INFO : _ThrowInfo = _ThrowInfo {
171178 attributes : 0 ,
172179 pnfnUnwind : ptr ! ( 0 ) ,
@@ -175,31 +182,22 @@ static mut THROW_INFO: _ThrowInfo = _ThrowInfo {
175182} ;
176183
177184static mut CATCHABLE_TYPE_ARRAY : _CatchableTypeArray = _CatchableTypeArray {
178- nCatchableTypes : 2 ,
179- arrayOfCatchableTypes : [ ptr ! ( 0 ) , ptr ! ( 0 ) ] ,
185+ nCatchableTypes : 1 ,
186+ arrayOfCatchableTypes : [ ptr ! ( 0 ) ] ,
180187} ;
181188
182- static mut CATCHABLE_TYPE1 : _CatchableType = _CatchableType {
183- properties : 1 ,
189+ static mut CATCHABLE_TYPE : _CatchableType = _CatchableType {
190+ properties : 0 ,
184191 pType : ptr ! ( 0 ) ,
185192 thisDisplacement : _PMD {
186193 mdisp : 0 ,
187194 pdisp : -1 ,
188195 vdisp : 0 ,
189196 } ,
190- sizeOrOffset : imp:: OFFSET ,
191- copy_function : ptr ! ( 0 ) ,
192- } ;
193-
194- static mut CATCHABLE_TYPE2 : _CatchableType = _CatchableType {
195- properties : 1 ,
196- pType : ptr ! ( 0 ) ,
197- thisDisplacement : _PMD {
198- mdisp : 0 ,
199- pdisp : -1 ,
200- vdisp : 0 ,
201- } ,
202- sizeOrOffset : imp:: OFFSET ,
197+ #[ cfg( bootstrap) ]
198+ sizeOrOffset : mem:: size_of :: < * mut u64 > ( ) as c_int ,
199+ #[ cfg( not( bootstrap) ) ]
200+ sizeOrOffset : mem:: size_of :: < [ u64 ; 2 ] > ( ) as c_int ,
203201 copy_function : ptr ! ( 0 ) ,
204202} ;
205203
@@ -221,16 +219,10 @@ extern "C" {
221219//
222220// Again, I'm not entirely sure what this is describing, it just seems to work.
223221#[ cfg_attr( not( test) , lang = "msvc_try_filter" ) ]
224- static mut TYPE_DESCRIPTOR1 : _TypeDescriptor = _TypeDescriptor {
222+ static mut TYPE_DESCRIPTOR : _TypeDescriptor = _TypeDescriptor {
225223 pVFTable : unsafe { & TYPE_INFO_VTABLE } as * const _ as * const _ ,
226224 spare : core:: ptr:: null_mut ( ) ,
227- name : imp:: NAME1 ,
228- } ;
229-
230- static mut TYPE_DESCRIPTOR2 : _TypeDescriptor = _TypeDescriptor {
231- pVFTable : unsafe { & TYPE_INFO_VTABLE } as * const _ as * const _ ,
232- spare : core:: ptr:: null_mut ( ) ,
233- name : imp:: NAME2 ,
225+ name : TYPE_NAME ,
234226} ;
235227
236228pub unsafe fn panic ( data : Box < dyn Any + Send > ) -> u32 {
@@ -246,6 +238,11 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
246238 let ptrs = mem:: transmute :: < _ , raw:: TraitObject > ( data) ;
247239 let mut ptrs = [ ptrs. data as u64 , ptrs. vtable as u64 ] ;
248240 let mut ptrs_ptr = ptrs. as_mut_ptr ( ) ;
241+ let throw_ptr = if cfg ! ( bootstrap) {
242+ & mut ptrs_ptr as * mut _ as * mut _
243+ } else {
244+ ptrs_ptr as * mut _
245+ } ;
249246
250247 // This... may seems surprising, and justifiably so. On 32-bit MSVC the
251248 // pointers between these structure are just that, pointers. On 64-bit MSVC,
@@ -270,17 +267,17 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
270267 atomic_store ( & mut THROW_INFO . pCatchableTypeArray as * mut _ as * mut u32 ,
271268 ptr ! ( & CATCHABLE_TYPE_ARRAY as * const _) as u32 ) ;
272269 atomic_store ( & mut CATCHABLE_TYPE_ARRAY . arrayOfCatchableTypes [ 0 ] as * mut _ as * mut u32 ,
273- ptr ! ( & CATCHABLE_TYPE1 as * const _) as u32 ) ;
274- atomic_store ( & mut CATCHABLE_TYPE_ARRAY . arrayOfCatchableTypes [ 1 ] as * mut _ as * mut u32 ,
275- ptr ! ( & CATCHABLE_TYPE2 as * const _) as u32 ) ;
276- atomic_store ( & mut CATCHABLE_TYPE1 . pType as * mut _ as * mut u32 ,
277- ptr ! ( & TYPE_DESCRIPTOR1 as * const _) as u32 ) ;
278- atomic_store ( & mut CATCHABLE_TYPE2 . pType as * mut _ as * mut u32 ,
279- ptr ! ( & TYPE_DESCRIPTOR2 as * const _) as u32 ) ;
270+ ptr ! ( & CATCHABLE_TYPE as * const _) as u32 ) ;
271+ atomic_store ( & mut CATCHABLE_TYPE . pType as * mut _ as * mut u32 ,
272+ ptr ! ( & TYPE_DESCRIPTOR as * const _) as u32 ) ;
273+
274+ extern "system" {
275+ #[ unwind( allowed) ]
276+ pub fn _CxxThrowException ( pExceptionObject : * mut c_void , pThrowInfo : * mut u8 ) -> !;
277+ }
280278
281- c:: _CxxThrowException ( & mut ptrs_ptr as * mut _ as * mut _ ,
282- & mut THROW_INFO as * mut _ as * mut _ ) ;
283- u32:: max_value ( )
279+ _CxxThrowException ( throw_ptr,
280+ & mut THROW_INFO as * mut _ as * mut _ ) ;
284281}
285282
286283pub fn payload ( ) -> [ u64 ; 2 ] {
0 commit comments