@@ -21,8 +21,9 @@ use rustc_target::abi::{Align, HasDataLayout, Size};
21
21
use crate :: const_eval:: CheckAlignment ;
22
22
23
23
use super :: {
24
- alloc_range, AllocId , AllocMap , AllocRange , Allocation , CheckInAllocMsg , GlobalAlloc , InterpCx ,
25
- InterpResult , Machine , MayLeak , Pointer , PointerArithmetic , Provenance , Scalar ,
24
+ alloc_range, AllocBytes , AllocId , AllocMap , AllocRange , Allocation , CheckInAllocMsg ,
25
+ GlobalAlloc , InterpCx , InterpResult , Machine , MayLeak , Pointer , PointerArithmetic , Provenance ,
26
+ Scalar ,
26
27
} ;
27
28
28
29
#[ derive( Debug , PartialEq , Copy , Clone ) ]
@@ -114,16 +115,16 @@ pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
114
115
/// A reference to some allocation that was already bounds-checked for the given region
115
116
/// and had the on-access machine hooks run.
116
117
#[ derive( Copy , Clone ) ]
117
- pub struct AllocRef < ' a , ' tcx , Prov : Provenance , Extra > {
118
- alloc : & ' a Allocation < Prov , Extra > ,
118
+ pub struct AllocRef < ' a , ' tcx , Prov : Provenance , Extra , Bytes : AllocBytes = Box < [ u8 ] > > {
119
+ alloc : & ' a Allocation < Prov , Extra , Bytes > ,
119
120
range : AllocRange ,
120
121
tcx : TyCtxt < ' tcx > ,
121
122
alloc_id : AllocId ,
122
123
}
123
124
/// A reference to some allocation that was already bounds-checked for the given region
124
125
/// and had the on-access machine hooks run.
125
- pub struct AllocRefMut < ' a , ' tcx , Prov : Provenance , Extra > {
126
- alloc : & ' a mut Allocation < Prov , Extra > ,
126
+ pub struct AllocRefMut < ' a , ' tcx , Prov : Provenance , Extra , Bytes : AllocBytes = Box < [ u8 ] > > {
127
+ alloc : & ' a mut Allocation < Prov , Extra , Bytes > ,
127
128
range : AllocRange ,
128
129
tcx : TyCtxt < ' tcx > ,
129
130
alloc_id : AllocId ,
@@ -483,7 +484,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
483
484
& self ,
484
485
id : AllocId ,
485
486
is_write : bool ,
486
- ) -> InterpResult < ' tcx , Cow < ' tcx , Allocation < M :: Provenance , M :: AllocExtra > > > {
487
+ ) -> InterpResult < ' tcx , Cow < ' tcx , Allocation < M :: Provenance , M :: AllocExtra , M :: Bytes > > > {
487
488
let ( alloc, def_id) = match self . tcx . try_get_global_alloc ( id) {
488
489
Some ( GlobalAlloc :: Memory ( mem) ) => {
489
490
// Memory of a constant or promoted or anonymous memory referenced by a static.
@@ -526,14 +527,25 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
526
527
)
527
528
}
528
529
530
+ /// Get the base address for the bytes in an `Allocation` specified by the
531
+ /// `AllocID` passed in; error if no such allocation exists.
532
+ ///
533
+ /// It is up to the caller to take sufficient care when using this address:
534
+ /// there could be provenance or uninit memory in there, and other memory
535
+ /// accesses could invalidate the exposed pointer.
536
+ pub fn alloc_base_addr ( & self , id : AllocId ) -> InterpResult < ' tcx , * const u8 > {
537
+ let alloc = self . get_alloc_raw ( id) ?;
538
+ Ok ( alloc. base_addr ( ) )
539
+ }
540
+
529
541
/// Gives raw access to the `Allocation`, without bounds or alignment checks.
530
542
/// The caller is responsible for calling the access hooks!
531
543
///
532
544
/// You almost certainly want to use `get_ptr_alloc`/`get_ptr_alloc_mut` instead.
533
545
fn get_alloc_raw (
534
546
& self ,
535
547
id : AllocId ,
536
- ) -> InterpResult < ' tcx , & Allocation < M :: Provenance , M :: AllocExtra > > {
548
+ ) -> InterpResult < ' tcx , & Allocation < M :: Provenance , M :: AllocExtra , M :: Bytes > > {
537
549
// The error type of the inner closure here is somewhat funny. We have two
538
550
// ways of "erroring": An actual error, or because we got a reference from
539
551
// `get_global_alloc` that we can actually use directly without inserting anything anywhere.
@@ -569,7 +581,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
569
581
ptr : Pointer < Option < M :: Provenance > > ,
570
582
size : Size ,
571
583
align : Align ,
572
- ) -> InterpResult < ' tcx , Option < AllocRef < ' a , ' tcx , M :: Provenance , M :: AllocExtra > > > {
584
+ ) -> InterpResult < ' tcx , Option < AllocRef < ' a , ' tcx , M :: Provenance , M :: AllocExtra , M :: Bytes > > >
585
+ {
573
586
let ptr_and_alloc = self . check_and_deref_ptr (
574
587
ptr,
575
588
size,
@@ -612,7 +625,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
612
625
fn get_alloc_raw_mut (
613
626
& mut self ,
614
627
id : AllocId ,
615
- ) -> InterpResult < ' tcx , ( & mut Allocation < M :: Provenance , M :: AllocExtra > , & mut M ) > {
628
+ ) -> InterpResult < ' tcx , ( & mut Allocation < M :: Provenance , M :: AllocExtra , M :: Bytes > , & mut M ) > {
616
629
// We have "NLL problem case #3" here, which cannot be worked around without loss of
617
630
// efficiency even for the common case where the key is in the map.
618
631
// <https://rust-lang.github.io/rfcs/2094-nll.html#problem-case-3-conditional-control-flow-across-functions>
@@ -641,7 +654,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
641
654
ptr : Pointer < Option < M :: Provenance > > ,
642
655
size : Size ,
643
656
align : Align ,
644
- ) -> InterpResult < ' tcx , Option < AllocRefMut < ' a , ' tcx , M :: Provenance , M :: AllocExtra > > > {
657
+ ) -> InterpResult < ' tcx , Option < AllocRefMut < ' a , ' tcx , M :: Provenance , M :: AllocExtra , M :: Bytes > > >
658
+ {
645
659
let parts = self . get_ptr_access ( ptr, size, align) ?;
646
660
if let Some ( ( alloc_id, offset, prov) ) = parts {
647
661
let tcx = * self . tcx ;
@@ -840,11 +854,11 @@ pub struct DumpAllocs<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> {
840
854
impl < ' a , ' mir , ' tcx , M : Machine < ' mir , ' tcx > > std:: fmt:: Debug for DumpAllocs < ' a , ' mir , ' tcx , M > {
841
855
fn fmt ( & self , fmt : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
842
856
// Cannot be a closure because it is generic in `Prov`, `Extra`.
843
- fn write_allocation_track_relocs < ' tcx , Prov : Provenance , Extra > (
857
+ fn write_allocation_track_relocs < ' tcx , Prov : Provenance , Extra , Bytes : AllocBytes > (
844
858
fmt : & mut std:: fmt:: Formatter < ' _ > ,
845
859
tcx : TyCtxt < ' tcx > ,
846
860
allocs_to_print : & mut VecDeque < AllocId > ,
847
- alloc : & Allocation < Prov , Extra > ,
861
+ alloc : & Allocation < Prov , Extra , Bytes > ,
848
862
) -> std:: fmt:: Result {
849
863
for alloc_id in alloc. provenance ( ) . provenances ( ) . filter_map ( |prov| prov. get_alloc_id ( ) )
850
864
{
@@ -912,7 +926,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a,
912
926
}
913
927
914
928
/// Reading and writing.
915
- impl < ' tcx , ' a , Prov : Provenance , Extra > AllocRefMut < ' a , ' tcx , Prov , Extra > {
929
+ impl < ' tcx , ' a , Prov : Provenance , Extra , Bytes : AllocBytes >
930
+ AllocRefMut < ' a , ' tcx , Prov , Extra , Bytes >
931
+ {
916
932
/// `range` is relative to this allocation reference, not the base of the allocation.
917
933
pub fn write_scalar ( & mut self , range : AllocRange , val : Scalar < Prov > ) -> InterpResult < ' tcx > {
918
934
let range = self . range . subrange ( range) ;
@@ -937,7 +953,7 @@ impl<'tcx, 'a, Prov: Provenance, Extra> AllocRefMut<'a, 'tcx, Prov, Extra> {
937
953
}
938
954
}
939
955
940
- impl < ' tcx , ' a , Prov : Provenance , Extra > AllocRef < ' a , ' tcx , Prov , Extra > {
956
+ impl < ' tcx , ' a , Prov : Provenance , Extra , Bytes : AllocBytes > AllocRef < ' a , ' tcx , Prov , Extra , Bytes > {
941
957
/// `range` is relative to this allocation reference, not the base of the allocation.
942
958
pub fn read_scalar (
943
959
& self ,
0 commit comments