diff --git a/gdb/jit.c b/gdb/jit.c
index 9fd5ae6..2b6cf77 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -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
diff --git a/gdb/regcache.c b/gdb/regcache.c
index f0ba0cf..a5c90a6 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -890,6 +890,17 @@ regcache_cooked_write_unsigned (struct regcache *regcache, int regnum,
   regcache_cooked_write (regcache, regnum, buf);
 }
 
+/* See regcache.h.  */
+
+void
+regcache_raw_set_cached_value (struct regcache *regcache, int regnum,
+			       const gdb_byte *buf)
+{
+  memcpy (register_buffer (regcache, regnum), buf,
+	  regcache->descr->sizeof_register[regnum]);
+  regcache->register_status[regnum] = REG_VALID;
+}
+
 void
 regcache_raw_write (struct regcache *regcache, int regnum,
 		    const gdb_byte *buf)
@@ -917,9 +928,7 @@ regcache_raw_write (struct regcache *regcache, int regnum,
   inferior_ptid = regcache->ptid;
 
   target_prepare_to_store (regcache);
-  memcpy (register_buffer (regcache, regnum), buf,
-	  regcache->descr->sizeof_register[regnum]);
-  regcache->register_status[regnum] = REG_VALID;
+  regcache_raw_set_cached_value (regcache, regnum, buf);
 
   /* Register a cleanup function for invalidating the register after it is
      written, in case of a failure.  */
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 1a4ff42..1bb0ce0 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -66,6 +66,14 @@ extern void regcache_raw_write_signed (struct regcache *regcache,
 extern void regcache_raw_write_unsigned (struct regcache *regcache,
 					 int regnum, ULONGEST val);
 
+/* Set a raw register's value in the regcache's buffer.  Unlike
+   regcache_raw_write, this is not write-through.  The intention is
+   allowing to change the buffer contents of a read-only regcache
+   allocated with regcache_xmalloc.  */
+
+extern void regcache_raw_set_cached_value
+  (struct regcache *regcache, int regnum, const gdb_byte *buf);
+
 /* Partial transfer of raw registers.  These perform read, modify,
    write style operations.  The read variant returns the status of the
    register.  */
diff --git a/gdb/testsuite/gdb.base/jit-reader.exp b/gdb/testsuite/gdb.base/jit-reader.exp
index b5e297a..642c257 100644
--- a/gdb/testsuite/gdb.base/jit-reader.exp
+++ b/gdb/testsuite/gdb.base/jit-reader.exp
@@ -57,10 +57,50 @@ if { [gdb_compile_shlib "${srcdir}/${subdir}/${jit_reader_src}" "${jit_reader_bi
     return -1
 }
 
+# Test "info registers" in the current frame, expecting RSP's value to
+# be SP.
+
+proc info_registers_current_frame {sp} {
+    global hex decimal
+
+    set any "\[^\r\n\]*"
+
+    gdb_test "info registers" \
+	[multi_line \
+	     "rax            $hex	$decimal" \
+	     "rbx            $hex	$decimal" \
+	     "rcx            $hex	$decimal" \
+	     "rdx            $hex	$decimal" \
+	     "rsi            $hex	$decimal" \
+	     "rdi            $hex	$decimal" \
+	     "rbp            $hex	$hex" \
+	     "rsp            $sp	$sp" \
+	     "r8             $hex	$decimal" \
+	     "r9             $hex	$decimal" \
+	     "r10            $hex	$decimal" \
+	     "r11            $hex	$decimal" \
+	     "r12            $hex	$decimal" \
+	     "r13            $hex	$decimal" \
+	     "r14            $hex	$decimal" \
+	     "r15            $hex	$decimal" \
+	     "rip            $hex	$hex$any" \
+	     "eflags         $hex	\\\[$any\\\]" \
+	     "cs             $hex	$decimal" \
+	     "ss             $hex	$decimal" \
+	     "ds             $hex	$decimal" \
+	     "es             $hex	$decimal" \
+	     "fs             $hex	$decimal" \
+	     "gs             $hex	$decimal" \
+	    ]
+}
+
 proc jit_reader_test {} {
     global jit_host_bin
     global jit_reader_bin
     global verbose
+    global hex decimal
+
+    set any "\[^\r\n\]*"
 
     clean_restart $jit_host_bin
     gdb_load_shlib $jit_reader_bin
@@ -73,7 +113,139 @@ proc jit_reader_test {} {
     gdb_run_cmd
     gdb_test "" "Program received signal SIGTRAP, .*" "expect SIGTRAP"
 
-    gdb_test "bt" "jit_function_00.*"
+    # Test the JIT reader unwinder.
+    with_test_prefix "with jit-reader" {
+
+	with_test_prefix "before mangling" {
+	    gdb_test "bt" \
+		[multi_line \
+		     "#0 ${any} in jit_function_00 ${any}" \
+		     "#1 ${any} in main ${any}" \
+		    ] \
+		"bt works"
+
+	    set sp_before_mangling \
+		[get_hexadecimal_valueof "\$sp" 0 "get sp"]
+
+	    gdb_test "up" "#1  $any in main $any\r\n$any  function $any" \
+		"move up to caller"
+
+	    set caller_sp \
+		[get_hexadecimal_valueof "\$sp" 0 "get caller sp"]
+	}
+
+	# Step over the instruction that mangles the stack pointer.
+	# While that confuses GDB's built-in unwinder, the JIT
+	# reader's unwinder understands the mangling and should thus
+	# be able to unwind at that location.
+	with_test_prefix "after mangling" {
+	    gdb_test "si" "in jit_function_00 .*" "step over stack mangling"
+
+	    set sp_after_mangling \
+		[get_hexadecimal_valueof "\$sp" 0 "get sp"]
+
+	    gdb_assert {$sp_before_mangling != $sp_after_mangling} \
+		"sp is mangled"
+
+	    # Check that the jit unwinder manages to backtrace through
+	    # the mangled stack pointer.
+	    gdb_test "bt" \
+		[multi_line \
+		     "#0 ${any} in jit_function_00 ${any}" \
+		     "#1 ${any} in main ${any}" \
+		    ] \
+		"bt works"
+
+	    with_test_prefix "current frame" {
+		info_registers_current_frame $sp_after_mangling
+
+		gdb_test "info frame" \
+		    "Stack level 0, frame at $sp_before_mangling.*in jit_function_00.*"
+	    }
+
+	    with_test_prefix "caller frame" {
+		gdb_test "up" "#1  $any in main $any\r\n$any  function $any" \
+		    "up to caller"
+
+		# Since the JIT unwinder only provides RIP/RSP/RBP,
+		# all other registers should show as "<not saved>".
+		gdb_test "info registers" \
+		    [multi_line \
+			 "rax            <not saved>" \
+			 "rbx            <not saved>" \
+			 "rcx            <not saved>" \
+			 "rdx            <not saved>" \
+			 "rsi            <not saved>" \
+			 "rdi            <not saved>" \
+			 "rbp            $hex	$hex" \
+			 "rsp            $caller_sp	$caller_sp" \
+			 "r8             <not saved>" \
+			 "r9             <not saved>" \
+			 "r10            <not saved>" \
+			 "r11            <not saved>" \
+			 "r12            <not saved>" \
+			 "r13            <not saved>" \
+			 "r14            <not saved>" \
+			 "r15            <not saved>" \
+			 "rip            $hex	$hex $any" \
+			 "eflags         <not saved>" \
+			 "cs             <not saved>" \
+			 "ss             <not saved>" \
+			 "ds             <not saved>" \
+			 "es             <not saved>" \
+			 "fs             <not saved>" \
+			 "gs             <not saved>" \
+			]
+
+		# Make sure that "info frame" doesn't crash.
+		gdb_test "info frame" "Stack level 1, .*in main.*"
+
+		# ... and that neither does printing a pseudo
+		# register.
+		gdb_test "print /x \$ebp" " = $hex" "print pseudo register"
+
+		# There's no way for the JIT reader API to support
+		# modifyiable values.
+		gdb_test "print \$rbp = -1" \
+		    "Attempt to assign to an unmodifiable value\." \
+		    "cannot assign to register"
+	    }
+	}
+    }
+
+    # Now unload the jit reader, and ensure that backtracing really
+    # doesn't work without it.
+    with_test_prefix "without jit-reader" {
+	gdb_test_no_output "jit-reader-unload ${jit_reader_bin}" \
+	    "jit-reader-unload"
+
+	# Check that we're no longer using the JIT unwinder, and that
+	# the built-in unwinder cannot backtrace through the mangled
+	# stack pointer.
+	gdb_test "bt" \
+	    [multi_line \
+		 "Backtrace stopped: Cannot access memory at address $sp_after_mangling" \
+		] \
+	    "bt shows error"
+
+	gdb_test "info frame" "Cannot access memory at address.*" \
+	    "info frame shows error"
+	info_registers_current_frame $sp_after_mangling
+	gdb_test "up" "Initial frame selected; you cannot go up\\." \
+	    "cannot go up"
+    }
+
+    with_test_prefix "with jit-reader again" {
+	gdb_test_no_output "jit-reader-load ${jit_reader_bin}" "jit-reader-load"
+
+	# Check that the jit unwinder manages to backtrace through
+	# the mangled stack pointer.
+	gdb_test "bt" \
+	    [multi_line \
+		 "#0 ${any} in jit_function_00 ${any}" \
+		 "#1 ${any} in main ${any}" \
+		]
+    }
 }
 
 jit_reader_test
diff --git a/gdb/testsuite/gdb.base/jithost.c b/gdb/testsuite/gdb.base/jithost.c
index 09ab377..afefc98 100644
--- a/gdb/testsuite/gdb.base/jithost.c
+++ b/gdb/testsuite/gdb.base/jithost.c
@@ -33,18 +33,32 @@ struct jit_code_entry only_entry;
 
 typedef void (jit_function_t) ();
 
-int main (int argc, char **argv)
+/* The code of the jit_function_00 function that is copied into an
+   mmapped buffer in the inferior at run time.
+
+   The second instruction mangles the stack pointer, meaning that when
+   stopped at the third instruction, GDB needs assistance from the JIT
+   unwinder in order to be able to unwind successfully.  */
+const unsigned char jit_function_00_code[] = {
+  0xcc,				/* int3 */
+  0x48, 0x83, 0xf4, 0xff,	/* xor $0xffffffffffffffff, %rsp */
+  0x48, 0x83, 0xf4, 0xff,	/* xor $0xffffffffffffffff, %rsp */
+  0xc3				/* ret */
+};
+
+int
+main (int argc, char **argv)
 {
+  struct jithost_abi *symfile;
   char *code = mmap (NULL, getpagesize (), PROT_WRITE | PROT_EXEC,
 		     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   jit_function_t *function = (jit_function_t *) code;
 
-  code[0] = 0xcc; /* SIGTRAP  */
-  code[1] = 0xc3; /* RET  */
+  memcpy (code, jit_function_00_code, sizeof (jit_function_00_code));
 
-  struct jithost_abi *symfile = malloc (sizeof (struct jithost_abi));
+  symfile = malloc (sizeof (struct jithost_abi));
   symfile->begin = code;
-  symfile->end = code + 2;
+  symfile->end = code + sizeof (jit_function_00_code);
 
   only_entry.symfile_addr = symfile;
   only_entry.symfile_size = sizeof (struct jithost_abi);
diff --git a/gdb/testsuite/gdb.base/jitreader.c b/gdb/testsuite/gdb.base/jitreader.c
index 850fb46..c18e40d 100644
--- a/gdb/testsuite/gdb.base/jitreader.c
+++ b/gdb/testsuite/gdb.base/jitreader.c
@@ -28,6 +28,7 @@ GDB_DECLARE_GPL_COMPATIBLE_READER;
 enum register_mapping
 {
   AMD64_RA = 16,
+  AMD64_RBP = 6,
   AMD64_RSP = 7,
 };
 
@@ -47,6 +48,11 @@ read_debug_info (struct gdb_reader_funcs *self,
   struct gdb_symtab *symtab = cbs->symtab_open (cbs, object, "");
   GDB_CORE_ADDR begin = (GDB_CORE_ADDR) symfile->begin;
   GDB_CORE_ADDR end = (GDB_CORE_ADDR) symfile->end;
+  struct reader_state *state = (struct reader_state *) self->priv_data;
+
+  /* Record the function's range, for the unwinder.  */
+  state->code_begin = begin;
+  state->code_end = end;
 
   cbs->block_open (cbs, symtab, NULL, begin, end, "jit_function_00");
 
@@ -91,11 +97,36 @@ read_register (struct gdb_unwind_callbacks *callbacks, int dw_reg,
   return 1;
 }
 
+/* Read the stack pointer into *VALUE.  IP is the address the inferior
+   is currently stopped at.  Takes care of demangling the stack
+   pointer if necessary.  */
+
+static int
+read_sp (struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cbs,
+	 uintptr_t ip, uintptr_t *value)
+{
+  struct reader_state *state = (struct reader_state *) self->priv_data;
+  uintptr_t sp;
+
+  if (!read_register (cbs, AMD64_RSP, &sp))
+    return GDB_FAIL;
+
+  /* If stopped at the instruction after the "xor $-1, %rsp", demangle
+     the stack pointer back.  */
+  if (ip == state->code_begin + 5)
+    sp ^= (uintptr_t) -1;
+
+  *value = sp;
+  return GDB_SUCCESS;
+}
+
 static enum gdb_status
 unwind_frame (struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cbs)
 {
   const int word_size = sizeof (uintptr_t);
-  uintptr_t this_sp, this_ip, prev_ip, prev_sp;
+  uintptr_t prev_sp, this_sp;
+  uintptr_t prev_ip, this_ip;
+  uintptr_t prev_bp, this_bp;
   struct reader_state *state = (struct reader_state *) self->priv_data;
 
   if (!read_register (cbs, AMD64_RA, &this_ip))
@@ -104,15 +135,25 @@ unwind_frame (struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cbs)
   if (this_ip >= state->code_end || this_ip < state->code_begin)
     return GDB_FAIL;
 
-  if (!read_register (cbs, AMD64_RSP, &this_sp))
+  /* Unwind RBP in order to make the unwinder that tries to unwind
+     from the just-unwound frame happy.  */
+  if (!read_register (cbs, AMD64_RBP, &this_bp))
     return GDB_FAIL;
+  /* RBP is unmodified.  */
+  prev_bp = this_bp;
 
-  if (cbs->target_read (this_sp, &prev_ip, word_size) == GDB_FAIL)
+  /* Fetch the demangled stack pointer.  */
+  if (!read_sp (self, cbs, this_ip, &this_sp))
     return GDB_FAIL;
 
+  /* The return address is saved on the stack.  */
+  if (cbs->target_read (this_sp, &prev_ip, word_size) == GDB_FAIL)
+    return GDB_FAIL;
   prev_sp = this_sp + word_size;
+
   write_register (cbs, AMD64_RA, prev_ip);
   write_register (cbs, AMD64_RSP, prev_sp);
+  write_register (cbs, AMD64_RBP, prev_bp);
   return GDB_SUCCESS;
 }
 
@@ -121,9 +162,11 @@ get_frame_id (struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cbs)
 {
   struct reader_state *state = (struct reader_state *) self->priv_data;
   struct gdb_frame_id frame_id;
-
+  uintptr_t ip;
   uintptr_t sp;
-  read_register (cbs, AMD64_RSP, &sp);
+
+  read_register (cbs, AMD64_RA, &ip);
+  read_sp (self, cbs, ip, &sp);
 
   frame_id.code_address = (GDB_CORE_ADDR) state->code_begin;
   frame_id.stack_address = (GDB_CORE_ADDR) sp;
@@ -141,7 +184,7 @@ destroy_reader (struct gdb_reader_funcs *self)
 struct gdb_reader_funcs *
 gdb_init_reader (void)
 {
-  struct reader_state *state = malloc (sizeof (struct reader_state));
+  struct reader_state *state = calloc (1, sizeof (struct reader_state));
   struct gdb_reader_funcs *reader_funcs =
     malloc (sizeof (struct gdb_reader_funcs));
 
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index b52fdd9..b7b8fad 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -5435,19 +5435,24 @@ proc get_integer_valueof { exp default } {
     return ${val}
 }
 
-proc get_hexadecimal_valueof { exp default } {
+# Retrieve the value of EXP in the inferior, as an hexadecimal value
+# (using "print /x").  DEFAULT is used as fallback if print fails.
+# TEST is the test message to use.  If can be ommitted, in which case
+# a test message is built from EXP.
+
+proc get_hexadecimal_valueof { exp default {test ""} } {
     global gdb_prompt
-    send_gdb "print /x ${exp}\n"
-    set test "get hexadecimal valueof \"${exp}\""
-    gdb_expect {
+
+    if {$test == ""} {
+	set test "get hexadecimal valueof \"${exp}\""
+    }
+
+    set val ${default}
+    gdb_test_multiple "print /x ${exp}" $test {
 	-re "\\$\[0-9\]* = (0x\[0-9a-zA-Z\]+).*$gdb_prompt $" {
 	    set val $expect_out(1,string)
 	    pass "$test"
 	}
-	timeout {
-	    set val ${default}
-	    fail "$test (timeout)"
-	}
     }
     return ${val}
 }
