From 3065c44b6025f8981fc2f638ba561f9b3afea6e6 Mon Sep 17 00:00:00 2001 From: mohanson Date: Thu, 28 Nov 2024 09:17:38 +0800 Subject: [PATCH] Mark unsound public methods as private utility functions --- definitions/src/asm.rs | 29 -------------- src/machine/asm/mod.rs | 86 ++++++++++++++++++++++++------------------ 2 files changed, 50 insertions(+), 65 deletions(-) diff --git a/definitions/src/asm.rs b/definitions/src/asm.rs index 858dd6fe..7a99e5c3 100644 --- a/definitions/src/asm.rs +++ b/definitions/src/asm.rs @@ -164,32 +164,3 @@ impl AsmCoreMachine { self.max_cycles = cycles; } } - -impl AsmCoreMachine { - /// Casts a raw pointer with an offset and size to a byte slice. - /// - /// # Safety - /// - /// - The `ptr` must be a valid memory address for reading `size` bytes. - /// - The `ptr + offset` must not overflow. - /// - The memory region specified by `ptr + offset` and `size` must remain - /// valid for the lifetime of the returned slice. - /// - /// Failing to satisfy these conditions results in undefined behavior. - pub unsafe fn cast_ptr_to_slice(&self, ptr: u64, offset: usize, size: usize) -> &[u8] { - let ptr = ptr as *const u8; - let ptr = ptr.add(offset); - std::slice::from_raw_parts(ptr, size) - } - - /// Provides similar functionality to `cast_ptr_to_slice` but returns mut slice. - /// - /// # Safety - /// - /// Same as `cast_ptr_to_slice`. - pub unsafe fn cast_ptr_to_slice_mut(&self, ptr: u64, offset: usize, size: usize) -> &mut [u8] { - let ptr = ptr as *mut u8; - let ptr = ptr.add(offset); - std::slice::from_raw_parts_mut(ptr, size) - } -} diff --git a/src/machine/asm/mod.rs b/src/machine/asm/mod.rs index f200cfc1..a5ede118 100644 --- a/src/machine/asm/mod.rs +++ b/src/machine/asm/mod.rs @@ -81,9 +81,12 @@ impl CoreMachine for Box { #[no_mangle] pub extern "C" fn inited_memory(frame_index: u64, machine: &mut AsmCoreMachine) { let addr_from = (frame_index << MEMORY_FRAME_SHIFTS) as usize; - let slice = unsafe { - machine.cast_ptr_to_slice_mut(machine.memory_ptr, addr_from, 1 << MEMORY_FRAME_SHIFTS) - }; + let slice = cast_ptr_to_slice_mut( + machine, + machine.memory_ptr, + addr_from, + 1 << MEMORY_FRAME_SHIFTS, + ); if machine.chaos_mode != 0 { let mut gen = rand::rngs::StdRng::seed_from_u64(machine.chaos_seed.into()); gen.fill_bytes(slice); @@ -237,10 +240,7 @@ impl<'a> FastMemory<'a> { let page_indices = get_page_indices(addr, size); for page in page_indices.0..=page_indices.1 { let frame_index = page >> MEMORY_FRAME_PAGE_SHIFTS; - let slice = unsafe { - self.0 - .cast_ptr_to_slice_mut(self.0.frames_ptr, frame_index as usize, 1) - }; + let slice = cast_ptr_to_slice_mut(self.0, self.0.frames_ptr, frame_index as usize, 1); slice[0] = 1; self.0.set_flag(page, FLAG_DIRTY)?; } @@ -256,10 +256,7 @@ impl<'a> Memory for FastMemory<'a> { return Ok(()); } self.prepare_memory(addr, value.len() as u64)?; - let slice = unsafe { - self.0 - .cast_ptr_to_slice_mut(self.0.memory_ptr, addr as usize, value.len()) - }; + let slice = cast_ptr_to_slice_mut(self.0, self.0.memory_ptr, addr as usize, value.len()); slice.copy_from_slice(value); Ok(()) } @@ -269,10 +266,7 @@ impl<'a> Memory for FastMemory<'a> { return Ok(()); } self.prepare_memory(addr, size)?; - let slice = unsafe { - self.0 - .cast_ptr_to_slice_mut(self.0.memory_ptr, addr as usize, size as usize) - }; + let slice = cast_ptr_to_slice_mut(self.0, self.0.memory_ptr, addr as usize, size as usize); memset(slice, value); Ok(()) } @@ -365,11 +359,9 @@ impl Memory for Box { type REG = u64; fn reset_memory(&mut self) -> Result<(), Error> { - let slice = - unsafe { self.cast_ptr_to_slice_mut(self.flags_ptr, 0, self.flags_size as usize) }; + let slice = cast_ptr_to_slice_mut(self, self.flags_ptr, 0, self.flags_size as usize); memset(slice, 0); - let slice = - unsafe { self.cast_ptr_to_slice_mut(self.frames_ptr, 0, self.frames_size as usize) }; + let slice = cast_ptr_to_slice_mut(self, self.frames_ptr, 0, self.frames_size as usize); memset(slice, 0); self.load_reservation_address = u64::MAX; self.last_read_frame = u64::MAX; @@ -434,7 +426,7 @@ impl Memory for Box { fn fetch_flag(&mut self, page: u64) -> Result { if page < self.memory_pages() as u64 { - let slice = unsafe { self.cast_ptr_to_slice(self.flags_ptr, page as usize, 1) }; + let slice = cast_ptr_to_slice(self, self.flags_ptr, page as usize, 1); Ok(slice[0]) } else { Err(Error::MemOutOfBound( @@ -446,7 +438,7 @@ impl Memory for Box { fn set_flag(&mut self, page: u64, flag: u8) -> Result<(), Error> { if page < self.memory_pages() as u64 { - let slice = unsafe { self.cast_ptr_to_slice_mut(self.flags_ptr, page as usize, 1) }; + let slice = cast_ptr_to_slice_mut(self, self.flags_ptr, page as usize, 1); slice[0] |= flag; // Clear last write page cache self.last_write_page = u64::MAX; @@ -461,7 +453,7 @@ impl Memory for Box { fn clear_flag(&mut self, page: u64, flag: u8) -> Result<(), Error> { if page < self.memory_pages() as u64 { - let slice = unsafe { self.cast_ptr_to_slice_mut(self.flags_ptr, page as usize, 1) }; + let slice = cast_ptr_to_slice_mut(self, self.flags_ptr, page as usize, 1); slice[0] &= !flag; // Clear last write page cache self.last_write_page = u64::MAX; @@ -489,8 +481,7 @@ impl Memory for Box { check_memory(self, page); self.set_flag(page, FLAG_DIRTY)?; } - let slice = - unsafe { self.cast_ptr_to_slice_mut(self.memory_ptr, addr as usize, value.len()) }; + let slice = cast_ptr_to_slice_mut(self, self.memory_ptr, addr as usize, value.len()); slice.copy_from_slice(value); Ok(()) } @@ -506,8 +497,7 @@ impl Memory for Box { check_memory(self, page); self.set_flag(page, FLAG_DIRTY)?; } - let slice = - unsafe { self.cast_ptr_to_slice_mut(self.memory_ptr, addr as usize, size as usize) }; + let slice = cast_ptr_to_slice_mut(self, self.memory_ptr, addr as usize, size as usize); memset(slice, value); Ok(()) } @@ -531,48 +521,48 @@ impl Memory for Box { fn execute_load16(&mut self, addr: u64) -> Result { check_memory_executable(self, addr, 2)?; - let slice = unsafe { self.cast_ptr_to_slice(self.memory_ptr, addr as usize, 2) }; + let slice = cast_ptr_to_slice(self, self.memory_ptr, addr as usize, 2); Ok(LittleEndian::read_u16(slice)) } fn execute_load32(&mut self, addr: u64) -> Result { check_memory_executable(self, addr, 4)?; - let slice = unsafe { self.cast_ptr_to_slice(self.memory_ptr, addr as usize, 4) }; + let slice = cast_ptr_to_slice(self, self.memory_ptr, addr as usize, 4); Ok(LittleEndian::read_u32(slice)) } fn load8(&mut self, addr: &u64) -> Result { let addr = *addr; check_memory_inited(self, addr, 1)?; - let slice = unsafe { self.cast_ptr_to_slice(self.memory_ptr, addr as usize, 1) }; + let slice = cast_ptr_to_slice(self, self.memory_ptr, addr as usize, 1); Ok(u64::from(slice[0])) } fn load16(&mut self, addr: &u64) -> Result { let addr = *addr; check_memory_inited(self, addr, 2)?; - let slice = unsafe { self.cast_ptr_to_slice(self.memory_ptr, addr as usize, 2) }; + let slice = cast_ptr_to_slice(self, self.memory_ptr, addr as usize, 2); Ok(u64::from(LittleEndian::read_u16(slice))) } fn load32(&mut self, addr: &u64) -> Result { let addr = *addr; check_memory_inited(self, addr, 4)?; - let slice = unsafe { self.cast_ptr_to_slice(self.memory_ptr, addr as usize, 4) }; + let slice = cast_ptr_to_slice(self, self.memory_ptr, addr as usize, 4); Ok(u64::from(LittleEndian::read_u32(slice))) } fn load64(&mut self, addr: &u64) -> Result { let addr = *addr; check_memory_inited(self, addr, 8)?; - let slice = unsafe { self.cast_ptr_to_slice(self.memory_ptr, addr as usize, 8) }; + let slice = cast_ptr_to_slice(self, self.memory_ptr, addr as usize, 8); Ok(LittleEndian::read_u64(slice)) } fn store8(&mut self, addr: &u64, value: &u64) -> Result<(), Error> { let addr = *addr; check_memory_writable(self, addr, 1)?; - let slice = unsafe { self.cast_ptr_to_slice_mut(self.memory_ptr, addr as usize, 1) }; + let slice = cast_ptr_to_slice_mut(self, self.memory_ptr, addr as usize, 1); slice[0] = *value as u8; Ok(()) } @@ -580,7 +570,7 @@ impl Memory for Box { fn store16(&mut self, addr: &u64, value: &u64) -> Result<(), Error> { let addr = *addr; check_memory_writable(self, addr, 2)?; - let slice = unsafe { self.cast_ptr_to_slice_mut(self.memory_ptr, addr as usize, 2) }; + let slice = cast_ptr_to_slice_mut(self, self.memory_ptr, addr as usize, 2); LittleEndian::write_u16(slice, *value as u16); Ok(()) } @@ -588,7 +578,7 @@ impl Memory for Box { fn store32(&mut self, addr: &u64, value: &u64) -> Result<(), Error> { let addr = *addr; check_memory_writable(self, addr, 4)?; - let slice = unsafe { self.cast_ptr_to_slice_mut(self.memory_ptr, addr as usize, 4) }; + let slice = cast_ptr_to_slice_mut(self, self.memory_ptr, addr as usize, 4); LittleEndian::write_u32(slice, *value as u32); Ok(()) } @@ -596,7 +586,7 @@ impl Memory for Box { fn store64(&mut self, addr: &u64, value: &u64) -> Result<(), Error> { let addr = *addr; check_memory_writable(self, addr, 8)?; - let slice = unsafe { self.cast_ptr_to_slice_mut(self.memory_ptr, addr as usize, 8) }; + let slice = cast_ptr_to_slice_mut(self, self.memory_ptr, addr as usize, 8); LittleEndian::write_u64(slice, *value as u64); Ok(()) } @@ -786,6 +776,30 @@ impl AsmMachine { } } +// Casts a raw pointer with an offset and size to a byte slice. +// We need machine here for the lifetime. +fn cast_ptr_to_slice(_machine: &AsmCoreMachine, ptr: u64, offset: usize, size: usize) -> &[u8] { + unsafe { + let ptr = ptr as *const u8; + let ptr = ptr.add(offset); + std::slice::from_raw_parts(ptr, size) + } +} + +// Provides similar functionality to `cast_ptr_to_slice` but returns mut slice. +fn cast_ptr_to_slice_mut( + _machine: &AsmCoreMachine, + ptr: u64, + offset: usize, + size: usize, +) -> &mut [u8] { + unsafe { + let ptr = ptr as *mut u8; + let ptr = ptr.add(offset); + std::slice::from_raw_parts_mut(ptr, size) + } +} + #[cfg(test)] mod tests { use ckb_vm_definitions::asm::TRACE_ITEM_LENGTH;