+2017-06-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #21528]
+ * elf/dl-minimal.c (__strtoul_internal): Removed.
+ (strtoul): Likewise.
+ * elf/dl-misc.c (_dl_strtoul): New function.
+ * elf/dl-tunables.c (tunables_strtoul): Removed.
+ (tunable_initialize): Replace tunables_strtoul with _dl_strtoul.
+ * elf/rtld.c (process_envvars): Likewise.
+ * sysdeps/unix/sysv/linux/dl-librecon.h (_dl_osversion_init):
+ Likewise.
+ * sysdeps/generic/ldsodefs.h (_dl_strtoul): New prototype.
+
2017-06-08 Zack Weinberg <zackw@panix.com>
* libio/bits/types/FILE.h, libio/bits/types/__FILE.h
/* Declarations of global functions. */
extern void weak_function free (void *ptr);
extern void * weak_function realloc (void *ptr, size_t n);
-extern unsigned long int weak_function __strtoul_internal (const char *nptr,
- char **endptr,
- int base,
- int group);
-extern unsigned long int weak_function strtoul (const char *nptr,
- char **endptr, int base);
/* Allocate an aligned memory block. */
rtld_hidden_weak (__assert_perror_fail)
#endif
\f
-unsigned long int weak_function
-__strtoul_internal (const char *nptr, char **endptr, int base, int group)
-{
- unsigned long int result = 0;
- long int sign = 1;
- unsigned max_digit;
-
- 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);
- base = 10;
- max_digit = 9;
- if (*nptr == '0')
- {
- if (nptr[1] == 'x' || nptr[1] == 'X')
- {
- base = 16;
- nptr += 2;
- }
- else
- {
- base = 8;
- max_digit = 7;
- }
- }
-
- while (1)
- {
- unsigned long int digval;
- if (*nptr >= '0' && *nptr <= '0' + max_digit)
- digval = *nptr - '0';
- else if (base == 16)
- {
- if (*nptr >= 'a' && *nptr <= 'f')
- digval = *nptr - 'a' + 10;
- else if (*nptr >= 'A' && *nptr <= 'F')
- digval = *nptr - 'A' + 10;
- else
- break;
- }
- else
- break;
-
- if (result > ULONG_MAX / base
- || (result == ULONG_MAX / base && digval > ULONG_MAX % base))
- {
- errno = ERANGE;
- if (endptr != NULL)
- *endptr = (char *) nptr;
- return ULONG_MAX;
- }
- result *= base;
- result += digval;
- ++nptr;
- }
-
- if (endptr != NULL)
- *endptr = (char *) nptr;
- return result * sign;
-}
-
-
#undef _itoa
/* We always use _itoa instead of _itoa_word in ld.so since the former
also has to be present and it is never about speed when these
return *low;
}
+
+/* A stripped down strtoul-like implementation for very early use. It
+ does not set errno if the result is outside bounds because it may get
+ called before errno may have been set up. */
+
+uint64_t
+internal_function
+_dl_strtoul (const char *nptr, char **endptr)
+{
+ uint64_t result = 0;
+ bool positive = true;
+ unsigned max_digit;
+
+ while (*nptr == ' ' || *nptr == '\t')
+ ++nptr;
+
+ if (*nptr == '-')
+ {
+ positive = false;
+ ++nptr;
+ }
+ else if (*nptr == '+')
+ ++nptr;
+
+ if (*nptr < '0' || *nptr > '9')
+ {
+ if (endptr != NULL)
+ *endptr = (char *) nptr;
+ return 0UL;
+ }
+
+ int base = 10;
+ max_digit = 9;
+ if (*nptr == '0')
+ {
+ if (nptr[1] == 'x' || nptr[1] == 'X')
+ {
+ base = 16;
+ nptr += 2;
+ }
+ else
+ {
+ base = 8;
+ max_digit = 7;
+ }
+ }
+
+ while (1)
+ {
+ int digval;
+ if (*nptr >= '0' && *nptr <= '0' + max_digit)
+ digval = *nptr - '0';
+ else if (base == 16)
+ {
+ if (*nptr >= 'a' && *nptr <= 'f')
+ digval = *nptr - 'a' + 10;
+ else if (*nptr >= 'A' && *nptr <= 'F')
+ digval = *nptr - 'A' + 10;
+ else
+ break;
+ }
+ else
+ break;
+
+ if (result >= (UINT64_MAX - digval) / base)
+ {
+ if (endptr != NULL)
+ *endptr = (char *) nptr;
+ return UINT64_MAX;
+ }
+ result *= base;
+ result += digval;
+ ++nptr;
+ }
+
+ if (endptr != NULL)
+ *endptr = (char *) nptr;
+
+ /* Avoid 64-bit multiplication. */
+ if (!positive)
+ result = -result;
+
+ return result;
+}
return NULL;
}
-/* A stripped down strtoul-like implementation for very early use. It does not
- set errno if the result is outside bounds because it gets called before
- errno may have been set up. */
-static uint64_t
-tunables_strtoul (const char *nptr)
-{
- uint64_t result = 0;
- long int sign = 1;
- unsigned max_digit;
-
- while (*nptr == ' ' || *nptr == '\t')
- ++nptr;
-
- if (*nptr == '-')
- {
- sign = -1;
- ++nptr;
- }
- else if (*nptr == '+')
- ++nptr;
-
- if (*nptr < '0' || *nptr > '9')
- return 0UL;
-
- int base = 10;
- max_digit = 9;
- if (*nptr == '0')
- {
- if (nptr[1] == 'x' || nptr[1] == 'X')
- {
- base = 16;
- nptr += 2;
- }
- else
- {
- base = 8;
- max_digit = 7;
- }
- }
-
- while (1)
- {
- int digval;
- if (*nptr >= '0' && *nptr <= '0' + max_digit)
- digval = *nptr - '0';
- else if (base == 16)
- {
- if (*nptr >= 'a' && *nptr <= 'f')
- digval = *nptr - 'a' + 10;
- else if (*nptr >= 'A' && *nptr <= 'F')
- digval = *nptr - 'A' + 10;
- else
- break;
- }
- else
- break;
-
- if (result >= (UINT64_MAX - digval) / base)
- return UINT64_MAX;
- result *= base;
- result += digval;
- ++nptr;
- }
-
- return result * sign;
-}
-
#define TUNABLE_SET_VAL_IF_VALID_RANGE(__cur, __val, __type, __default_min, \
__default_max) \
({ \
if (cur->type.type_code != TUNABLE_TYPE_STRING)
{
- val = tunables_strtoul (strval);
+ val = _dl_strtoul (strval, NULL);
valp = &val;
}
else
/* Mask for the important hardware capabilities. */
if (!__libc_enable_secure
&& memcmp (envline, "HWCAP_MASK", 10) == 0)
- GLRO(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL,
- 0, 0);
+ GLRO(dl_hwcap_mask) = _dl_strtoul (&envline[11], NULL);
break;
#endif
extern unsigned long int _dl_higher_prime_number (unsigned long int n)
internal_function attribute_hidden;
+/* A stripped down strtoul-like implementation. */
+uint64_t internal_function _dl_strtoul (const char *, char **)
+ internal_function attribute_hidden;
+
/* Function used as argument for `_dl_receive_error' function. The
arguments are the error code, error string, and the objname the
error occurred in. */
for (i = 0; i < 3; i++, p = q + 1)
{
- j = __strtoul_internal (p, &q, 0, 0);
+ j = _dl_strtoul (p, &q);
if (j >= 255 || p == q || (i < 2 && *q && *q != '.'))
{
osversion = 0;