From 98343f1e12c3b04a88ea3093f6f13105ae04f349 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 7 Jun 2026 13:49:32 +0100 Subject: [PATCH] libc: core: add mitigation for a potential bochs issue in strtoll --- lib/libc/core/stdlib/strtoll.c | 35 ++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/libc/core/stdlib/strtoll.c b/lib/libc/core/stdlib/strtoll.c index 0e3e008..7d88ef8 100644 --- a/lib/libc/core/stdlib/strtoll.c +++ b/lib/libc/core/stdlib/strtoll.c @@ -28,14 +28,14 @@ * SUCH DAMAGE. */ +#include #include #include #include +#include +#include -long long strtoll( - const char *restrict ptr, - char **restrict endptr, - register int base) +long long strtoll(const char *restrict ptr, char **restrict endptr, int base) { const char *s = ptr; long long acc; @@ -64,8 +64,31 @@ long long strtoll( base = c == '0' ? 8 : 10; } - cutoff = (long long)LLONG_MAX / (long long)base; - cutlim = (long long)LLONG_MAX % (long long)base; + /* XXX cannot just divide by base here. Doing so results in a #DE + * exception when running under Bochs. Not sure if this is a bug in the + * kernel or in Bochs, but this switch statement is here as a workaround + * until the issue is resolved. */ + switch (base) { + case 2: + cutoff = (long long)LLONG_MAX / (long long)2; + cutlim = (long long)LLONG_MAX % (long long)2; + break; + case 8: + cutoff = (long long)LLONG_MAX / (long long)8; + cutlim = (long long)LLONG_MAX % (long long)8; + break; + case 10: + cutoff = (long long)LLONG_MAX / (long long)10; + cutlim = (long long)LLONG_MAX % (long long)10; + break; + case 16: + cutoff = (long long)LLONG_MAX / (long long)16; + cutlim = (long long)LLONG_MAX % (long long)16; + break; + default: + return -1; + } + for (acc = 0, any = 0;; c = *s++) { if (isdigit(c)) { c -= '0';