mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-15 04:31:49 +08:00
PR26448 UBSAN: symbols.c:1586 left shift of negative value
Besides avoiding the UB, this also makes right shifts inside expression symbols unsigned, consistent with the way gas evaluates expressions in source. PR 26448 * symbols.c: Include limits.h. (resolve_symbol_value <O_left_shift, O_right_shift>): Do an unsigned shift. Warn if shift count larger than valueT size.
This commit is contained in:
parent
b2f386b99c
commit
d8d6da137d
@ -1,3 +1,10 @@
|
||||
2020-08-26 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR 26448
|
||||
* symbols.c: Include limits.h.
|
||||
(resolve_symbol_value <O_left_shift, O_right_shift>): Do an
|
||||
unsigned shift. Warn if shift count larger than valueT size.
|
||||
|
||||
2020-08-26 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR 26447
|
||||
|
@ -26,6 +26,13 @@
|
||||
#include "subsegs.h"
|
||||
#include "write.h"
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifndef CHAR_BIT
|
||||
#define CHAR_BIT 8
|
||||
#endif
|
||||
|
||||
struct symbol_flags
|
||||
{
|
||||
/* Whether the symbol is a local_symbol. */
|
||||
@ -1559,14 +1566,24 @@ resolve_symbol_value (symbolS *symp)
|
||||
|
||||
right = 1;
|
||||
}
|
||||
if ((op == O_left_shift || op == O_right_shift)
|
||||
&& (valueT) right >= sizeof (valueT) * CHAR_BIT)
|
||||
{
|
||||
as_warn_value_out_of_range (_("shift count"), right, 0,
|
||||
sizeof (valueT) * CHAR_BIT - 1,
|
||||
NULL, 0);
|
||||
left = right = 0;
|
||||
}
|
||||
|
||||
switch (symp->x->value.X_op)
|
||||
{
|
||||
case O_multiply: left *= right; break;
|
||||
case O_divide: left /= right; break;
|
||||
case O_modulus: left %= right; break;
|
||||
case O_left_shift: left <<= right; break;
|
||||
case O_right_shift: left >>= right; break;
|
||||
case O_left_shift:
|
||||
left = (valueT) left << (valueT) right; break;
|
||||
case O_right_shift:
|
||||
left = (valueT) left >> (valueT) right; break;
|
||||
case O_bit_inclusive_or: left |= right; break;
|
||||
case O_bit_or_not: left |= ~right; break;
|
||||
case O_bit_exclusive_or: left ^= right; break;
|
||||
|
Loading…
Reference in New Issue
Block a user