diff --git a/src/syscall/proc.c b/src/syscall/proc.c index fe2aa533..48e9e629 100644 --- a/src/syscall/proc.c +++ b/src/syscall/proc.c @@ -1074,9 +1074,7 @@ int64_t sys_ptrace(guest_t *g, _Static_assert(sizeof(struct rusage) == sizeof(linux_rusage_t), "host and guest rusage layouts must match on LP64"); -static int write_rusage_to_guest(guest_t *g, - uint64_t gva, - const struct rusage *ru) +int write_rusage_to_guest(guest_t *g, uint64_t gva, const struct rusage *ru) { linux_rusage_t lru; memcpy(&lru, ru, sizeof(lru)); diff --git a/src/syscall/proc.h b/src/syscall/proc.h index b57686c7..03830413 100644 --- a/src/syscall/proc.h +++ b/src/syscall/proc.h @@ -323,6 +323,13 @@ void proc_children_cpu_add(const struct rusage *ru); /* Read the accumulated guest-children CPU time, in microseconds. */ void proc_children_cpu_us(uint64_t *utime_us, uint64_t *stime_us); +/* Write a macOS struct rusage to guest memory as linux_rusage_t. The field + * layout matches on LP64; ru_maxrss is converted from macOS bytes to Linux + * kilobytes. Returns the guest_write_small result (0 on success, negative on + * fault). + */ +int write_rusage_to_guest(guest_t *g, uint64_t gva, const struct rusage *ru); + /* Collect host PIDs of active (non-exited) fork children. Writes up to max_pids * entries into out[]. * diff --git a/src/syscall/sys.c b/src/syscall/sys.c index 09ebe7dd..1abb4ea3 100644 --- a/src/syscall/sys.c +++ b/src/syscall/sys.c @@ -74,8 +74,9 @@ static linux_rlimit64_t guest_nofile_limit = { }; #define RLIMIT_CACHE_SIZE ((int) (ARRAY_SIZE(cached_linux_rlimits))) -_Static_assert(sizeof(struct rusage) == sizeof(linux_rusage_t), - "host and guest rusage layouts must match on LP64"); +/* The full-size assertion lives with write_rusage_to_guest() in proc.c; this + * offset check guards the fast memcpy translation done there. + */ _Static_assert(offsetof(struct rusage, ru_maxrss) == offsetof(linux_rusage_t, ru_maxrss), "ru_maxrss offset must stay aligned for fast translation"); @@ -529,12 +530,7 @@ int64_t sys_getrusage(guest_t *g, int who, uint64_t usage_gva) if (getrusage(who, &mac_usage) < 0) return linux_errno(); - linux_rusage_t lin_usage; - memcpy(&lin_usage, &mac_usage, sizeof(lin_usage)); - lin_usage.ru_maxrss = - mac_usage.ru_maxrss / 1024; /* macOS: bytes -> Linux: KB */ - - if (guest_write_small(g, usage_gva, &lin_usage, sizeof(lin_usage)) < 0) + if (write_rusage_to_guest(g, usage_gva, &mac_usage) < 0) return -LINUX_EFAULT; return 0;