diff options
Diffstat (limited to 'elf')
-rw-r--r-- | elf/dl-minimal.c | 127 | ||||
-rw-r--r-- | elf/dl-runtime.c | 8 | ||||
-rw-r--r-- | elf/dlerror.c | 4 |
3 files changed, 133 insertions, 6 deletions
diff --git a/elf/dl-minimal.c b/elf/dl-minimal.c index 6592ca0baf..4c15d83f8e 100644 --- a/elf/dl-minimal.c +++ b/elf/dl-minimal.c @@ -18,6 +18,7 @@ Boston, MA 02111-1307, USA. */ #include <errno.h> +#include <limits.h> #include <string.h> #include <unistd.h> #include <sys/types.h> @@ -202,3 +203,129 @@ __assert_perror_fail (int errnum, } #endif + +/* This function is only used in eval.c. */ +long int +weak_function +__strtol_internal (const char *nptr, char **endptr, int base, int group) +{ + long int result = 0; + long int sign = 1; + + while (*nptr == ' ' || *nptr == '\t') + ++nptr; + + if (*nptr == '-') + { + sign = -1; + ++nptr; + } + else if (*nptr == '+') + ++nptr; + + if (*nptr < '0' || *nptr > '9') + { + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; + } + + assert (base == 0); + if (*nptr == '0') + { + if (nptr[1] == 'x' || nptr[1] == 'X') + { + base = 16; + nptr += 2; + } + else + base = 8; + } + else + base = 10; + + while (*nptr >= '0' && *nptr <= '9') + { + long int digval = *nptr - '0'; + if (result > LONG_MAX / 10 + || (result == (sign ? LONG_MAX : LONG_MAX + 1) / 10 + && digval > (sign ? LONG_MAX : LONG_MAX + 1) % 10)) + { + errno = ERANGE; + return LONG_MAX * sign; + } + result *= 10; + result += digval; + } + + return result * sign; +} + +long int +weak_function +strtol (const char *nptr, char **endptr, int base) +{ + return __strtol_internal (nptr, endptr, base, 0); +} + +unsigned long int +weak_function +__strtoul_internal (const char *nptr, char **endptr, int base, int group) +{ + long int result = 0; + long int sign = 1; + + while (*nptr == ' ' || *nptr == '\t') + ++nptr; + + if (*nptr == '-') + { + sign = -1; + ++nptr; + } + else if (*nptr == '+') + ++nptr; + + if (*nptr < '0' || *nptr > '9') + { + if (endptr != NULL) + *endptr = (char *) nptr; + return 0UL; + } + + assert (base == 0); + if (*nptr == '0') + { + if (nptr[1] == 'x' || nptr[1] == 'X') + { + base = 16; + nptr += 2; + } + else + base = 8; + } + else + base = 10; + + while (*nptr >= '0' && *nptr <= '9') + { + long int digval = *nptr - '0'; + if (result > LONG_MAX / 10 + || (result == ULONG_MAX / 10 && digval > ULONG_MAX % 10)) + { + errno = ERANGE; + return ULONG_MAX; + } + result *= 10; + result += digval; + } + + return result * sign; +} + +unsigned long int +weak_function +strtoul (const char *nptr, char **endptr, int base) +{ + return (unsigned long int) __strtoul_internal (nptr, endptr, base, 0); +} diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 10daa98c06..53601b809f 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -128,13 +128,13 @@ fixup ( { value = _dl_lookup_versioned_symbol(strtab + sym->st_name, &sym, scope, l->l_name, - version, DL_LOOKUP_NOPLT); + version, ELF_MACHINE_JMP_SLOT); break; } } case 0: value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope, - l->l_name, DL_LOOKUP_NOPLT); + l->l_name, ELF_MACHINE_JMP_SLOT); } /* Currently value contains the base load address of the object @@ -205,13 +205,13 @@ profile_fixup ( value = _dl_lookup_versioned_symbol(strtab + sym->st_name, &sym, scope, l->l_name, version, - DL_LOOKUP_NOPLT); + ELF_MACHINE_JMP_SLOT); break; } } case 0: value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope, - l->l_name, DL_LOOKUP_NOPLT); + l->l_name, ELF_MACHINE_JMP_SLOT); } /* Currently value contains the base load address of the object diff --git a/elf/dlerror.c b/elf/dlerror.c index 00d367b0a4..ba25611bbb 100644 --- a/elf/dlerror.c +++ b/elf/dlerror.c @@ -72,8 +72,8 @@ dlerror (void) buf = result->errstring; else { - if (asprintf (&buf, "%s: %s", - result->errstring, strerror (result->errcode)) == -1) + if (__asprintf (&buf, "%s: %s", + result->errstring, strerror (result->errcode)) == -1) buf = NULL; /* We don't need the error string anymore. */ |