diff options
Diffstat (limited to 'gdb/jit.c')
-rw-r--r-- | gdb/jit.c | 51 |
1 files changed, 32 insertions, 19 deletions
@@ -51,6 +51,7 @@ static const char *const jit_descriptor_name = "__jit_debug_descriptor"; static const struct program_space_data *jit_program_space_data = NULL; static void jit_inferior_init (struct gdbarch *gdbarch); +static void jit_inferior_exit_hook (struct inferior *inf); /* An unwinder is registered for every gdbarch. This key is used to remember if the unwinder has been registered for a particular @@ -218,6 +219,8 @@ jit_reader_load_command (char *args, int from_tty) prev_cleanup = make_cleanup (xfree, so_name); loaded_jit_reader = jit_reader_load (so_name); + reinit_frame_cache (); + jit_inferior_created_hook (); do_cleanups (prev_cleanup); } @@ -229,6 +232,8 @@ jit_reader_unload_command (char *args, int from_tty) if (!loaded_jit_reader) error (_("No JIT reader loaded.")); + reinit_frame_cache (); + jit_inferior_exit_hook (current_inferior ()); loaded_jit_reader->functions->destroy (loaded_jit_reader->functions); gdb_dlclose (loaded_jit_reader->handle); @@ -1090,7 +1095,7 @@ struct jit_unwind_private { /* Cached register values. See jit_frame_sniffer to see how this works. */ - struct gdb_reg_value **registers; + struct regcache *regcache; /* The frame being unwound. */ struct frame_info *this_frame; @@ -1115,11 +1120,12 @@ jit_unwind_reg_set_impl (struct gdb_unwind_callbacks *cb, int dwarf_regnum, fprintf_unfiltered (gdb_stdlog, _("Could not recognize DWARF regnum %d"), dwarf_regnum); + value->free (value); return; } - gdb_assert (priv->registers); - priv->registers[gdb_reg] = value; + regcache_raw_set_cached_value (priv->regcache, gdb_reg, value->value); + value->free (value); } static void @@ -1162,14 +1168,10 @@ jit_dealloc_cache (struct frame_info *this_frame, void *cache) struct gdbarch *frame_arch; int i; - gdb_assert (priv_data->registers); + gdb_assert (priv_data->regcache != NULL); frame_arch = get_frame_arch (priv_data->this_frame); - for (i = 0; i < gdbarch_num_regs (frame_arch); i++) - if (priv_data->registers[i] && priv_data->registers[i]->free) - priv_data->registers[i]->free (priv_data->registers[i]); - - xfree (priv_data->registers); + regcache_xfree (priv_data->regcache); xfree (priv_data); } @@ -1188,6 +1190,8 @@ jit_frame_sniffer (const struct frame_unwind *self, struct jit_unwind_private *priv_data; struct gdb_unwind_callbacks callbacks; struct gdb_reader_funcs *funcs; + struct address_space *aspace; + struct gdbarch *gdbarch; callbacks.reg_get = jit_unwind_reg_get_impl; callbacks.reg_set = jit_unwind_reg_set_impl; @@ -1200,11 +1204,12 @@ jit_frame_sniffer (const struct frame_unwind *self, gdb_assert (!*cache); + aspace = get_frame_address_space (this_frame); + gdbarch = get_frame_arch (this_frame); + *cache = XCNEW (struct jit_unwind_private); priv_data = (struct jit_unwind_private *) *cache; - priv_data->registers = - XCNEWVEC (struct gdb_reg_value *, - gdbarch_num_regs (get_frame_arch (this_frame))); + priv_data->regcache = regcache_xmalloc (gdbarch, aspace); priv_data->this_frame = this_frame; callbacks.priv_data = priv_data; @@ -1240,7 +1245,7 @@ jit_frame_this_id (struct frame_info *this_frame, void **cache, struct gdb_reader_funcs *funcs; struct gdb_unwind_callbacks callbacks; - priv.registers = NULL; + priv.regcache = NULL; priv.this_frame = this_frame; /* We don't expect the frame_id function to set any registers, so we @@ -1264,17 +1269,25 @@ static struct value * jit_frame_prev_register (struct frame_info *this_frame, void **cache, int reg) { struct jit_unwind_private *priv = (struct jit_unwind_private *) *cache; - struct gdb_reg_value *value; + struct gdbarch *gdbarch; if (priv == NULL) return frame_unwind_got_optimized (this_frame, reg); - gdb_assert (priv->registers); - value = priv->registers[reg]; - if (value && value->defined) - return frame_unwind_got_bytes (this_frame, reg, value->value); + gdbarch = get_regcache_arch (priv->regcache); + if (reg < gdbarch_num_regs (gdbarch)) + { + gdb_byte *buf = (gdb_byte *) alloca (register_size (gdbarch, reg)); + enum register_status status; + + status = regcache_raw_read (priv->regcache, reg, buf); + if (status == REG_VALID) + return frame_unwind_got_bytes (this_frame, reg, buf); + else + return frame_unwind_got_optimized (this_frame, reg); + } else - return frame_unwind_got_optimized (this_frame, reg); + return gdbarch_pseudo_register_read_value (gdbarch, priv->regcache, reg); } /* Relay everything back to the unwinder registered by the JIT debug |