@@ -35,11 +35,21 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll
3535 assert_eq ! ( offset as usize as u64 , offset) ;
3636 let offset = offset as usize ;
3737 if offset > next_offset {
38- llvals. push ( cx. const_bytes ( & alloc. bytes [ next_offset..offset] ) ) ;
38+ // This `inspect` is okay since we have check that it is not within a relocation, it is
39+ // within the bounds of the allocation, and it doesn't affect interpreter execution (we
40+ // inspect the result after interpreter execution). Any undef byte is replaced with
41+ // some arbitrary byte value.
42+ //
43+ // FIXME: relay undef bytes to codegen as undef const bytes
44+ let bytes = alloc. inspect_with_undef_and_ptr_outside_interpreter ( next_offset..offset) ;
45+ llvals. push ( cx. const_bytes ( bytes) ) ;
3946 }
4047 let ptr_offset = read_target_uint (
4148 dl. endian ,
42- & alloc. bytes [ offset..( offset + pointer_size) ] ,
49+ // This `inspect` is okay since it is within the bounds of the allocation, it doesn't
50+ // affect interpreter execution (we inspect the result after interpreter execution),
51+ // and we properly interpret the relocation as a relocation pointer offset.
52+ alloc. inspect_with_undef_and_ptr_outside_interpreter ( offset..( offset + pointer_size) ) ,
4353 ) . expect ( "const_alloc_to_llvm: could not read relocation pointer" ) as u64 ;
4454 llvals. push ( cx. scalar_to_backend (
4555 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
5161 ) ) ;
5262 next_offset = offset + pointer_size;
5363 }
54- if alloc. bytes . len ( ) >= next_offset {
55- llvals. push ( cx. const_bytes ( & alloc. bytes [ next_offset ..] ) ) ;
64+ if alloc. len ( ) >= next_offset {
65+ let range = next_offset..alloc. len ( ) ;
66+ // This `inspect` is okay since we have check that it is after all relocations, it is
67+ // within the bounds of the allocation, and it doesn't affect interpreter execution (we
68+ // inspect the result after interpreter execution). Any undef byte is replaced with some
69+ // arbitrary byte value.
70+ //
71+ // FIXME: relay undef bytes to codegen as undef const bytes
72+ let bytes = alloc. inspect_with_undef_and_ptr_outside_interpreter ( range) ;
73+ llvals. push ( cx. const_bytes ( bytes) ) ;
5674 }
5775
5876 cx. const_struct ( & llvals, true )
@@ -437,7 +455,23 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
437455 //
438456 // We could remove this hack whenever we decide to drop macOS 10.10 support.
439457 if self . tcx . sess . target . target . options . is_like_osx {
440- let sect_name = if alloc. bytes . iter ( ) . all ( |b| * b == 0 ) {
458+ assert_eq ! ( alloc. relocations. len( ) , 0 ) ;
459+
460+ let is_zeroed = {
461+ // Treats undefined bytes as if they were defined with the byte value that
462+ // happens to be currently assigned in mir. This is valid since reading
463+ // undef bytes may yield arbitrary values.
464+ //
465+ // FIXME: ignore undef bytes even with representation `!= 0`.
466+ //
467+ // The `inspect` method is okay here because we checked relocations, and
468+ // because we are doing this access to inspect the final interpreter state
469+ // (not as part of the interpreter execution).
470+ alloc. inspect_with_undef_and_ptr_outside_interpreter ( 0 ..alloc. len ( ) )
471+ . iter ( )
472+ . all ( |b| * b == 0 )
473+ } ;
474+ let sect_name = if is_zeroed {
441475 CStr :: from_bytes_with_nul_unchecked ( b"__DATA,__thread_bss\0 " )
442476 } else {
443477 CStr :: from_bytes_with_nul_unchecked ( b"__DATA,__thread_data\0 " )
@@ -456,10 +490,17 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
456490 section. as_str ( ) . as_ptr ( ) as * const _ ,
457491 section. as_str ( ) . len ( ) as c_uint ,
458492 ) ;
493+ assert ! ( alloc. relocations. is_empty( ) ) ;
494+
495+ // The `inspect` method is okay here because we checked relocations, and
496+ // because we are doing this access to inspect the final interpreter state (not
497+ // as part of the interpreter execution).
498+ let bytes = alloc. inspect_with_undef_and_ptr_outside_interpreter (
499+ 0 ..alloc. len ( ) ) ;
459500 let alloc = llvm:: LLVMMDStringInContext (
460501 self . llcx ,
461- alloc . bytes . as_ptr ( ) as * const _ ,
462- alloc . bytes . len ( ) as c_uint ,
502+ bytes. as_ptr ( ) as * const _ ,
503+ bytes. len ( ) as c_uint ,
463504 ) ;
464505 let data = [ section, alloc] ;
465506 let meta = llvm:: LLVMMDNodeInContext ( self . llcx , data. as_ptr ( ) , 2 ) ;
0 commit comments