This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PR22714, Assembler preprocessor loses track of \@
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Wed, 31 Jan 2018 17:00:44 +1030
- Subject: PR22714, Assembler preprocessor loses track of \@
- Authentication-results: sourceware.org; auth=none
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.
diff --git a/gas/app.c b/gas/app.c
index da39421..9cafff0 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;
}
--
Alan Modra
Australia Development Lab, IBM