aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2021-01-23 12:20:11 -0700
committerTom Tromey <tom@tromey.com>2021-01-23 20:33:25 -0700
commitb10bae18753862874628f902796eb1cd3925f95d (patch)
treeb2f9a8be71b6ca2276eef3ca352e280958e90bd3
parent3637a558a50141676f9997979491296dc007168d (diff)
downloadbinutils-b10bae18753862874628f902796eb1cd3925f95d.zip
binutils-b10bae18753862874628f902796eb1cd3925f95d.tar.gz
binutils-b10bae18753862874628f902796eb1cd3925f95d.tar.bz2
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 <tom@tromey.com> PR compile/25575 * compile/compile-loc2c.c (note_register): New function. (pushf_register_address, pushf_register): Use it.
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/compile/compile-loc2c.c18
2 files changed, 22 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 8fa20fa..9f9681f 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
2021-01-23 Tom Tromey <tom@tromey.com>
+ PR compile/25575
+ * compile/compile-loc2c.c (note_register): New function.
+ (pushf_register_address, pushf_register): Use it.
+
+2021-01-23 Tom Tromey <tom@tromey.com>
+
* symtab.h (struct symbol_computed_ops) <generate_c_location>:
Change type of "registers_used".
* dwarf2/loc.h (dwarf2_compile_property_to_c): Update.
diff --git a/gdb/compile/compile-loc2c.c b/gdb/compile/compile-loc2c.c
index ee9595c..ef81979 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<bool> &registers_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 ());