This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
CGEN RFA/PATCH: gas/cgen.c, longjmp crash protection
- To: binutils at sourceware dot cygnus dot com, Nick Clifton <nickc at redhat dot com>
- Subject: CGEN RFA/PATCH: gas/cgen.c, longjmp crash protection
- From: "Frank Ch. Eigler" <fche at redhat dot com>
- Date: Fri, 23 Jun 2000 16:13:44 -0400
Hi -
The following patch intends to make it safe for a cgen-based gas
target to call gas_cgen_md_operand from its md_operand. This is
important for targets that rely on overloaded mnemonics, or
unusual inputs that cause unanticipated recursion during
parsing. In the absence of this patch, gas can crash when
longjmp()ing through an uninitialized jmp_buf. May I commit?
2000-06-23 Frank Ch. Eigler <fche@redhat.com>
* cgen.c (expr_jmp_buf_p): New validity flag for expr_jmp_buf.
(gas_cgen_parse_operand): Set it around expression() call.
(gas_cgen_md_operand): Test for it before longjmp().
Index: cgen.c
===================================================================
RCS file: /cvs/src/src/gas/cgen.c,v
retrieving revision 1.2
diff -p -u -r1.2 cgen.c
--- cgen.c 1999/06/03 12:51:21 1.2
+++ cgen.c 2000/06/23 20:09:54
@@ -232,6 +232,7 @@ gas_cgen_record_fixup_exp (frag, where,
/* Used for communication between the next two procedures. */
static jmp_buf expr_jmp_buf;
+static int expr_jmp_buf_p;
/* Callback for cgen interface. Parse the expression at *STRP.
The result is an error message or NULL for success (in which case
@@ -279,12 +280,15 @@ gas_cgen_parse_operand (cd, want, strP,
This is done via gas_cgen_md_operand. */
if (setjmp (expr_jmp_buf) != 0)
{
+ expr_jmp_buf_p = 0;
input_line_pointer = (char *) hold;
* resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR;
return "illegal operand";
}
+ expr_jmp_buf_p = 1;
expression (& exp);
+ expr_jmp_buf_p = 0;
* strP = input_line_pointer;
input_line_pointer = hold;
@@ -328,7 +332,9 @@ void
gas_cgen_md_operand (expressionP)
expressionS * expressionP;
{
- longjmp (expr_jmp_buf, 1);
+ /* Don't longjmp if we're not called from within cgen_parse_operand(). */
+ if (expr_jmp_buf_p)
+ longjmp (expr_jmp_buf, 1);
}
/* Finish assembling instruction INSN.