Skip to content

Commit ad11856

Browse files
committed
Fiddle a HasDataLayout through the allocation methods
1 parent 04210f3 commit ad11856

File tree

1 file changed

+41
-19
lines changed

1 file changed

+41
-19
lines changed

src/librustc/mir/interpret/allocation.rs

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use std::iter;
1818
use mir;
1919
use std::ops::{Deref, DerefMut};
2020
use rustc_data_structures::sorted_map::SortedMap;
21+
use rustc_target::abi::HasDataLayout;
2122

2223
/// Used by `check_bounds` to indicate whether the pointer needs to be just inbounds
2324
/// or also inbounds of a *live* allocation.
@@ -76,16 +77,17 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
7677
#[inline(always)]
7778
pub fn check_bounds(
7879
&self,
80+
cx: &impl HasDataLayout,
7981
ptr: Pointer<Tag>,
8082
size: Size,
8183
) -> EvalResult<'tcx> {
8284
// if ptr.offset is in bounds, then so is ptr (because offset checks for overflow)
83-
self.check_bounds_ptr(ptr.offset(size, &*self)?)
85+
self.check_bounds_ptr(ptr.offset(size, cx)?)
8486
}
8587
}
8688

8789
/// Byte accessors
88-
impl<'tcx, Tag, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
90+
impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
8991
/// The last argument controls whether we error out when there are undefined
9092
/// or pointer bytes. You should never call this, call `get_bytes` or
9193
/// `get_bytes_with_undef_and_ptr` instead,
@@ -95,21 +97,22 @@ impl<'tcx, Tag, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
9597
/// on that.
9698
fn get_bytes_internal(
9799
&self,
100+
cx: &impl HasDataLayout,
98101
ptr: Pointer<Tag>,
99102
size: Size,
100103
align: Align,
101104
check_defined_and_ptr: bool,
102105
) -> EvalResult<'tcx, &[u8]> {
103106
assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`");
104107
self.check_align(ptr.into(), align)?;
105-
self.check_bounds(ptr, size, InboundsCheck::Live)?;
108+
self.check_bounds(cx, ptr, size)?;
106109

107110
if check_defined_and_ptr {
108111
self.check_defined(ptr, size)?;
109-
self.check_relocations(ptr, size)?;
112+
self.check_relocations(cx, ptr, size)?;
110113
} else {
111114
// We still don't want relocations on the *edges*
112-
self.check_relocation_edges(ptr, size)?;
115+
self.check_relocation_edges(cx, ptr, size)?;
113116
}
114117

115118
AllocationExtra::memory_read(self, ptr, size)?;
@@ -123,39 +126,42 @@ impl<'tcx, Tag, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
123126
#[inline]
124127
fn get_bytes(
125128
&self,
129+
cx: &impl HasDataLayout,
126130
ptr: Pointer<Tag>,
127131
size: Size,
128132
align: Align
129133
) -> EvalResult<'tcx, &[u8]> {
130-
self.get_bytes_internal(ptr, size, align, true)
134+
self.get_bytes_internal(cx, ptr, size, align, true)
131135
}
132136

133137
/// It is the caller's responsibility to handle undefined and pointer bytes.
134138
/// However, this still checks that there are no relocations on the *edges*.
135139
#[inline]
136140
fn get_bytes_with_undef_and_ptr(
137141
&self,
142+
cx: &impl HasDataLayout,
138143
ptr: Pointer<Tag>,
139144
size: Size,
140145
align: Align
141146
) -> EvalResult<'tcx, &[u8]> {
142-
self.get_bytes_internal(ptr, size, align, false)
147+
self.get_bytes_internal(cx, ptr, size, align, false)
143148
}
144149

145150
/// Just calling this already marks everything as defined and removes relocations,
146151
/// so be sure to actually put data there!
147152
fn get_bytes_mut(
148153
&mut self,
154+
cx: &impl HasDataLayout,
149155
ptr: Pointer<Tag>,
150156
size: Size,
151157
align: Align,
152158
) -> EvalResult<'tcx, &mut [u8]> {
153159
assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`");
154160
self.check_align(ptr.into(), align)?;
155-
self.check_bounds(ptr, size, InboundsCheck::Live)?;
161+
self.check_bounds(cx, ptr, size)?;
156162

