mirror of
https://github.com/ringtailsoftware/uvm32.git
synced 2026-06-05 22:43:39 +00:00
Test parsing of syscall args, and responses to invalid behaviour
This commit is contained in:
parent
46b6d1efba
commit
9d9e7542fc
5 changed files with 301 additions and 0 deletions
33
test/syscall_args/Makefile
Normal file
33
test/syscall_args/Makefile
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
C_COMPILER=gcc
|
||||||
|
|
||||||
|
UNITY_ROOT=../unity
|
||||||
|
|
||||||
|
CFLAGS=-std=c99
|
||||||
|
CFLAGS += -Wall
|
||||||
|
CFLAGS += -Werror
|
||||||
|
CFLAGS += -DUVM32_MEMORY_SIZE=16384
|
||||||
|
|
||||||
|
SUITE_NAME=tests
|
||||||
|
|
||||||
|
TARGET_BASE1=test1
|
||||||
|
TARGET1 = $(TARGET_BASE1)
|
||||||
|
SRC_FILES1=$(UNITY_ROOT)/src/unity.c test/${SUITE_NAME}.c test/test_runners/${SUITE_NAME}_Runner.c ../../uvm32/uvm32.c
|
||||||
|
INC_DIRS=-I$(UNITY_ROOT)/src -I../../uvm32/ -I../../common -Irom
|
||||||
|
|
||||||
|
.PHONY: rom
|
||||||
|
|
||||||
|
default: $(SRC_FILES1) rom
|
||||||
|
@$(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(SYMBOLS) $(SRC_FILES1) rom/rom-header.c -o $(TARGET1)
|
||||||
|
@ ./$(TARGET1)
|
||||||
|
|
||||||
|
rom:
|
||||||
|
@(cd rom && make)
|
||||||
|
|
||||||
|
test/test_runners/${SUITE_NAME}_Runner.c: test/${SUITE_NAME}.c
|
||||||
|
@mkdir -p test/test_runners
|
||||||
|
@ruby $(UNITY_ROOT)/auto/generate_test_runner.rb test/${SUITE_NAME}.c test/test_runners/${SUITE_NAME}_Runner.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(TARGET1) test/test_runners
|
||||||
|
(cd rom && make clean)
|
||||||
|
|
||||||
13
test/syscall_args/rom/Makefile
Normal file
13
test/syscall_args/rom/Makefile
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
TOPDIR=../../../
|
||||||
|
PROJECT:=$(shell basename ${PWD})
|
||||||
|
SRCS=${PROJECT}.c ${TOPDIR}/apps/crt0.S
|
||||||
|
all: all_common
|
||||||
|
@# Convert ROM to C file and header
|
||||||
|
@xxd -i ${PROJECT}.bin > ${PROJECT}-header.c
|
||||||
|
@echo "extern unsigned char ${PROJECT}_bin[]; extern int ${PROJECT}_bin_len;" > ${PROJECT}-header.h
|
||||||
|
|
||||||
|
test: test_common
|
||||||
|
clean: clean_common
|
||||||
|
rm -f ${PROJECT}-header.h ${PROJECT}-header.c
|
||||||
|
|
||||||
|
include ${TOPDIR}/apps/makefile.common
|
||||||
68
test/syscall_args/rom/rom.c
Normal file
68
test/syscall_args/rom/rom.c
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
#include "uvm32_target.h"
|
||||||
|
#include "../shared.h"
|
||||||
|
|
||||||
|
void syscall_a_test(void) {
|
||||||
|
// two strings
|
||||||
|
syscall((uint32_t)SYSCALL_A, (uint32_t)SYSCALL_A_DATA0, (uint32_t)SYSCALL_A_DATA1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void syscall_b_test(void) {
|
||||||
|
// two null values
|
||||||
|
syscall((uint32_t)SYSCALL_B, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void syscall_c_test(void) {
|
||||||
|
// valid buffer
|
||||||
|
uint8_t buf[32];
|
||||||
|
for (int i=0;i<32;i++) {
|
||||||
|
buf[i] = i;
|
||||||
|
}
|
||||||
|
syscall((uint32_t)SYSCALL_C, (uint32_t)buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
void syscall_d_test(void) {
|
||||||
|
// invalid address
|
||||||
|
syscall((uint32_t)SYSCALL_D, 0xFF000000, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void syscall_ef_test(void) {
|
||||||
|
// ask for two values, then send them back
|
||||||
|
uint32_t a, b;
|
||||||
|
syscall((uint32_t)SYSCALL_E, (uint32_t)&a, (uint32_t)&b);
|
||||||
|
syscall((uint32_t)SYSCALL_F, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void syscall_gh_test(void) {
|
||||||
|
// ask for a buffer, mutate it, send it back
|
||||||
|
uint8_t buf[32];
|
||||||
|
syscall((uint32_t)SYSCALL_G, (uint32_t)buf, 32);
|
||||||
|
for (int i=0;i<32;i++) {
|
||||||
|
buf[i] *= 2;
|
||||||
|
}
|
||||||
|
syscall((uint32_t)SYSCALL_H, (uint32_t)buf, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
switch(syscall(SYSCALL_PICKTEST, 0, 0)) {
|
||||||
|
case SYSCALL_A:
|
||||||
|
syscall_a_test();
|
||||||
|
break;
|
||||||
|
case SYSCALL_B:
|
||||||
|
syscall_b_test();
|
||||||
|
break;
|
||||||
|
case SYSCALL_C:
|
||||||
|
syscall_c_test();
|
||||||
|
break;
|
||||||
|
case SYSCALL_D:
|
||||||
|
syscall_d_test();
|
||||||
|
break;
|
||||||
|
case SYSCALL_E:
|
||||||
|
syscall_ef_test();
|
||||||
|
break;
|
||||||
|
case SYSCALL_G:
|
||||||
|
syscall_gh_test();
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
16
test/syscall_args/shared.h
Normal file
16
test/syscall_args/shared.h
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#define SYSCALL_BASE 0x200
|
||||||
|
|
||||||
|
|
||||||
|
#define SYSCALL_A_DATA0 "Hello\033" // non-printing char
|
||||||
|
#define SYSCALL_A_DATA1 "" // empty string
|
||||||
|
|
||||||
|
#define SYSCALL_PICKTEST SYSCALL_BASE+0
|
||||||
|
#define SYSCALL_A SYSCALL_BASE+1
|
||||||
|
#define SYSCALL_B SYSCALL_BASE+2
|
||||||
|
#define SYSCALL_C SYSCALL_BASE+3
|
||||||
|
#define SYSCALL_D SYSCALL_BASE+4
|
||||||
|
#define SYSCALL_E SYSCALL_BASE+5
|
||||||
|
#define SYSCALL_F SYSCALL_BASE+6
|
||||||
|
#define SYSCALL_G SYSCALL_BASE+7
|
||||||
|
#define SYSCALL_H SYSCALL_BASE+8
|
||||||
|
|
||||||
171
test/syscall_args/test/tests.c
Normal file
171
test/syscall_args/test/tests.c
Normal file
|
|
@ -0,0 +1,171 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include "unity.h"
|
||||||
|
#include "uvm32.h"
|
||||||
|
#include "../common/uvm32_common_custom.h"
|
||||||
|
|
||||||
|
#include "rom-header.h"
|
||||||
|
#include "../shared.h"
|
||||||
|
|
||||||
|
static uvm32_state_t vmst;
|
||||||
|
static uvm32_evt_t evt;
|
||||||
|
|
||||||
|
void setUp(void) {
|
||||||
|
// runs before each test
|
||||||
|
uvm32_init(&vmst);
|
||||||
|
uvm32_load(&vmst, rom_bin, rom_bin_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tearDown(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_syscall_args_two_strings(void) {
|
||||||
|
// run the vm
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
// check for picktest syscall
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_PICKTEST);
|
||||||
|
uvm32_setval(&vmst, &evt, RET, SYSCALL_A);
|
||||||
|
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_A);
|
||||||
|
TEST_ASSERT_EQUAL(0, strcmp(uvm32_getcstr(&vmst, &evt, ARG0), SYSCALL_A_DATA0));
|
||||||
|
TEST_ASSERT_EQUAL(0, strcmp(uvm32_getcstr(&vmst, &evt, ARG1), SYSCALL_A_DATA1));
|
||||||
|
// run vm to completion
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_syscall_args_bad_string(void) {
|
||||||
|
// run the vm
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
// check for picktest syscall
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_PICKTEST);
|
||||||
|
uvm32_setval(&vmst, &evt, RET, SYSCALL_B);
|
||||||
|
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_B);
|
||||||
|
|
||||||
|
// try to read C string from the first null ptr
|
||||||
|
const char *s0 = uvm32_getcstr(&vmst, &evt, ARG0);
|
||||||
|
TEST_ASSERT_EQUAL(0, strlen(s0)); // tried to read a null pointer, get back a zero length string (not a NULL we might read)
|
||||||
|
// attempt to run vm, should be stuck in err
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_ERR);
|
||||||
|
|
||||||
|
// try to read C string from the second null ptr
|
||||||
|
const char *s1 = uvm32_getcstr(&vmst, &evt, ARG1);
|
||||||
|
TEST_ASSERT_EQUAL(0, strlen(s1)); // tried to read a null pointer, get back a zero length string (not a NULL we might read)
|
||||||
|
// attempt to run vm, should be stuck in err
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_ERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_syscall_args_bufrd(void) {
|
||||||
|
// run the vm
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
// check for picktest syscall
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_PICKTEST);
|
||||||
|
uvm32_setval(&vmst, &evt, RET, SYSCALL_C);
|
||||||
|
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_C);
|
||||||
|
|
||||||
|
// get buffer described by ptr=ARG0,len=ARG1
|
||||||
|
uvm32_evt_syscall_buf_t buf = uvm32_getbuf(&vmst, &evt, ARG0, ARG1);
|
||||||
|
uint8_t expected[32];
|
||||||
|
for (int i=0;i<32;i++) {
|
||||||
|
expected[i] = i;
|
||||||
|
}
|
||||||
|
TEST_ASSERT_EQUAL(32, buf.len);
|
||||||
|
TEST_ASSERT_EQUAL(0, memcmp(buf.ptr, expected, 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_syscall_args_bufrd_bad_addr(void) {
|
||||||
|
// run the vm
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
// check for picktest syscall
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_PICKTEST);
|
||||||
|
uvm32_setval(&vmst, &evt, RET, SYSCALL_D);
|
||||||
|
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_D);
|
||||||
|
|
||||||
|
// get buffer described by ptr=ARG0,len=ARG1
|
||||||
|
uvm32_evt_syscall_buf_t buf = uvm32_getbuf(&vmst, &evt, ARG0, ARG1);
|
||||||
|
TEST_ASSERT_EQUAL(0, buf.len); // it was invalid, should get a safe zero length buffer
|
||||||
|
// attempt to run vm, should be stuck in err
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_ERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_syscall_args_bufrd_ptrs(void) {
|
||||||
|
// run the vm
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
// check for picktest syscall
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_PICKTEST);
|
||||||
|
uvm32_setval(&vmst, &evt, RET, SYSCALL_E);
|
||||||
|
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_E);
|
||||||
|
|
||||||
|
// get uint32_t buffer described by ptr=ARG0
|
||||||
|
uvm32_evt_syscall_buf_t buf0 = uvm32_getbuf_fixed(&vmst, &evt, ARG0, 4);
|
||||||
|
TEST_ASSERT_EQUAL(4, buf0.len); // check read ok
|
||||||
|
uint32_t rspa = 0xABCD1234;
|
||||||
|
memcpy(buf0.ptr, &rspa, 4); // send it back
|
||||||
|
|
||||||
|
// get uint32_t buffer described by ptr=ARG1
|
||||||
|
uvm32_evt_syscall_buf_t buf1 = uvm32_getbuf_fixed(&vmst, &evt, ARG1, 4);
|
||||||
|
TEST_ASSERT_EQUAL(4, buf1.len); // check read ok
|
||||||
|
uint32_t rspb = 0x9876DECF;
|
||||||
|
memcpy(buf1.ptr, &rspb, 4); // send it back
|
||||||
|
|
||||||
|
// check the same values are sent back
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_F);
|
||||||
|
TEST_ASSERT_EQUAL(rspa, uvm32_getval(&vmst, &evt, ARG0));
|
||||||
|
TEST_ASSERT_EQUAL(rspb, uvm32_getval(&vmst, &evt, ARG1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_syscall_args_buf_pass(void) {
|
||||||
|
// run the vm
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
// check for picktest syscall
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_PICKTEST);
|
||||||
|
uvm32_setval(&vmst, &evt, RET, SYSCALL_G);
|
||||||
|
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_G);
|
||||||
|
|
||||||
|
// get buffer described by ptr=ARG0,len=ARG1
|
||||||
|
uvm32_evt_syscall_buf_t buf0 = uvm32_getbuf(&vmst, &evt, ARG0, ARG1);
|
||||||
|
TEST_ASSERT_EQUAL(32, buf0.len);
|
||||||
|
// fill with a pattern
|
||||||
|
for (int i=0;i<32;i++) {
|
||||||
|
buf0.ptr[i] = i;
|
||||||
|
}
|
||||||
|
// expect every element to be doubled then sent back
|
||||||
|
uvm32_run(&vmst, &evt, 1000);
|
||||||
|
TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_SYSCALL);
|
||||||
|
TEST_ASSERT_EQUAL(evt.data.syscall.code, SYSCALL_H);
|
||||||
|
|
||||||
|
// get buffer described by ptr=ARG0,len=ARG1
|
||||||
|
uvm32_evt_syscall_buf_t buf1 = uvm32_getbuf(&vmst, &evt, ARG0, ARG1);
|
||||||
|
TEST_ASSERT_EQUAL(32, buf1.len);
|
||||||
|
for (int i=0;i<32;i++) {
|
||||||
|
TEST_ASSERT_EQUAL(i*2, buf1.ptr[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue