mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 14:49:38 +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:
@ -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>
|
2020-08-26 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
PR 26447
|
PR 26447
|
||||||
|
@ -26,6 +26,13 @@
|
|||||||
#include "subsegs.h"
|
#include "subsegs.h"
|
||||||
#include "write.h"
|
#include "write.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_LIMITS_H
|
||||||
|
#include <limits.h>
|
||||||
|
#endif
|
||||||
|
#ifndef CHAR_BIT
|
||||||
|
#define CHAR_BIT 8
|
||||||
|
#endif
|
||||||
|
|
||||||
struct symbol_flags
|
struct symbol_flags
|
||||||
{
|
{
|
||||||
/* Whether the symbol is a local_symbol. */
|
/* Whether the symbol is a local_symbol. */
|
||||||
@ -1559,14 +1566,24 @@ resolve_symbol_value (symbolS *symp)
|
|||||||
|
|
||||||
right = 1;
|
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)
|
switch (symp->x->value.X_op)
|
||||||
{
|
{
|
||||||
case O_multiply: left *= right; break;
|
case O_multiply: left *= right; break;
|
||||||
case O_divide: left /= right; break;
|
case O_divide: left /= right; break;
|
||||||
case O_modulus: left %= right; break;
|
case O_modulus: left %= right; break;
|
||||||
case O_left_shift: left <<= right; break;
|
case O_left_shift:
|
||||||
case O_right_shift: left >>= right; break;
|
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_inclusive_or: left |= right; break;
|
||||||
case O_bit_or_not: left |= ~right; break;
|
case O_bit_or_not: left |= ~right; break;
|
||||||
case O_bit_exclusive_or: left ^= right; break;
|
case O_bit_exclusive_or: left ^= right; break;
|
||||||
|
Reference in New Issue
Block a user