Fix codegen with explicit allocation byte access
This commit is contained in:
parent
7b941e368f
commit
df58fcffbc
1 changed files with 48 additions and 7 deletions
|
@ -35,11 +35,21 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll
|
|||
assert_eq!(offset as usize as u64, offset);
|
||||
let offset = offset as usize;
|
||||
if offset > next_offset {
|
||||
llvals.push(cx.const_bytes(&alloc.bytes[next_offset..offset]));
|
||||
// This `inspect` is okay since we have check that it is not within a relocation, it is
|
||||
// within the bounds of the allocation, and it doesn't affect interpreter execution (we
|
||||
// inspect the result after interpreter execution). Any undef byte is replaced with
|
||||
// some arbitrary byte value.
|
||||
//
|
||||
// FIXME: relay undef bytes to codegen as undef const bytes
|
||||
let bytes = alloc.inspect_with_undef_and_ptr_outside_interpreter(next_offset..offset);
|
||||
llvals.push(cx.const_bytes(bytes));
|
||||
}
|
||||
let ptr_offset = read_target_uint(
|
||||
dl.endian,
|
||||
&alloc.bytes[offset..(offset + pointer_size)],
|
||||
// This `inspect` is okay since it is within the bounds of the allocation, it doesn't
|
||||
// affect interpreter execution (we inspect the result after interpreter execution),
|
||||
// and we properly interpret the relocation as a relocation pointer offset.
|
||||
alloc.inspect_with_undef_and_ptr_outside_interpreter(offset..(offset + pointer_size)),
|
||||
).expect("const_alloc_to_llvm: could not read relocation pointer") as u64;
|
||||
llvals.push(cx.scalar_to_backend(
|
||||
Pointer::new(alloc_id, Size::from_bytes(ptr_offset)).into(),
|
||||
|
@ -51,8 +61,16 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll
|
|||
));
|
||||
next_offset = offset + pointer_size;
|
||||
}
|
||||
if alloc.bytes.len() >= next_offset {
|
||||
llvals.push(cx.const_bytes(&alloc.bytes[next_offset ..]));
|
||||
if alloc.len() >= next_offset {
|
||||
let range = next_offset..alloc.len();
|
||||
// This `inspect` is okay since we have check that it is after all relocations, it is
|
||||
// within the bounds of the allocation, and it doesn't affect interpreter execution (we
|
||||
// inspect the result after interpreter execution). Any undef byte is replaced with some
|
||||
// arbitrary byte value.
|
||||
//
|
||||
// FIXME: relay undef bytes to codegen as undef const bytes
|
||||
let bytes = alloc.inspect_with_undef_and_ptr_outside_interpreter(range);
|
||||
llvals.push(cx.const_bytes(bytes));
|
||||
}
|
||||
|
||||
cx.const_struct(&llvals, true)
|
||||
|
@ -437,7 +455,23 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
|
|||
//
|
||||
// We could remove this hack whenever we decide to drop macOS 10.10 support.
|
||||
if self.tcx.sess.target.target.options.is_like_osx {
|
||||
let sect_name = if alloc.bytes.iter().all(|b| *b == 0) {
|
||||
assert_eq!(alloc.relocations.len(), 0);
|
||||
|
||||
let is_zeroed = {
|
||||
// Treats undefined bytes as if they were defined with the byte value that
|
||||
// happens to be currently assigned in mir. This is valid since reading
|
||||
// undef bytes may yield arbitrary values.
|
||||
//
|
||||
// FIXME: ignore undef bytes even with representation `!= 0`.
|
||||
//
|
||||
// The `inspect` method is okay here because we checked relocations, and
|
||||
// because we are doing this access to inspect the final interpreter state
|
||||
// (not as part of the interpreter execution).
|
||||
alloc.inspect_with_undef_and_ptr_outside_interpreter(0..alloc.len())
|
||||
.iter()
|
||||
.all(|b| *b == 0)
|
||||
};
|
||||
let sect_name = if is_zeroed {
|
||||
CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_bss\0")
|
||||
} else {
|
||||
CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_data\0")
|
||||
|
@ -456,10 +490,17 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
|
|||
section.as_str().as_ptr() as *const _,
|
||||
section.as_str().len() as c_uint,
|
||||
);
|
||||
assert!(alloc.relocations.is_empty());
|
||||
|
||||
// The `inspect` method is okay here because we checked relocations, and
|
||||
// because we are doing this access to inspect the final interpreter state (not
|
||||
// as part of the interpreter execution).
|
||||
let bytes = alloc.inspect_with_undef_and_ptr_outside_interpreter(
|
||||
0..alloc.len());
|
||||
let alloc = llvm::LLVMMDStringInContext(
|
||||
self.llcx,
|
||||
alloc.bytes.as_ptr() as *const _,
|
||||
alloc.bytes.len() as c_uint,
|
||||
bytes.as_ptr() as *const _,
|
||||
bytes.len() as c_uint,
|
||||
);
|
||||
let data = [section, alloc];
|
||||
let meta = llvm::LLVMMDNodeInContext(self.llcx, data.as_ptr(), 2);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue