From 3076e59490428c9719765f9b007d6d0d0238f006 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 10 May 2019 16:57:31 +0100 Subject: [PATCH] A series of fixes to addres problems detected by compiling the assembler with address sanitization enabled. PR 24538 gas * macro.c (get_any_string): Increase size of buffer used to hold decimal value of expression result. * dw2gencfi.c (get_debugseg_name): Handle an empty name. * dwarf2dbg.c (get_filenum): Catch integer wraparound when extending allocate file array. (dwarf2_directive_filename): Add extra checks of the computed file number. * config/tc-arm.c (arm_tc_equal_in_insn): Insert copy of name into warning hash table. (s_arm_eabi_attribute): Check for obj_elf_vendor_attribute returning -1. * config/tc-i386.c (i386_output_nops): Catch an attempt to generate nops of negative lengths. * as.h (MAX_LITTLENUMS): Move definition to here from... * config/atof-ieee.c: ...here. * config/tc-aarch64.c: ...here. * config/tc-arc.c: ...here. * config/tc-arm.c: ...here. * config/tc-epiphany.c: ...here. * config/tc-i386.c: ...here. * config/tc-ia64.c: ...here. (And correct the value). * config/tc-m32c.c: ...here. * config/tc-m32r.c: ...here. * config/tc-metag.c: ...here. * config/tc-microblaze.c: ...here. * config/tc-nds32.c: ...here. * config/tc-or1k.c: ...here. * config/tc-score.c: ...here. * config/tc-score7.c: ...here. * config/tc-tic4x.c: ...here. * config/tc-tilegx.c: ...here. * config/tc-tilepro.c: ...here. * config/tc-visium.c: ...here. * config/tc-sh.c (md_assemble): Add check for an instruction with no opcodes. * config/tc-mips.c (mips_lookup_insn): Add check for very short instruction name. * config/tc-tic54x.c: Use unsigned chars to access is_end_of_line array. (tic54x_start_line_hook): Check for an empty line. (next_line_shows_parallel): Do not walk off the end of the string. (tic54x_macro_start): Check for too much macro nesting. (tic54x_start_label): Add label_start parameter. Use this parameter to check the first character of the label. * config/tc-tic54x.h (TC_START_LABEL_WITHOUT_COLON): Pass line_start variable to tic54x_start_label. PR 24538 opcodes * ia64-opc.c (ia64_find_matching_opcode): Check for reaching the end of the table prematurely. --- gas/ChangeLog | 51 ++++++++++++++++++++++++++++ gas/as.h | 4 +++ gas/config/atof-ieee.c | 2 -- gas/config/tc-aarch64.c | 3 -- gas/config/tc-arc.c | 3 -- gas/config/tc-arm.c | 7 ++-- gas/config/tc-epiphany.c | 3 -- gas/config/tc-i386.c | 11 +++++- gas/config/tc-ia64.c | 2 -- gas/config/tc-m32c.c | 3 -- gas/config/tc-m32r.c | 3 -- gas/config/tc-metag.c | 3 -- gas/config/tc-microblaze.c | 5 +-- gas/config/tc-mips.c | 2 +- gas/config/tc-nds32.c | 3 -- gas/config/tc-or1k.c | 3 -- gas/config/tc-score.c | 3 +- gas/config/tc-score7.c | 3 +- gas/config/tc-sh.c | 30 +++++++---------- gas/config/tc-tic4x.c | 6 ++-- gas/config/tc-tic54x.c | 68 ++++++++++++++++++++------------------ gas/config/tc-tic54x.h | 9 +++-- gas/config/tc-tilegx.c | 3 -- gas/config/tc-tilepro.c | 3 -- gas/config/tc-visium.c | 3 -- gas/dw2gencfi.c | 48 +++++++++++++-------------- gas/dwarf2dbg.c | 17 ++++++++-- gas/macro.c | 2 +- gas/read.c | 3 +- opcodes/ChangeLog | 6 ++++ opcodes/ia64-opc.c | 5 ++- 31 files changed, 178 insertions(+), 139 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index c524feca4bf..57be17561fc 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,54 @@ +2019-05-10 Nick Clifton + + PR 24538 + * macro.c (get_any_string): Increase size of buffer used to hold + decimal value of expression result. + * dw2gencfi.c (get_debugseg_name): Handle an empty name. + * dwarf2dbg.c (get_filenum): Catch integer wraparound when + extending allocate file array. + (dwarf2_directive_filename): Add extra checks of the computed file + number. + * config/tc-arm.c (arm_tc_equal_in_insn): Insert copy of name into + warning hash table. + (s_arm_eabi_attribute): Check for obj_elf_vendor_attribute + returning -1. + * config/tc-i386.c (i386_output_nops): Catch an attempt to + generate nops of negative lengths. + * as.h (MAX_LITTLENUMS): Move definition to here from... + * config/atof-ieee.c: ...here. + * config/tc-aarch64.c: ...here. + * config/tc-arc.c: ...here. + * config/tc-arm.c: ...here. + * config/tc-epiphany.c: ...here. + * config/tc-i386.c: ...here. + * config/tc-ia64.c: ...here. (And correct the value). + * config/tc-m32c.c: ...here. + * config/tc-m32r.c: ...here. + * config/tc-metag.c: ...here. + * config/tc-microblaze.c: ...here. + * config/tc-nds32.c: ...here. + * config/tc-or1k.c: ...here. + * config/tc-score.c: ...here. + * config/tc-score7.c: ...here. + * config/tc-tic4x.c: ...here. + * config/tc-tilegx.c: ...here. + * config/tc-tilepro.c: ...here. + * config/tc-visium.c: ...here. + * config/tc-sh.c (md_assemble): Add check for an instruction with + no opcodes. + * config/tc-mips.c (mips_lookup_insn): Add check for very short + instruction name. + * config/tc-tic54x.c: Use unsigned chars to access is_end_of_line + array. + (tic54x_start_line_hook): Check for an empty line. + (next_line_shows_parallel): Do not walk off the end of the string. + (tic54x_macro_start): Check for too much macro nesting. + (tic54x_start_label): Add label_start parameter. Use this + parameter to check the first character of the label. + + * config/tc-tic54x.h (TC_START_LABEL_WITHOUT_COLON): Pass + line_start variable to tic54x_start_label. + 2019-05-10 Faraz Shahbazker * config/tc-mips.c (macro) : diff --git a/gas/as.h b/gas/as.h index 5b7ea8de98d..96b551eded3 100644 --- a/gas/as.h +++ b/gas/as.h @@ -479,6 +479,10 @@ void as_bad_value_out_of_range (const char *, offsetT, offsetT, offsetT, const char *, unsigned); void print_version_id (void); char * app_push (void); + +/* Number of littlenums required to hold an extended precision number. */ +#define MAX_LITTLENUMS 6 + char * atof_ieee (char *, int, LITTLENUM_TYPE *); const char * ieee_md_atof (int, char *, int *, bfd_boolean); const char * vax_md_atof (int, char *, int *); diff --git a/gas/config/atof-ieee.c b/gas/config/atof-ieee.c index eab218e0af2..9bb9e55d266 100644 --- a/gas/config/atof-ieee.c +++ b/gas/config/atof-ieee.c @@ -695,8 +695,6 @@ print_gen (gen) } #endif -#define MAX_LITTLENUMS 6 - /* This is a utility function called from various tc-*.c files. It is here in order to reduce code duplication. diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 7b9ebbd1edd..1f8d94ea1e2 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -238,9 +238,6 @@ set_fatal_syntax_error (const char *error) set_error (AARCH64_OPDE_FATAL_SYNTAX_ERROR, error); } -/* Number of littlenums required to hold an extended precision number. */ -#define MAX_LITTLENUMS 6 - /* Return value for certain parsers when the parsing fails; those parsers return the information of the parsed result, e.g. register number, on success. */ diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c index 6cc4726e2ef..c1d5ea3d470 100644 --- a/gas/config/tc-arc.c +++ b/gas/config/tc-arc.c @@ -48,9 +48,6 @@ #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) \ && (SUB_OPCODE (x) == 0x28)) -/* Equal to MAX_PRECISION in atof-ieee.c. */ -#define MAX_LITTLENUMS 6 - #ifndef TARGET_WITH_CPU #define TARGET_WITH_CPU "arc700" #endif /* TARGET_WITH_CPU */ diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 20a2dee1aaa..2ec3ea04465 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -528,9 +528,6 @@ const char * fp_const[] = "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0 }; -/* Number of littlenums required to hold an extended precision number. */ -#define MAX_LITTLENUMS 6 - LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS]; #define FAIL (-1) @@ -4746,7 +4743,7 @@ s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED) { int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC); - if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) + if (tag >= 0 && tag < NUM_KNOWN_OBJ_ATTRIBUTES) attributes_set_explicitly[tag] = 1; } @@ -23436,7 +23433,7 @@ arm_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char * name) already_warned = hash_new (); /* Only warn about the symbol once. To keep the code simple we let hash_insert do the lookup for us. */ - if (hash_insert (already_warned, name, NULL) == NULL) + if (hash_insert (already_warned, nbuf, NULL) == NULL) as_warn (_("[-mwarn-syms]: Assignment makes a symbol match an ARM instruction: %s"), name); } else diff --git a/gas/config/tc-epiphany.c b/gas/config/tc-epiphany.c index 61a4acb21b4..ca24520ffef 100644 --- a/gas/config/tc-epiphany.c +++ b/gas/config/tc-epiphany.c @@ -1008,9 +1008,6 @@ md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED, of LITTLENUMS emitted is stored in *SIZEP. An error message is returned, or NULL on OK. */ -/* Equal to MAX_PRECISION in atof-ieee.c. */ -#define MAX_LITTLENUMS 6 - const char * md_atof (int type, char *litP, int *sizeP) { diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 7159432f133..08dd9963e1c 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1299,7 +1299,16 @@ i386_output_nops (char *where, const unsigned char *const *patt, /* Place the longer NOP first. */ int last; int offset; - const unsigned char *nops = patt[max_single_nop_size - 1]; + const unsigned char *nops; + + if (max_single_nop_size < 1) + { + as_fatal (_("i386_output_nops called to generate nops of at most %d bytes!"), + max_single_nop_size); + return; + } + + nops = patt[max_single_nop_size - 1]; /* Use the smaller one if the requsted one isn't available. */ if (nops == NULL) diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index 1cfee960cfd..8f25e557e09 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -11570,8 +11570,6 @@ tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, fixS *fixp) of LITTLENUMS emitted is stored in *SIZE. An error message is returned, or NULL on OK. */ -#define MAX_LITTLENUMS 5 - const char * md_atof (int type, char *lit, int *size) { diff --git a/gas/config/tc-m32c.c b/gas/config/tc-m32c.c index 07501df27a5..851d4c1971a 100644 --- a/gas/config/tc-m32c.c +++ b/gas/config/tc-m32c.c @@ -1135,9 +1135,6 @@ md_number_to_chars (char * buf, valueT val, int n) type, and store the appropriate bytes in *litP. The number of LITTLENUMS emitted is stored in *sizeP . An error message is returned, or NULL on OK. */ -/* Equal to MAX_PRECISION in atof-ieee.c. */ -#define MAX_LITTLENUMS 6 - const char * md_atof (int type, char * litP, int * sizeP) { diff --git a/gas/config/tc-m32r.c b/gas/config/tc-m32r.c index 2b4c5ad2d68..c20cb72ce17 100644 --- a/gas/config/tc-m32r.c +++ b/gas/config/tc-m32r.c @@ -2103,9 +2103,6 @@ md_number_to_chars (char *buf, valueT val, int n) of LITTLENUMS emitted is stored in *SIZEP. An error message is returned, or NULL on OK. */ -/* Equal to MAX_PRECISION in atof-ieee.c. */ -#define MAX_LITTLENUMS 6 - const char * md_atof (int type, char *litP, int *sizeP) { diff --git a/gas/config/tc-metag.c b/gas/config/tc-metag.c index 1d275ad71a2..c7bb36d5b9c 100644 --- a/gas/config/tc-metag.c +++ b/gas/config/tc-metag.c @@ -6705,9 +6705,6 @@ md_number_to_chars (char * buf, valueT val, int n) emitted is stored in *sizeP . An error message is returned, or NULL on OK. */ -/* Equal to MAX_PRECISION in atof-ieee.c */ -#define MAX_LITTLENUMS 6 - const char * md_atof (int type, char * litP, int * sizeP) { diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c index ab90c6b20f9..c9ab452b3e8 100644 --- a/gas/config/tc-microblaze.c +++ b/gas/config/tc-microblaze.c @@ -1766,13 +1766,10 @@ md_undefined_symbol (char * name ATTRIBUTE_UNUSED) return NULL; } -/* Various routines to kill one day. */ -/* Equal to MAX_PRECISION in atof-ieee.c */ -#define MAX_LITTLENUMS 6 - /* Turn a string in input_line_pointer into a floating point constant of type type, and store the appropriate bytes in *litP. The number of LITTLENUMS emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/ + const char * md_atof (int type, char * litP, int * sizeP) { diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 05527d8084d..1c5dc7a8830 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -14250,7 +14250,7 @@ mips_lookup_insn (struct hash_control *hash, const char *start, opend = dot != NULL ? dot - name : length; if (opend >= 3 && name[opend - 2] == '1' && name[opend - 1] == '6') suffix = 2; - else if (name[opend - 2] == '3' && name[opend - 1] == '2') + else if (opend >= 2 && name[opend - 2] == '3' && name[opend - 1] == '2') suffix = 4; else suffix = 0; diff --git a/gas/config/tc-nds32.c b/gas/config/tc-nds32.c index 3c2652e1b5a..d01ca3d2026 100644 --- a/gas/config/tc-nds32.c +++ b/gas/config/tc-nds32.c @@ -7316,9 +7316,6 @@ md_number_to_chars (char *buf, valueT val, int n) number_to_chars_littleendian (buf, val, n); } -/* Equal to MAX_PRECISION in atof-ieee.c. */ -#define MAX_LITTLENUMS 6 - /* This function is called to convert an ASCII string into a floating point value in format used by the CPU. */ diff --git a/gas/config/tc-or1k.c b/gas/config/tc-or1k.c index a88ed6a53d2..28fa7c50104 100644 --- a/gas/config/tc-or1k.c +++ b/gas/config/tc-or1k.c @@ -275,9 +275,6 @@ md_number_to_chars (char * buf, valueT val, int n) type, and store the appropriate bytes in *litP. The number of LITTLENUMS emitted is stored in *sizeP . An error message is returned, or NULL on OK. */ -/* Equal to MAX_PRECISION in atof-ieee.c. */ -#define MAX_LITTLENUMS 6 - const char * md_atof (int type, char * litP, int * sizeP) { diff --git a/gas/config/tc-score.c b/gas/config/tc-score.c index 4bbeeb02570..648e0d22ebb 100644 --- a/gas/config/tc-score.c +++ b/gas/config/tc-score.c @@ -300,7 +300,6 @@ size_t md_longopts_size = sizeof (md_longopts); ? s3_INSN16_SIZE : (s3_GET_INSN_CLASS (type) == INSN_CLASS_48) \ ? s3_INSN48_SIZE : s3_INSN_SIZE) -#define s3_MAX_LITTLENUMS 6 #define s3_INSN_NAME_LEN 16 /* Relax will need some padding for alignment. */ @@ -6657,7 +6656,7 @@ static const char * s3_atof (int type, char *litP, int *sizeP) { int prec; - LITTLENUM_TYPE words[s3_MAX_LITTLENUMS]; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; char *t; int i; diff --git a/gas/config/tc-score7.c b/gas/config/tc-score7.c index f60ab494b88..90cd5e3962d 100644 --- a/gas/config/tc-score7.c +++ b/gas/config/tc-score7.c @@ -142,7 +142,6 @@ static void s7_do_lw_pic (char *); #define s7_GET_INSN_SIZE(type) ((s7_GET_INSN_CLASS (type) == INSN_CLASS_16) \ ? s7_INSN16_SIZE : s7_INSN_SIZE) -#define s7_MAX_LITTLENUMS 6 #define s7_INSN_NAME_LEN 16 /* Relax will need some padding for alignment. */ @@ -6209,7 +6208,7 @@ static const char * s7_atof (int type, char *litP, int *sizeP) { int prec; - LITTLENUM_TYPE words[s7_MAX_LITTLENUMS]; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; char *t; int i; diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c index aa8ddbb244d..c9d47df9f6e 100644 --- a/gas/config/tc-sh.c +++ b/gas/config/tc-sh.c @@ -2525,37 +2525,31 @@ md_assemble (char *str) char *name = initial_str; int name_length = 0; const sh_opcode_info *op; - int found = 0; + bfd_boolean found = FALSE; - /* identify opcode in string */ + /* Identify opcode in string. */ while (ISSPACE (*name)) - { - name++; - } - while (!ISSPACE (name[name_length])) - { - name_length++; - } + name++; + + while (name[name_length] != '\0' && !ISSPACE (name[name_length])) + name_length++; - /* search for opcode in full list */ + /* Search for opcode in full list. */ for (op = sh_table; op->name; op++) { if (strncasecmp (op->name, name, name_length) == 0 && op->name[name_length] == '\0') { - found = 1; + found = TRUE; break; } } - if ( found ) - { - as_bad (_("opcode not valid for this cpu variant")); - } + if (found) + as_bad (_("opcode not valid for this cpu variant")); else - { - as_bad (_("unknown opcode")); - } + as_bad (_("unknown opcode")); + return; } diff --git a/gas/config/tc-tic4x.c b/gas/config/tc-tic4x.c index a4b37e33245..f20d93b5b16 100644 --- a/gas/config/tc-tic4x.c +++ b/gas/config/tc-tic4x.c @@ -52,9 +52,6 @@ #define TIC4X_ALT_SYNTAX -/* Equal to MAX_PRECISION in atof-ieee.c. */ -#define MAX_LITTLENUMS 6 /* (12 bytes) */ - /* Handle of the inst mnemonic hash table. */ static struct hash_control *tic4x_op_hash = NULL; @@ -2487,7 +2484,8 @@ md_assemble (char *str) first_inst = inst; ok = 0; } - } while (!ok && !strcmp (inst->name, inst[1].name) && inst++); + } + while (!ok && !strcmp (inst->name, inst[1].name) && inst++); if (ok > 0) { diff --git a/gas/config/tc-tic54x.c b/gas/config/tc-tic54x.c index dc217ad54dd..6e2b05d39b8 100644 --- a/gas/config/tc-tic54x.c +++ b/gas/config/tc-tic54x.c @@ -185,7 +185,8 @@ static struct hash_control *subsym_recurse_hash; /* Prevent infinite recurse. * static struct hash_control *math_hash; /* Built-in math functions. */ /* Allow maximum levels of macro nesting; level 0 is the main substitution symbol table. The other assembler only does 32 levels, so there! */ -static struct hash_control *subsym_hash[100]; +#define MAX_SUBSYM_HASH 100 +static struct hash_control *subsym_hash[MAX_SUBSYM_HASH]; /* Keep track of local labels so we can substitute them before GAS sees them since macros use their own 'namespace' for local labels, use a separate hash @@ -336,7 +337,7 @@ tic54x_asg (int x ATTRIBUTE_UNUSED) str = input_line_pointer; while ((c = *input_line_pointer) != ',') { - if (is_end_of_line[(int) *input_line_pointer]) + if (is_end_of_line[(unsigned char) c]) break; ++input_line_pointer; } @@ -645,7 +646,7 @@ tic54x_struct (int arg) { /* Offset is ignored in inner structs. */ SKIP_WHITESPACE (); - if (!is_end_of_line[(int) *input_line_pointer]) + if (!is_end_of_line[(unsigned char) *input_line_pointer]) start_offset = get_absolute_expression (); else start_offset = 0; @@ -835,7 +836,7 @@ tic54x_struct_field (int type) int longword_align = 0; SKIP_WHITESPACE (); - if (!is_end_of_line[(int) *input_line_pointer]) + if (!is_end_of_line[(unsigned char) *input_line_pointer]) count = get_absolute_expression (); switch (type) @@ -1105,7 +1106,7 @@ tic54x_global (int type) if (c == ',') { input_line_pointer++; - if (is_end_of_line[(int) *input_line_pointer]) + if (is_end_of_line[(unsigned char) *input_line_pointer]) c = *input_line_pointer; } } @@ -1487,7 +1488,7 @@ tic54x_version (int x ATTRIBUTE_UNUSED) SKIP_WHITESPACE (); ver = input_line_pointer; - while (!is_end_of_line[(int) *input_line_pointer]) + while (!is_end_of_line[(unsigned char) *input_line_pointer]) ++input_line_pointer; c = *input_line_pointer; *input_line_pointer = 0; @@ -1645,7 +1646,7 @@ tic54x_align_words (int arg) /* Only ".align" with no argument is allowed within .struct/.union. */ int count = arg; - if (!is_end_of_line[(int) *input_line_pointer]) + if (!is_end_of_line[(unsigned char) *input_line_pointer]) { if (arg == 2) as_warn (_("Argument to .even ignored")); @@ -1913,7 +1914,7 @@ tic54x_include (int ignored ATTRIBUTE_UNUSED) else { filename = input_line_pointer; - while (!is_end_of_line[(int) *input_line_pointer]) + while (!is_end_of_line[(unsigned char) *input_line_pointer]) ++input_line_pointer; c = *input_line_pointer; *input_line_pointer = '\0'; @@ -1949,7 +1950,7 @@ tic54x_message (int type) else { msg = input_line_pointer; - while (!is_end_of_line[(int) *input_line_pointer]) + while (!is_end_of_line[(unsigned char) *input_line_pointer]) ++input_line_pointer; c = *input_line_pointer; *input_line_pointer = 0; @@ -2027,7 +2028,7 @@ tic54x_loop (int count) ILLEGAL_WITHIN_STRUCT (); SKIP_WHITESPACE (); - if (!is_end_of_line[(int) *input_line_pointer]) + if (!is_end_of_line[(unsigned char) *input_line_pointer]) count = get_absolute_expression (); do_repeat ((size_t) count, "LOOP", "ENDLOOP"); @@ -2052,7 +2053,7 @@ tic54x_break (int ignore ATTRIBUTE_UNUSED) ILLEGAL_WITHIN_STRUCT (); SKIP_WHITESPACE (); - if (!is_end_of_line[(int) *input_line_pointer]) + if (!is_end_of_line[(unsigned char) *input_line_pointer]) cond = get_absolute_expression (); if (cond) @@ -2140,7 +2141,7 @@ tic54x_sblock (int ignore ATTRIBUTE_UNUSED) seg->flags |= SEC_TIC54X_BLOCK; c = *input_line_pointer; - if (!is_end_of_line[(int) c]) + if (!is_end_of_line[(unsigned char) c]) ++input_line_pointer; } @@ -2239,7 +2240,7 @@ tic54x_var (int ignore ATTRIBUTE_UNUSED) if (c == ',') { ++input_line_pointer; - if (is_end_of_line[(int) *input_line_pointer]) + if (is_end_of_line[(unsigned char) *input_line_pointer]) c = *input_line_pointer; } } @@ -2275,7 +2276,7 @@ tic54x_mlib (int ignore ATTRIBUTE_UNUSED) { SKIP_WHITESPACE (); len = 0; - while (!is_end_of_line[(int) *input_line_pointer] + while (!is_end_of_line[(unsigned char) *input_line_pointer] && !ISSPACE (*input_line_pointer)) { obstack_1grow (¬es, *input_line_pointer); @@ -2497,7 +2498,11 @@ md_parse_option (int c, const char *arg) void tic54x_macro_start (void) { - ++macro_level; + if (++macro_level >= MAX_SUBSYM_HASH) + { + as_fatal (_("Macro nesting is too deep")); + return; + } subsym_hash[macro_level] = hash_new (); local_label_hash[macro_level] = hash_new (); } @@ -3081,7 +3086,7 @@ get_operands (struct opstruct operands[], char *line) int expecting_operand = 0; int i; - while (numexp < MAX_OPERANDS && !is_end_of_line[(int) *lptr]) + while (numexp < MAX_OPERANDS && !is_end_of_line[(unsigned char) *lptr]) { int paren_not_balanced = 0; char *op_start, *op_end; @@ -3143,7 +3148,7 @@ get_operands (struct opstruct operands[], char *line) while (*lptr && ISSPACE (*lptr++)) ; - if (!is_end_of_line[(int) *lptr]) + if (!is_end_of_line[(unsigned char) *lptr]) { as_bad (_("Extra junk on line")); return -1; @@ -4195,7 +4200,7 @@ static int next_line_shows_parallel (char *next_line) { /* Look for the second half. */ - while (ISSPACE (*next_line)) + while (*next_line != 0 && ISSPACE (*next_line)) ++next_line; return (next_line[0] == PARALLEL_SEPARATOR @@ -4411,10 +4416,9 @@ subsym_substitute (char *line, int forced) if (strstr (line, ".macro")) return line; - while (!is_end_of_line[(int) *ptr]) + unsigned char current_char; + while (!is_end_of_line[(current_char = * (unsigned char *) ptr)]) { - int current_char = *ptr; - /* Need to update this since LINE may have been modified. */ if (eval_line) eval_end = strrchr (ptr, ','); @@ -4734,9 +4738,13 @@ tic54x_start_line_hook (void) char *replacement = NULL; /* Work with a copy of the input line, including EOL char. */ - endp = input_line_pointer; - while (!is_end_of_line[(int) *endp++]) - ; + for (endp = input_line_pointer; ; endp ++) + { + unsigned char c = * (unsigned char *) endp; + if (c == 0 || is_end_of_line [c]) + break; + } + line = xmemdup0 (input_line_pointer, endp - input_line_pointer); /* Scan ahead for parallel insns. */ @@ -5333,7 +5341,7 @@ tic54x_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, Don't allow labels to start with '.' */ int -tic54x_start_label (int nul_char, int next_char) +tic54x_start_label (char * label_start, int nul_char, int next_char) { char *rest; @@ -5344,18 +5352,14 @@ tic54x_start_label (int nul_char, int next_char) /* Disallow labels starting with "." */ if (next_char != ':') { - char *label = input_line_pointer; - - while (!is_end_of_line[(int) label[-1]]) - --label; - if (*label == '.') + if (*label_start == '.') { - as_bad (_("Invalid label '%s'"), label); + as_bad (_("Invalid label '%s'"), label_start); return 0; } } - if (is_end_of_line[(int) next_char]) + if (is_end_of_line[(unsigned char) next_char]) return 1; rest = input_line_pointer; diff --git a/gas/config/tc-tic54x.h b/gas/config/tc-tic54x.h index 0eda39603eb..2797ae4823b 100644 --- a/gas/config/tc-tic54x.h +++ b/gas/config/tc-tic54x.h @@ -64,10 +64,13 @@ struct bit_info #define TC_FRAG_TYPE int #define TC_FRAG_INIT(FRAGP, MAX_BYTES) do {(FRAGP)->tc_frag_data = 0;}while (0) -/* tell GAS whether the given token is indeed a code label */ +/* Tell GAS whether the given token is indeed a code label. + Note - we make of the knowledge that this macro will be called from + read.c:read_a_source_file() in that we also pass the local variable + line_start. */ #define TC_START_LABEL_WITHOUT_COLON(NUL_CHAR, NEXT_CHAR) \ - tic54x_start_label(NUL_CHAR, NEXT_CHAR) -extern int tic54x_start_label (int, int); + tic54x_start_label (line_start, NUL_CHAR, NEXT_CHAR) +extern int tic54x_start_label (char *, int, int); /* custom handling for relocations in cons expressions */ #define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \ diff --git a/gas/config/tc-tilegx.c b/gas/config/tc-tilegx.c index eea6c5f84d4..e840e5dc85f 100644 --- a/gas/config/tc-tilegx.c +++ b/gas/config/tc-tilegx.c @@ -1314,9 +1314,6 @@ const pseudo_typeS md_pseudo_table[] = { NULL, 0, 0 } }; -/* Equal to MAX_PRECISION in atof-ieee.c */ -#define MAX_LITTLENUMS 6 - void md_number_to_chars (char * buf, valueT val, int n) { diff --git a/gas/config/tc-tilepro.c b/gas/config/tc-tilepro.c index 8eb9ce31617..146e270f7de 100644 --- a/gas/config/tc-tilepro.c +++ b/gas/config/tc-tilepro.c @@ -1198,9 +1198,6 @@ const pseudo_typeS md_pseudo_table[] = { NULL, 0, 0 } }; -/* Equal to MAX_PRECISION in atof-ieee.c */ -#define MAX_LITTLENUMS 6 - /* Turn the string pointed to by litP into a floating point constant of type TYPE, and emit the appropriate bytes. The number of LITTLENUMS emitted is stored in *SIZEP. An error message is diff --git a/gas/config/tc-visium.c b/gas/config/tc-visium.c index bbd320e5edc..68863112301 100644 --- a/gas/config/tc-visium.c +++ b/gas/config/tc-visium.c @@ -821,9 +821,6 @@ md_begin (void) emitted is stored in *sizeP . An error message is returned, or NULL on OK. */ -/* Equal to MAX_PRECISION in atof-ieee.c. */ -#define MAX_LITTLENUMS 6 - const char * md_atof (int type, char *litP, int *sizeP) { diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c index d85997b267b..f30734d384b 100644 --- a/gas/dw2gencfi.c +++ b/gas/dw2gencfi.c @@ -225,37 +225,37 @@ emit_expr_encoded (expressionS *exp, int encoding, bfd_boolean emit_encoding) static char * get_debugseg_name (segT seg, const char *base_name) { - const char *name; + const char * name; + const char * dollar; + const char * dot; if (!seg) - name = ""; - else - { - const char * dollar; - const char * dot; + return concat (base_name, NULL); - name = bfd_get_section_name (stdoutput, seg); + name = bfd_get_section_name (stdoutput, seg); - dollar = strchr (name, '$'); - dot = strchr (name + 1, '.'); + if (name == NULL || *name == 0) + return concat (base_name, NULL); + + dollar = strchr (name, '$'); + dot = strchr (name + 1, '.'); - if (!dollar && !dot) - { - if (!strcmp (base_name, ".eh_frame_entry") - && strcmp (name, ".text") != 0) - return concat (base_name, ".", name, NULL); + if (!dollar && !dot) + { + if (!strcmp (base_name, ".eh_frame_entry") + && strcmp (name, ".text") != 0) + return concat (base_name, ".", name, NULL); - name = ""; - } - else if (!dollar) - name = dot; - else if (!dot) - name = dollar; - else if (dot < dollar) - name = dot; - else - name = dollar; + name = ""; } + else if (!dollar) + name = dot; + else if (!dot) + name = dollar; + else if (dot < dollar) + name = dot; + else + name = dollar; return concat (base_name, name, NULL); } diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c index b77751d8af3..cc36957cb48 100644 --- a/gas/dwarf2dbg.c +++ b/gas/dwarf2dbg.c @@ -751,8 +751,14 @@ get_filenum (const char *filename, unsigned int num) unsigned int old = files_allocated; files_allocated = i + 32; - files = XRESIZEVEC (struct file_entry, files, files_allocated); + /* Catch wraparound. */ + if (files_allocated <= old) + { + as_bad (_("file number %u is too big"), i); + return 0; + } + files = XRESIZEVEC (struct file_entry, files, files_allocated); memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry)); } @@ -803,13 +809,18 @@ dwarf2_directive_filename (void) being supplied. Turn off gas generated debug info. */ debug_type = DEBUG_NONE; - if (num < (int) files_in_use && files[num].filename != 0) + if (num < (offsetT) files_in_use && files[num].filename != 0) { as_bad (_("file number %ld already allocated"), (long) num); return NULL; } + else if (num < 0) + { + as_bad (_("file number %ld is too small!"), (long) num); + return NULL; + } - get_filenum (filename, num); + get_filenum (filename, (unsigned int) num); return filename; } diff --git a/gas/macro.c b/gas/macro.c index b79d9221493..e00a18bdad4 100644 --- a/gas/macro.c +++ b/gas/macro.c @@ -374,7 +374,7 @@ get_any_string (size_t idx, sb *in, sb *out) else if (in->ptr[idx] == '%' && macro_alternate) { offsetT val; - char buf[20]; + char buf[64]; /* Turns the next expression into a string. */ /* xgettext: no-c-format */ diff --git a/gas/read.c b/gas/read.c index ac0048d832d..58d79b2787a 100644 --- a/gas/read.c +++ b/gas/read.c @@ -3760,7 +3760,8 @@ ignore_rest_of_line (void) input_line_pointer++; /* Return pointing just after end-of-line. */ - know (is_end_of_line[(unsigned char) input_line_pointer[-1]]); + if (input_line_pointer <= buffer_limit) + know (is_end_of_line[(unsigned char) input_line_pointer[-1]]); } /* Sets frag for given symbol to zero_address_frag, except when the diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index ff72dba218e..c648a2c31a2 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,9 @@ +2019-05-10 Nick Clifton + + PR 24538 + * ia64-opc.c (ia64_find_matching_opcode): Check for reaching the + end of the table prematurely. + 2019-05-10 Faraz Shahbazker * mips-opc.c (mips_opcodes): Enable ADD, SUB, DADD and DSUB diff --git a/opcodes/ia64-opc.c b/opcodes/ia64-opc.c index b6e95f11e6f..5aa1198ec53 100644 --- a/opcodes/ia64-opc.c +++ b/opcodes/ia64-opc.c @@ -123,7 +123,7 @@ static short find_main_ent (short nameindex) { short start = 0; - short end = sizeof (main_table) / sizeof (struct ia64_main_table); + short end = ARRAY_SIZE (main_table); short i = (start + end) / 2; if (nameindex < main_table[0].name_index @@ -612,6 +612,9 @@ ia64_find_matching_opcode (const char *name, short place) const char *suffix; short name_index; + if ((unsigned) place >= ARRAY_SIZE (main_table)) + return NULL; + if (strlen (name) > 128) { return NULL; -- 2.30.2