mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-23 06:17:10 +00:00
Introduces the following routines to provide safe access to memory: _mem_probe() _mem_safe_read() _mem_safe_write() _mem_safe_write_to_text_section() Those routines will return an error if the memory is not accessible rather than potentially crash. This implementation is based on the image's boundaries; thus it allows read/write access to the data/bss/init sections and read access only to the text/rodata sections. All other memory is considered invalid, even if addressable. This includes the leftover from the RAM at the end of the image, since there is no support for using it (e.g. there is no dynamic allocator). Change-Id: I6093688ecfd9b00d61be0fd453ada7bb8915c897 Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
165 lines
5.4 KiB
C
165 lines
5.4 KiB
C
/*
|
|
* Copyright (c) 2015 Wind River Systems, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef _debug__mem_safe__h_
|
|
#define _debug__mem_safe__h_
|
|
|
|
#include <errno.h>
|
|
|
|
/**
|
|
* @file safe memory access routines
|
|
*
|
|
* This module provides functions for safely writing to and reading from
|
|
* memory, as well as probing if a memory address is accessible. For the
|
|
* latter, permissions can be specified (read/write).
|
|
*/
|
|
|
|
#define SYS_MEM_SAFE_READ 0
|
|
#define SYS_MEM_SAFE_WRITE 1
|
|
|
|
/**
|
|
* @brief verify memory at an address is accessible
|
|
*
|
|
* Probe memory for read or write access by specifying the @a perm, either
|
|
* SYS_MEM_SAFE_WRITE or SYS_MEM_SAFE_READ. A size @a num_bytes specifying
|
|
* the number of bytes to access must also be specified: for a 32-bit system,
|
|
* it can only take the values 1,2 or 4 (8/16/32 bits). Both @p and @buf must
|
|
* be naturally aligned to @num_bytes.
|
|
*
|
|
* On a read, the value read from the memory location @a p is returned through
|
|
* @a buf; on a write, the value contained in @a buf is written to memory at
|
|
* memory location @a p.
|
|
*
|
|
* @param p The pointer (address) to the location to probe
|
|
* @param perm Either SYS_MEM_PROBE_READ or SYS_MEM_PROBE_WRITE
|
|
* @param num_bytes The number of bytes to probe, must be either 1, 2 or 4
|
|
* @param buf On reads, will contain the value read; on writes, contains the
|
|
* value to write
|
|
*
|
|
* @return 0 or an error
|
|
* @error
|
|
* -EINVAL if an invalid parameter is passed
|
|
* -EFAULT if the address is not accessible.
|
|
*/
|
|
|
|
extern int _mem_probe(void *p, int perm, size_t num_bytes, void *buf);
|
|
|
|
/**
|
|
* @brief safely read memory
|
|
*
|
|
* @details Read @a num_bytes bytes at address @a src from buffer pointed to
|
|
* by @a buf. The @a width parameter specifies bus width of each memory access
|
|
* in bytes. If @a width is 0 a target optimal access width is used. All other
|
|
* values of access width are target dependent and optional. When @a width is
|
|
* non-zero, the both @a num_bytes and @a src must be a multiple of @a width.
|
|
*
|
|
* @param src The address to read from
|
|
* @param buf The destination buffer to receive the data read
|
|
* @param num_bytes The number of bytes to read
|
|
* @param width The access width
|
|
*
|
|
* @return 0 or an error
|
|
*
|
|
* @error
|
|
* -EFAULT if there was an error reading memory
|
|
* -EINVAL if access width, num_bytes and addresses are not compatible.
|
|
*/
|
|
|
|
extern int _mem_safe_read(void *src, char *buf, size_t num_bytes,
|
|
int width);
|
|
|
|
/**
|
|
* @brief safely write memory
|
|
*
|
|
* @details Write @a num_bytes bytes to address @a dest from buffer pointed to
|
|
* by @a buf. The @a width parameter specifies bus width of each memory access
|
|
* in bytes. If @a width is 0 a target optimal access width is used. All other
|
|
* values of access width are target dependent and optional. When @a width is
|
|
* non-zero, the both @a num_bytes and @a dest must be a multiple of @a width.
|
|
*
|
|
* @param dest The address to write to
|
|
* @param buf The source buffer to write in memory
|
|
* @param num_bytes The number of bytes to write
|
|
* @param width The access width
|
|
*
|
|
* @return 0 or an error
|
|
*
|
|
* @error
|
|
* -EFAULT if there was an error writing memory
|
|
* -EINVAL if access width, num_bytes and addresses are not compatible.
|
|
*/
|
|
|
|
extern int _mem_safe_write(void *dest, char *buf, size_t num_bytes,
|
|
int width);
|
|
|
|
/**
|
|
* @brief write to text section
|
|
*
|
|
* @details Write @a num_bytes bytes to address @a dest from buffer pointed to
|
|
* by @a buf.
|
|
*
|
|
* @param dest The address to write to
|
|
* @param buf The source buffer to write in memory
|
|
* @param num_bytes The number of bytes to write
|
|
*
|
|
* @return 0 or an error
|
|
*
|
|
* @error
|
|
* -EFAULT if there was an error writing memory
|
|
*/
|
|
|
|
extern int _mem_safe_write_to_text_section(void *dest, char *buf,
|
|
size_t num_bytes);
|
|
|
|
/**
|
|
* @brief add to the table of valid regions
|
|
*
|
|
* @details Add a new region that is considered valid to read from or both
|
|
* read from and write to. The region starts at @a addr and its size is @a
|
|
* num_bytes. The read/write permissions are specified via @a perm and can
|
|
* take the values either SYS_MEM_SAFE_READ or SYS_MEM_SAFE_WRITE.
|
|
*
|
|
* The table size is specified via the CONFIG_MEM_SAFE_NUM_REGIONS kconfig
|
|
* option.
|
|
*
|
|
* If the implementation of safe memory access chosen does not need this API,
|
|
* it is still available, but results in a no-op and always returns success
|
|
* (0).
|
|
*
|
|
* @param addr The address to write to
|
|
* @param num_bytes The size of the region in bytes
|
|
* @param perm The access permissions, either SYS_MEM_SAFE_WRITE or
|
|
* SYS_MEM_SAFE_READ
|
|
*
|
|
* @return 0 or an error
|
|
*
|
|
* @error
|
|
* -ENOMEM if there there is no space left in the table of regions
|
|
* -EINVAL if passing invalid permissions
|
|
*/
|
|
|
|
#ifdef CONFIG_MEM_SAFE_CHECK_BOUNDARIES
|
|
extern int _mem_safe_region_add(void *addr, size_t num_bytes, int perm);
|
|
#else
|
|
static inline int _mem_safe_region_add(void *addr, size_t num_bytes,
|
|
int perm)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#endif /* _debug__mem_safe__h_ */
|