aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-12-12 09:29:45 +1030
committerAlan Modra <amodra@gmail.com>2019-12-12 21:58:33 +1030
commit4f7cc14110d67a180f5408a91ac53a91f88f776e (patch)
tree06f9b92f65556383e9d7cad287ce1b51882c7243 /gas
parent84bc4ba8168154fae0da7d56dcd11df0d4bc44f2 (diff)
downloadgdb-4f7cc14110d67a180f5408a91ac53a91f88f776e.zip
gdb-4f7cc14110d67a180f5408a91ac53a91f88f776e.tar.gz
gdb-4f7cc14110d67a180f5408a91ac53a91f88f776e.tar.bz2
gas signed overflow fixes
* config/tc-aarch64.c (get_aarch64_insn): Avoid signed overflow. * config/tc-metag.c (parse_dalu): Likewise. * config/tc-tic4x.c (md_pcrel_from): Likewise. * config/tc-tic6x.c (tic6x_output_unwinding): Likewise. * config/tc-csky.c (parse_fexp): Use an unsigned char temp buffer. Don't use register keyword. Avoid signed overflow and remove now unneccesary char masks. Formatting. * config/tc-ia64.c (operand_match): Don't use shifts to sign extend. * config/tc-mep.c (mep_apply_fix): Likewise. * config/tc-pru.c (md_apply_fix): Likewise. * config/tc-riscv.c (load_const): Likewise. * config/tc-nios2.c (md_apply_fix): Likewise. Don't potentially truncate fixup before right shift. Tidy BFD_RELOC_NIOS2_HIADJ16 calculation.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog17
-rw-r--r--gas/config/tc-aarch64.c3
-rw-r--r--gas/config/tc-csky.c59
-rw-r--r--gas/config/tc-ia64.c10
-rw-r--r--gas/config/tc-mep.c2
-rw-r--r--gas/config/tc-metag.c4
-rw-r--r--gas/config/tc-nios2.c8
-rw-r--r--gas/config/tc-pru.c9
-rw-r--r--gas/config/tc-riscv.c4
-rw-r--r--gas/config/tc-tic4x.c2
-rw-r--r--gas/config/tc-tic6x.c2
11 files changed, 68 insertions, 52 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index d8c5a17..a65b7d3 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,22 @@
2019-12-12 Alan Modra <amodra@gmail.com>
+ * config/tc-aarch64.c (get_aarch64_insn): Avoid signed overflow.
+ * config/tc-metag.c (parse_dalu): Likewise.
+ * config/tc-tic4x.c (md_pcrel_from): Likewise.
+ * config/tc-tic6x.c (tic6x_output_unwinding): Likewise.
+ * config/tc-csky.c (parse_fexp): Use an unsigned char temp buffer.
+ Don't use register keyword. Avoid signed overflow and remove now
+ unneccesary char masks. Formatting.
+ * config/tc-ia64.c (operand_match): Don't use shifts to sign extend.
+ * config/tc-mep.c (mep_apply_fix): Likewise.
+ * config/tc-pru.c (md_apply_fix): Likewise.
+ * config/tc-riscv.c (load_const): Likewise.
+ * config/tc-nios2.c (md_apply_fix): Likewise. Don't potentially
+ truncate fixup before right shift. Tidy BFD_RELOC_NIOS2_HIADJ16
+ calculation.
+
+2019-12-12 Alan Modra <amodra@gmail.com>
+
* config/obj-evax.c (crc32, encode_32, encode_16, decode_16):
Remove unnecessary prototypes.
(number_of_codings): Delete, use ARRAY_SIZE instead throughout.
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index cd46016..8879451 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -5024,7 +5024,8 @@ get_aarch64_insn (char *buf)
{
unsigned char *where = (unsigned char *) buf;
uint32_t result;
- result = (where[0] | (where[1] << 8) | (where[2] << 16) | (where[3] << 24));
+ result = ((where[0] | (where[1] << 8) | (where[2] << 16)
+ | ((uint32_t) where[3] << 24)));
return result;
}
diff --git a/gas/config/tc-csky.c b/gas/config/tc-csky.c
index 970c72a..6fa6ee5 100644
--- a/gas/config/tc-csky.c
+++ b/gas/config/tc-csky.c
@@ -1777,8 +1777,8 @@ static char *
parse_fexp (char *s, expressionS *e, unsigned char isdouble, uint64_t *dbnum)
{
int length; /* Number of chars in an object. */
- register char const *err = NULL; /* Error from scanning float literal. */
- char temp[8];
+ const char *err = NULL; /* Error from scanning float literal. */
+ unsigned char temp[8];
/* input_line_pointer->1st char of a flonum (we hope!). */
input_line_pointer = s;
@@ -1788,9 +1788,9 @@ parse_fexp (char *s, expressionS *e, unsigned char isdouble, uint64_t *dbnum)
input_line_pointer += 2;
if (isdouble)
- err = md_atof ('d', temp, &length);
+ err = md_atof ('d', (char *) temp, &length);
else
- err = md_atof ('f', temp, &length);
+ err = md_atof ('f', (char *) temp, &length);
know (length <= 8);
know (err != NULL || length > 0);
@@ -1818,41 +1818,42 @@ parse_fexp (char *s, expressionS *e, unsigned char isdouble, uint64_t *dbnum)
{
uint32_t fnum;
if (target_big_endian)
- fnum = (((temp[0] << 24) & 0xffffffff)
- | ((temp[1] << 16) & 0xffffff)
- | ((temp[2] << 8) & 0xffff)
- | (temp[3] & 0xff));
+ fnum = (((uint32_t) temp[0] << 24)
+ | (temp[1] << 16)
+ | (temp[2] << 8)
+ | temp[3]);
else
- fnum = (((temp[3] << 24) & 0xffffffff)
- | ((temp[2] << 16) & 0xffffff)
- | ((temp[1] << 8) & 0xffff)
- | (temp[0] & 0xff));
- e->X_add_number = fnum; }
+ fnum = (((uint32_t) temp[3] << 24)
+ | (temp[2] << 16)
+ | (temp[1] << 8)
+ | temp[0]);
+ e->X_add_number = fnum;
+ }
else
{
if (target_big_endian)
{
- *dbnum = (((temp[0] << 24) & 0xffffffff)
- | ((temp[1] << 16) & 0xffffff)
- | ((temp[2] << 8) & 0xffff)
- | (temp[3] & 0xff));
+ *dbnum = (((uint32_t) temp[0] << 24)
+ | (temp[1] << 16)
+ | (temp[2] << 8)
+ | temp[3]);
*dbnum <<= 32;
- *dbnum |= (((temp[4] << 24) & 0xffffffff)
- | ((temp[5] << 16) & 0xffffff)
- | ((temp[6] << 8) & 0xffff)
- | (temp[7] & 0xff));
+ *dbnum |= (((uint32_t) temp[4] << 24)
+ | (temp[5] << 16)
+ | (temp[6] << 8)
+ | temp[7]);
}
else
{
- *dbnum = (((temp[7] << 24) & 0xffffffff)
- | ((temp[6] << 16) & 0xffffff)
- | ((temp[5] << 8) & 0xffff)
- | (temp[4] & 0xff));
+ *dbnum = (((uint32_t) temp[7] << 24)
+ | (temp[6] << 16)
+ | (temp[5] << 8)
+ | temp[4]);
*dbnum <<= 32;
- *dbnum |= (((temp[3] << 24) & 0xffffffff)
- | ((temp[2] << 16) & 0xffffff)
- | ((temp[1] << 8) & 0xffff)
- | (temp[0] & 0xff));
+ *dbnum |= (((uint32_t) temp[3] << 24)
+ | (temp[2] << 16)
+ | (temp[1] << 8)
+ | temp[0]);
}
}
return input_line_pointer;
diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c
index 0c618e8..5eb024e 100644
--- a/gas/config/tc-ia64.c
+++ b/gas/config/tc-ia64.c
@@ -5839,9 +5839,8 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
/* Sign-extend 32-bit unsigned numbers, so that the following range
checks will work. */
val = e->X_add_number;
- if (((val & (~(bfd_vma) 0 << 32)) == 0)
- && ((val & ((bfd_vma) 1 << 31)) != 0))
- val = ((val << 32) >> 32);
+ if ((val & (~(bfd_vma) 0 << 32)) == 0)
+ val = (val ^ ((bfd_vma) 1 << 31)) - ((bfd_vma) 1 << 31);
/* Check for 0x100000000. This is valid because
0x100000000-1 is the same as ((uint32_t) -1). */
@@ -5879,9 +5878,8 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
/* Sign-extend 32-bit unsigned numbers, so that the following range
checks will work. */
val = e->X_add_number;
- if (((val & (~(bfd_vma) 0 << 32)) == 0)
- && ((val & ((bfd_vma) 1 << 31)) != 0))
- val = ((val << 32) >> 32);
+ if ((val & (~(bfd_vma) 0 << 32)) == 0)
+ val = (val ^ ((bfd_vma) 1 << 31)) - ((bfd_vma) 1 << 31);
}
else
val = e->X_add_number;
diff --git a/gas/config/tc-mep.c b/gas/config/tc-mep.c
index c0d48e8..18e96c8 100644
--- a/gas/config/tc-mep.c
+++ b/gas/config/tc-mep.c
@@ -1790,7 +1790,7 @@ mep_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
switch (fixP->fx_cgen.opinfo)
{
case BFD_RELOC_MEP_LOW16:
- *valP = ((long)(*valP & 0xffff)) << 16 >> 16;
+ *valP = ((*valP & 0xffff) ^ 0x8000) - 0x8000;
break;
case BFD_RELOC_MEP_HI16U:
*valP >>= 16;
diff --git a/gas/config/tc-metag.c b/gas/config/tc-metag.c
index c7bb36d..d056e9a 100644
--- a/gas/config/tc-metag.c
+++ b/gas/config/tc-metag.c
@@ -5340,7 +5340,7 @@ parse_dalu (const char *line, metag_insn *insn,
/* Only MOV instructions have a DSP register as a
destination. Set the MOV DSPe.r opcode. The simple
OR'ing is OK because the usual MOV opcode is 0x00. */
- insn->bits = (0x91 << 24);
+ insn->bits = 0x91u << 24;
du_shift = 0;
l1_shift = 2;
regs_shift[0] = 19;
@@ -5455,7 +5455,7 @@ parse_dalu (const char *line, metag_insn *insn,
du_shift = 0;
l1_shift = 2;
regs_shift[1] = 14;
- insn->bits = (0x92 << 24); /* Set opcode. */
+ insn->bits = 0x92u << 24; /* Set opcode. */
}
}
}
diff --git a/gas/config/tc-nios2.c b/gas/config/tc-nios2.c
index ec572a6..f1a0200 100644
--- a/gas/config/tc-nios2.c
+++ b/gas/config/tc-nios2.c
@@ -1384,7 +1384,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
nios2_diagnose_overflow (fixup, howto, fixP, value);
/* Apply the right shift. */
- fixup = ((signed)fixup) >> howto->rightshift;
+ fixup = (offsetT) fixup >> howto->rightshift;
/* Truncate the fixup to right size. */
switch (fixP->fx_r_type)
@@ -1396,13 +1396,11 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
fixup = fixup & 0xFFFF;
break;
case BFD_RELOC_NIOS2_HIADJ16:
- fixup = ((((fixup >> 16) & 0xFFFF) + ((fixup >> 15) & 0x01))
- & 0xFFFF);
+ fixup = ((fixup + 0x8000) >> 16) & 0xFFFF;
break;
default:
{
- int n = sizeof (fixup) * 8 - howto->bitsize;
- fixup = (fixup << n) >> n;
+ fixup &= ((valueT) 1 << howto->bitsize) - 1;
break;
}
}
diff --git a/gas/config/tc-pru.c b/gas/config/tc-pru.c
index 2e2058c..6de9f3c 100644
--- a/gas/config/tc-pru.c
+++ b/gas/config/tc-pru.c
@@ -642,7 +642,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
{
unsigned char *where;
valueT value = *valP;
- long n;
/* Assert that the fixup is one we can handle. */
gas_assert (fixP != NULL && valP != NULL
@@ -801,11 +800,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
pru_diagnose_overflow (fixup, howto, fixP, insn);
/* Apply the right shift. */
- fixup = ((offsetT)fixup) >> howto->rightshift;
+ fixup = (offsetT) fixup >> howto->rightshift;
/* Truncate the fixup to right size. */
- n = sizeof (fixup) * 8 - howto->bitsize;
- fixup = (fixup << n) >> n;
+ if (howto->bitsize == 0)
+ fixup = 0;
+ else
+ fixup &= ((valueT) 2 << (howto->bitsize - 1)) - 1;
/* Fix up the instruction. Non-contiguous bitfields need
special handling. */
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 055d80c..7ec1028 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1043,9 +1043,9 @@ static void
load_const (int reg, expressionS *ep)
{
int shift = RISCV_IMM_BITS;
- bfd_vma upper_imm;
+ bfd_vma upper_imm, sign = (bfd_vma) 1 << (RISCV_IMM_BITS - 1);
expressionS upper = *ep, lower = *ep;
- lower.X_add_number = (int32_t) ep->X_add_number << (32-shift) >> (32-shift);
+ lower.X_add_number = ((ep->X_add_number & (sign + sign - 1)) ^ sign) - sign;
upper.X_add_number -= lower.X_add_number;
if (ep->X_op != O_constant)
diff --git a/gas/config/tc-tic4x.c b/gas/config/tc-tic4x.c
index b5588b9..bbbd696 100644
--- a/gas/config/tc-tic4x.c
+++ b/gas/config/tc-tic4x.c
@@ -2937,7 +2937,7 @@ md_pcrel_from (fixS *fixP)
unsigned int op;
buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
- op = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
+ op = ((unsigned) buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
return ((fixP->fx_where + fixP->fx_frag->fr_address) >> 2) +
tic4x_pc_offset (op);
diff --git a/gas/config/tc-tic6x.c b/gas/config/tc-tic6x.c
index cd12c82..6260ecb 100644
--- a/gas/config/tc-tic6x.c
+++ b/gas/config/tc-tic6x.c
@@ -5060,7 +5060,7 @@ tic6x_output_unwinding (bfd_boolean need_extab)
if (unwind->personality_index == -1)
{
tmp = md_chars_to_number (unwind->frag_start + 4, 4);
- tmp |= ((unwind->data_bytes - 8) >> 2) << 24;
+ tmp |= (valueT) ((unwind->data_bytes - 8) >> 2) << 24;
md_number_to_chars (unwind->frag_start + 4, tmp, 4);
}
else if (unwind->personality_index == 1 || unwind->personality_index == 2)