libc: core: add mitigation for a potential bochs issue in strtoll
This commit is contained in:
@@ -28,14 +28,14 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <magenta/log.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
long long strtoll(
|
long long strtoll(const char *restrict ptr, char **restrict endptr, int base)
|
||||||
const char *restrict ptr,
|
|
||||||
char **restrict endptr,
|
|
||||||
register int base)
|
|
||||||
{
|
{
|
||||||
const char *s = ptr;
|
const char *s = ptr;
|
||||||
long long acc;
|
long long acc;
|
||||||
@@ -64,8 +64,31 @@ long long strtoll(
|
|||||||
base = c == '0' ? 8 : 10;
|
base = c == '0' ? 8 : 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
cutoff = (long long)LLONG_MAX / (long long)base;
|
/* XXX cannot just divide by base here. Doing so results in a #DE
|
||||||
cutlim = (long long)LLONG_MAX % (long long)base;
|
* 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++) {
|
for (acc = 0, any = 0;; c = *s++) {
|
||||||
if (isdigit(c)) {
|
if (isdigit(c)) {
|
||||||
c -= '0';
|
c -= '0';
|
||||||
|
|||||||
Reference in New Issue
Block a user