kernel: remove gdb_server
This is unmaintained and currently has no known users. It was added to support a Wind River project. If in the future we need it again, we should re-introduce it with an exception-based mechanism for catching out-of-bounds memory queries from the debugger. The mem_safe subsystem is also removed, it is only used by the GDB server. If its functionality is needed in the future, it shoudl be replaced with an exception-based mechanism. The _image_{ram, rom, text}_{start, end} linker variables have been left in place, they will be re-purposed and expanded to support memory protection. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
af416a98b0
commit
0f669132a0
16 changed files with 1 additions and 3562 deletions
|
@ -180,8 +180,6 @@ SECTIONS
|
|||
{
|
||||
_image_ram_start = .;
|
||||
__data_ram_start = .;
|
||||
*(.top_of_image_ram)
|
||||
*(.top_of_image_ram.*)
|
||||
*(.data)
|
||||
*(".data.*")
|
||||
|
||||
|
@ -222,8 +220,6 @@ SECTIONS
|
|||
*/
|
||||
*(.noinit)
|
||||
*(".noinit.*")
|
||||
*(.bottom_of_image_ram)
|
||||
*(.bottom_of_image_ram.*)
|
||||
} GROUP_LINK_IN(RAMABLE_REGION)
|
||||
|
||||
/* Define linker symbols */
|
||||
|
|
|
@ -130,8 +130,6 @@ SECTIONS
|
|||
KEXEC_PGALIGN_PAD(MMU_PAGE_SIZE)
|
||||
_image_ram_start = .;
|
||||
__data_ram_start = .;
|
||||
*(.top_of_image_ram)
|
||||
*(.top_of_image_ram.*)
|
||||
*(.data)
|
||||
*(".data.*")
|
||||
|
||||
|
@ -193,9 +191,6 @@ SECTIONS
|
|||
*/
|
||||
*(.noinit)
|
||||
*(".noinit.*")
|
||||
|
||||
*(.bottom_of_image_ram)
|
||||
*(.bottom_of_image_ram.*)
|
||||
} GROUP_LINK_IN(RAMABLE_REGION)
|
||||
|
||||
|
||||
|
|
|
@ -1,154 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _debug__mem_safe__h_
|
||||
#define _debug__mem_safe__h_
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief 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 @a p and @a buf
|
||||
* must be naturally aligned to @a 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
|
||||
*
|
||||
* @retval 0 OK
|
||||
* @retval -EINVAL If an invalid parameter is passed
|
||||
* @retval -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
|
||||
*
|
||||
* @retval 0 OK
|
||||
* @retval -EFAULT If there was an error reading memory
|
||||
* @retval -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
|
||||
*
|
||||
* @retval 0 OK
|
||||
* @retval -EFAULT If there was an error writing memory
|
||||
* @retval -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
|
||||
*
|
||||
* @retval 0 Success
|
||||
* @retval -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_EXTRA_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
|
||||
*
|
||||
* @retval 0 OK
|
||||
* @retval -ENOMEM If there there is no space left in the table of regions
|
||||
* @retval -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
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _debug__mem_safe__h_ */
|
|
@ -151,53 +151,6 @@ config OMIT_FRAME_POINTER
|
|||
If unsure, disable OVERRIDE_FRAME_POINTER_DEFAULT to allow the compiler
|
||||
to adopt sensible defaults for your architecture.
|
||||
|
||||
menu "Safe memory access"
|
||||
|
||||
config MEM_SAFE
|
||||
bool
|
||||
prompt "Enable safe memory access"
|
||||
default n
|
||||
help
|
||||
Add the routines available in mem_safe.h to the system. This is added
|
||||
as a kconfig option instead of simply linking against the library
|
||||
because some implementations might require initialization.
|
||||
|
||||
choice
|
||||
prompt "Safe memory access implementation"
|
||||
depends on MEM_SAFE
|
||||
default MEM_SAFE_CHECK_BOUNDARIES
|
||||
|
||||
config MEM_SAFE_CHECK_BOUNDARIES
|
||||
bool
|
||||
prompt "Software validation of memory access within memory regions"
|
||||
help
|
||||
This implementation checks the application image's text/rodata
|
||||
boundaries for its read-only region and the data/bss/noinit boundaries
|
||||
for its read-write region, in software.
|
||||
|
||||
Other regions can be added as needed by using the
|
||||
sys_mem_safe_region_add() API. The number of regions that can be added
|
||||
is controlled via the MEM_SAFE_NUM_EXTRA_REGIONS kconfig option.
|
||||
|
||||
This implementation requires initialization and thus consumes some boot
|
||||
time.
|
||||
|
||||
endchoice
|
||||
|
||||
config MEM_SAFE_NUM_EXTRA_REGIONS
|
||||
int
|
||||
prompt "Number of safe memory access regions to be added at runtime"
|
||||
depends on MEM_SAFE_CHECK_BOUNDARIES
|
||||
default 0
|
||||
help
|
||||
The functions available in mem_safe.h check if memory is within
|
||||
read-only or read-write regions before accessing it instead of crashing.
|
||||
The kernel image is added as a valid region automatically, but other
|
||||
regions can be added if the application makes access to additional
|
||||
memory outside of the image's boundaries.
|
||||
|
||||
endmenu
|
||||
|
||||
#
|
||||
# Generic Debugging Options
|
||||
#
|
||||
|
@ -211,55 +164,6 @@ config DEBUG_INFO
|
|||
|
||||
NOTE: Does not currently work with the x86 IAMCU ABI.
|
||||
|
||||
#
|
||||
# GDB Server options
|
||||
#
|
||||
|
||||
config GDB_SERVER
|
||||
bool
|
||||
prompt "Enable GDB Server [EXPERIMENTAL]"
|
||||
default n
|
||||
select CACHE_FLUSHING
|
||||
select REBOOT
|
||||
select MEM_SAFE
|
||||
select DEBUG_INFO
|
||||
select UART_CONSOLE_DEBUG_SERVER_HOOKS
|
||||
help
|
||||
This option enables the GDB Server support.
|
||||
|
||||
config GDB_SERVER_MAX_SW_BP
|
||||
int "Maximum number of GDB Server Software breakpoints"
|
||||
default 100
|
||||
depends on GDB_SERVER
|
||||
help
|
||||
This option specifies the maximum number of Software breakpoints
|
||||
|
||||
config GDB_SERVER_INTERRUPT_DRIVEN
|
||||
bool
|
||||
prompt "Enable GDB interrupt mode"
|
||||
default y
|
||||
depends on GDB_SERVER
|
||||
select CONSOLE_HANDLER
|
||||
help
|
||||
This option enables interrupt support for GDB Server.
|
||||
|
||||
config GDB_REMOTE_SERIAL_EXT_NOTIF_PREFIX_STR
|
||||
string
|
||||
prompt "Trigger string for remote serial ext. via notifi. packets"
|
||||
default "WrCons"
|
||||
depends on GDB_SERVER
|
||||
help
|
||||
The value of this option depends on the string the GDB client use to
|
||||
prefix the notification packets.
|
||||
|
||||
config GDB_SERVER_BOOTLOADER
|
||||
bool
|
||||
prompt "Enable the bootloader mode"
|
||||
default n
|
||||
depends on GDB_SERVER
|
||||
help
|
||||
This option enables the bootloader mode of the GDB Server.
|
||||
|
||||
#
|
||||
# Miscellaneous debugging options
|
||||
#
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
ccflags-y +=-I$(srctree)/include/debug
|
||||
CFLAGS_gdb_server.o =-I$(srctree)/include/drivers
|
||||
|
||||
obj-y =
|
||||
obj-$(CONFIG_MEM_SAFE_CHECK_BOUNDARIES) += mem_safe_check_boundaries.o
|
||||
obj-$(CONFIG_GDB_SERVER) += gdb_server.o
|
||||
obj- = dummy.o
|
||||
|
||||
ifeq ($(CONFIG_OPENOCD_SUPPORT),y)
|
||||
lib-y += openocd.o
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,283 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file safe memory access routines, software implementation that verifies
|
||||
* accesses are within memory region boundaries.
|
||||
*
|
||||
* @details See debug/Kconfig and the "Safe memory access" help for details.
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <init.h>
|
||||
#include <errno.h>
|
||||
#include <toolchain.h>
|
||||
#include <linker/linker-defs.h>
|
||||
#include <misc/util.h>
|
||||
#include <debug/mem_safe.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NUM_REGIONS (CONFIG_MEM_SAFE_NUM_EXTRA_REGIONS + 2)
|
||||
|
||||
/*
|
||||
* The table of regions has the RO regions at the bottom and the RW regions at
|
||||
* the top, and regions are added by moving the ro_end/rw_end pointers towards
|
||||
* each other. The table is full when the pointers cross, i.e. when ro_end >
|
||||
* rw_end.
|
||||
*/
|
||||
struct {
|
||||
vaddr_t addr;
|
||||
vaddr_t last_byte;
|
||||
} mem_regions[NUM_REGIONS];
|
||||
|
||||
#define ro_base 0
|
||||
#define rw_base (NUM_REGIONS - 1)
|
||||
|
||||
static int ro_end = ro_base;
|
||||
static int rw_end = rw_base;
|
||||
|
||||
#define IMAGE_ROM_START ((vaddr_t)&_image_rom_start)
|
||||
#define IMAGE_ROM_END ((vaddr_t)&_image_rom_end)
|
||||
|
||||
#define IMAGE_RAM_START ((vaddr_t)&_image_ram_start)
|
||||
#define IMAGE_RAM_END ((vaddr_t)&_image_ram_end)
|
||||
|
||||
#define IMAGE_TEXT_START ((vaddr_t)&_image_text_start)
|
||||
#define IMAGE_TEXT_END ((vaddr_t)&_image_text_end)
|
||||
|
||||
#define VALID_PERMISSION_MASK 0x00000001 /* permissions use only the lsb */
|
||||
|
||||
static inline void write_to_mem(void *dest, void *src, int width)
|
||||
{
|
||||
switch (width) {
|
||||
case 4:
|
||||
*((vaddr_t *)dest) = *((const vaddr_t *)src);
|
||||
break;
|
||||
case 2:
|
||||
*((u16_t *)dest) = *((const u16_t *)src);
|
||||
break;
|
||||
case 1:
|
||||
*((char *)dest) = *((const char *)src);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int is_in_region(int slot, vaddr_t addr, vaddr_t end_addr)
|
||||
{
|
||||
vaddr_t region_start = mem_regions[slot].addr;
|
||||
vaddr_t region_last_byte = mem_regions[slot].last_byte;
|
||||
|
||||
return addr >= region_start && end_addr <= region_last_byte;
|
||||
}
|
||||
|
||||
static inline int is_in_a_ro_region(vaddr_t addr, vaddr_t end_addr)
|
||||
{
|
||||
int slot = ro_base;
|
||||
|
||||
while (slot < ro_end && slot <= rw_end) {
|
||||
if (is_in_region(slot, addr, end_addr)) {
|
||||
return 1;
|
||||
}
|
||||
++slot;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int is_in_a_rw_region(vaddr_t addr, vaddr_t end_addr)
|
||||
{
|
||||
int slot = rw_base;
|
||||
|
||||
while (slot > rw_end && slot >= ro_end) {
|
||||
if (is_in_region(slot, addr, end_addr)) {
|
||||
return 1;
|
||||
}
|
||||
--slot;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int mem_probe_no_check(void *p, int perm, size_t num_bytes,
|
||||
void *buf)
|
||||
{
|
||||
vaddr_t addr = (vaddr_t)p;
|
||||
vaddr_t end_addr = addr + num_bytes - 1;
|
||||
|
||||
int is_in_rw = is_in_a_rw_region(addr, end_addr);
|
||||
int is_in_ro = is_in_a_ro_region(addr, end_addr);
|
||||
|
||||
int valid_mem;
|
||||
void *src, *dest;
|
||||
|
||||
if (perm == SYS_MEM_SAFE_READ) {
|
||||
dest = buf; src = p;
|
||||
valid_mem = is_in_rw || is_in_ro;
|
||||
} else {
|
||||
dest = p; src = buf;
|
||||
valid_mem = is_in_rw;
|
||||
}
|
||||
|
||||
if (likely(valid_mem)) {
|
||||
write_to_mem(dest, src, num_bytes);
|
||||
return 0;
|
||||
}
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
static inline int is_perm_valid(int perm)
|
||||
{
|
||||
return !(perm & ~VALID_PERMISSION_MASK);
|
||||
}
|
||||
|
||||
static inline int is_num_bytes_valid(size_t num_bytes)
|
||||
{
|
||||
return is_power_of_two(num_bytes) && num_bytes <= sizeof(vaddr_t);
|
||||
}
|
||||
|
||||
int _mem_probe(void *p, int perm, size_t num_bytes, void *buf)
|
||||
{
|
||||
if (unlikely(!is_perm_valid(perm))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unlikely(!is_num_bytes_valid(num_bytes))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return mem_probe_no_check(p, perm, num_bytes, buf);
|
||||
}
|
||||
|
||||
static inline int mem_access(void *p, void *buf, size_t num_bytes,
|
||||
int len, int perm)
|
||||
{
|
||||
char *p_char = p, *buf_char = buf, *p_end = ((char *)p + len);
|
||||
|
||||
while (p_char < p_end) {
|
||||
int error = mem_probe_no_check(p_char, perm, num_bytes, buf_char);
|
||||
|
||||
if (unlikely(error < 0)) {
|
||||
return error;
|
||||
}
|
||||
p_char += num_bytes;
|
||||
buf_char += num_bytes;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int get_align(const u32_t value)
|
||||
{
|
||||
return (value & 1) ? 1 : (value & 2) ? 2 : 4;
|
||||
}
|
||||
|
||||
static inline int get_width(const void *p1, const void *p2,
|
||||
size_t num_bytes, int width)
|
||||
{
|
||||
vaddr_t p1_addr = (vaddr_t)p1, p2_addr = (vaddr_t)p2;
|
||||
|
||||
if (width == 0) {
|
||||
u32_t align_check = num_bytes | p1_addr | p2_addr;
|
||||
|
||||
return get_align(align_check);
|
||||
}
|
||||
|
||||
if (unlikely(p1_addr & (width - 1) || num_bytes & (width - 1))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
int _mem_safe_read(void *src, char *buf, size_t num_bytes, int width)
|
||||
{
|
||||
width = get_width(src, buf, num_bytes, width);
|
||||
return unlikely(width < 0) ? -EINVAL :
|
||||
mem_access(src, buf, width, num_bytes, SYS_MEM_SAFE_READ);
|
||||
}
|
||||
|
||||
int _mem_safe_write(void *dest, char *buf, size_t num_bytes, int width)
|
||||
{
|
||||
width = get_width(dest, buf, num_bytes, width);
|
||||
return unlikely(width < 0) ? -EINVAL :
|
||||
mem_access(dest, buf, width, num_bytes, SYS_MEM_SAFE_WRITE);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_XIP)
|
||||
int _mem_safe_write_to_text_section(void *dest, char *buf, size_t num_bytes)
|
||||
{
|
||||
ARG_UNUSED(dest);
|
||||
ARG_UNUSED(buf);
|
||||
ARG_UNUSED(num_bytes);
|
||||
|
||||
/* cannot write to text section when it's in ROM */
|
||||
return -EFAULT;
|
||||
}
|
||||
#else
|
||||
int _mem_safe_write_to_text_section(void *dest, char *buf, size_t num_bytes)
|
||||
{
|
||||
vaddr_t v = (vaddr_t)dest;
|
||||
int is_in_text = ((v >= IMAGE_TEXT_START) &&
|
||||
((v + num_bytes) <= IMAGE_TEXT_END));
|
||||
|
||||
if (unlikely(!is_in_text)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
memcpy(dest, buf, num_bytes);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_XIP */
|
||||
|
||||
int _mem_safe_region_add(void *addr, size_t num_bytes, int perm)
|
||||
{
|
||||
if (unlikely(!is_perm_valid(perm))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int slot;
|
||||
int key = irq_lock();
|
||||
|
||||
if (unlikely(ro_end > rw_end)) {
|
||||
irq_unlock(key);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (perm == SYS_MEM_SAFE_WRITE) {
|
||||
slot = rw_end;
|
||||
--rw_end;
|
||||
} else {
|
||||
slot = ro_end;
|
||||
++ro_end;
|
||||
}
|
||||
|
||||
mem_regions[slot].addr = (vaddr_t)addr;
|
||||
mem_regions[slot].last_byte = mem_regions[slot].addr + num_bytes - 1;
|
||||
|
||||
irq_unlock(key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init(struct device *unused)
|
||||
{
|
||||
void *addr;
|
||||
size_t num_bytes;
|
||||
|
||||
ARG_UNUSED(unused);
|
||||
|
||||
addr = (void *)IMAGE_ROM_START;
|
||||
num_bytes = (int)(IMAGE_ROM_END - IMAGE_ROM_START);
|
||||
(void)_mem_safe_region_add(addr, num_bytes, SYS_MEM_SAFE_READ);
|
||||
|
||||
addr = (void *)IMAGE_RAM_START;
|
||||
num_bytes = (int)(IMAGE_RAM_END - IMAGE_RAM_START);
|
||||
(void)_mem_safe_region_add(addr, num_bytes, SYS_MEM_SAFE_WRITE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
|
@ -1,13 +0,0 @@
|
|||
BOARD ?= qemu_x86
|
||||
CONF_FILE = prj_$(BOARD).conf
|
||||
|
||||
# This testcase requires a special linker script, from the testcase itself.
|
||||
# The only boards that have one are the ones listed below.
|
||||
valid_board_qemu_x86 = y
|
||||
valid_board_qemu_cortex_m3 = y
|
||||
|
||||
ifneq ($(valid_board_$(BOARD)),y)
|
||||
$(error not a supported board for this testcase)
|
||||
endif
|
||||
|
||||
include $(ZEPHYR_BASE)/Makefile.test
|
|
@ -1,96 +0,0 @@
|
|||
Title: Safe Memory Access
|
||||
|
||||
Description:
|
||||
|
||||
This test verifies that the safe memory access (_mem_safe) functions as
|
||||
intended.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Building and Running Project:
|
||||
|
||||
This project outputs to the console. It can be built and executed
|
||||
on QEMU as follows:
|
||||
|
||||
make run
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Troubleshooting:
|
||||
|
||||
Problems caused by out-dated project information can be addressed by
|
||||
issuing one of the following commands then rebuilding the project:
|
||||
|
||||
make clean # discard results of previous builds
|
||||
# but keep existing configuration info
|
||||
or
|
||||
make pristine # discard results of previous builds
|
||||
# and restore pre-defined configuration info
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Sample Output:
|
||||
|
||||
testing SUCCESS of READ on RO memory with width 1.......PASS
|
||||
testing SUCCESS of READ on RO memory with width 2.......PASS
|
||||
testing SUCCESS of READ on RO memory with width 4.......PASS
|
||||
testing FAILURE of WRITE on RO memory with width 1.......PASS
|
||||
testing FAILURE of WRITE on RO memory with width 2.......PASS
|
||||
testing FAILURE of WRITE on RO memory with width 4.......PASS
|
||||
testing SUCCESS of READ on RW memory with width 1.......PASS
|
||||
testing SUCCESS of READ on RW memory with width 2.......PASS
|
||||
testing SUCCESS of READ on RW memory with width 4.......PASS
|
||||
testing SUCCESS of WRITE on RW memory with width 1.......PASS
|
||||
testing SUCCESS of WRITE on RW memory with width 2.......PASS
|
||||
testing SUCCESS of WRITE on RW memory with width 4.......PASS
|
||||
testing FAILURE of INVALID ACCESS on RW memory with width 4.......PASS
|
||||
testing FAILURE of READ on RO memory with width 0.......PASS
|
||||
testing SUCCESS of READ on RO memory with width 1.......PASS
|
||||
testing SUCCESS of READ on RO memory with width 2.......PASS
|
||||
testing FAILURE of READ on RO memory with width 3.......PASS
|
||||
testing SUCCESS of READ on RO memory with width 4.......PASS
|
||||
testing FAILURE of READ on RO memory with width 5.......PASS
|
||||
testing FAILURE of READ on RO memory with width 8.......PASS
|
||||
testing SUCCESS of READ on RO memory with width 1.......PASS
|
||||
testing SUCCESS of READ on RO memory with width 1.......PASS
|
||||
testing SUCCESS of READ on RW memory with width 1.......PASS
|
||||
testing SUCCESS of READ on RW memory with width 1.......PASS
|
||||
testing FAILURE of WRITE on RO memory with width 1.......PASS
|
||||
testing FAILURE of WRITE on RO memory with width 1.......PASS
|
||||
testing SUCCESS of WRITE on RW memory with width 1.......PASS
|
||||
testing SUCCESS of WRITE on RW memory with width 1.......PASS
|
||||
testing FAILURE of READ on out-of-image memory with width 1.......PASS
|
||||
testing FAILURE of READ on out-of-image memory with width 1.......PASS
|
||||
testing SUCCESS of adding extra RO region.......PASS
|
||||
testing SUCCESS of adding extra RW region.......PASS
|
||||
testing FAILURE of adding extra region that won't fit.......PASS
|
||||
testing SUCCESS of READ on out-of-image memory with width 1.......PASS
|
||||
testing SUCCESS of READ on out-of-image memory with width 1.......PASS
|
||||
testing SUCCESS of READ on out-of-image memory with width 1.......PASS
|
||||
testing SUCCESS of READ on out-of-image memory with width 1.......PASS
|
||||
testing FAILURE of WRITE on out-of-image memory with width 1.......PASS
|
||||
testing FAILURE of WRITE on out-of-image memory with width 1.......PASS
|
||||
testing SUCCESS of WRITE on out-of-image memory with width 1.......PASS
|
||||
testing SUCCESS of WRITE on out-of-image memory with width 1.......PASS
|
||||
testing FAILURE of READ on out-of-image memory with width 1.......PASS
|
||||
testing FAILURE of READ on out-of-image memory with width 1.......PASS
|
||||
testing FAILURE of READ on out-of-image memory with width 1.......PASS
|
||||
testing FAILURE of READ on out-of-image memory with width 1.......PASS
|
||||
testing FAILURE of WRITE on RO memory with width 1.......PASS
|
||||
testing SUCCESS of _mem_probe() reading RO values.......PASS
|
||||
testing SUCCESS of _mem_probe() reading RW values.......PASS
|
||||
testing SUCCESS of _mem_probe() writing values.......PASS
|
||||
testing SUCCESS of _mem_safe_read(size: 16, width: 0).......PASS
|
||||
testing SUCCESS of _mem_safe_read(size: 16, width: 4).......PASS
|
||||
testing SUCCESS of _mem_safe_read(size: 14, width: 2).......PASS
|
||||
testing SUCCESS of _mem_safe_read(size: 15, width: 1).......PASS
|
||||
testing FAILURE of _mem_safe_read() with bad params.......PASS (-22)
|
||||
testing SUCCESS of _mem_safe_write(size: 16, width: 0).......PASS
|
||||
testing SUCCESS of _mem_safe_write(size: 16, width: 4).......PASS
|
||||
testing SUCCESS of _mem_safe_write(size: 14, width: 2).......PASS
|
||||
testing SUCCESS of _mem_safe_write(size: 15, width: 1).......PASS
|
||||
testing FAILURE of _mem_safe_write() with bad params.......PASS (-22)
|
||||
===================================================================
|
||||
PASS - main.
|
||||
===================================================================
|
||||
PROJECT EXECUTION SUCCESSFUL
|
|
@ -1,3 +0,0 @@
|
|||
CONFIG_MEM_SAFE=y
|
||||
CONFIG_MEM_SAFE_NUM_EXTRA_REGIONS=2
|
||||
CONFIG_CACHE_FLUSHING=y
|
|
@ -1,3 +0,0 @@
|
|||
CONFIG_MEM_SAFE=y
|
||||
CONFIG_MEM_SAFE_NUM_EXTRA_REGIONS=2
|
||||
CONFIG_CACHE_FLUSHING=y
|
|
@ -1,6 +0,0 @@
|
|||
ccflags-y += -I${ZEPHYR_BASE}/tests/include
|
||||
DQUOTE = "
|
||||
BUILD_ARCH = $(strip $(subst $(DQUOTE),,$(CONFIG_ARCH)))
|
||||
|
||||
obj-y += main.o
|
||||
obj-y += asm_$(BUILD_ARCH).o
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ brief architecture specific support for the mem_probe tests
|
||||
*/
|
||||
|
||||
#include <arch/x86/asm.h>
|
||||
|
||||
GDATA(foo)
|
||||
GTEXT(add_ten_to_foo)
|
||||
|
||||
SECTION_FUNC(TEXT, add_ten_to_foo)
|
||||
addl $10, foo
|
||||
ret
|
|
@ -1,410 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ brief tests for the mem_probe functionalities
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <misc/util.h>
|
||||
#include <linker/linker-defs.h>
|
||||
#include <debug/mem_safe.h>
|
||||
#include <tc_util.h>
|
||||
#include <cache.h>
|
||||
|
||||
#define MY_DATA_SIZE 16
|
||||
const char __aligned(4) real_rodata[MY_DATA_SIZE] = "0123456789abcdef";
|
||||
char *rodata = (char *)real_rodata;
|
||||
char __aligned(4) rwdata[MY_DATA_SIZE+1];
|
||||
char __aligned(4) buffer[MY_DATA_SIZE+1];
|
||||
|
||||
#if MY_DATA_SIZE != 16
|
||||
#error never verified with values other than 16!
|
||||
#endif
|
||||
|
||||
#define ROM_START ((u32_t)&_image_rom_start)
|
||||
#define ROM_END ((u32_t)&_image_rom_end)
|
||||
#define RAM_START ((u32_t)&_image_ram_start)
|
||||
#define RAM_END ((u32_t)&_image_ram_end)
|
||||
|
||||
char * const p_image_rom_start = (char *)ROM_START;
|
||||
char * const p_image_rom_end = (char *)ROM_END;
|
||||
char * const p_image_ram_start = (char *)RAM_START;
|
||||
char * const p_image_ram_end = (char *)RAM_END;
|
||||
|
||||
char *rw_data_after_image = (char *)(RAM_END + KB(1));
|
||||
char *rw_data_after_image_end;
|
||||
char *ro_data_after_image = (char *)(RAM_END + KB(3));
|
||||
char *ro_data_after_image_end;
|
||||
|
||||
int foo;
|
||||
|
||||
#define PROBE_BUFFER_SIZE 32
|
||||
char top_of_ram[PROBE_BUFFER_SIZE] __in_section(top_of_image_ram, 0, 0);
|
||||
char bottom_of_ram[PROBE_BUFFER_SIZE] __in_section(bottom_of_image_ram, 0, 0);
|
||||
|
||||
static void update_rv(int *rv, int last_result)
|
||||
{
|
||||
*rv = *rv == TC_FAIL ? *rv : last_result;
|
||||
if (last_result == TC_FAIL) {
|
||||
TC_PRINT("FAIL\n");
|
||||
} else {
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
}
|
||||
|
||||
#define RO 0
|
||||
#define RW 1
|
||||
#define INVALID -1
|
||||
static int mem_range_check(const void *p)
|
||||
{
|
||||
u32_t addr = (u32_t)p;
|
||||
|
||||
if (addr >= ROM_START && addr < ROM_END) {
|
||||
return RO;
|
||||
} else if (addr >= RAM_START && addr < RAM_END) {
|
||||
return RW;
|
||||
} else {
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
static int test_width(char *mem, int perm, int width, int expected)
|
||||
{
|
||||
char *rights_str = perm == SYS_MEM_SAFE_READ ? "READ" :
|
||||
perm == SYS_MEM_SAFE_WRITE ? "WRITE" :
|
||||
"INVALID ACCESS";
|
||||
int mem_type = mem_range_check(mem);
|
||||
char *mem_range_str = mem_type == RO ? "RO" :
|
||||
mem_type == RW ? "RW" : "out-of-image";
|
||||
|
||||
TC_PRINT("testing %s of %s on %s memory with width %d.......",
|
||||
expected == 0 ? "SUCCESS" : "FAILURE",
|
||||
rights_str, mem_range_str, width);
|
||||
|
||||
int rv = _mem_probe(mem, perm, width, buffer);
|
||||
|
||||
return rv == expected ? TC_PASS : TC_FAIL;
|
||||
}
|
||||
|
||||
static int test_width_read(char *mem, int width, int expected)
|
||||
{
|
||||
return test_width(mem, SYS_MEM_SAFE_READ, width, expected);
|
||||
}
|
||||
|
||||
static int test_width_write(char *mem, int width, int expected)
|
||||
{
|
||||
return test_width(mem, SYS_MEM_SAFE_WRITE, width, expected);
|
||||
}
|
||||
|
||||
typedef int (*access_func)(void *, char *, size_t, int);
|
||||
static int test_mem_safe_access(void *p, char *buf, int size,
|
||||
int width, int perm)
|
||||
{
|
||||
int rc;
|
||||
char *func_str = (perm == SYS_MEM_SAFE_WRITE) ? "write" : "read";
|
||||
|
||||
access_func func = (perm == SYS_MEM_SAFE_WRITE) ?
|
||||
_mem_safe_write : _mem_safe_read;
|
||||
|
||||
TC_PRINT("testing SUCCESS of _mem_safe_%s(size: %d, width: %d).......",
|
||||
func_str, size, width);
|
||||
rc = func(p, buf, size, width);
|
||||
if (rc < 0) {
|
||||
TC_PRINT("(%d)", rc);
|
||||
return TC_FAIL;
|
||||
}
|
||||
|
||||
if (memcmp(p, buf, size) != 0) {
|
||||
TC_PRINT("(bad data)");
|
||||
return TC_FAIL;
|
||||
}
|
||||
|
||||
return TC_PASS;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
/* reference symbols so that they get included */
|
||||
top_of_ram[0] = 'a';
|
||||
bottom_of_ram[PROBE_BUFFER_SIZE - 1] = 'z';
|
||||
|
||||
int rv = TC_PASS;
|
||||
int rc; /* temporary return code */
|
||||
|
||||
buffer[MY_DATA_SIZE] = '\0';
|
||||
rwdata[MY_DATA_SIZE] = '\0';
|
||||
|
||||
TC_START("safe memory access routines\n");
|
||||
|
||||
/****
|
||||
* _mem_probe()
|
||||
*/
|
||||
|
||||
/* test access perm */
|
||||
|
||||
update_rv(&rv, test_width_read(rodata, 1, 0));
|
||||
update_rv(&rv, test_width_read(rodata, 2, 0));
|
||||
update_rv(&rv, test_width_read(rodata, 4, 0));
|
||||
|
||||
update_rv(&rv, test_width_write(rodata, 1, -EFAULT));
|
||||
update_rv(&rv, test_width_write(rodata, 2, -EFAULT));
|
||||
update_rv(&rv, test_width_write(rodata, 4, -EFAULT));
|
||||
|
||||
update_rv(&rv, test_width_read(rwdata, 1, 0));
|
||||
update_rv(&rv, test_width_read(rwdata, 2, 0));
|
||||
update_rv(&rv, test_width_read(rwdata, 4, 0));
|
||||
|
||||
update_rv(&rv, test_width_write(rwdata, 1, 0));
|
||||
update_rv(&rv, test_width_write(rwdata, 2, 0));
|
||||
update_rv(&rv, test_width_write(rwdata, 4, 0));
|
||||
|
||||
const int invalid_access_right = 3;
|
||||
|
||||
update_rv(&rv, test_width(rwdata, invalid_access_right, 4, -EINVAL));
|
||||
|
||||
/* test alignments constraints */
|
||||
|
||||
update_rv(&rv, test_width_read(rodata, 0, -EINVAL));
|
||||
update_rv(&rv, test_width_read(rodata, 1, 0));
|
||||
update_rv(&rv, test_width_read(rodata, 2, 0));
|
||||
update_rv(&rv, test_width_read(rodata, 3, -EINVAL));
|
||||
update_rv(&rv, test_width_read(rodata, 4, 0));
|
||||
update_rv(&rv, test_width_read(rodata, 5, -EINVAL));
|
||||
update_rv(&rv, test_width_read(rodata, 8, -EINVAL));
|
||||
|
||||
/* test image limits */
|
||||
|
||||
update_rv(&rv, test_width_read(p_image_rom_start, 1, 0));
|
||||
update_rv(&rv, test_width_read(p_image_rom_end - 1, 1, 0));
|
||||
update_rv(&rv, test_width_read(p_image_ram_start, 1, 0));
|
||||
update_rv(&rv, test_width_read(p_image_ram_end - 1, 1, 0));
|
||||
|
||||
update_rv(&rv, test_width_write(p_image_rom_start, 1, -EFAULT));
|
||||
update_rv(&rv, test_width_write(p_image_rom_end - 1, 1, -EFAULT));
|
||||
update_rv(&rv, test_width_write(p_image_ram_start, 1, 0));
|
||||
update_rv(&rv, test_width_write(p_image_ram_end - 1, 1, 0));
|
||||
|
||||
update_rv(&rv, test_width_read(p_image_rom_start - 1, 1, -EFAULT));
|
||||
update_rv(&rv, test_width_read(p_image_ram_end, 1, -EFAULT));
|
||||
|
||||
/* test out-of-image valid regions */
|
||||
|
||||
rw_data_after_image_end = rw_data_after_image + KB(1);
|
||||
ro_data_after_image_end = ro_data_after_image + KB(1);
|
||||
|
||||
TC_PRINT("testing SUCCESS of adding extra RO region.......");
|
||||
int region_add_rc = _mem_safe_region_add(ro_data_after_image, KB(1),
|
||||
SYS_MEM_SAFE_READ);
|
||||
if (region_add_rc < 0) {
|
||||
update_rv(&rv, TC_FAIL);
|
||||
TC_PRINT("FAIL (%d)\n", region_add_rc);
|
||||
} else {
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
|
||||
TC_PRINT("testing SUCCESS of adding extra RW region.......");
|
||||
region_add_rc = _mem_safe_region_add(rw_data_after_image, KB(1),
|
||||
SYS_MEM_SAFE_WRITE);
|
||||
if (region_add_rc < 0) {
|
||||
update_rv(&rv, TC_FAIL);
|
||||
TC_PRINT("FAIL (%d)\n", region_add_rc);
|
||||
} else {
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
|
||||
TC_PRINT("testing FAILURE of adding extra region that won't fit.......");
|
||||
region_add_rc = _mem_safe_region_add(rw_data_after_image, KB(1),
|
||||
SYS_MEM_SAFE_WRITE);
|
||||
if (region_add_rc < 0) {
|
||||
TC_PRINT("PASS\n");
|
||||
} else {
|
||||
TC_PRINT("FAIL\n");
|
||||
}
|
||||
|
||||
update_rv(&rv, test_width_read(ro_data_after_image, 1, 0));
|
||||
update_rv(&rv, test_width_read(ro_data_after_image_end - 1, 1, 0));
|
||||
update_rv(&rv, test_width_read(rw_data_after_image, 1, 0));
|
||||
update_rv(&rv, test_width_read(rw_data_after_image_end - 1, 1, 0));
|
||||
|
||||
update_rv(&rv, test_width_write(ro_data_after_image, 1, -EFAULT));
|
||||
update_rv(&rv, test_width_write(ro_data_after_image_end - 1, 1, -EFAULT));
|
||||
update_rv(&rv, test_width_write(rw_data_after_image, 1, 0));
|
||||
update_rv(&rv, test_width_write(rw_data_after_image_end - 1, 1, 0));
|
||||
|
||||
update_rv(&rv, test_width_read(ro_data_after_image - 1, 1, -EFAULT));
|
||||
update_rv(&rv, test_width_read(ro_data_after_image_end, 1, -EFAULT));
|
||||
update_rv(&rv, test_width_read(rw_data_after_image - 1, 1, -EFAULT));
|
||||
update_rv(&rv, test_width_read(rw_data_after_image_end, 1, -EFAULT));
|
||||
|
||||
/*
|
||||
* Test the dividing line between rom and ram, even in non-xip images:
|
||||
* it might hit ROM or invalid memory, but never RAM.
|
||||
*/
|
||||
update_rv(&rv, test_width_write(p_image_ram_start - 1, 1, -EFAULT));
|
||||
|
||||
TC_PRINT("testing SUCCESS of _mem_probe() reading RO values.......");
|
||||
(void)_mem_probe(rodata, SYS_MEM_SAFE_READ, 4, buffer);
|
||||
(void)_mem_probe(rodata+4, SYS_MEM_SAFE_READ, 4, buffer+4);
|
||||
(void)_mem_probe(rodata+8, SYS_MEM_SAFE_READ, 2, buffer+8);
|
||||
(void)_mem_probe(rodata+10, SYS_MEM_SAFE_READ, 2, buffer+10);
|
||||
(void)_mem_probe(rodata+12, SYS_MEM_SAFE_READ, 1, buffer+12);
|
||||
(void)_mem_probe(rodata+13, SYS_MEM_SAFE_READ, 1, buffer+13);
|
||||
(void)_mem_probe(rodata+14, SYS_MEM_SAFE_READ, 1, buffer+14);
|
||||
(void)_mem_probe(rodata+15, SYS_MEM_SAFE_READ, 1, buffer+15);
|
||||
|
||||
if (memcmp(rodata, buffer, 16) != 0) {
|
||||
TC_PRINT("FAIL\n");
|
||||
update_rv(&rv, TC_FAIL);
|
||||
} else {
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
|
||||
memcpy(rwdata, rodata, MY_DATA_SIZE);
|
||||
memset(buffer, '-', MY_DATA_SIZE);
|
||||
|
||||
TC_PRINT("testing SUCCESS of _mem_probe() reading RW values.......");
|
||||
(void)_mem_probe(rwdata, SYS_MEM_SAFE_READ, 4, buffer);
|
||||
(void)_mem_probe(rwdata+4, SYS_MEM_SAFE_READ, 4, buffer+4);
|
||||
(void)_mem_probe(rwdata+8, SYS_MEM_SAFE_READ, 2, buffer+8);
|
||||
(void)_mem_probe(rwdata+10, SYS_MEM_SAFE_READ, 2, buffer+10);
|
||||
(void)_mem_probe(rwdata+12, SYS_MEM_SAFE_READ, 1, buffer+12);
|
||||
(void)_mem_probe(rwdata+13, SYS_MEM_SAFE_READ, 1, buffer+13);
|
||||
(void)_mem_probe(rwdata+14, SYS_MEM_SAFE_READ, 1, buffer+14);
|
||||
(void)_mem_probe(rwdata+15, SYS_MEM_SAFE_READ, 1, buffer+15);
|
||||
|
||||
if (memcmp(rwdata, buffer, 16) != 0) {
|
||||
TC_PRINT("FAIL\n");
|
||||
update_rv(&rv, TC_FAIL);
|
||||
} else {
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
|
||||
memcpy(buffer, rodata, MY_DATA_SIZE);
|
||||
memset(rwdata, '-', MY_DATA_SIZE);
|
||||
|
||||
TC_PRINT("testing SUCCESS of _mem_probe() writing values.......");
|
||||
(void)_mem_probe(rwdata, SYS_MEM_SAFE_WRITE, 4, buffer);
|
||||
(void)_mem_probe(rwdata+4, SYS_MEM_SAFE_WRITE, 4, buffer+4);
|
||||
(void)_mem_probe(rwdata+8, SYS_MEM_SAFE_WRITE, 2, buffer+8);
|
||||
(void)_mem_probe(rwdata+10, SYS_MEM_SAFE_WRITE, 2, buffer+10);
|
||||
(void)_mem_probe(rwdata+12, SYS_MEM_SAFE_WRITE, 1, buffer+12);
|
||||
(void)_mem_probe(rwdata+13, SYS_MEM_SAFE_WRITE, 1, buffer+13);
|
||||
(void)_mem_probe(rwdata+14, SYS_MEM_SAFE_WRITE, 1, buffer+14);
|
||||
(void)_mem_probe(rwdata+15, SYS_MEM_SAFE_WRITE, 1, buffer+15);
|
||||
|
||||
if (memcmp(rwdata, buffer, 16) != 0) {
|
||||
TC_PRINT("FAIL\n");
|
||||
update_rv(&rv, TC_FAIL);
|
||||
} else {
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
|
||||
/*****
|
||||
* _mem_safe_read()
|
||||
*/
|
||||
|
||||
memset(buffer, '-', MY_DATA_SIZE);
|
||||
|
||||
update_rv(&rv, test_mem_safe_access(rodata, buffer, MY_DATA_SIZE,
|
||||
0, SYS_MEM_SAFE_READ));
|
||||
|
||||
update_rv(&rv, test_mem_safe_access(rodata, buffer, MY_DATA_SIZE,
|
||||
4, SYS_MEM_SAFE_READ));
|
||||
|
||||
update_rv(&rv, test_mem_safe_access(rodata, buffer, MY_DATA_SIZE-2,
|
||||
2, SYS_MEM_SAFE_READ));
|
||||
|
||||
update_rv(&rv, test_mem_safe_access(rodata, buffer, MY_DATA_SIZE-1,
|
||||
1, SYS_MEM_SAFE_READ));
|
||||
|
||||
TC_PRINT("testing FAILURE of _mem_safe_read() with bad params.......");
|
||||
rc = _mem_safe_read(rodata+1, buffer, MY_DATA_SIZE-1, 2);
|
||||
if (rc == 0) {
|
||||
TC_PRINT("FAIL\n");
|
||||
update_rv(&rv, TC_FAIL);
|
||||
} else {
|
||||
TC_PRINT("PASS (%d)\n", rc);
|
||||
}
|
||||
|
||||
|
||||
/*****
|
||||
* _mem_safe_write()
|
||||
*/
|
||||
|
||||
memcpy(buffer, rodata, MY_DATA_SIZE);
|
||||
memset(rwdata, '-', MY_DATA_SIZE);
|
||||
update_rv(&rv, test_mem_safe_access(rwdata, buffer, MY_DATA_SIZE,
|
||||
0, SYS_MEM_SAFE_WRITE));
|
||||
|
||||
memcpy(buffer, rodata, MY_DATA_SIZE);
|
||||
memset(rwdata, '-', MY_DATA_SIZE);
|
||||
update_rv(&rv, test_mem_safe_access(rwdata, buffer, MY_DATA_SIZE,
|
||||
4, SYS_MEM_SAFE_WRITE));
|
||||
|
||||
memcpy(buffer, rodata, MY_DATA_SIZE);
|
||||
memset(rwdata, '-', MY_DATA_SIZE);
|
||||
update_rv(&rv, test_mem_safe_access(rwdata, buffer, MY_DATA_SIZE - 2,
|
||||
2, SYS_MEM_SAFE_WRITE));
|
||||
|
||||
memcpy(buffer, rodata, MY_DATA_SIZE);
|
||||
memset(rwdata, '-', MY_DATA_SIZE);
|
||||
update_rv(&rv, test_mem_safe_access(rwdata, buffer, MY_DATA_SIZE - 1,
|
||||
1, SYS_MEM_SAFE_WRITE));
|
||||
|
||||
memcpy(buffer, rodata, MY_DATA_SIZE);
|
||||
memset(rwdata, '-', MY_DATA_SIZE);
|
||||
|
||||
TC_PRINT("testing FAILURE of _mem_safe_write() with bad params.......");
|
||||
rc = _mem_safe_write(rwdata+1, buffer, MY_DATA_SIZE-1, 2);
|
||||
if (rc == 0) {
|
||||
TC_PRINT("FAIL\n");
|
||||
update_rv(&rv, TC_FAIL);
|
||||
} else {
|
||||
TC_PRINT("PASS (%d)\n", rc);
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_XIP)
|
||||
/*****
|
||||
* _mem_safe_write_to_text_section()
|
||||
*/
|
||||
|
||||
extern void add_ten_to_foo(void);
|
||||
foo = 0;
|
||||
memset(buffer, 0x90, 7);
|
||||
|
||||
TC_PRINT("testing FAILURE of _mem_safe_write_to_text_section(&data).......");
|
||||
if (_mem_safe_write_to_text_section(&foo, buffer, 1) == 0) {
|
||||
TC_PRINT("FAIL\n");
|
||||
} else {
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
|
||||
TC_PRINT("testing SUCCESS of _mem_safe_write_to_text_section(&text).......");
|
||||
add_ten_to_foo();
|
||||
if (foo != 10) {
|
||||
TC_PRINT("FAIL\n");
|
||||
} else {
|
||||
if (_mem_safe_write_to_text_section((void *)add_ten_to_foo,
|
||||
buffer, 7) < 0) {
|
||||
TC_PRINT("FAIL\n");
|
||||
} else {
|
||||
|
||||
sys_cache_flush((vaddr_t)add_ten_to_foo, 7);
|
||||
add_ten_to_foo();
|
||||
if (foo != 10) {
|
||||
TC_PRINT("FAIL\n");
|
||||
} else {
|
||||
TC_PRINT("PASS\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TC_END_RESULT(rv);
|
||||
TC_END_REPORT(rv);
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
[test]
|
||||
tags = kernel core
|
||||
platform_whitelist = qemu_x86 qemu_cortex_m3
|
||||
filter = not CONFIG_X86_IAMCU
|
||||
timeout = 200
|
Loading…
Add table
Add a link
Reference in a new issue