157163
self.mark_definedness(ptr, size, true)?;
158-
self.clear_relocations(ptr, size)?;
164+
self.clear_relocations(cx, ptr, size)?;
159165

160166
AllocationExtra::memory_written(self, ptr, size)?;
161167

@@ -167,24 +173,30 @@ impl<'tcx, Tag, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
167173
}
168174

169175
/// Relocations
170-
impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
176+
impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
171177
/// Return all relocations overlapping with the given ptr-offset pair.
172178
fn relocations(
173179
&self,
180+
cx: &impl HasDataLayout,
174181
ptr: Pointer<Tag>,
175182
size: Size,
176183
) -> EvalResult<'tcx, &[(Size, (Tag, AllocId))]> {
177184
// We have to go back `pointer_size - 1` bytes, as that one would still overlap with
178185
// the beginning of this range.
179-
let start = ptr.offset.bytes().saturating_sub(self.pointer_size().bytes() - 1);
186+
let start = ptr.offset.bytes().saturating_sub(cx.data_layout().pointer_size.bytes() - 1);
180187
let end = ptr.offset + size; // this does overflow checking
181188
Ok(self.relocations.range(Size::from_bytes(start)..end))
182189
}
183190

184191
/// Check that there ar eno relocations overlapping with the given range.
185192
#[inline(always)]
186-
fn check_relocations(&self, ptr: Pointer<Tag>, size: Size) -> EvalResult<'tcx> {
187-
if self.relocations(ptr, size)?.len() != 0 {
193+
fn check_relocations(
194+
&self,
195+
cx: &impl HasDataLayout,
196+
ptr: Pointer<Tag>,
197+
size: Size,
198+
) -> EvalResult<'tcx> {
199+
if self.relocations(cx, ptr, size)?.len() != 0 {
188200
err!(ReadPointerAsBytes)
189201
} else {
190202
Ok(())
@@ -197,17 +209,22 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
197209
/// uninitialized. This is a somewhat odd "spooky action at a distance",
198210
/// but it allows strictly more code to run than if we would just error
199211
/// immediately in that case.
200-
fn clear_relocations(&mut self, ptr: Pointer<Tag>, size: Size) -> EvalResult<'tcx> {
212+
fn clear_relocations(
213+
&mut self,
214+
cx: &impl HasDataLayout,
215+
ptr: Pointer<Tag>,
216+
size: Size,
217+
) -> EvalResult<'tcx> {
201218
// Find the start and end of the given range and its outermost relocations.
202219
let (first, last) = {
203220
// Find all relocations overlapping the given range.
204-
let relocations = self.relocations(ptr, size)?;
221+
let relocations = self.relocations(cx, ptr, size)?;
205222
if relocations.is_empty() {
206223
return Ok(());
207224
}
208225

209226
(relocations.first().unwrap().0,
210-
relocations.last().unwrap().0 + self.pointer_size())
227+
relocations.last().unwrap().0 + cx.data_layout().pointer_size)
211228
};
212229
let start = ptr.offset;
213230
let end = start + size;
@@ -230,9 +247,14 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
230247
/// Error if there are relocations overlapping with the edges of the
231248
/// given memory range.
232249
#[inline]
233-
fn check_relocation_edges(&self, ptr: Pointer<Tag>, size: Size) -> EvalResult<'tcx> {
234-
self.check_relocations(ptr, Size::ZERO)?;
235-
self.check_relocations(ptr.offset(size, self)?, Size::ZERO)?;
250+
fn check_relocation_edges(
251+
&self,
252+
cx: &impl HasDataLayout,
253+
ptr: Pointer<Tag>,
254+
size: Size,
255+
) -> EvalResult<'tcx> {
256+
self.check_relocations(cx, ptr, Size::ZERO)?;
257+
self.check_relocations(cx, ptr.offset(size, cx)?, Size::ZERO)?;
236258
Ok(())
237259
}
238260
}

0 commit comments

Comments
 (0)