From ad36c8765d8a2fae0bf33460588f815d136ac9a0 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Thu, 31 Aug 2023 16:25:50 -0500 Subject: [PATCH] Michael Shavit hit a problem with 8 byte wide writes, so switch from signed atolx() to unsigned strtoul() which has the side effect of not parsing the kmg suffixes. (Poke me if I should mention that in the help text...) Test cases (with results from another implementation): $ devmem 0x000000008b300000 8 0x8FFFFFFFFFFFFFFF $ devmem 0x000000008b300000 8 0x8fffffffffffffff $ devmem 0x000000008b300000 8 500k $ devmem 0x000000008b300000 8 0x0000000007d000 $ devmem 0x000000008b300000 8 0xFFFFFFFFFFFFFFFF $ devmem 0x000000008b300000 8 0xffffffffffffffff $ devmem 0x000000008b300000 4 0xFFFFFFFF $ devmem 0x000000008b300000 4 0xffffffff $ devmem 0x000000008b300000 4 0x1FFFFFFFF devmem: data: 8589934591 exceeds write width: 4 Dunno how to set up a qemu instance that can devmem for testing under mkroot, so no tests/devmem.test yet. (And it wouldn't be target agnostic like the rest of the tests anyway. Hmmm...) --- toys/other/devmem.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/toys/other/devmem.c b/toys/other/devmem.c index 9c4dd871..4d558fb4 100644 --- a/toys/other/devmem.c +++ b/toys/other/devmem.c @@ -17,11 +17,20 @@ config DEVMEM #define FOR_devmem #include "toys.h" +unsigned long long atollu(char *str) +{ + char *end = str; + unsigned long long llu = strtoul(str, &end, 0); + + if (*end) error_exit("bad %s", str); + + return llu; +} + void devmem_main(void) { int writing = toys.optc == 3, page_size = sysconf(_SC_PAGESIZE), bytes = 4,fd; - unsigned long long data = 0, map_off, map_len; - unsigned long addr = atolx(*toys.optargs); + unsigned long long data = 0, map_off, map_len, addr = atollu(*toys.optargs); void *map, *p; // WIDTH? @@ -34,13 +43,14 @@ void devmem_main(void) } // DATA? Report out of range values as errors rather than truncating. - if (writing) data = atolx_range(toys.optargs[2], 0, (1ULL<<(8*bytes))-1); + if (writing && (data = atollu(toys.optargs[2]))>(~0ULL)>>(64-8*bytes)) + error_exit("%llx>%d bytes", data, bytes); // Map in just enough. if (CFG_TOYBOX_FORK) { fd = xopen("/dev/mem", (writing ? O_RDWR : O_RDONLY) | O_SYNC); - map_off = addr & ~(page_size - 1); + map_off = addr & ~(page_size - 1ULL); map_len = (addr+bytes-map_off); map = xmmap(0, map_len, writing ? PROT_WRITE : PROT_READ, MAP_SHARED, fd, map_off); -- 2.39.2