aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2014-10-14 13:36:20 +1030
committerAlan Modra <amodra@gmail.com>2014-10-14 14:36:35 +1030
commit65879393f04e14a9ab8797a8e66e0ec8d94108b5 (patch)
tree7f4300ec569ff44c6fd1c412f4ddad82d040477c
parent9495b2e66f772783eb89cfa755e1e09641fa44eb (diff)
downloadgdb-65879393f04e14a9ab8797a8e66e0ec8d94108b5.zip
gdb-65879393f04e14a9ab8797a8e66e0ec8d94108b5.tar.gz
gdb-65879393f04e14a9ab8797a8e66e0ec8d94108b5.tar.bz2
Avoid undefined behaviour with signed expressions
PR 17453 bfd/ * libbfd.c (COERCE16, COERCE32, COERCE64): Use unsigned types. (EIGHT_GAZILLION): Delete. binutils/ * dwarf.c (read_leb128): Avoid signed overflow. (read_debug_line_header): Likewise. gas/ * config/tc-i386.c (fits_in_signed_long): Use unsigned param and expression to avoid signed overflow. (fits_in_signed_byte, fits_in_unsigned_byte, fits_in_unsigned_word, fits_in_signed_word, fits_in_unsigned_long): Similarly. * expr.c (operand <'-'>): Avoid signed overflow. * read.c (s_comm_internal): Likewise.
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/libbfd.c7
-rw-r--r--binutils/ChangeLog6
-rw-r--r--binutils/dwarf.c8
-rw-r--r--gas/ChangeLog10
-rw-r--r--gas/config/tc-i386.c25
-rw-r--r--gas/expr.c3
-rw-r--r--gas/read.c2
-rw-r--r--gas/write.c2
9 files changed, 43 insertions, 26 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index be3ae38..f9e81d3 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2014-10-14 Alan Modra <amodra@gmail.com>
+
+ PR 17453
+ * libbfd.c (COERCE16, COERCE32, COERCE64): Use unsigned types.
+ (EIGHT_GAZILLION): Delete.
+
2014-10-13 Alan Modra <amodra@gmail.com>
PR 17467
diff --git a/bfd/libbfd.c b/bfd/libbfd.c
index 6676dff..d98a9d2 100644
--- a/bfd/libbfd.c
+++ b/bfd/libbfd.c
@@ -548,11 +548,10 @@ DESCRIPTION
.*/
/* Sign extension to bfd_signed_vma. */
-#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000)
-#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
-#define EIGHT_GAZILLION ((bfd_int64_t) 1 << 63)
+#define COERCE16(x) (((bfd_vma) (x) ^ 0x8000) - 0x8000)
+#define COERCE32(x) (((bfd_vma) (x) ^ 0x80000000) - 0x80000000)
#define COERCE64(x) \
- (((bfd_int64_t) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION)
+ (((bfd_uint64_t) (x) ^ ((bfd_uint64_t) 1 << 63)) - ((bfd_uint64_t) 1 << 63))
bfd_vma
bfd_getb16 (const void *p)
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index b6800f1..0b297cb 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,6 +1,12 @@
2014-10-14 Alan Modra <amodra@gmail.com>
PR 17453
+ * dwarf.c (read_leb128): Avoid signed overflow.
+ (read_debug_line_header): Likewise.
+
+2014-10-14 Alan Modra <amodra@gmail.com>
+
+ PR 17453
* readelf.c (process_program_headers): Correct fscanf format used
for interpreter.
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 3f4095a..ee982de 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -259,7 +259,7 @@ read_leb128 (unsigned char *data,
*length_return = num_read;
if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
- result |= -1L << shift;
+ result |= (dwarf_vma) -1 << shift;
return result;
}
@@ -2661,14 +2661,10 @@ read_debug_line_header (struct dwarf_section * section,
linfo->li_max_ops_per_insn = 1;
SAFE_BYTE_GET_AND_INC (linfo->li_default_is_stmt, hdrptr, 1, end);
- SAFE_BYTE_GET_AND_INC (linfo->li_line_base, hdrptr, 1, end);
+ SAFE_SIGNED_BYTE_GET_AND_INC (linfo->li_line_base, hdrptr, 1, end);
SAFE_BYTE_GET_AND_INC (linfo->li_line_range, hdrptr, 1, end);
SAFE_BYTE_GET_AND_INC (linfo->li_opcode_base, hdrptr, 1, end);
- /* Sign extend the line base field. */
- linfo->li_line_base <<= 24;
- linfo->li_line_base >>= 24;
-
* end_of_sequence = data + linfo->li_length + initial_length_size;
return hdrptr;
}
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 5eb4813..1b4fda9 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,15 @@
2014-10-14 Alan Modra <amodra@gmail.com>
+ PR 17453
+ * config/tc-i386.c (fits_in_signed_long): Use unsigned param and
+ expression to avoid signed overflow.
+ (fits_in_signed_byte, fits_in_unsigned_byte, fits_in_unsigned_word,
+ fits_in_signed_word, fits_in_unsigned_long): Similarly.
+ * expr.c (operand <'-'>): Avoid signed overflow.
+ * read.c (s_comm_internal): Likewise.
+
+2014-10-14 Alan Modra <amodra@gmail.com>
+
* config/tc-sparc.c (sparc_md_end): Fix unused variable warnings.
2014-10-09 Jose E. Marchesi <jose.marchesi@oracle.com>
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 68ca7e4..38e9781 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -1946,47 +1946,46 @@ mode_from_disp_size (i386_operand_type t)
}
static INLINE int
-fits_in_signed_byte (offsetT num)
+fits_in_signed_byte (addressT num)
{
- return (num >= -128) && (num <= 127);
+ return num + 0x80 <= 0xff;
}
static INLINE int
-fits_in_unsigned_byte (offsetT num)
+fits_in_unsigned_byte (addressT num)
{
- return (num & 0xff) == num;
+ return num <= 0xff;
}
static INLINE int
-fits_in_unsigned_word (offsetT num)
+fits_in_unsigned_word (addressT num)
{
- return (num & 0xffff) == num;
+ return num <= 0xffff;
}
static INLINE int
-fits_in_signed_word (offsetT num)
+fits_in_signed_word (addressT num)
{
- return (-32768 <= num) && (num <= 32767);
+ return num + 0x8000 <= 0xffff;
}
static INLINE int
-fits_in_signed_long (offsetT num ATTRIBUTE_UNUSED)
+fits_in_signed_long (addressT num ATTRIBUTE_UNUSED)
{
#ifndef BFD64
return 1;
#else
- return (!(((offsetT) -1 << 31) & num)
- || (((offsetT) -1 << 31) & num) == ((offsetT) -1 << 31));
+ return num + 0x80000000 <= 0xffffffff;
#endif
} /* fits_in_signed_long() */
static INLINE int
-fits_in_unsigned_long (offsetT num ATTRIBUTE_UNUSED)
+fits_in_unsigned_long (addressT num ATTRIBUTE_UNUSED)
{
#ifndef BFD64
return 1;
#else
- return (num & (((offsetT) 2 << 31) - 1)) == num;
+ return num <= 0xffffffff;
#endif
} /* fits_in_unsigned_long() */
diff --git a/gas/expr.c b/gas/expr.c
index eb7255f..0ccfbd3 100644
--- a/gas/expr.c
+++ b/gas/expr.c
@@ -1021,7 +1021,8 @@ operand (expressionS *expressionP, enum expr_mode mode)
/* input_line_pointer -> char after operand. */
if (c == '-')
{
- expressionP->X_add_number = - expressionP->X_add_number;
+ expressionP->X_add_number
+ = - (addressT) expressionP->X_add_number;
/* Notice: '-' may overflow: no warning is given.
This is compatible with other people's
assemblers. Sigh. */
diff --git a/gas/read.c b/gas/read.c
index 2d5fdf1..9fd0335 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -1704,7 +1704,7 @@ s_comm_internal (int param,
temp = get_absolute_expr (&exp);
size = temp;
- size &= ((offsetT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
+ size &= ((addressT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
if (exp.X_op == O_absent)
{
as_bad (_("missing size expression"));
diff --git a/gas/write.c b/gas/write.c
index 0657b56..263b002 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -2309,7 +2309,7 @@ relax_align (register relax_addressT address, /* Address now. */
relax_addressT mask;
relax_addressT new_address;
- mask = ~((~0) << alignment);
+ mask = ~((relax_addressT) ~0 << alignment);
new_address = (address + mask) & (~mask);
#ifdef LINKER_RELAXING_SHRINKS_ONLY
if (linkrelax)