From ab1fadc6b2f057b817e1fc093650b63d9f6dd6c5 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 31 Jan 2018 13:34:18 +1030 Subject: [PATCH 1/1] PR22714, Assembler preprocessor loses track of \@ The PR22714 testcase is such that the input buffer processed by do_scrub_chars ends on this line 1: bug "Returning to usermode but unexpected PSR bits set?", \@ right at the backslash. (The line is part of a macro definition.) The next input buffer then starts with '@' which starts a comment on ARM, and the check for \@ fails due to to == tostart. Now it would be possible to simply access to[-1] in this particular case, but that's ugly, and to be absolutely safe from people deliberately trying to crash gas we'd need the read.c:read_a_source_file buffer passed to do_scrub_chars to have a single byte pad at the start. PR 22714 * app.c (last_char): New static var. (struct app_save): Add last_char field. (app_push, app_pop): Handle it. (do_scrub_chars): Use last_char in test for "\@". Set last_char. --- gas/ChangeLog | 8 ++++++++ gas/app.c | 22 +++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 4fc81fa387..fe30bad79a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2018-01-31 Alan Modra + + PR 22714 + * app.c (last_char): New static var. + (struct app_save): Add last_char field. + (app_push, app_pop): Handle it. + (do_scrub_chars): Use last_char in test for "\@". Set last_char. + 2018-01-29 Eric Botcazou PR gas/22738 diff --git a/gas/app.c b/gas/app.c index da39421380..9cafff055d 100644 --- a/gas/app.c +++ b/gas/app.c @@ -55,6 +55,9 @@ static const char mri_pseudo[] = ".mri 0"; static const char symver_pseudo[] = ".symver"; static const char * symver_state; #endif +#ifdef TC_ARM +static char last_char; +#endif static char lex[256]; static const char symbol_chars[] = @@ -242,6 +245,9 @@ struct app_save #if defined TC_ARM && defined OBJ_ELF const char * symver_state; #endif +#ifdef TC_ARM + char last_char; +#endif }; char * @@ -271,6 +277,9 @@ app_push (void) #if defined TC_ARM && defined OBJ_ELF saved->symver_state = symver_state; #endif +#ifdef TC_ARM + saved->last_char = last_char; +#endif /* do_scrub_begin() is not useful, just wastes time. */ @@ -310,6 +319,9 @@ app_pop (char *arg) #if defined TC_ARM && defined OBJ_ELF symver_state = saved->symver_state; #endif +#ifdef TC_ARM + last_char = saved->last_char; +#endif free (arg); } @@ -1285,7 +1297,7 @@ do_scrub_chars (size_t (*get) (char *, size_t), char *tostart, size_t tolen) #ifdef TC_ARM /* For the ARM, care is needed not to damage occurrences of \@ by stripping the @ onwards. Yuck. */ - if (to > tostart && *(to - 1) == '\\') + if ((to > tostart ? to[-1] : last_char) == '\\') /* Do not treat the @ as a start-of-comment. */ goto de_fault; #endif @@ -1465,6 +1477,10 @@ do_scrub_chars (size_t (*get) (char *, size_t), char *tostart, size_t tolen) fromeof: /* We have reached the end of the input. */ +#ifdef TC_ARM + if (to > tostart) + last_char = to[-1]; +#endif return to - tostart; tofull: @@ -1478,5 +1494,9 @@ do_scrub_chars (size_t (*get) (char *, size_t), char *tostart, size_t tolen) else saved_input = NULL; +#ifdef TC_ARM + if (to > tostart) + last_char = to[-1]; +#endif return to - tostart; } -- 2.34.1