@@ -53,6 +53,7 @@ use rustc_span::symbol::Symbol;
53
53
use std:: any:: Any ;
54
54
use std:: ffi:: CStr ;
55
55
use std:: io:: Write ;
56
+ use std:: mem:: ManuallyDrop ;
56
57
57
58
mod back {
58
59
pub mod archive;
@@ -408,8 +409,9 @@ pub struct ModuleLlvm {
408
409
llcx : & ' static mut llvm:: Context ,
409
410
llmod_raw : * const llvm:: Module ,
410
411
411
- // independent from llcx and llmod_raw, resources get disposed by drop impl
412
- tm : OwnedTargetMachine ,
412
+ // This field is `ManuallyDrop` because it is important that the `TargetMachine`
413
+ // is disposed prior to the `Context` being disposed otherwise UAFs can occur.
414
+ tm : ManuallyDrop < OwnedTargetMachine > ,
413
415
}
414
416
415
417
unsafe impl Send for ModuleLlvm { }
@@ -420,15 +422,23 @@ impl ModuleLlvm {
420
422
unsafe {
421
423
let llcx = llvm:: LLVMRustContextCreate ( tcx. sess . fewer_names ( ) ) ;
422
424
let llmod_raw = context:: create_module ( tcx, llcx, mod_name) as * const _ ;
423
- ModuleLlvm { llmod_raw, llcx, tm : create_target_machine ( tcx, mod_name) }
425
+ ModuleLlvm {
426
+ llmod_raw,
427
+ llcx,
428
+ tm : ManuallyDrop :: new ( create_target_machine ( tcx, mod_name) ) ,
429
+ }
424
430
}
425
431
}
426
432
427
433
fn new_metadata ( tcx : TyCtxt < ' _ > , mod_name : & str ) -> Self {
428
434
unsafe {
429
435
let llcx = llvm:: LLVMRustContextCreate ( tcx. sess . fewer_names ( ) ) ;
430
436
let llmod_raw = context:: create_module ( tcx, llcx, mod_name) as * const _ ;
431
- ModuleLlvm { llmod_raw, llcx, tm : create_informational_target_machine ( tcx. sess ) }
437
+ ModuleLlvm {
438
+ llmod_raw,
439
+ llcx,
440
+ tm : ManuallyDrop :: new ( create_informational_target_machine ( tcx. sess ) ) ,
441
+ }
432
442
}
433
443
}
434
444
@@ -449,7 +459,7 @@ impl ModuleLlvm {
449
459
}
450
460
} ;
451
461
452
- Ok ( ModuleLlvm { llmod_raw, llcx, tm } )
462
+ Ok ( ModuleLlvm { llmod_raw, llcx, tm : ManuallyDrop :: new ( tm ) } )
453
463
}
454
464
}
455
465
@@ -461,6 +471,7 @@ impl ModuleLlvm {
461
471
impl Drop for ModuleLlvm {
462
472
fn drop ( & mut self ) {
463
473
unsafe {
474
+ ManuallyDrop :: drop ( & mut self . tm ) ;
464
475
llvm:: LLVMContextDispose ( & mut * ( self . llcx as * mut _ ) ) ;
465
476
}
466
477
}
0 commit comments