diff --git a/gdb/testsuite/gdb.arch/amd64-jit-reader.c
b/gdb/testsuite/gdb.arch/amd64-jit-reader.c
new file mode 100644
index 0000000..2887abd
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-jit-reader.c
@@ -0,0 +1,117 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "jit-reader.h"
+
+GDB_DECLARE_GPL_COMPATIBLE_READER
+
+extern struct gdb_reader_funcs *gdb_init_reader (void);
+
+static enum gdb_status debug_info_provider (struct gdb_reader_funcs *self,
+                                            struct gdb_symbol_callbacks *cb,
+                                            void *memory, long memory_sz);
+static enum gdb_status frame_unwinder (struct gdb_reader_funcs *self,
+                                       struct gdb_unwind_callbacks *cb);
+static struct gdb_frame_id frame_id_provider(struct gdb_reader_funcs *self,
+                                             struct gdb_unwind_callbacks *cb);
+static void destructor (struct gdb_reader_funcs *self);
+
+#define DATA_COOKIE 0xdeaffead
+static int jit_data = DATA_COOKIE;
+
+static struct gdb_reader_funcs jit_reader_funcs =
+{
+  1,  /* version */
+  (void *)&jit_data,
+  debug_info_provider,
+  frame_unwinder,
+  frame_id_provider,
+  destructor
+};
+
+struct gdb_reader_funcs *
+gdb_init_reader (void)
+{
+  fprintf (stderr, "Test JIT reader loaded.\n");
+  return &jit_reader_funcs;
+}
+
+enum gdb_status
+debug_info_provider (struct gdb_reader_funcs *self,
+                     struct gdb_symbol_callbacks *cb,
+                     void *memory, long memory_sz)
+{
+  if (*(int *)(self->priv_data) != DATA_COOKIE)
+    return GDB_FAIL;
+  fprintf (stderr, "Debug info provider called for %p..%p.\n",
+           memory, (void *)(memory_sz + (char *)memory));
+  return GDB_SUCCESS;
+}
+
+void
+destructor (struct gdb_reader_funcs *self)
+{
+  fprintf (stderr, "Test JIT reader unloaded.\n");
+  return;
+}
+
+static GDB_CORE_ADDR
+_get_frame_register (struct gdb_unwind_callbacks *cb, int reg_no)
+{
+  struct gdb_reg_value *reg = cb->reg_get (cb, reg_no);
+  GDB_CORE_ADDR reg_value = *(GDB_CORE_ADDR *)reg->value;
+  reg->free (reg);
+  return reg_value;
+}
+
+static void
+_set_frame_register (struct gdb_unwind_callbacks *cb, int reg_no,
+                    GDB_CORE_ADDR value)
+{
+  struct gdb_reg_value *reg = cb->reg_get (cb, reg_no);
+  *(GDB_CORE_ADDR *)(reg->value) = value;
+  reg->defined = 1;
+  (cb->reg_set)(cb, reg_no, reg);
+}
+
+#define REG_BP 6
+#define REG_PC 16
+#define REG_SP 7
+enum gdb_status
+frame_unwinder (struct gdb_reader_funcs *self,
+                struct gdb_unwind_callbacks *cb)
+{
+  GDB_CORE_ADDR bp = _get_frame_register (cb, REG_BP);
+  GDB_CORE_ADDR pc = _get_frame_register (cb, REG_PC);
+  GDB_CORE_ADDR sp = _get_frame_register (cb, REG_SP);
+  GDB_CORE_ADDR word;
+  cb->target_read(bp, &word, 8);
+  if (word != bp)
+    return GDB_FAIL;
+
+  /* We are at the frame that xxx-jit-unwind program altered for us.
+     We have:
+      BP-8   +--------------+
+             | Previous BP  |
+      BP     +--------------+
+             | BP (wrong!)  |
+      BP+8   +--------------+
+             | Previous PC  |
+             +--------------+
+    Save outer frame's BP, PC and SP.  */
+  cb->target_read (bp - 8, &word, 8);
+  _set_frame_register (cb, REG_BP, word);
+  cb->target_read (bp + 8, &word, 8);
+  _set_frame_register (cb, REG_PC, word);
+  _set_frame_register (cb, REG_SP, bp + 16);
+  return GDB_SUCCESS;
+}
+
+struct gdb_frame_id frame_id_provider (struct gdb_reader_funcs *self,
+                                       struct gdb_unwind_callbacks *cb)
+{
+  struct gdb_frame_id frame_id =
+      { _get_frame_register (cb, REG_PC),
+        _get_frame_register (cb, REG_SP) };
+  fprintf (stderr, "frame_id_provider called.\n");
+  return frame_id;
+}
diff --git a/gdb/testsuite/gdb.arch/amd64-jit-reader.exp
b/gdb/testsuite/gdb.arch/amd64-jit-reader.exp
new file mode 100644
index 0000000..513e8b0
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-jit-reader.exp
@@ -0,0 +1,60 @@
+if {[skip_shlib_tests]} {
+    untested "Shared libraries are not supported"
+    return -1
+}
+
+if {[get_compiler_info]} {
+    return -1
+}
+
+if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
+    verbose "Skipping amd64 JIT reader tests."
+    return
+}
+
+set testfile "amd64-jit-unwind"
+set srcfile ${testfile}.c
+set binfile [standard_output_file ${testfile}]
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}"
executable [list debug]] != "" } {
+    untested "could not compile test program"
+    return -1
+}
+
+set jit_reader "amd64-jit-reader"
+set jit_reader_source "${srcdir}/${subdir}/${jit_reader}.c"
+set jit_reader_binfile [standard_output_file ${jit_reader}.so]
+
+if { [gdb_compile_shlib ${jit_reader_source} ${jit_reader_binfile}
{additional_flags="-I.."}] != "" } {
+    untested "Cannot compile amd-jit-reader"
+    return  -1
+}
+
+# Check that GDB is unable to show the backtrace for jit-unwind without
+# JIT reader.
+clean_restart $testfile
+if { ![runto_main] } {
+    fail "Can't run to main"
+    return
+}
+gdb_breakpoint [gdb_get_line_number "break backtrace-broken" ]
+gdb_continue_to_breakpoint "break backtrace-broken"
+gdb_test "where" "Backtrace stopped: frame did not save the .*"
+gdb_test "continue" "Continuing\..*$inferior_exited_re.*"
+
+# Check that GDB shows backtrace with JIT reader present
+# and that JIT reader can be unloaded.
+clean_restart $testfile
+if { ![runto_main] } {
+    fail "Can't run to main"
+    return
+}
+gdb_test "jit-reader-load ${jit_reader_binfile}" "Test JIT reader loaded."
+gdb_breakpoint [gdb_get_line_number "break backtrace-broken" ]
+gdb_continue_to_breakpoint "break backtrace-broken"
+gdb_test_sequence "where"  "Bad backtrace" {
+    "\[\r\n\]+#0 .* break_unwind_chain \\(\\) at "
+    "\[\r\n\]+#1 .* break_unwind_chain_1 \\(\\) at "
+    "\[\r\n\]+#2 .* main \\(.*\\) at"
+}
+gdb_test "continue"  "Continuing\..*$inferior_exited_re.*"
+gdb_test "jit-reader-unload" "Test JIT reader unloaded."
diff --git a/gdb/testsuite/gdb.arch/amd64-jit-unwind.c
b/gdb/testsuite/gdb.arch/amd64-jit-unwind.c
new file mode 100644
index 0000000..c2ae3de
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-jit-unwind.c
@@ -0,0 +1,43 @@
+/* This test program is part of GDB, the GNU debugger.
+
+   Copyright 2011-2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* This program is used to verify that a JIT handler can unwind custom
+   stack frames.  */
+
+#include <stdint.h>
+#include <stdio.h>
+static void break_unwind_chain()
+{
+  /* Save outer frame address, then corrupt the frame chain by setting
+     the outer frame address in it to self.  */
+  void *outer_fp = *(void **)__builtin_frame_address(0);
+  *(void  **)__builtin_frame_address(0) = __builtin_frame_address(0);
+  /* Now restore it so that we can return.  The test sets the
+     breakpoint just before this happens, and GDB will not be able to
+     show the backtrace without JIT reader.  */
+  *(void **)__builtin_frame_address(0) = outer_fp; /* break backtrace-broken */
+}
+
+static void break_unwind_chain_1()
+{
+  break_unwind_chain();
+}
+
+int main(int argc, char *argv[])
+{
+  break_unwind_chain_1();
+}
