diff options
author | Nick Clifton <nickc@redhat.com> | 2016-03-16 11:33:55 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2016-03-16 11:33:55 +0000 |
commit | 5f2b6bc955535ebfc280a04c22c937cfedb83916 (patch) | |
tree | 1e3ab4d035b80a0ea3f91f113d4bf7ce070e00e2 /gas/read.c | |
parent | 9bff188f0da2859bd5efa8d0def8c0f93d0be410 (diff) | |
download | gdb-5f2b6bc955535ebfc280a04c22c937cfedb83916.zip gdb-5f2b6bc955535ebfc280a04c22c937cfedb83916.tar.gz gdb-5f2b6bc955535ebfc280a04c22c937cfedb83916.tar.bz2 |
Fix checking bignum values that are being inserted into byte sized containers.
* read.c (emit_expr_with_reloc): Add code check a bignum with
nbytes == 1.
* config/rx/rx-parse.y (rx_intop): Accept bignum values for sizes
other than 32-bits.
* testsuite/gas/elf/bignum.s: New test source file.
* testsuite/gas/elf/bignum.d: New test driver file.
* testsuite/gas/elf/elf.exp: Run the new test.
Diffstat (limited to 'gas/read.c')
-rw-r--r-- | gas/read.c | 21 |
1 files changed, 20 insertions, 1 deletions
@@ -4411,7 +4411,8 @@ emit_expr_with_reloc (expressionS *exp, if ((get & mask) != 0 && ((get & mask) != mask || (get & hibit) == 0)) - { /* Leading bits contain both 0s & 1s. */ + { + /* Leading bits contain both 0s & 1s. */ #if defined (BFD64) && BFD_HOST_64BIT_LONG_LONG #ifndef __MSVCRT__ as_warn (_("value 0x%llx truncated to 0x%llx"), @@ -4437,16 +4438,34 @@ emit_expr_with_reloc (expressionS *exp, if (nbytes < size) { int i = nbytes / CHARS_PER_LITTLENUM; + if (i != 0) { LITTLENUM_TYPE sign = 0; if ((generic_bignum[--i] & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) != 0) sign = ~(LITTLENUM_TYPE) 0; + while (++i < exp->X_add_number) if (generic_bignum[i] != sign) break; } + else if (nbytes == 1) + { + /* We have nbytes == 1 and CHARS_PER_LITTLENUM == 2 (probably). + Check that bits 8.. of generic_bignum[0] match bit 7 + and that they match all of generic_bignum[1..exp->X_add_number]. */ + LITTLENUM_TYPE sign = (generic_bignum[0] & (1 << 7)) ? -1 : 0; + LITTLENUM_TYPE himask = LITTLENUM_MASK & ~ 0xFF; + + if ((generic_bignum[0] & himask) == (sign & himask)) + { + while (++i < exp->X_add_number) + if (generic_bignum[i] != sign) + break; + } + } + if (i < exp->X_add_number) as_warn (_("bignum truncated to %d bytes"), nbytes); size = nbytes; |