aboutsummaryrefslogtreecommitdiff
path: root/gas/read.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2023-03-01 12:58:41 +1030
committerAlan Modra <amodra@gmail.com>2023-03-01 13:28:13 +1030
commitd80081ef39c729b0f5f548c9567be2d80dcc2fd0 (patch)
tree0ae6caa3423858c9d4fc02e307bed3a4802ec8e4 /gas/read.c
parentd09f4d4a9b96dcb4b732fe13549506be5b276ec2 (diff)
downloadbinutils-d80081ef39c729b0f5f548c9567be2d80dcc2fd0.zip
binutils-d80081ef39c729b0f5f548c9567be2d80dcc2fd0.tar.gz
binutils-d80081ef39c729b0f5f548c9567be2d80dcc2fd0.tar.bz2
Catch overflow in gas s_space
Also fix an error introduced in 1998 in reporting a zero count for negative counts. * read.c (s_space): Use unsigned multiply, and catch overflow. Correct order of tests for invalid repeat counts. Ensure ignored directives don't affect mri_pending_align.
Diffstat (limited to 'gas/read.c')
-rw-r--r--gas/read.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/gas/read.c b/gas/read.c
index 5d83d35..cff4462 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -3328,27 +3328,37 @@ s_space (int mult)
if (exp.X_op == O_constant)
{
- offsetT repeat;
+ addressT repeat = exp.X_add_number;
+ addressT total;
- repeat = exp.X_add_number;
- if (mult)
- repeat *= mult;
- bytes = repeat;
- if (repeat <= 0)
+ bytes = 0;
+ if ((offsetT) repeat < 0)
+ {
+ as_warn (_(".space repeat count is negative, ignored"));
+ goto getout;
+ }
+ if (repeat == 0)
{
if (!flag_mri)
as_warn (_(".space repeat count is zero, ignored"));
- else if (repeat < 0)
- as_warn (_(".space repeat count is negative, ignored"));
goto getout;
}
+ if ((unsigned int) mult <= 1)
+ total = repeat;
+ else if (gas_mul_overflow (repeat, mult, &total)
+ || (offsetT) total < 0)
+ {
+ as_warn (_(".space repeat count overflow, ignored"));
+ goto getout;
+ }
+ bytes = total;
/* If we are in the absolute section, just bump the offset. */
if (now_seg == absolute_section)
{
if (val.X_op != O_constant || val.X_add_number != 0)
as_warn (_("ignoring fill value in absolute section"));
- abs_section_offset += repeat;
+ abs_section_offset += total;
goto getout;
}
@@ -3358,13 +3368,13 @@ s_space (int mult)
if (mri_common_symbol != NULL)
{
S_SET_VALUE (mri_common_symbol,
- S_GET_VALUE (mri_common_symbol) + repeat);
+ S_GET_VALUE (mri_common_symbol) + total);
goto getout;
}
if (!need_pass_2)
p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
- (offsetT) repeat, (char *) 0);
+ (offsetT) total, (char *) 0);
}
else
{