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.
This commit is contained in:
parent
9495b2e66f
commit
65879393f0
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
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.
|
||||
|
|
|
@ -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() */
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue