@@ -51,9 +51,7 @@ use alloc::boxed::Box;
51
51
use core:: any:: Any ;
52
52
use core:: mem;
53
53
use 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} ;
57
55
58
56
// First up, a whole bunch of type definitions. There's a few platform-specific
59
57
// oddities here, and a lot that's just blatantly copied from LLVM. The purpose
@@ -76,18 +74,19 @@ use libc::{c_int, c_uint};
76
74
// sort of operation. For example, if you compile this C++ code on MSVC and emit
77
75
// the LLVM IR:
78
76
//
79
- // #include <stdin.h>
77
+ // #include <stdint.h>
78
+ //
79
+ // struct rust_panic {
80
+ // uint64_t x[2];
81
+ // }
80
82
//
81
83
// void foo() {
82
- // uint64_t a[2] = {0, 1};
84
+ // rust_panic a = {0, 1};
83
85
// throw a;
84
86
// }
85
87
//
86
88
// 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,
91
90
//
92
91
// In any case, these structures are all constructed in a similar manner, and
93
92
// it's just somewhat verbose for us.
@@ -98,10 +97,9 @@ use libc::{c_int, c_uint};
98
97
#[ macro_use]
99
98
mod imp {
100
99
pub type ptr_t = * mut u8 ;
101
- pub const OFFSET : i32 = 4 ;
102
100
101
+ #[ cfg( bootstrap) ]
103
102
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 ] ;
105
103
106
104
macro_rules! ptr {
107
105
( 0 ) => ( core:: ptr:: null_mut( ) ) ;
@@ -113,10 +111,9 @@ mod imp {
113
111
#[ macro_use]
114
112
mod imp {
115
113
pub type ptr_t = u32 ;
116
- pub const OFFSET : i32 = 8 ;
117
114
115
+ #[ cfg( bootstrap) ]
118
116
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 ] ;
120
117
121
118
extern "C" {
122
119
pub static __ImageBase: u8 ;
@@ -141,7 +138,7 @@ pub struct _ThrowInfo {
141
138
#[ repr( C ) ]
142
139
pub struct _CatchableTypeArray {
143
140
pub nCatchableTypes : c_int ,
144
- pub arrayOfCatchableTypes : [ imp:: ptr_t ; 2 ] ,
141
+ pub arrayOfCatchableTypes : [ imp:: ptr_t ; 1 ] ,
145
142
}
146
143
147
144
#[ repr( C ) ]
@@ -164,9 +161,19 @@ pub struct _PMD {
164
161
pub struct _TypeDescriptor {
165
162
pub pVFTable : * const u8 ,
166
163
pub spare : * mut u8 ,
164
+ #[ cfg( bootstrap) ]
167
165
pub name : [ u8 ; 7 ] ,
166
+ #[ cfg( not( bootstrap) ) ]
167
+ pub name : [ u8 ; 11 ] ,
168
168
}
169
169
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
+
170
177
static mut THROW_INFO : _ThrowInfo = _ThrowInfo {
171
178
attributes : 0 ,
172
179
pnfnUnwind : ptr ! ( 0 ) ,
@@ -175,31 +182,22 @@ static mut THROW_INFO: _ThrowInfo = _ThrowInfo {
175
182
} ;
176
183
177
184
static mut CATCHABLE_TYPE_ARRAY : _CatchableTypeArray = _CatchableTypeArray {
178
- nCatchableTypes : 2 ,
179
- arrayOfCatchableTypes : [ ptr ! ( 0 ) , ptr ! ( 0 ) ] ,
185
+ nCatchableTypes : 1 ,
186
+ arrayOfCatchableTypes : [ ptr ! ( 0 ) ] ,
180
187
} ;
181
188
182
- static mut CATCHABLE_TYPE1 : _CatchableType = _CatchableType {
183
- properties : 1 ,
189
+ static mut CATCHABLE_TYPE : _CatchableType = _CatchableType {
190
+ properties : 0 ,
184
191
pType : ptr ! ( 0 ) ,
185
192
thisDisplacement : _PMD {
186
193
mdisp : 0 ,
187
194
pdisp : -1 ,
188
195
vdisp : 0 ,
189
196
} ,
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 ,
203
201
copy_function : ptr ! ( 0 ) ,
204
202
} ;
205
203
@@ -221,16 +219,10 @@ extern "C" {
221
219
//
222
220
// Again, I'm not entirely sure what this is describing, it just seems to work.
223
221
#[ cfg_attr( not( test) , lang = "msvc_try_filter" ) ]
224
- static mut TYPE_DESCRIPTOR1 : _TypeDescriptor = _TypeDescriptor {
222
+ static mut TYPE_DESCRIPTOR : _TypeDescriptor = _TypeDescriptor {
225
223
pVFTable : unsafe { & TYPE_INFO_VTABLE } as * const _ as * const _ ,
226
224
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 ,
234
226
} ;
235
227
236
228
pub unsafe fn panic ( data : Box < dyn Any + Send > ) -> u32 {
@@ -246,6 +238,11 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
246
238
let ptrs = mem:: transmute :: < _ , raw:: TraitObject > ( data) ;
247
239
let mut ptrs = [ ptrs. data as u64 , ptrs. vtable as u64 ] ;
248
240
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
+ } ;
249
246
250
247
// This... may seems surprising, and justifiably so. On 32-bit MSVC the
251
248
// 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 {
270
267
atomic_store ( & mut THROW_INFO . pCatchableTypeArray as * mut _ as * mut u32 ,
271
268
ptr ! ( & CATCHABLE_TYPE_ARRAY as * const _) as u32 ) ;
272
269
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
+ }
280
278
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 _ ) ;
284
281
}
285
282
286
283
pub fn payload ( ) -> [ u64 ; 2 ] {
0 commit comments