From: Tom Tromey Date: Sat, 23 Jan 2021 19:20:11 +0000 (-0700) Subject: Avoid crash when "compile" expression uses cooked register X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b10bae18753862874628f902796eb1cd3925f95d;p=binutils-gdb.git Avoid crash when "compile" expression uses cooked register If the "compile" command is used with an expression that happens to require a cooked register, then GDB can crash. This patch does not fix the bug, but at least turns the crash into an error instead. 2021-01-23 Tom Tromey PR compile/25575 * compile/compile-loc2c.c (note_register): New function. (pushf_register_address, pushf_register): Use it. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8fa20fae30f..9f9681fef84 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2021-01-23 Tom Tromey + + PR compile/25575 + * compile/compile-loc2c.c (note_register): New function. + (pushf_register_address, pushf_register): Use it. + 2021-01-23 Tom Tromey * symtab.h (struct symbol_computed_ops) : diff --git a/gdb/compile/compile-loc2c.c b/gdb/compile/compile-loc2c.c index ee9595c78ed..ef819799eb4 100644 --- a/gdb/compile/compile-loc2c.c +++ b/gdb/compile/compile-loc2c.c @@ -505,6 +505,20 @@ print_label (string_file *stream, unsigned int scope, int target) stream->printf ("__label_%u_%s", scope, pulongest (target)); } +/* Note that a register was used. */ + +static void +note_register (int regnum, std::vector ®isters_used) +{ + gdb_assert (regnum >= 0); + /* If the expression uses a cooked register, then we currently can't + compile it. We would need a gdbarch method to handle this + situation. */ + if (regnum >= registers_used.size ()) + error (_("Expression uses \"cooked\" register and cannot be compiled.")); + registers_used[regnum] = true; +} + /* Emit code that pushes a register's address on the stack. REGISTERS_USED is an out parameter which is updated to note which register was needed by this expression. */ @@ -516,7 +530,7 @@ pushf_register_address (int indent, string_file *stream, { std::string regname = compile_register_name_mangled (gdbarch, regnum); - registers_used[regnum] = true; + note_register (regnum, registers_used); pushf (indent, stream, "(" GCC_UINTPTR ") &" COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s", regname.c_str ()); @@ -534,7 +548,7 @@ pushf_register (int indent, string_file *stream, { std::string regname = compile_register_name_mangled (gdbarch, regnum); - registers_used[regnum] = true; + note_register (regnum, registers_used); if (offset == 0) pushf (indent, stream, COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s", regname.c_str ());