Browse Source

* bfd.c (bfd_scan_vma): Clamp overflows to max bfd_vma value.

Correct value returned in "end" for "0x<non-hex>".
readline_4_3-import-branch
Alan Modra 25 years ago
parent
commit
88eaccc28e
  1. 5
      bfd/ChangeLog
  2. 59
      bfd/bfd.c

5
bfd/ChangeLog

@ -1,3 +1,8 @@
2002-02-15 Alan Modra <amodra@bigpond.net.au>
* bfd.c (bfd_scan_vma): Clamp overflows to max bfd_vma value.
Correct value returned in "end" for "0x<non-hex>".
2002-02-14 Nick Clifton <nickc@cambridge.redhat.com> 2002-02-14 Nick Clifton <nickc@cambridge.redhat.com>
* cpu-arm.c (processors): Replace 'arch' field with 'mach'. * cpu-arm.c (processors): Replace 'arch' field with 'mach'.

59
bfd/bfd.c

@ -1008,7 +1008,8 @@ DESCRIPTION
in hex if a leading "0x" or "0X" is found, otherwise in hex if a leading "0x" or "0X" is found, otherwise
in octal if a leading zero is found, otherwise in decimal. in octal if a leading zero is found, otherwise in decimal.
Overflow is not detected. If the value would overflow, the maximum <<bfd_vma>> value is
returned.
*/ */
bfd_vma bfd_vma
@ -1018,47 +1019,63 @@ bfd_scan_vma (string, end, base)
int base; int base;
{ {
bfd_vma value; bfd_vma value;
int digit; bfd_vma cutoff;
unsigned int cutlim;
int overflow;
/* Let the host do it if possible. */ /* Let the host do it if possible. */
if (sizeof (bfd_vma) <= sizeof (unsigned long)) if (sizeof (bfd_vma) <= sizeof (unsigned long))
return (bfd_vma) strtoul (string, (char **) end, base); return (bfd_vma) strtoul (string, (char **) end, base);
/* A negative base makes no sense, and we only need to go as high as hex. */
if ((base < 0) || (base > 16))
return (bfd_vma) 0;
if (base == 0) if (base == 0)
{ {
if (string[0] == '0') if (string[0] == '0')
{ {
if ((string[1] == 'x') || (string[1] == 'X')) if ((string[1] == 'x') || (string[1] == 'X'))
base = 16; base = 16;
/* XXX should we also allow "0b" or "0B" to set base to 2? */
else else
base = 8; base = 8;
} }
else
base = 10;
} }
if ((base == 16) && if ((base < 2) || (base > 36))
(string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) base = 10;
if (base == 16
&& string[0] == '0'
&& (string[1] == 'x' || string[1] == 'X')
&& ISXDIGIT (string[2]))
{
string += 2; string += 2;
/* XXX should we also skip over "0b" or "0B" if base is 2? */ }
/* Speed could be improved with a table like hex_value[] in gas. */ cutoff = (~ (bfd_vma) 0) / (bfd_vma) base;
#define HEX_VALUE(c) \ cutlim = (~ (bfd_vma) 0) % (bfd_vma) base;
(ISXDIGIT (c) \ value = 0;
? (ISDIGIT (c) \ overflow = 0;
? (c - '0') \ while (1)
: (10 + c - (ISLOWER (c) ? 'a' : 'A'))) \ {
: 42) unsigned int digit;
for (value = 0; (digit = HEX_VALUE (* string)) < base; string ++) digit = *string;
if (ISDIGIT (digit))
digit = digit - '0';
else if (ISALPHA (digit))
digit = TOUPPER (digit) - 'A' + 10;
else
break;
if (digit >= (unsigned int) base)
break;
if (value > cutoff || (value == cutoff && digit > cutlim))
overflow = 1;
value = value * base + digit; value = value * base + digit;
++string;
}
if (overflow)
value = ~ (bfd_vma) 0;
if (end) if (end != NULL)
*end = string; *end = string;
return value; return value;

Loading…
Cancel
Save