From 2e57ce7b1422a025a65ad4ef0b1f2f4c214b9eec Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 27 Aug 2015 22:50:38 +0930 Subject: More fallout from "Allow symbol and label names to be enclosed in double quotes" Some of the TC_START_LABEL implementations need to adjust the end of the symbol, when a colon doesn't mean a label definition. That means they need access to nul_char both the restore the NUL location (it may be a quote rather than a colon) and to store the new nul_char. Others need adjusting to step over a potential trailing quote. PR gas/18581 * config/tc-aarch64.h (TC_START_LABEL): Redefine. * config/tc-arm.c (tc_start_label_without_colon): Delete params. Use input_line_pointer directly. * config/tc-arm.h (TC_START_LABEL): Redefine. (TC_START_LABEL_WITHOUT_COLON): Redefine. (tc_start_label_without_colon): Update prototype. * config/tc-bfin.c (bfin_start_label): Delete ptr param. Check for NUL instead. * config/tc-bfin.h (bfin_start_label): Update prototype. (TC_START_LABEL): Redefine. * config/tc-d30v.h (TC_START_LABEL): Redefine. * config/tc-fr30.c (restore_colon): Rewrite. (fr30_is_colon_insn): Add nul_char param. Return int. Bump i_l_p over quote. Update restore_colon calls. * config/tc-fr30.h (TC_START_LABEL): Redefine. (fr30_is_colon_insn): Update prototype. * config/tc-m32c.c (restore_colon, m32c_is_colon_insn): As above. * config/tc-m32c.h (TC_START_LABEL): Redefine. (m32c_is_colon_insn): Update prototype. * config/tc-m32r.h (TC_START_LABEL): Redefine. * config/tc-mep.h (TC_START_LABEL): Redefine. * config/tc-nds32.h (TC_START_LABEL): Redefine. * config/tc-tic54x.c (tic54x_start_label): Replace params with nul_char and next_char. Step over trailing quote. * config/tc-tic54x.h (TC_START_LABEL_WITHOUT_COLON): Redefine. (tic54x_start_label): Update prototype. * read.c (TC_START_LABEL): Redefine. Update invocation. (TC_START_LABEL_WITHOUT_COLON): Update invocation. * config/tc-nios2.c (s_nios2_set): Save initial input_line_pointer and restore if calling s_set. Don't restore delim again. --- gas/config/tc-aarch64.h | 4 ++-- gas/config/tc-arm.c | 4 ++-- gas/config/tc-arm.h | 8 +++++--- gas/config/tc-bfin.c | 4 ++-- gas/config/tc-bfin.h | 5 +++-- gas/config/tc-d30v.h | 3 ++- gas/config/tc-fr30.c | 42 ++++++++++++++++++++++-------------------- gas/config/tc-fr30.h | 10 +++++----- gas/config/tc-m32c.c | 36 ++++++++++++++++++------------------ gas/config/tc-m32c.h | 10 +++++----- gas/config/tc-m32r.h | 3 ++- gas/config/tc-mep.h | 3 ++- gas/config/tc-nds32.h | 3 ++- gas/config/tc-nios2.c | 4 ++-- gas/config/tc-tic54x.c | 41 ++++++++++++++++++++--------------------- gas/config/tc-tic54x.h | 5 +++-- 16 files changed, 97 insertions(+), 88 deletions(-) (limited to 'gas/config') diff --git a/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h index 86b70d6..951a436 100644 --- a/gas/config/tc-aarch64.h +++ b/gas/config/tc-aarch64.h @@ -91,8 +91,8 @@ void aarch64_copy_symbol_attributes (symbolS *, symbolS *); (aarch64_copy_symbol_attributes (DEST, SRC)) #endif -#define TC_START_LABEL(C,S,STR) ((C) == ':' \ - || ((C) == '/' && aarch64_data_in_code ())) +#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) \ + (NEXT_CHAR == ':' || (NEXT_CHAR == '/' && aarch64_data_in_code ())) #define tc_canonicalize_symbol_name(str) aarch64_canonicalize_symbol_name (str); #define obj_adjust_symtab() aarch64_adjust_symtab () diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 68581cb..efc522a 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -3311,13 +3311,13 @@ add_to_lit_pool (unsigned int nbytes) } bfd_boolean -tc_start_label_without_colon (char unused1 ATTRIBUTE_UNUSED, const char * rest) +tc_start_label_without_colon (void) { bfd_boolean ret = TRUE; if (codecomposer_syntax && asmfunc_state == WAITING_ASMFUNC_NAME) { - const char *label = rest; + const char *label = input_line_pointer; while (!is_end_of_line[(int) label[-1]]) --label; diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h index 98038be..42f2d90 100644 --- a/gas/config/tc-arm.h +++ b/gas/config/tc-arm.h @@ -104,8 +104,9 @@ extern int arm_optimize_expr (expressionS *, operatorT, expressionS *); #define md_start_line_hook() arm_start_line_hook () -#define TC_START_LABEL_WITHOUT_COLON(c, l) tc_start_label_without_colon (c, l) -extern bfd_boolean tc_start_label_without_colon (char, const char *); +#define TC_START_LABEL_WITHOUT_COLON(NUL_CHAR, NEXT_CHAR) \ + tc_start_label_without_colon () +extern bfd_boolean tc_start_label_without_colon (void); #define tc_frob_label(S) arm_frob_label (S) @@ -179,7 +180,8 @@ void arm_copy_symbol_attributes (symbolS *, symbolS *); (arm_copy_symbol_attributes (DEST, SRC)) #endif -#define TC_START_LABEL(C,S,STR) (C == ':' || (C == '/' && arm_data_in_code ())) +#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) \ + (NEXT_CHAR == ':' || (NEXT_CHAR == '/' && arm_data_in_code ())) #define tc_canonicalize_symbol_name(str) arm_canonicalize_symbol_name (str); #define obj_adjust_symtab() arm_adjust_symtab () diff --git a/gas/config/tc-bfin.c b/gas/config/tc-bfin.c index 3736d79..656e515 100644 --- a/gas/config/tc-bfin.c +++ b/gas/config/tc-bfin.c @@ -1970,9 +1970,9 @@ bfin_eol_in_insn (char *line) } bfd_boolean -bfin_start_label (char *s, char *ptr) +bfin_start_label (char *s) { - while (s != ptr) + while (*s != 0) { if (*s == '(' || *s == '[') return FALSE; diff --git a/gas/config/tc-bfin.h b/gas/config/tc-bfin.h index 4c3a40e..47b585b 100644 --- a/gas/config/tc-bfin.h +++ b/gas/config/tc-bfin.h @@ -38,7 +38,7 @@ #define WORKING_DOT_WORD -extern bfd_boolean bfin_start_label (char *, char *); +extern bfd_boolean bfin_start_label (char *); #define md_number_to_chars number_to_chars_littleendian #define md_convert_frag(b,s,f) as_fatal ("bfin convert_frag\n"); @@ -58,7 +58,8 @@ extern bfd_boolean bfin_eol_in_insn (char *); #define DOUBLESLASH_LINE_COMMENTS -#define TC_START_LABEL(c, s, ptr) (c == ':' && bfin_start_label (s, ptr)) +#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) \ + (NEXT_CHAR == ':' && bfin_start_label (STR)) #define tc_fix_adjustable(FIX) bfin_fix_adjustable (FIX) extern bfd_boolean bfin_fix_adjustable (struct fix *); diff --git a/gas/config/tc-d30v.h b/gas/config/tc-d30v.h index 87e47ee..c28c260 100644 --- a/gas/config/tc-d30v.h +++ b/gas/config/tc-d30v.h @@ -46,7 +46,8 @@ extern long md_pcrel_from_section (struct fix *, segT); int d30v_cleanup (int); #define md_cleanup() d30v_cleanup (FALSE) -#define TC_START_LABEL(ch, s, ptr) (ch == ':' && d30v_cleanup (FALSE)) +#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) \ + (NEXT_CHAR == ':' && d30v_cleanup (FALSE)) void d30v_start_line (void); #define md_start_line_hook() d30v_start_line () diff --git a/gas/config/tc-fr30.c b/gas/config/tc-fr30.c index 6a6c67f..c6e80e3 100644 --- a/gas/config/tc-fr30.c +++ b/gas/config/tc-fr30.c @@ -324,19 +324,16 @@ md_atof (int type, char * litP, int * sizeP) } /* Worker function for fr30_is_colon_insn(). */ -static char -restore_colon (int advance_i_l_p_by) +static int +restore_colon (char *next_i_l_p, char *nul_char) { - char c; - /* Restore the colon, and advance input_line_pointer to the end of the new symbol. */ - * input_line_pointer = ':'; - input_line_pointer += advance_i_l_p_by; - c = * input_line_pointer; - * input_line_pointer = 0; - - return c; + *input_line_pointer = *nul_char; + input_line_pointer = next_i_l_p; + *nul_char = *next_i_l_p; + *next_i_l_p = 0; + return 1; } /* Determines if the symbol starting at START and ending in @@ -344,13 +341,16 @@ restore_colon (int advance_i_l_p_by) (but which has now been replaced bu a NUL) is in fact an LDI:8, LDI:20, LDI:32, CALL:D. JMP:D, RET:D or Bcc:D instruction. If it is, then it restores the colon, advances INPUT_LINE_POINTER - to the real end of the instruction/symbol, and returns the character - that really terminated the symbol. Otherwise it returns 0. */ -char -fr30_is_colon_insn (char * start) + to the real end of the instruction/symbol, saves the char there to + NUL_CHAR and pokes a NUL, and returns 1. Otherwise it returns 0. */ +int +fr30_is_colon_insn (char *start, char *nul_char) { char * i_l_p = input_line_pointer; + if (*nul_char == '"') + ++i_l_p; + /* Check to see if the symbol parsed so far is 'ldi'. */ if ( (start[0] != 'l' && start[0] != 'L') || (start[1] != 'd' && start[1] != 'D') @@ -384,7 +384,7 @@ fr30_is_colon_insn (char * start) break; if (len == -1) - return restore_colon (1); + return restore_colon (i_l_p + 1, nul_char); } } @@ -394,15 +394,17 @@ fr30_is_colon_insn (char * start) /* Check to see if the text following the colon is '8'. */ if (i_l_p[1] == '8' && (i_l_p[2] == ' ' || i_l_p[2] == '\t')) - return restore_colon (2); + return restore_colon (i_l_p + 2, nul_char); /* Check to see if the text following the colon is '20'. */ - else if (i_l_p[1] == '2' && i_l_p[2] =='0' && (i_l_p[3] == ' ' || i_l_p[3] == '\t')) - return restore_colon (3); + else if (i_l_p[1] == '2' && i_l_p[2] =='0' + && (i_l_p[3] == ' ' || i_l_p[3] == '\t')) + return restore_colon (i_l_p + 3, nul_char); /* Check to see if the text following the colon is '32'. */ - else if (i_l_p[1] == '3' && i_l_p[2] =='2' && (i_l_p[3] == ' ' || i_l_p[3] == '\t')) - return restore_colon (3); + else if (i_l_p[1] == '3' && i_l_p[2] =='2' + && (i_l_p[3] == ' ' || i_l_p[3] == '\t')) + return restore_colon (i_l_p + 3, nul_char); return 0; } diff --git a/gas/config/tc-fr30.h b/gas/config/tc-fr30.h index ecec847..db4d8e8 100644 --- a/gas/config/tc-fr30.h +++ b/gas/config/tc-fr30.h @@ -58,8 +58,8 @@ extern const struct relax_type md_relax_table[]; /* We need a special version of the TC_START_LABEL macro so that we allow the LDI:8, LDI:20, LDI:32 and delay slot instructions to be - parsed as such. We need to be able to change the contents of - the local variable 'c' which is passed to this macro as 'character'. */ -#define TC_START_LABEL(character, s, i_l_p) \ - ((character) != ':' ? 0 : (character = fr30_is_colon_insn (s)) ? 0 : ((character = ':'), 1)) -extern char fr30_is_colon_insn (char *); + parsed as such. We need to be able to change the contents of the + var storing what was at the NUL delimiter. */ +#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) \ + (NEXT_CHAR == ':' && !fr30_is_colon_insn (STR, &NUL_CHAR)) +extern int fr30_is_colon_insn (char *, char *); diff --git a/gas/config/tc-m32c.c b/gas/config/tc-m32c.c index 2c8136b..10eba14 100644 --- a/gas/config/tc-m32c.c +++ b/gas/config/tc-m32c.c @@ -1247,19 +1247,16 @@ m32c_fix_adjustable (fixS * fixP) } /* Worker function for m32c_is_colon_insn(). */ -static char -restore_colon (int advance_i_l_p_by) +static int +restore_colon (char *next_i_l_p, char *nul_char) { - char c; - /* Restore the colon, and advance input_line_pointer to the end of the new symbol. */ - * input_line_pointer = ':'; - input_line_pointer += advance_i_l_p_by; - c = * input_line_pointer; - * input_line_pointer = 0; - - return c; + *input_line_pointer = *nul_char; + input_line_pointer = next_i_l_p; + *nul_char = *next_i_l_p; + *next_i_l_p = 0; + return 1; } /* Determines if the symbol starting at START and ending in @@ -1267,28 +1264,31 @@ restore_colon (int advance_i_l_p_by) (but which has now been replaced bu a NUL) is in fact an :Z, :S, :Q, or :G suffix. If it is, then it restores the colon, advances INPUT_LINE_POINTER - to the real end of the instruction/symbol, and returns the character - that really terminated the symbol. Otherwise it returns 0. */ -char -m32c_is_colon_insn (char *start ATTRIBUTE_UNUSED) + to the real end of the instruction/symbol, saves the char there to + NUL_CHAR and pokes a NUL, and returns 1. Otherwise it returns 0. */ +int +m32c_is_colon_insn (char *start ATTRIBUTE_UNUSED, char *nul_char) { char * i_l_p = input_line_pointer; + if (*nul_char == '"') + ++i_l_p; + /* Check to see if the text following the colon is 'G' */ if (TOLOWER (i_l_p[1]) == 'g' && (i_l_p[2] == ' ' || i_l_p[2] == '\t')) - return restore_colon (2); + return restore_colon (i_l_p + 2, nul_char); /* Check to see if the text following the colon is 'Q' */ if (TOLOWER (i_l_p[1]) == 'q' && (i_l_p[2] == ' ' || i_l_p[2] == '\t')) - return restore_colon (2); + return restore_colon (i_l_p + 2, nul_char); /* Check to see if the text following the colon is 'S' */ if (TOLOWER (i_l_p[1]) == 's' && (i_l_p[2] == ' ' || i_l_p[2] == '\t')) - return restore_colon (2); + return restore_colon (i_l_p + 2, nul_char); /* Check to see if the text following the colon is 'Z' */ if (TOLOWER (i_l_p[1]) == 'z' && (i_l_p[2] == ' ' || i_l_p[2] == '\t')) - return restore_colon (2); + return restore_colon (i_l_p + 2, nul_char); return 0; } diff --git a/gas/config/tc-m32c.h b/gas/config/tc-m32c.h index 66fffc5..3a077b6 100644 --- a/gas/config/tc-m32c.h +++ b/gas/config/tc-m32c.h @@ -78,10 +78,10 @@ extern long md_pcrel_from_section (struct fix *, segT); /* We need a special version of the TC_START_LABEL macro so that we allow the :Z, :S, :Q and :G suffixes to be - parsed as such. We need to be able to change the contents of - the local variable 'c' which is passed to this macro as 'character'. */ -#define TC_START_LABEL(character, s, i_l_p) \ - ((character) != ':' ? 0 : (character = m32c_is_colon_insn (s)) ? 0 : ((character = ':'), 1)) -extern char m32c_is_colon_insn (char *); + parsed as such. We need to be able to change the contents of the + var storing what was at the NUL delimiter. */ +#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) \ + (NEXT_CHAR == ':' && !m32c_is_colon_insn (STR, &NUL_CHAR)) +extern int m32c_is_colon_insn (char *, char *); #define H_TICK_HEX 1 diff --git a/gas/config/tc-m32r.h b/gas/config/tc-m32r.h index 6f350e1..60bc57d 100644 --- a/gas/config/tc-m32r.h +++ b/gas/config/tc-m32r.h @@ -100,7 +100,8 @@ extern int m32r_force_relocation (struct fix *); /* Ensure insns at labels are aligned to 32 bit boundaries. */ int m32r_fill_insn (int); -#define TC_START_LABEL(ch, s, ptr) (ch == ':' && m32r_fill_insn (0)) +#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) \ + (NEXT_CHAR == ':' && m32r_fill_insn (0)) #define md_cleanup() m32r_fill_insn (1) #define md_elf_section_change_hook m32r_elf_section_change_hook diff --git a/gas/config/tc-mep.h b/gas/config/tc-mep.h index 8d70ad1..7f2d2b7 100644 --- a/gas/config/tc-mep.h +++ b/gas/config/tc-mep.h @@ -97,7 +97,8 @@ extern void mep_prepare_relax_scan (fragS *, offsetT *, relax_substateT); #define VTEXT_SECTION_NAME ".vtext" /* Needed to process pending instructions when a label is encountered. */ -#define TC_START_LABEL(ch, s, ptr) ((ch == ':') && mep_flush_pending_output ()) +#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) \ + (NEXT_CHAR == ':' && mep_flush_pending_output ()) #define tc_unrecognized_line(c) mep_unrecognized_line (c) extern int mep_unrecognized_line (int); diff --git a/gas/config/tc-nds32.h b/gas/config/tc-nds32.h index fb4e03b..b6c32e4 100644 --- a/gas/config/tc-nds32.h +++ b/gas/config/tc-nds32.h @@ -131,7 +131,8 @@ extern void nds32_do_align (int); #define md_macro_start() nds32_macro_start () #define md_macro_end() nds32_macro_end () #define md_macro_info(args) nds32_macro_info (args) -#define TC_START_LABEL(C, S, STR) (C == ':' && nds32_start_label (0, 0)) +#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) \ + (NEXT_CHAR == ':' && nds32_start_label (0, 0)) #define tc_check_label(label) nds32_check_label (label) #define tc_frob_label(label) nds32_frob_label (label) #define md_end md_end diff --git a/gas/config/tc-nios2.c b/gas/config/tc-nios2.c index 8dd7604..5bb00ec 100644 --- a/gas/config/tc-nios2.c +++ b/gas/config/tc-nios2.c @@ -566,6 +566,7 @@ s_nios2_sdata (int ignore ATTRIBUTE_UNUSED) static void s_nios2_set (int equiv) { + char *save = input_line_pointer; char *directive; char delim = get_symbol_name (&directive); char *endline = input_line_pointer; @@ -610,8 +611,7 @@ s_nios2_set (int equiv) /* If we fall through to here, either we have ".set XXX, YYY" or we have ".set XXX" where XXX is unknown or we have a syntax error. */ - input_line_pointer = directive; - *endline = delim; + input_line_pointer = save; s_set (equiv); } diff --git a/gas/config/tc-tic54x.c b/gas/config/tc-tic54x.c index 2637d10..d8df85d 100644 --- a/gas/config/tc-tic54x.c +++ b/gas/config/tc-tic54x.c @@ -5357,22 +5357,21 @@ tic54x_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax, I guess, except I've never seen a definition of MRI syntax). - C is the character that used to be at *REST, which points to the end of the - label. - Don't allow labels to start with '.' */ int -tic54x_start_label (int c, char *rest) +tic54x_start_label (int nul_char, int next_char) { + char *rest; + /* If within .struct/.union, no auto line labels, please. */ if (current_stag != NULL) return 0; /* Disallow labels starting with "." */ - if (c != ':') + if (next_char != ':') { - char *label = rest; + char *label = input_line_pointer; while (!is_end_of_line[(int) label[-1]]) --label; @@ -5383,22 +5382,22 @@ tic54x_start_label (int c, char *rest) } } - if (is_end_of_line[(int) c]) + if (is_end_of_line[(int) next_char]) return 1; - if (ISSPACE (c)) - while (ISSPACE (c = *++rest)) - ; - if (c == '.') - { - /* Don't let colon () define a label for any of these... */ - return (strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4])) - && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7])) - && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6])) - && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6])) - && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4])) - && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4])); - } + rest = input_line_pointer; + if (nul_char == '"') + ++rest; + while (ISSPACE (next_char)) + next_char = *++rest; + if (next_char != '.') + return 1; - return 1; + /* Don't let colon () define a label for any of these... */ + return ((strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4])) + && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7])) + && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6])) + && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6])) + && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4])) + && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4]))); } diff --git a/gas/config/tc-tic54x.h b/gas/config/tc-tic54x.h index 0dacf21..9dd6f44 100644 --- a/gas/config/tc-tic54x.h +++ b/gas/config/tc-tic54x.h @@ -65,8 +65,9 @@ struct bit_info #define TC_FRAG_INIT(FRAGP) do {(FRAGP)->tc_frag_data = 0;}while (0) /* tell GAS whether the given token is indeed a code label */ -#define TC_START_LABEL_WITHOUT_COLON(c,ptr) tic54x_start_label(c,ptr) -extern int tic54x_start_label (int, char *); +#define TC_START_LABEL_WITHOUT_COLON(NUL_CHAR, NEXT_CHAR) \ + tic54x_start_label(NUL_CHAR, NEXT_CHAR) +extern int tic54x_start_label (int, int); /* custom handling for relocations in cons expressions */ #define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \ -- cgit v1.1