@@ -11,7 +11,7 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
11
11
use std:: fmt;
12
12
use std:: fs;
13
13
use std:: path:: { Path , PathBuf } ;
14
- use walrus:: { FunctionId , ImportId , MemoryId , Module , TableId } ;
14
+ use walrus:: { FunctionId , ImportId , MemoryId , Module , TableId , ValType } ;
15
15
16
16
mod binding;
17
17
@@ -53,6 +53,9 @@ pub struct Context<'a> {
53
53
/// names.
54
54
memory_indices : HashMap < MemoryId , usize > ,
55
55
table_indices : HashMap < TableId , usize > ,
56
+
57
+ /// A flag to track if the stack pointer setter shim has been injected.
58
+ stack_pointer_shim_injected : bool ,
56
59
}
57
60
58
61
#[ derive( Default ) ]
@@ -100,6 +103,7 @@ impl<'a> Context<'a> {
100
103
aux,
101
104
memory_indices : Default :: default ( ) ,
102
105
table_indices : Default :: default ( ) ,
106
+ stack_pointer_shim_injected : false ,
103
107
} )
104
108
}
105
109
@@ -3305,6 +3309,47 @@ impl<'a> Context<'a> {
3305
3309
format ! ( "{}{}" , name, cnt)
3306
3310
}
3307
3311
}
3312
+
3313
+ fn inject_stack_pointer_shim ( & mut self ) -> Result < ( ) , Error > {
3314
+ if self . stack_pointer_shim_injected {
3315
+ return Ok ( ( ) ) ;
3316
+ }
3317
+ let stack_pointer = match self . aux . shadow_stack_pointer {
3318
+ Some ( s) => s,
3319
+ // In theory this shouldn't happen since malloc is included in
3320
+ // most wasm binaries (and may be gc'd out) and that almost
3321
+ // always pulls in a stack pointer. We can try to synthesize
3322
+ // something here later if necessary.
3323
+ None => bail ! ( "failed to find shadow stack pointer" ) ,
3324
+ } ;
3325
+
3326
+ use walrus:: ir:: * ;
3327
+
3328
+ let mut builder =
3329
+ walrus:: FunctionBuilder :: new ( & mut self . module . types , & [ ValType :: I32 ] , & [ ValType :: I32 ] ) ;
3330
+ builder. name ( "__wbindgen_add_to_stack_pointer" . to_string ( ) ) ;
3331
+
3332
+ let mut body = builder. func_body ( ) ;
3333
+ let arg = self . module . locals . add ( ValType :: I32 ) ;
3334
+
3335
+ // Create a shim function that mutate the stack pointer
3336
+ // to avoid exporting a mutable global.
3337
+ body. local_get ( arg)
3338
+ . global_get ( stack_pointer)
3339
+ . binop ( BinaryOp :: I32Add )
3340
+ . global_set ( stack_pointer)
3341
+ . global_get ( stack_pointer) ;
3342
+
3343
+ let add_to_stack_pointer_func = builder. finish ( vec ! [ arg] , & mut self . module . funcs ) ;
3344
+
3345
+ self . module
3346
+ . exports
3347
+ . add ( "__wbindgen_add_to_stack_pointer" , add_to_stack_pointer_func) ;
3348
+
3349
+ self . stack_pointer_shim_injected = true ;
3350
+
3351
+ Ok ( ( ) )
3352
+ }
3308
3353
}
3309
3354
3310
3355
fn check_duplicated_getter_and_setter_names (
0 commit comments