gas: Fix internal error on long local labels

Prior to this commit, on an input such as "88888888888:", GAS hits a
signed integer overflow and likely an assertion failure. I see:

$ echo "88888888888:" | bin/aarch64-none-elf-as
{standard input}: Assembler messages:
{standard input}:1: Internal error in fb_label_name at ../gas/symbols.c:2049.
Please report this bug.

To fix this issue, I've taken two steps:

1. Change the type used for processing local labels in
   read_a_source_file() from int to long, to allow representing more
   local labels, and also since all uses of this variable (temp) are
   actually of type long.

2. Detect if we would overflow and bail out with an error message
   instead of actually overflowing and hitting the assertion in
   fb_label_name().

gas/ChangeLog:

2020-08-06  Alex Coplan  <alex.coplan@arm.com>

	* read.c (read_a_source_file): Use long for local labels, detect
	overflow and raise an error for overly-long labels.
	* testsuite/gas/all/gas.exp: Add local-label-overflow test.
	* testsuite/gas/all/local-label-overflow.d: New test.
	* testsuite/gas/all/local-label-overflow.l: Error output.
	* testsuite/gas/all/local-label-overflow.s: Input.
This commit is contained in:
Alex Coplan 2020-08-06 17:39:03 +01:00
parent ed908db649
commit d27aad4ec3
6 changed files with 32 additions and 3 deletions

View File

@ -1,3 +1,12 @@
2020-08-06 Alex Coplan <alex.coplan@arm.com>
* read.c (read_a_source_file): Use long for local labels, detect
overflow and raise an error for overly-long labels.
* testsuite/gas/all/gas.exp: Add local-label-overflow test.
* testsuite/gas/all/local-label-overflow.d: New test.
* testsuite/gas/all/local-label-overflow.l: Error output.
* testsuite/gas/all/local-label-overflow.s: Input.
2020-08-04 Christian Groessler <chris@groessler.org>
* gas/testsuite/gas/z8k/inout.d: Adapt to correct encoding of

View File

@ -40,6 +40,8 @@
#include "dw2gencfi.h"
#include "wchar.h"
#include <limits.h>
#ifndef TC_START_LABEL
#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) (NEXT_CHAR == ':')
#endif
@ -816,7 +818,7 @@ read_a_source_file (const char *name)
char nul_char;
char next_char;
char *s; /* String of symbol, '\0' appended. */
int temp;
long temp;
pseudo_typeS *pop;
#ifdef WARN_COMMENTS
@ -1212,10 +1214,21 @@ read_a_source_file (const char *name)
/* Read the whole number. */
while (ISDIGIT (*input_line_pointer))
{
temp = (temp * 10) + *input_line_pointer - '0';
const long digit = *input_line_pointer - '0';
if (temp > (LONG_MAX - digit) / 10)
{
as_bad (_("local label too large near %s"), backup);
temp = -1;
break;
}
temp = temp * 10 + digit;
++input_line_pointer;
}
/* Overflow: stop processing the label. */
if (temp == -1)
continue;
if (LOCAL_LABELS_DOLLAR
&& *input_line_pointer == '$'
&& *(input_line_pointer + 1) == ':')
@ -1224,7 +1237,7 @@ read_a_source_file (const char *name)
if (dollar_label_defined (temp))
{
as_fatal (_("label \"%d$\" redefined"), temp);
as_fatal (_("label \"%ld$\" redefined"), temp);
}
define_dollar_label (temp);

View File

@ -102,6 +102,7 @@ if { ![istarget "bfin-*-*"] } then {
}
gas_test_error "assign-bad.s" "" "== assignment for symbol already set"
run_dump_test assign-bad-recursive
run_dump_test local-label-overflow
run_dump_test simple-forward
run_dump_test forward

View File

@ -0,0 +1,3 @@
#source: local-label-overflow.s
#error_output: local-label-overflow.l
#notarget: hppa*-*-* ia64-*-vms mmix-*-* sh-*-pe

View File

@ -0,0 +1,2 @@
[^:]*: Assembler messages:
.*: Error: local label too large near 888888888888888888888888888:

View File

@ -0,0 +1 @@
8888888888888888888888888888: