|
|
|
@ -1008,7 +1008,8 @@ DESCRIPTION |
|
|
|
in hex if a leading "0x" or "0X" is found, otherwise |
|
|
|
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 |
|
|
|
@ -1018,48 +1019,64 @@ bfd_scan_vma (string, end, base) |
|
|
|
int base; |
|
|
|
{ |
|
|
|
bfd_vma value; |
|
|
|
int digit; |
|
|
|
bfd_vma cutoff; |
|
|
|
unsigned int cutlim; |
|
|
|
int overflow; |
|
|
|
|
|
|
|
/* Let the host do it if possible. */ |
|
|
|
if (sizeof (bfd_vma) <= sizeof (unsigned long)) |
|
|
|
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 (string[0] == '0') |
|
|
|
{ |
|
|
|
if ((string[1] == 'x') || (string[1] == 'X')) |
|
|
|
base = 16; |
|
|
|
/* XXX should we also allow "0b" or "0B" to set base to 2? */ |
|
|
|
else |
|
|
|
base = 8; |
|
|
|
} |
|
|
|
else |
|
|
|
base = 10; |
|
|
|
} |
|
|
|
|
|
|
|
if ((base == 16) && |
|
|
|
(string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) |
|
|
|
string += 2; |
|
|
|
/* XXX should we also skip over "0b" or "0B" if base is 2? */ |
|
|
|
if ((base < 2) || (base > 36)) |
|
|
|
base = 10; |
|
|
|
|
|
|
|
if (base == 16 |
|
|
|
&& string[0] == '0' |
|
|
|
&& (string[1] == 'x' || string[1] == 'X') |
|
|
|
&& ISXDIGIT (string[2])) |
|
|
|
{ |
|
|
|
string += 2; |
|
|
|
} |
|
|
|
|
|
|
|
/* Speed could be improved with a table like hex_value[] in gas. */ |
|
|
|
#define HEX_VALUE(c) \ |
|
|
|
(ISXDIGIT (c) \ |
|
|
|
? (ISDIGIT (c) \ |
|
|
|
? (c - '0') \ |
|
|
|
: (10 + c - (ISLOWER (c) ? 'a' : 'A'))) \ |
|
|
|
: 42) |
|
|
|
cutoff = (~ (bfd_vma) 0) / (bfd_vma) base; |
|
|
|
cutlim = (~ (bfd_vma) 0) % (bfd_vma) base; |
|
|
|
value = 0; |
|
|
|
overflow = 0; |
|
|
|
while (1) |
|
|
|
{ |
|
|
|
unsigned int digit; |
|
|
|
|
|
|
|
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; |
|
|
|
++string; |
|
|
|
} |
|
|
|
|
|
|
|
for (value = 0; (digit = HEX_VALUE (* string)) < base; string ++) |
|
|
|
value = value * base + digit; |
|
|
|
if (overflow) |
|
|
|
value = ~ (bfd_vma) 0; |
|
|
|
|
|
|
|
if (end) |
|
|
|
* end = string; |
|
|
|
if (end != NULL) |
|
|
|
*end = string; |
|
|
|
|
|
|
|
return value; |
|
|
|
} |
|
|
|
|