commit 9cb5624e66351c704ec986b94d38389a923eafdf from: Benjamin Stürz date: Fri Jul 19 18:33:03 2024 UTC fix readv & writev commit - e24fa9f6d4fd3018196358ea4be202b60f9c6a88 commit + 9cb5624e66351c704ec986b94d38389a923eafdf blob - ad3b92558169ad5a4f69fdba5a972d750e48c16f blob + 4c921f64a2976a7a459f2cb885b1080547dda6ff --- src/data.dst +++ src/data.dst @@ -26,3 +26,8 @@ struct elf64_phdr { memsz: u64, aign: u64, }; + +struct linux_iovec { + base: u64, + len: u64, +}; blob - 5ce02ee3ef69ce0d1b9549ae62ac662c1fd8bbd2 blob + ebb28a6be67eeb7b23209862c78f9fd75a3a20c9 --- src/ecall.c +++ src/ecall.c @@ -480,13 +480,32 @@ void ecall (void) dbg ("write(%d, %p, %zu)", i0, ptr (const void, a1), (size_t)a2); break; case SYS_readv: - ret = map (readv (i0, ptr (const struct iovec, a1), i2)); - dbg ("readv(%d, %p, %d)", i0, ptr (const struct iovec, a1), i2); - break; case SYS_writev: - ret = map (writev (i0, ptr (const struct iovec, a1), i2)); - dbg ("writev(%d, %p, %d)", i0, ptr (const struct iovec, a1), i2); + { + const uint8_t *piv = ptr (const uint8_t, a1); + struct linux_iovec liv; + struct iovec *iov; + size_t num = i2; + + iov = calloc (num, sizeof (*iov)); + + for (size_t i = 0; i < num; ++i) { + decode_linux_iovec (&liv, piv + i * sizeof (liv)); + iov[i].iov_base = (void *)liv.base; + iov[i].iov_len = (size_t)liv.len; + } + + if (a7 == SYS_readv) { + ret = map (readv (i0, iov, num)); + dbg ("readv(%d, %p, %zu)", i0, piv, num); + } else { + ret = map (writev (i0, iov, i2)); + dbg ("writev(%d, %p, %d)", i0, piv, i2); + } + + free (iov); break; + } case SYS_pread: ret = map (pread (i0, ptr (void, a1), (size_t)a2, (off_t)a3)); dbg ("pread(%d, %p, %zu, %llu)", i0, ptr (void, a1), (size_t)a2, (unsigned long long)a3);