From 74267d94dfa52c00dd3f2937f91c406ec2eaa2d2 Mon Sep 17 00:00:00 2001 From: Toby Jaffey Date: Fri, 12 Dec 2025 14:45:25 +0000 Subject: [PATCH] Handle syscall cstring argument when pointing to extram --- test/extram/rom/rom.c | 19 ++++++++++++++ test/extram/test/tests.c | 40 +++++++++++++++++++++++++++++ uvm32/uvm32.c | 54 ++++++++++++++++++++++++++++++---------- 3 files changed, 100 insertions(+), 13 deletions(-) diff --git a/test/extram/rom/rom.c b/test/extram/rom/rom.c index 9b8367e..2bc3b0f 100644 --- a/test/extram/rom/rom.c +++ b/test/extram/rom/rom.c @@ -42,6 +42,25 @@ void main(void) { uint16_t *p = (uint16_t *)UVM32_EXTRAM_BASE; printdec(p[7]); // short read } break; + case TEST9: { + uint8_t *p = (uint8_t *)UVM32_EXTRAM_BASE; + p[0] = 'h'; + p[1] = 'e'; + p[2] = 'l'; + p[3] = 'l'; + p[4] = 'o'; + printbuf(p, 5); // try to print from extram (unterminated) + } break; + case TEST10: { + uint8_t *p = (uint8_t *)UVM32_EXTRAM_BASE; + p[0] = 'h'; + p[1] = 'e'; + p[2] = 'l'; + p[3] = 'l'; + p[4] = 'o'; + p[5] = '\0'; + println(p); // try to print from extram (terminated) + } break; } } diff --git a/test/extram/test/tests.c b/test/extram/test/tests.c index 21e8e9a..88e3bdd 100644 --- a/test/extram/test/tests.c +++ b/test/extram/test/tests.c @@ -189,4 +189,44 @@ void test_extram_short_read(void) { TEST_ASSERT_EQUAL(0xCDEF, uvm32_getval(&vmst, &evt, ARG0)); } +void test_extram_buf_unterminated(void) { + // run the vm + uvm32_run(&vmst, &evt, 100); + TEST_ASSERT_EQUAL(false, uvm32_extramDirty(&vmst)); + + // 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, TEST9); + + uvm32_run(&vmst, &evt, 100); + TEST_ASSERT_EQUAL(true, uvm32_extramDirty(&vmst)); + // check for printbuf of val + TEST_ASSERT_EQUAL(UVM32_EVT_SYSCALL, evt.typ); + TEST_ASSERT_EQUAL(evt.data.syscall.code, UVM32_SYSCALL_PRINTBUF); + uvm32_evt_syscall_buf_t buf = uvm32_getbuf(&vmst, &evt, ARG0, ARG1); + TEST_ASSERT_EQUAL(5, buf.len); + TEST_ASSERT_EQUAL(0, memcmp(buf.ptr, "hello", 5)); +} + +void test_extram_buf_terminated(void) { + // run the vm + uvm32_run(&vmst, &evt, 100); + TEST_ASSERT_EQUAL(false, uvm32_extramDirty(&vmst)); + + // 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, TEST9); + + uvm32_run(&vmst, &evt, 100); + TEST_ASSERT_EQUAL(true, uvm32_extramDirty(&vmst)); + // check for printbuf of val + TEST_ASSERT_EQUAL(UVM32_EVT_SYSCALL, evt.typ); + TEST_ASSERT_EQUAL(evt.data.syscall.code, UVM32_SYSCALL_PRINTBUF); + const char *str = uvm32_getcstr(&vmst, &evt, ARG0); + TEST_ASSERT_NOT_EQUAL(NULL, str); + TEST_ASSERT_EQUAL(0, strcmp(str, "hello")); +} + diff --git a/uvm32/uvm32.c b/uvm32/uvm32.c index 122bd33..9ce2c68 100644 --- a/uvm32/uvm32.c +++ b/uvm32/uvm32.c @@ -104,26 +104,54 @@ bool uvm32_load(uvm32_state_t *vmst, const uint8_t *rom, int len) { // Read C-string up to terminator and return len,ptr bool get_safeptr_null_terminated(uvm32_state_t *vmst, uint32_t addr, uvm32_evt_syscall_buf_t *buf) { - uint32_t ptrstart = addr - MINIRV32_RAM_IMAGE_OFFSET; - uint32_t p = ptrstart; - if (p >= UVM32_MEMORY_SIZE) { - setStatusErr(vmst, UVM32_ERR_MEM_RD); - buf->ptr = (uint8_t *)NULL; - buf->len = 0; - return false; - } - while(vmst->memory[p] != '\0') { - p++; + if (MINIRV32_MMIO_RANGE(addr)) { + if (vmst->extram == NULL) { + return false; + } else { + + uint32_t ptrstart = addr - UVM32_EXTRAM_BASE;; + uint32_t p = ptrstart; + if (p >= vmst->extramLen) { + setStatusErr(vmst, UVM32_ERR_MEM_RD); + buf->ptr = (uint8_t *)NULL; + buf->len = 0; + return false; + } + while(vmst->memory[p] != '\0') { + p++; + if (p >= vmst->extramLen) { + setStatusErr(vmst, UVM32_ERR_MEM_RD); + buf->ptr = (uint8_t *)NULL; + buf->len = 0; + return false; + } + } + buf->ptr = (uint8_t *)&vmst->extram[ptrstart/4]; // extram is uint32_t* + buf->len = p - ptrstart; + return true; + } + } else { + uint32_t ptrstart = addr - MINIRV32_RAM_IMAGE_OFFSET; + uint32_t p = ptrstart; if (p >= UVM32_MEMORY_SIZE) { setStatusErr(vmst, UVM32_ERR_MEM_RD); buf->ptr = (uint8_t *)NULL; buf->len = 0; return false; } + while(vmst->memory[p] != '\0') { + p++; + if (p >= UVM32_MEMORY_SIZE) { + setStatusErr(vmst, UVM32_ERR_MEM_RD); + buf->ptr = (uint8_t *)NULL; + buf->len = 0; + return false; + } + } + buf->ptr = &vmst->memory[ptrstart]; + buf->len = p - ptrstart; + return true; } - buf->ptr = &vmst->memory[ptrstart]; - buf->len = p - ptrstart; - return true; } bool get_safeptr(uvm32_state_t *vmst, uint32_t addr, uint32_t len, uvm32_evt_syscall_buf_t *buf) {