diff --git a/SOURCES/gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-1of3.patch b/SOURCES/gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-1of3.patch
new file mode 100644
index 0000000..a163ecd
--- /dev/null
+++ b/SOURCES/gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-1of3.patch
@@ -0,0 +1,218 @@
+commit 6e22494e5076e4d3c0b2c2785883162f83db499e
+Author: Jan Kratochvil <jan.kratochvil@redhat.com>
+Date:   Fri Jun 26 15:11:14 2015 +0200
+
+    Do not skip prologue for asm (.S) files
+    
+    GDB tries to skip prologue for .S files according to .debug_line but it then
+    places the breakpoint to a location where it is never hit.
+    
+    This is because #defines in .S files cause prologue skipping which is
+    completely inappropriate, for s390x:
+    
+    glibc/sysdeps/unix/syscall-template.S
+    78:/* This is a "normal" system call stub: if there is an error,
+    79:   it returns -1 and sets errno.  */
+    80:
+    81:T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
+    82:     ret
+    
+    00000000000f4210 T __select
+     Line Number Statements:
+      Extended opcode 2: set Address to 0xf41c8
+      Advance Line by 80 to 81
+      Copy
+      Advance PC by 102 to 0xf422e
+      Special opcode 6: advance Address by 0 to 0xf422e and Line by 1 to 82
+      Special opcode 34: advance Address by 2 to 0xf4230 and Line by 1 to 83
+      Advance PC by 38 to 0xf4256
+      Extended opcode 1: End of Sequence
+      Compilation Unit @ offset 0x28b3e0:
+     <0><28b3eb>: Abbrev Number: 1 (DW_TAG_compile_unit)
+        <28b3ec>   DW_AT_stmt_list   : 0x7b439
+        <28b3f0>   DW_AT_low_pc	 : 0xf41c8
+        <28b3f8>   DW_AT_high_pc     : 0xf4256
+        <28b400>   DW_AT_name        : ../sysdeps/unix/syscall-template.S
+        <28b423>   DW_AT_comp_dir    : /usr/src/debug////////glibc-2.17-c758a686/misc
+        <28b452>   DW_AT_producer    : GNU AS 2.23.52.0.1
+        <28b465>   DW_AT_language    : 32769        (MIPS assembler)
+    
+    without debuginfo or with debuginfo and the fix - correct address:
+    (gdb) b select
+    Breakpoint 1 at 0xf4210
+    
+    It is also where .dynsym+.symtab point to:
+    00000000000f4210 T __select
+    00000000000f4210 W select
+    
+    with debuginfo, without the fix:
+    (gdb) b select
+    Breakpoint 1 at 0xf41c8: file ../sysdeps/unix/syscall-template.S, line 81.
+    
+    One part is to behave for asm files similar way like for 'locations_valid':
+      /* Symtab has been compiled with both optimizations and debug info so that
+         GDB may stop skipping prologues as variables locations are valid already
+         at function entry points.  */
+      unsigned int locations_valid : 1;
+    
+    The other part is to extend the 'locations_valid'-like functionality more.
+    
+    Both minsym_found and find_function_start_sal need to be patched, otherwise
+    their addresses do not match and GDB regresses on ppc64:
+    
+    gdb/ChangeLog
+    2015-06-26  Jan Kratochvil  <jan.kratochvil@redhat.com>
+    
+    	* linespec.c (minsym_found): Reset sal.PC for COMPUNIT_LOCATIONS_VALID
+    	and language_asm..
+    	* symtab.c (find_function_start_sal): Likewise.
+    
+    gdb/testsuite/ChangeLog
+    2015-06-26  Jan Kratochvil  <jan.kratochvil@redhat.com>
+    
+    	* gdb.arch/amd64-prologue-skip.S: New file.
+    	* gdb.arch/amd64-prologue-skip.exp: New file.
+
+Index: gdb-7.6.1/gdb/linespec.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/linespec.c
++++ gdb-7.6.1/gdb/linespec.c
+@@ -3386,7 +3386,9 @@ collect_symbols (struct symbol *sym, voi
+ }
+ 
+ /* We've found a minimal symbol MSYMBOL in OBJFILE to associate with our
+-   linespec; return the SAL in RESULT.  */
++   linespec; return the SAL in RESULT.  This function should return SALs
++   matching those from find_function_start_sal, otherwise false
++   multiple-locations breakpoints could be placed.  */
+ 
+ static void
+ minsym_found (struct linespec_state *self, struct objfile *objfile,
+@@ -3408,7 +3410,23 @@ minsym_found (struct linespec_state *sel
+     sal = find_pc_sect_line (pc, NULL, 0);
+ 
+   if (self->funfirstline)
+-    skip_prologue_sal (&sal);
++    {
++      if (sal.symtab != NULL
++	  && (sal.symtab->locations_valid
++	      || sal.symtab->language == language_asm))
++	{
++	  /* If gdbarch_convert_from_func_ptr_addr does not apply then
++	     sal.SECTION, sal.LINE&co. will stay correct from above.
++	     If gdbarch_convert_from_func_ptr_addr applies then
++	     sal.SECTION is cleared from above and sal.LINE&co. will
++	     stay correct from the last find_pc_sect_line above.  */
++	  sal.pc = SYMBOL_VALUE_ADDRESS (msymbol);
++	  sal.pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc,
++						       &current_target);
++	}
++      else
++	skip_prologue_sal (&sal);
++    }
+ 
+   if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc))
+     add_sal_to_sals (self, result, &sal, SYMBOL_NATURAL_NAME (msymbol), 0);
+Index: gdb-7.6.1/gdb/symtab.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/symtab.c
++++ gdb-7.6.1/gdb/symtab.c
+@@ -2762,7 +2762,9 @@ skip_prologue_using_lineinfo (CORE_ADDR
+ /* Given a function symbol SYM, find the symtab and line for the start
+    of the function.
+    If the argument FUNFIRSTLINE is nonzero, we want the first line
+-   of real code inside the function.  */
++   of real code inside the function.
++   This function should return SALs matching those from minsym_found,
++   otherwise false multiple-locations breakpoints could be placed.  */
+ 
+ struct symtab_and_line
+ find_function_start_sal (struct symbol *sym, int funfirstline)
+@@ -2773,6 +2775,14 @@ find_function_start_sal (struct symbol *
+   sal = find_pc_sect_line (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
+ 			   SYMBOL_OBJ_SECTION (sym), 0);
+ 
++  if (funfirstline && sal.symtab != NULL
++      && (sal.symtab->locations_valid
++	  || sal.symtab->language == language_asm))
++    {
++      sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
++      return sal;
++    }
++
+   /* We always should have a line for the function start address.
+      If we don't, something is odd.  Create a plain SAL refering
+      just the PC and hope that skip_prologue_sal (if requested)
+Index: gdb-7.6.1/gdb/testsuite/gdb.arch/amd64-prologue-skip.S
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.arch/amd64-prologue-skip.S
+@@ -0,0 +1,28 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++   Copyright 2015 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/>.  */
++
++	.text
++/*0*/	hlt
++pushrbp: .globl pushrbp
++#define PUSHRBP push %rbp; mov %rsp, %rbp; nop
++/*1*/	PUSHRBP
++/*6*/	hlt
++
++/*7*/	hlt
++#define MINSYM nop; .globl minsym; minsym: nop
++/*8*/	MINSYM
++/*a*/	hlt
+Index: gdb-7.6.1/gdb/testsuite/gdb.arch/amd64-prologue-skip.exp
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.arch/amd64-prologue-skip.exp
+@@ -0,0 +1,35 @@
++# Copyright 2010-2015 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/>.
++
++standard_testfile .S
++set binfile ${binfile}.o
++
++if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
++    verbose "Skipping ${testfile}."
++    return
++}
++
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {debug}] != "" } {
++    untested ${testfile}
++    return
++}
++
++clean_restart ${binfile}
++
++gdb_test "break *pushrbp" " at 0x1: file .*"
++gdb_test "break pushrbp" " at 0x1: file .*"
++
++gdb_test "break *minsym" " at 0x9: file .*"
++gdb_test "break minsym" " at 0x9: file .*"
diff --git a/SOURCES/gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-2of3.patch b/SOURCES/gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-2of3.patch
new file mode 100644
index 0000000..d87cfa9
--- /dev/null
+++ b/SOURCES/gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-2of3.patch
@@ -0,0 +1,98 @@
+From gdb-patches-return-123876-listarch-gdb-patches=sources dot redhat dot com at sourceware dot org Mon Jun 29 16:37:14 2015
+Return-Path: <gdb-patches-return-123876-listarch-gdb-patches=sources dot redhat dot com at sourceware dot org>
+Delivered-To: listarch-gdb-patches at sources dot redhat dot com
+Received: (qmail 98411 invoked by alias); 29 Jun 2015 16:37:14 -0000
+Mailing-List: contact gdb-patches-help at sourceware dot org; run by ezmlm
+Precedence: bulk
+List-Id: <gdb-patches.sourceware.org>
+List-Subscribe: <mailto:gdb-patches-subscribe at sourceware dot org>
+List-Archive: <http://sourceware.org/ml/gdb-patches/>
+List-Post: <mailto:gdb-patches at sourceware dot org>
+List-Help: <mailto:gdb-patches-help at sourceware dot org>, <http://sourceware dot org/ml/#faqs>
+Sender: gdb-patches-owner at sourceware dot org
+Delivered-To: mailing list gdb-patches at sourceware dot org
+Received: (qmail 98402 invoked by uid 89); 29 Jun 2015 16:37:13 -0000
+Authentication-Results: sourceware.org; auth=none
+X-Virus-Found: No
+X-Spam-SWARE-Status: No, score=-3.5 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=no version=3.3.2
+X-HELO: mx1.redhat.com
+Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 29 Jun 2015 16:37:13 +0000
+Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24])	by mx1.redhat.com (Postfix) with ESMTPS id DF7D48EA29	for <gdb-patches@sourceware.org>; Mon, 29 Jun 2015 16:37:11 +0000 (UTC)
+Received: from host1.jankratochvil.net (ovpn-116-41.ams2.redhat.com [10.36.116.41])	by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t5TGb8I0022607	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO)	for <gdb-patches@sourceware.org>; Mon, 29 Jun 2015 12:37:11 -0400
+Date: Mon, 29 Jun 2015 18:37:08 +0200
+From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
+To: gdb-patches at sourceware dot org
+Subject: [testsuite patch] Fix testsuite regression by: Do not skip prologue for asm (.S) files
+Message-ID: <20150629163708.GA28795@host1.jankratochvil.net>
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="wac7ysb48OaltWcw"
+Content-Disposition: inline
+User-Agent: Mutt/1.5.23 (2014-03-12)
+X-IsSubscribed: yes
+
+
+--wac7ysb48OaltWcw
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+
+Hi,
+
+I have somehow missed gdb.asm/asm-source.exp PASS->FAIL even on x86_64.
+
+It has no longer valid assumption that "break" breaks after the prologue even
+in assembler.  So I have changed this assumption of the testfile.
+
+Tested it FAIL->PASSes on x86_64, ppc64 and s390x.
+
+OK for check-in?
+
+
+Jan
+
+--wac7ysb48OaltWcw
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline; filename=2
+
+gdb/testsuite/
+2015-06-29  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* gdb.asm/asm-source.exp (f at main): Stop at gdbasm_enter.
+	(n at main): New.
+	* gdb.asm/asmsrc1.s: Add comment "mark: main enter".
+
+Index: gdb-7.6.1/gdb/testsuite/gdb.asm/asm-source.exp
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/gdb.asm/asm-source.exp
++++ gdb-7.6.1/gdb/testsuite/gdb.asm/asm-source.exp
+@@ -272,6 +272,7 @@ if { [istarget "m6811-*-*"] || [istarget
+ }
+ 
+ # Collect some line numbers.
++set line_enter      [expr [gdb_get_line_number "main enter" "asmsrc1.s"] + 1]
+ set line_main       [expr [gdb_get_line_number "main start" "asmsrc1.s"] + 1]
+ set line_call_foo2  [expr [gdb_get_line_number "call foo2"  "asmsrc1.s"] + 1]
+ set line_search_comment [expr [gdb_get_line_number "search" "asmsrc1.s"] + 1]
+@@ -295,7 +296,10 @@ if ![runto_main] then {
+ }
+ 
+ # Execute the `f' command and see if the result includes source info.
+-gdb_test "f" "asmsrc1\[.\]s:$line_main.*several_nops" "f at main"
++gdb_test "f" "asmsrc1\[.\]s:$line_enter.*gdbasm_enter" "f at main"
++
++# Execute the `n' command.
++gdb_test "n" "$line_main\[ 	\]*.*several_nops" "n at main"
+ 
+ # See if we properly `next' over a macro with several insns.
+ gdb_test "n" "$line_call_foo2\[ 	\]*.*foo2" "next over macro"
+Index: gdb-7.6.1/gdb/testsuite/gdb.asm/asmsrc1.s
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/gdb.asm/asmsrc1.s
++++ gdb-7.6.1/gdb/testsuite/gdb.asm/asmsrc1.s
+@@ -34,6 +34,7 @@
+ 
+ 	.global main
+ 	gdbasm_declare main
++	comment "mark: main enter"
+ 	gdbasm_enter
+ 
+ 	comment "Call a macro that consists of several lines of assembler code."
diff --git a/SOURCES/gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch b/SOURCES/gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch
new file mode 100644
index 0000000..af7271a
--- /dev/null
+++ b/SOURCES/gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch
@@ -0,0 +1,226 @@
+These testcases have been created by compiling glibc-2.17-78 on
+RHEL-7.1 s390x/ppc64 boxes, and then taking the "select.o" file
+present at $builddir/misc/select.o.
+
+Index: gdb-7.6.1/gdb/testsuite/gdb.arch/s390x-prologue-skip.exp
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.arch/s390x-prologue-skip.exp
+@@ -0,0 +1,34 @@
++# Copyright 2015 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/>.
++
++if { ![istarget s390x-*linux-*] || ![is_lp64_target] } {
++    verbose "Skipping s390x-prologue-skip.exp"
++    return
++}
++
++set testfile "s390x-prologue-skip"
++set uufile "${srcdir}/${subdir}/${testfile}.o.uu"
++set ofile "${srcdir}/${subdir}/${testfile}.o"
++
++if { [catch "system \"uudecode -o ${ofile} ${uufile}\"" ] != 0 } {
++    untested "failed uudecode"
++    return -1
++}
++
++gdb_exit
++gdb_start
++gdb_load $ofile
++
++gdb_test "break select" "Breakpoint $decimal at 0x48: file ../sysdeps/unix/syscall-template.S, line 81." "breakpoint on select"
+Index: gdb-7.6.1/gdb/testsuite/gdb.arch/s390x-prologue-skip.o.uu
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.arch/s390x-prologue-skip.o.uu
+@@ -0,0 +1,64 @@
++begin 644 s390x-prologue-skip.o.uu
++M?T5,1@("`0`````````````!`!8````!````````````````````````````
++M``+```````!```````!``!(`#^LE\!``).O?\&@`)+D$`.^G^_]@X^#P```D
++MP.4`````N00``NLE\+``!`J.N00`TKD$`"#`Y0````"Y!``MZ]_Q"``$I_0`
++M"L`0`````+\/$`"G=/_7"HZG2?`!N2$`),"T``````?^````5@`"````.0$!
++M^PX-``$!`0$````!```!+BXO<WES9&5P<R]U;FEX``!S>7-C86QL+71E;7!L
++M871E+E,``0`````)`@```````````]```0)F$P("``$!````CP`"``````@!
++M```````````````````````````N+B]S>7-D97!S+W5N:7@O<WES8V%L;"UT
++M96UP;&%T92Y3`"]R;V]T+V=L:6)C+V=L:6)C+3(N,3<M-S@N96PW+G-R8R]G
++M;&EB8RTR+C$W+6,W-3AA-C@V+VUI<V,`1TY5($%3(#(N,C,N-3(N,"XQ`(`!
++M`1$`$`81`1(!`P@;""4($P4`````````````````+``"``````@`````````
++M`````````````````&@`````````````````````````%``````!>E(``7@.
++M`1L,#Z`!````````&````!P`````````1`!,CP6.!HT'2`[``@```!`````X
++M`````````"```````"YS>6UT86(`+G-T<G1A8@`N<VAS=')T86(`+G)E;&$N
++M=&5X=``N9&%T80`N8G-S`"YN;W1E+D=.52US=&%C:P`N<F5L82YD96)U9U]L
++M:6YE`"YR96QA+F1E8G5G7VEN9F\`+F1E8G5G7V%B8G)E=@`N<F5L82YD96)U
++M9U]A<F%N9V5S`"YR96QA+F5H7V9R86UE````````````````````````````
++M````````````````````````````````````````````````````````````
++M````````(`````$`````````!@```````````````````$``````````:```
++M``````````````````0``````````````!L````$````````````````````
++M``````````F``````````&`````0`````0`````````(`````````!@````F
++M`````0`````````#````````````````````J```````````````````````
++M````````!```````````````+`````@``````````P``````````````````
++M`*@```````````````````````````````0``````````````#$````!````
++M``````````````````````````"H```````````````````````````````!
++M``````````````!&`````0``````````````````````````````J```````
++M``!:`````````````````````0``````````````00````0`````````````
++M````````````````">``````````&````!`````&``````````@`````````
++M&````%<````!``````````````````````````````$"`````````),`````
++M```````````````!``````````````!2````!```````````````````````
++M```````)^`````````!@````$`````@`````````"``````````8````8P``
++M``$``````````````````````````````94`````````%```````````````
++M``````$``````````````'8````!``````````````````````````````&P
++M`````````#`````````````````````0``````````````!Q````!```````
++M```````````````````````*6``````````P````$`````L`````````"```
++M```````8````B@````$``````````@```````````````````>``````````
++M2`````````````````````@``````````````(4````$````````````````
++M``````````````J(`````````#`````0````#0`````````(`````````!@`
++M```1`````P`````````````````````````````"*`````````"4````````
++M`````````````0```````````````0````(`````````````````````````
++M````!T`````````!L````!$````*``````````@`````````&`````D````#
++M``````````````````````````````CP`````````(X`````````````````
++M```!`````````````````````````````````````````````````P```0``
++M`````````````````````````P```P```````````````````````````P``
++M!````````````````````````````P``"```````````````````````````
++M`P``"@```````````````````````````P``!@``````````````````````
++M`````P``"P```````````````````````````P``#0``````````````````
++M`````````P``!0`````````````````````````!$```````````````````
++M```````````;$``````````````````````````````V$@```0````````!(
++M`````````"`````_$`````````````````````````````!7$@```0``````
++M``!6`````````!````!I$`````````````````````````````!Y(@```0``
++M``````!(`````````"````"'(@```0````````!(`````````"``7U]L:6)C
++M7V5N86)L95]A<WEN8V-A;F-E;`!?7VQI8F-?9&ES86)L95]A<WEN8V-A;F-E
++M;`!?7W-E;&5C=`!?7VQI8F-?;75L=&EP;&5?=&AR96%D<P!?7W-E;&5C=%]N
++M;V-A;F-E;`!?7W-Y<V-A;&Q?97)R;W(`7U]L:6)C7W-E;&5C=`!S96QE8W0`
++M````````````'`````H````3``````````(`````````-@````L````3````
++M``````(`````````2@````T````3``````````(`````````8@````\````3
++M``````````(`````````1@````$````6````````````````````!@````4`
++M```$````````````````````#`````8````$````````````````````$```
++M``$````6````````````````````&`````$````6`````````&@`````````
++M!@````0````$````````````````````$`````$````6````````````````
++L````(`````$````%````````````````````/`````$````%`````````$@`
++`
++end
+Index: gdb-7.6.1/gdb/testsuite/gdb.arch/ppc64-prologue-skip.exp
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.arch/ppc64-prologue-skip.exp
+@@ -0,0 +1,34 @@
++# Copyright 2015 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/>.
++
++if { ![istarget powerpc64-*linux-*] || ![is_lp64_target] } {
++    verbose "Skipping ppc64-prologue-skip.exp"
++    return
++}
++
++set testfile "ppc64-prologue-skip"
++set uufile "${srcdir}/${subdir}/${testfile}.o.uu"
++set ofile "${srcdir}/${subdir}/${testfile}.o"
++
++if { [catch "system \"uudecode -o ${ofile} ${uufile}\"" ] != 0 } {
++    untested "failed uudecode"
++    return -1
++}
++
++gdb_exit
++gdb_start
++gdb_load $ofile
++
++gdb_test "break ___newselect_nocancel" "Breakpoint $decimal at 0xc: file ../sysdeps/unix/syscall-template.S, line 81." "breakpoint on ___newselect_nocancel"
+Index: gdb-7.6.1/gdb/testsuite/gdb.arch/ppc64-prologue-skip.o.uu
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.arch/ppc64-prologue-skip.o.uu
+@@ -0,0 +1,70 @@
++begin 644 ppc64-skip-prologue.o.uu
++M?T5,1@("`0`````````````!`!4````!````````````````````````````
++M``-(``````!```````!``!0`$8%-B-`L"@``0,(`-#@``(Y$```"3.,`('P(
++M`J;X`0`0^"'_D4@```%@````Z`$`@#@A`'!\"`.F3H``(/@A_X%]*`*F^2$`
++MD/CA`-#XP0#(^*$`P/B!`+CX80"P2````6````#X80!PZ.$`T.C!`,CHH0#`
++MZ($`N.AA`+`X``".1````GP``";X80!X^`$`B.AA`'!(```!8````.DA`)#H
++M`0"(Z&$`>'TH`Z9\#_$@."$`@$SC`"!+__]@```````,($``````````O``(
++M7U]S96QE8W0```````````````````````````!6``(````Y!`'[#@T``0$!
++M`0````$```$N+B]S>7-D97!S+W5N:7@``'-Y<V-A;&PM=&5M<&QA=&4N4P`!
++M``````D"```````````#T``!`BT3`@D``0$```"/``(`````"`$`````````
++M`````````````````"XN+W-Y<V1E<',O=6YI>"]S>7-C86QL+71E;7!L871E
++M+E,`+W)O;W0O9VQI8F,O9VQI8F,M,BXQ-RTW."YE;#<N<W)C+V=L:6)C+3(N
++M,3<M8S<U.&$V.#8O;6ES8P!'3E4@05,@,BXR,RXU,BXP+C$`@`$!$0`0!A$!
++M$@$#"!L()0@3!0`````````````````L``(`````"```````````````````
++M````````V``````````````````````````0``````%Z4@`$>$$!&PP!````
++M`#`````8`````````+P`20YP$4%^1`X`009!0@Z``4(107Y2$49_20X`!D$&
++M1@``````+G-Y;71A8@`N<W1R=&%B`"YS:'-T<G1A8@`N<F5L82YT97AT`"YD
++M871A`"YB<W,`+G)E;&$N;W!D`"YN;W1E+D=.52US=&%C:P`N<F5L82YD96)U
++M9U]L:6YE`"YR96QA+F1E8G5G7VEN9F\`+F1E8G5G7V%B8G)E=@`N<F5L82YD
++M96)U9U]A<F%N9V5S`"YR96QA+F5H7V9R86UE````````````````````````
++M````````````````````````````````````````````````````````````
++M`````````"`````!``````````8```````````````````!``````````-@`
++M```````````````````$```````````````;````!```````````````````
++M```````````*>`````````!(````$@````$`````````"``````````8````
++M)@````$``````````P```````````````````1@`````````````````````
++M``````````$``````````````"P````(``````````,`````````````````
++M``$8```````````````````````````````!```````````````V`````0``
++M```````#```````````````````!&``````````0````````````````````
++M"```````````````,0````0`````````````````````````````"L``````
++M````,````!(````%``````````@`````````&````#L````!````````````
++M``````````````````$H```````````````````````````````!````````
++M``````!0`````0`````````````````````````````!*`````````!:````
++M`````````````````0``````````````2P````0`````````````````````
++M````````"O``````````&````!(````(``````````@`````````&````&$`
++M```!``````````````````````````````&"`````````),`````````````
++M```````!``````````````!<````!``````````````````````````````+
++M"`````````!@````$@````H`````````"``````````8````;0````$`````
++M`````````````````````````A4`````````%`````````````````````$`
++M`````````````(`````!``````````````````````````````(P````````
++M`#`````````````````````0``````````````![````!```````````````
++M```````````````+:``````````P````$@````T`````````"``````````8
++M````E`````$``````````@```````````````````F``````````2```````
++M``````````````@``````````````(\````$````````````````````````
++M``````N8`````````!@````2````#P`````````(`````````!@````1````
++M`P`````````````````````````````"J`````````">````````````````
++M`````0```````````````0````(`````````````````````````````"$@`
++M```````!L````!,````+``````````@`````````&`````D````#````````
++M``````````````````````GX`````````'H````````````````````!````
++M`````````````````````````````````````````````P```0``````````
++M`````````````````P```P```````````````````````````P``!```````
++M`````````````````````P``!0```````````````````````````P``"@``
++M`````````````````````````P``#````````````````````````````P``
++M"````````````````````````````P``#0``````````````````````````
++M`P``#P```````````````````````````P``!P``````````````````````
++M```!$@``!0```````````````````-@````*$@```0`````````,````````
++M`#`````@$``````````````````````````````P$```````````````````
++M``````````!*$`````````````````````````````!E(@``!0``````````
++M`````````-@```!S(@``!0```````````````````-@`7U]S96QE8W0`7U]?
++M;F5W<V5L96-T7VYO8V%N8V5L`%]?<WES8V%L;%]E<G)O<@!?7VQI8F-?96YA
++M8FQE7V%S>6YC8V%N8V5L`%]?;&EB8U]D:7-A8FQE7V%S>6YC8V%N8V5L`%]?
++M;&EB8U]S96QE8W0`<V5L96-T```````````````````D````#0````H`````
++M``````````````!<````#@````H```````````````````"4````#P````H`
++M`````````````````````````0```"8````````````````````(````````
++M`#,```````````````````!&`````0```"8````````````````````&````
++M!@````$````````````````````,````!P````$````````````````````0
++M`````0```"8````````````````````8`````0```"8`````````V```````
++M```&````!0````$````````````````````0`````0```"8`````````````
++6```````<`````0```!H`````````````
++`
++end
diff --git a/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-1of9.patch b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-1of9.patch
new file mode 100644
index 0000000..5327189
--- /dev/null
+++ b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-1of9.patch
@@ -0,0 +1,865 @@
+From 2ccd146855365598ad2644ef8139f2f2a6747b90 Mon Sep 17 00:00:00 2001
+From: Ulrich Weigand <uweigand@de.ibm.com>
+Date: Fri, 13 Sep 2013 14:11:15 +0000
+Subject: [PATCH 2/3] 2013-09-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
+
+	* s390-tdep.h (S390_IS_GREGSET_REGNUM): New macro.
+	(S390_IS_FPREGSET_REGNUM): New macro.
+	* s390-tdep.c (s390_dwarf_regmap): Make const.
+	(regnum_is_gpr_full): New function for replacing repeated code.
+	(s390_pseudo_register_name): Use it.
+	(s390_pseudo_register_type): Likewise.
+	(s390_pseudo_register_read): Likewise.
+	(s390_pseudo_register_write): Likewise.
+	(s390_unwind_pseudo_register): Likewise.
+	(s390_regmap_gregset): New format for regmap.
+	(s390x_regmap_gregset): Likewise.
+	(s390_regmap_fpregset): Likewise.
+	(s390_regmap_upper): Likewise.
+	(s390_regmap_last_break): Likewise.
+	(s390_regmap_system_call): Likewise.
+	(s390_supply_regset): Adjust to new regmap format.
+	(s390_collect_regset): Likewise.
+	* s390-nat.c (s390_native_supply): Adjust to new regmap format.
+	(s390_native_collect): Likewise.
+	(supply_gregset): Likewise.
+	(fill_gregset): Likewise.
+	(supply_fpregset): Likewise.
+	(fill_fpregset): Likewise.
+	(fetch_regset): Likewise.
+	(store_regset): Likewise.
+	(s390_linux_fetch_inferior_registers): Likewise.
+	(s390_linux_fetch_inferior_registers): Likewise.
+---
+ gdb/ChangeLog   |  30 +++++
+ gdb/s390-nat.c  | 233 +++++++++++++++++------------------
+ gdb/s390-tdep.c | 369 +++++++++++++++++++++++++++-----------------------------
+ gdb/s390-tdep.h |  20 ++-
+ 4 files changed, 328 insertions(+), 324 deletions(-)
+
+Index: gdb-7.6.1/gdb/s390-nat.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/s390-nat.c
++++ gdb-7.6.1/gdb/s390-nat.c
+@@ -63,139 +63,139 @@ static int have_regset_system_call = 0;
+ 
+ #define regmap_fpregset s390_regmap_fpregset
+ 
+-/* When debugging a 32-bit executable running under a 64-bit kernel,
+-   we have to fix up the 64-bit registers we get from the kernel
+-   to make them look like 32-bit registers.  */
++/* Fill the regset described by MAP into REGCACHE, using the values
++   from REGP.  The MAP array represents each register as a pair
++   (offset, regno) of short integers and is terminated with -1. */
+ 
+ static void
+-s390_native_supply (struct regcache *regcache, int regno,
+-		    const gdb_byte *regp, int *regmap)
++s390_native_supply (struct regcache *regcache, const short *map,
++		    const gdb_byte *regp)
+ {
+-  int offset = regmap[regno];
++  for (; map[0] >= 0; map += 2)
++    regcache_raw_supply (regcache, map[1], regp + map[0]);
++}
++
++/* Collect the register REGNO out of the regset described by MAP from
++   REGCACHE into REGP.  If REGNO == -1, do this for all registers in
++   this regset. */
+ 
++static void
++s390_native_collect (const struct regcache *regcache, const short *map,
++		     int regno, gdb_byte *regp)
++{
++  for (; map[0] >= 0; map += 2)
++    if (regno == -1 || regno == map[1])
++      regcache_raw_collect (regcache, map[1], regp + map[0]);
++}
++
++/* Fill GDB's register array with the general-purpose register values
++   in *REGP.
++
++   When debugging a 32-bit executable running under a 64-bit kernel,
++   we have to fix up the 64-bit registers we get from the kernel to
++   make them look like 32-bit registers.  */
++
++void
++supply_gregset (struct regcache *regcache, const gregset_t *regp)
++{
+ #ifdef __s390x__
+   struct gdbarch *gdbarch = get_regcache_arch (regcache);
+-  if (offset != -1 && gdbarch_ptr_bit (gdbarch) == 32)
++  if (gdbarch_ptr_bit (gdbarch) == 32)
+     {
+       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
++      ULONGEST pswm = 0, pswa = 0;
++      gdb_byte buf[4];
++      const short *map;
+ 
+-      if (regno == S390_PSWM_REGNUM)
+-	{
+-	  ULONGEST pswm;
+-	  gdb_byte buf[4];
+-
+-	  pswm = extract_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
+-					   8, byte_order);
+-
+-	  store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000);
+-	  regcache_raw_supply (regcache, regno, buf);
+-	  return;
+-	}
+-
+-      if (regno == S390_PSWA_REGNUM)
++      for (map = regmap_gregset; map[0] >= 0; map += 2)
+ 	{
+-	  ULONGEST pswm, pswa;
+-	  gdb_byte buf[4];
++	  const gdb_byte *p = (const gdb_byte *) regp + map[0];
++	  int regno = map[1];
+ 
+-	  pswa = extract_unsigned_integer (regp + regmap[S390_PSWA_REGNUM],
+-					   8, byte_order);
+-	  pswm = extract_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
+-					   8, byte_order);
+-
+-	  store_unsigned_integer (buf, 4, byte_order,
+-				  (pswa & 0x7fffffff) | (pswm & 0x80000000));
+-	  regcache_raw_supply (regcache, regno, buf);
+-	  return;
++	  if (regno == S390_PSWM_REGNUM)
++	    pswm = extract_unsigned_integer (p, 8, byte_order);
++	  else if (regno == S390_PSWA_REGNUM)
++	    pswa = extract_unsigned_integer (p, 8, byte_order);
++	  else
++	    {
++	      if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
++		  || regno == S390_ORIG_R2_REGNUM)
++		p += 4;
++	      regcache_raw_supply (regcache, regno, p);
++	    }
+ 	}
+ 
+-      if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
+-	  || regno == S390_ORIG_R2_REGNUM)
+-	offset += 4;
++      store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000);
++      regcache_raw_supply (regcache, S390_PSWM_REGNUM, buf);
++      store_unsigned_integer (buf, 4, byte_order,
++			      (pswa & 0x7fffffff) | (pswm & 0x80000000));
++      regcache_raw_supply (regcache, S390_PSWA_REGNUM, buf);
++      return;
+     }
+ #endif
+ 
+-  if (offset != -1)
+-    regcache_raw_supply (regcache, regno, regp + offset);
++  s390_native_supply (regcache, regmap_gregset, (const gdb_byte *) regp);
+ }
+ 
+-static void
+-s390_native_collect (const struct regcache *regcache, int regno,
+-		     gdb_byte *regp, int *regmap)
+-{
+-  int offset = regmap[regno];
++/* Fill register REGNO (if it is a general-purpose register) in
++   *REGP with the value in GDB's register array.  If REGNO is -1,
++   do this for all registers.  */
+ 
++void
++fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
++{
+ #ifdef __s390x__
+   struct gdbarch *gdbarch = get_regcache_arch (regcache);
+-  if (offset != -1 && gdbarch_ptr_bit (gdbarch) == 32)
++  if (gdbarch_ptr_bit (gdbarch) == 32)
+     {
+-      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
++      gdb_byte *psw_p[2];
++      const short *map;
+ 
+-      if (regno == S390_PSWM_REGNUM)
++      for (map = regmap_gregset; map[0] >= 0; map += 2)
+ 	{
+-	  ULONGEST pswm;
+-	  gdb_byte buf[4];
++	  gdb_byte *p = (gdb_byte *) regp + map[0];
++	  int reg = map[1];
+ 
+-	  regcache_raw_collect (regcache, regno, buf);
+-	  pswm = extract_unsigned_integer (buf, 4, byte_order);
++	  if (reg >= S390_PSWM_REGNUM && reg <= S390_PSWA_REGNUM)
++	    psw_p[reg - S390_PSWM_REGNUM] = p;
+ 
+-	  /* We don't know the final addressing mode until the PSW address
+-	     is known, so leave it as-is.  When the PSW address is collected
+-	     (below), the addressing mode will be updated.  */
+-	  store_unsigned_integer (regp + regmap[S390_PSWM_REGNUM],
+-				  4, byte_order, pswm & 0xfff7ffff);
+-	  return;
++	  else if (regno == -1 || regno == reg)
++	    {
++	      if ((reg >= S390_R0_REGNUM && reg <= S390_R15_REGNUM)
++		  || reg == S390_ORIG_R2_REGNUM)
++		{
++		  memset (p, 0, 4);
++		  p += 4;
++		}
++	      regcache_raw_collect (regcache, reg, p + 4);
++	    }
+ 	}
+ 
+-      if (regno == S390_PSWA_REGNUM)
++      if (regno == -1
++	  || regno == S390_PSWM_REGNUM || regno == S390_PSWA_REGNUM)
+ 	{
+-	  ULONGEST pswa;
++	  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
++	  ULONGEST pswa, pswm;
+ 	  gdb_byte buf[4];
+ 
+-	  regcache_raw_collect (regcache, regno, buf);
++	  regcache_raw_collect (regcache, S390_PSWM_REGNUM, buf);
++	  pswm = extract_unsigned_integer (buf, 4, byte_order);
++	  regcache_raw_collect (regcache, S390_PSWA_REGNUM, buf);
+ 	  pswa = extract_unsigned_integer (buf, 4, byte_order);
+ 
+-	  store_unsigned_integer (regp + regmap[S390_PSWA_REGNUM],
+-				  8, byte_order, pswa & 0x7fffffff);
+-
+-	  /* Update basic addressing mode bit in PSW mask, see above.  */
+-	  store_unsigned_integer (regp + regmap[S390_PSWM_REGNUM] + 4,
+-				  4, byte_order, pswa & 0x80000000);
+-	  return;
+-	}
+-
+-      if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM)
+-	  || regno == S390_ORIG_R2_REGNUM)
+-	{
+-	  memset (regp + offset, 0, 4);
+-	  offset += 4;
++	  if (regno == -1 || regno == S390_PSWM_REGNUM)
++	    store_unsigned_integer (psw_p[0], 8, byte_order,
++				    ((pswm & 0xfff7ffff) << 32) |
++				    (pswa & 0x80000000));
++	  if (regno == -1 || regno == S390_PSWA_REGNUM)
++	    store_unsigned_integer (psw_p[1], 8, byte_order,
++				    pswa & 0x7fffffff);
+ 	}
++      return;
+     }
+ #endif
+ 
+-  if (offset != -1)
+-    regcache_raw_collect (regcache, regno, regp + offset);
+-}
+-
+-/* Fill GDB's register array with the general-purpose register values
+-   in *REGP.  */
+-void
+-supply_gregset (struct regcache *regcache, const gregset_t *regp)
+-{
+-  int i;
+-  for (i = 0; i < S390_NUM_REGS; i++)
+-    s390_native_supply (regcache, i, (const gdb_byte *) regp, regmap_gregset);
+-}
+-
+-/* Fill register REGNO (if it is a general-purpose register) in
+-   *REGP with the value in GDB's register array.  If REGNO is -1,
+-   do this for all registers.  */
+-void
+-fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
+-{
+-  int i;
+-  for (i = 0; i < S390_NUM_REGS; i++)
+-    if (regno == -1 || regno == i)
+-      s390_native_collect (regcache, i, (gdb_byte *) regp, regmap_gregset);
++  s390_native_collect (regcache, regmap_gregset, regno, (gdb_byte *) regp);
+ }
+ 
+ /* Fill GDB's register array with the floating-point register values
+@@ -203,9 +203,7 @@ fill_gregset (const struct regcache *reg
+ void
+ supply_fpregset (struct regcache *regcache, const fpregset_t *regp)
+ {
+-  int i;
+-  for (i = 0; i < S390_NUM_REGS; i++)
+-    s390_native_supply (regcache, i, (const gdb_byte *) regp, regmap_fpregset);
++  s390_native_supply (regcache, regmap_fpregset, (const gdb_byte *) regp);
+ }
+ 
+ /* Fill register REGNO (if it is a general-purpose register) in
+@@ -214,10 +212,7 @@ supply_fpregset (struct regcache *regcac
+ void
+ fill_fpregset (const struct regcache *regcache, fpregset_t *regp, int regno)
+ {
+-  int i;
+-  for (i = 0; i < S390_NUM_REGS; i++)
+-    if (regno == -1 || regno == i)
+-      s390_native_collect (regcache, i, (gdb_byte *) regp, regmap_fpregset);
++  s390_native_collect (regcache, regmap_fpregset, regno, (gdb_byte *) regp);
+ }
+ 
+ /* Find the TID for the current inferior thread to use with ptrace.  */
+@@ -311,12 +306,10 @@ store_fpregs (const struct regcache *reg
+    process/thread TID and store their values in GDB's register cache.  */
+ static void
+ fetch_regset (struct regcache *regcache, int tid,
+-	      int regset, int regsize, int *regmap)
++	      int regset, int regsize, const short *regmap)
+ {
+-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+   gdb_byte *buf = alloca (regsize);
+   struct iovec iov;
+-  int i;
+ 
+   iov.iov_base = buf;
+   iov.iov_len = regsize;
+@@ -324,8 +317,7 @@ fetch_regset (struct regcache *regcache,
+   if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
+     perror_with_name (_("Couldn't get register set"));
+ 
+-  for (i = 0; i < S390_NUM_REGS; i++)
+-    s390_native_supply (regcache, i, buf, regmap);
++  s390_native_supply (regcache, regmap, buf);
+ }
+ 
+ /* Store all registers in the kernel's register set whose number is REGSET,
+@@ -333,12 +325,10 @@ fetch_regset (struct regcache *regcache,
+    GDB's register cache back to process/thread TID.  */
+ static void
+ store_regset (struct regcache *regcache, int tid,
+-	      int regset, int regsize, int *regmap)
++	      int regset, int regsize, const short *regmap)
+ {
+-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+   gdb_byte *buf = alloca (regsize);
+   struct iovec iov;
+-  int i;
+ 
+   iov.iov_base = buf;
+   iov.iov_len = regsize;
+@@ -346,8 +336,7 @@ store_regset (struct regcache *regcache,
+   if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
+     perror_with_name (_("Couldn't get register set"));
+ 
+-  for (i = 0; i < S390_NUM_REGS; i++)
+-    s390_native_collect (regcache, i, buf, regmap);
++  s390_native_collect (regcache, regmap, -1, buf);
+ 
+   if (ptrace (PTRACE_SETREGSET, tid, (long) regset, (long) &iov) < 0)
+     perror_with_name (_("Couldn't set register set"));
+@@ -378,12 +367,10 @@ s390_linux_fetch_inferior_registers (str
+ {
+   int tid = s390_inferior_tid ();
+ 
+-  if (regnum == -1 
+-      || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1))
++  if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum))
+     fetch_regs (regcache, tid);
+ 
+-  if (regnum == -1 
+-      || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1))
++  if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum))
+     fetch_fpregs (regcache, tid);
+ 
+   if (have_regset_last_break)
+@@ -406,12 +393,10 @@ s390_linux_store_inferior_registers (str
+ {
+   int tid = s390_inferior_tid ();
+ 
+-  if (regnum == -1 
+-      || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1))
++  if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum))
+     store_regs (regcache, tid, regnum);
+ 
+-  if (regnum == -1 
+-      || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1))
++  if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum))
+     store_fpregs (regcache, tid, regnum);
+ 
+   /* S390_LAST_BREAK_REGNUM is read-only.  */
+Index: gdb-7.6.1/gdb/s390-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/s390-tdep.c
++++ gdb-7.6.1/gdb/s390-tdep.c
+@@ -141,7 +141,7 @@ s390_write_pc (struct regcache *regcache
+ 
+ /* DWARF Register Mapping.  */
+ 
+-static int s390_dwarf_regmap[] =
++static const short s390_dwarf_regmap[] =
+ {
+   /* General Purpose Registers.  */
+   S390_R0_REGNUM, S390_R1_REGNUM, S390_R2_REGNUM, S390_R3_REGNUM,
+@@ -212,6 +212,14 @@ s390_adjust_frame_regnum (struct gdbarch
+ 
+ /* Pseudo registers.  */
+ 
++static int
++regnum_is_gpr_full (struct gdbarch_tdep *tdep, int regnum)
++{
++  return (tdep->gpr_full_regnum != -1
++	  && regnum >= tdep->gpr_full_regnum
++	  && regnum <= tdep->gpr_full_regnum + 15);
++}
++
+ static const char *
+ s390_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
+ {
+@@ -223,9 +231,7 @@ s390_pseudo_register_name (struct gdbarc
+   if (regnum == tdep->cc_regnum)
+     return "cc";
+ 
+-  if (tdep->gpr_full_regnum != -1
+-      && regnum >= tdep->gpr_full_regnum
+-      && regnum < tdep->gpr_full_regnum + 16)
++  if (regnum_is_gpr_full (tdep, regnum))
+     {
+       static const char *full_name[] = {
+ 	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+@@ -248,9 +254,7 @@ s390_pseudo_register_type (struct gdbarc
+   if (regnum == tdep->cc_regnum)
+     return builtin_type (gdbarch)->builtin_int;
+ 
+-  if (tdep->gpr_full_regnum != -1
+-      && regnum >= tdep->gpr_full_regnum
+-      && regnum < tdep->gpr_full_regnum + 16)
++  if (regnum_is_gpr_full (tdep, regnum))
+     return builtin_type (gdbarch)->builtin_uint64;
+ 
+   internal_error (__FILE__, __LINE__, _("invalid regnum"));
+@@ -295,9 +299,7 @@ s390_pseudo_register_read (struct gdbarc
+       return status;
+     }
+ 
+-  if (tdep->gpr_full_regnum != -1
+-      && regnum >= tdep->gpr_full_regnum
+-      && regnum < tdep->gpr_full_regnum + 16)
++  if (regnum_is_gpr_full (tdep, regnum))
+     {
+       enum register_status status;
+       ULONGEST val_upper;
+@@ -352,9 +354,7 @@ s390_pseudo_register_write (struct gdbar
+       return;
+     }
+ 
+-  if (tdep->gpr_full_regnum != -1
+-      && regnum >= tdep->gpr_full_regnum
+-      && regnum < tdep->gpr_full_regnum + 16)
++  if (regnum_is_gpr_full (tdep, regnum))
+     {
+       regnum -= tdep->gpr_full_regnum;
+       val = extract_unsigned_integer (buf, regsize, byte_order);
+@@ -409,175 +409,166 @@ s390_pseudo_register_reggroup_p (struct
+ }
+ 
+ 
+-/* Core file register sets.  */
++/* Maps for register sets.  */
+ 
+-int s390_regmap_gregset[S390_NUM_REGS] =
+-{
+-  /* Program Status Word.  */
+-  0x00, 0x04,
+-  /* General Purpose Registers.  */
+-  0x08, 0x0c, 0x10, 0x14,
+-  0x18, 0x1c, 0x20, 0x24,
+-  0x28, 0x2c, 0x30, 0x34,
+-  0x38, 0x3c, 0x40, 0x44,
+-  /* Access Registers.  */
+-  0x48, 0x4c, 0x50, 0x54,
+-  0x58, 0x5c, 0x60, 0x64,
+-  0x68, 0x6c, 0x70, 0x74,
+-  0x78, 0x7c, 0x80, 0x84,
+-  /* Floating Point Control Word.  */
+-  -1,
+-  /* Floating Point Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* GPR Uppper Halves.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* GNU/Linux-specific optional "registers".  */
+-  0x88, -1, -1,
+-};
++const short s390_regmap_gregset[] =
++  {
++    0x00, S390_PSWM_REGNUM,
++    0x04, S390_PSWA_REGNUM,
++    0x08, S390_R0_REGNUM,
++    0x0c, S390_R1_REGNUM,
++    0x10, S390_R2_REGNUM,
++    0x14, S390_R3_REGNUM,
++    0x18, S390_R4_REGNUM,
++    0x1c, S390_R5_REGNUM,
++    0x20, S390_R6_REGNUM,
++    0x24, S390_R7_REGNUM,
++    0x28, S390_R8_REGNUM,
++    0x2c, S390_R9_REGNUM,
++    0x30, S390_R10_REGNUM,
++    0x34, S390_R11_REGNUM,
++    0x38, S390_R12_REGNUM,
++    0x3c, S390_R13_REGNUM,
++    0x40, S390_R14_REGNUM,
++    0x44, S390_R15_REGNUM,
++    0x48, S390_A0_REGNUM,
++    0x4c, S390_A1_REGNUM,
++    0x50, S390_A2_REGNUM,
++    0x54, S390_A3_REGNUM,
++    0x58, S390_A4_REGNUM,
++    0x5c, S390_A5_REGNUM,
++    0x60, S390_A6_REGNUM,
++    0x64, S390_A7_REGNUM,
++    0x68, S390_A8_REGNUM,
++    0x6c, S390_A9_REGNUM,
++    0x70, S390_A10_REGNUM,
++    0x74, S390_A11_REGNUM,
++    0x78, S390_A12_REGNUM,
++    0x7c, S390_A13_REGNUM,
++    0x80, S390_A14_REGNUM,
++    0x84, S390_A15_REGNUM,
++    0x88, S390_ORIG_R2_REGNUM,
++    -1, -1
++  };
+ 
+-int s390x_regmap_gregset[S390_NUM_REGS] =
+-{
+-  /* Program Status Word.  */
+-  0x00, 0x08,
+-  /* General Purpose Registers.  */
+-  0x10, 0x18, 0x20, 0x28,
+-  0x30, 0x38, 0x40, 0x48,
+-  0x50, 0x58, 0x60, 0x68,
+-  0x70, 0x78, 0x80, 0x88,
+-  /* Access Registers.  */
+-  0x90, 0x94, 0x98, 0x9c,
+-  0xa0, 0xa4, 0xa8, 0xac,
+-  0xb0, 0xb4, 0xb8, 0xbc,
+-  0xc0, 0xc4, 0xc8, 0xcc,
+-  /* Floating Point Control Word.  */
+-  -1,
+-  /* Floating Point Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* GPR Uppper Halves.  */
+-  0x10, 0x18, 0x20, 0x28,
+-  0x30, 0x38, 0x40, 0x48,
+-  0x50, 0x58, 0x60, 0x68,
+-  0x70, 0x78, 0x80, 0x88,
+-  /* GNU/Linux-specific optional "registers".  */
+-  0xd0, -1, -1,
+-};
++const short s390x_regmap_gregset[] =
++  {
++    0x00, S390_PSWM_REGNUM,
++    0x08, S390_PSWA_REGNUM,
++    0x10, S390_R0_REGNUM,
++    0x18, S390_R1_REGNUM,
++    0x20, S390_R2_REGNUM,
++    0x28, S390_R3_REGNUM,
++    0x30, S390_R4_REGNUM,
++    0x38, S390_R5_REGNUM,
++    0x40, S390_R6_REGNUM,
++    0x48, S390_R7_REGNUM,
++    0x50, S390_R8_REGNUM,
++    0x58, S390_R9_REGNUM,
++    0x60, S390_R10_REGNUM,
++    0x68, S390_R11_REGNUM,
++    0x70, S390_R12_REGNUM,
++    0x78, S390_R13_REGNUM,
++    0x80, S390_R14_REGNUM,
++    0x88, S390_R15_REGNUM,
++    0x90, S390_A0_REGNUM,
++    0x94, S390_A1_REGNUM,
++    0x98, S390_A2_REGNUM,
++    0x9c, S390_A3_REGNUM,
++    0xa0, S390_A4_REGNUM,
++    0xa4, S390_A5_REGNUM,
++    0xa8, S390_A6_REGNUM,
++    0xac, S390_A7_REGNUM,
++    0xb0, S390_A8_REGNUM,
++    0xb4, S390_A9_REGNUM,
++    0xb8, S390_A10_REGNUM,
++    0xbc, S390_A11_REGNUM,
++    0xc0, S390_A12_REGNUM,
++    0xc4, S390_A13_REGNUM,
++    0xc8, S390_A14_REGNUM,
++    0xcc, S390_A15_REGNUM,
++    0x10, S390_R0_UPPER_REGNUM,
++    0x18, S390_R1_UPPER_REGNUM,
++    0x20, S390_R2_UPPER_REGNUM,
++    0x28, S390_R3_UPPER_REGNUM,
++    0x30, S390_R4_UPPER_REGNUM,
++    0x38, S390_R5_UPPER_REGNUM,
++    0x40, S390_R6_UPPER_REGNUM,
++    0x48, S390_R7_UPPER_REGNUM,
++    0x50, S390_R8_UPPER_REGNUM,
++    0x58, S390_R9_UPPER_REGNUM,
++    0x60, S390_R10_UPPER_REGNUM,
++    0x68, S390_R11_UPPER_REGNUM,
++    0x70, S390_R12_UPPER_REGNUM,
++    0x78, S390_R13_UPPER_REGNUM,
++    0x80, S390_R14_UPPER_REGNUM,
++    0x88, S390_R15_UPPER_REGNUM,
++    0xd0, S390_ORIG_R2_REGNUM,
++    -1, -1
++  };
+ 
+-int s390_regmap_fpregset[S390_NUM_REGS] =
+-{
+-  /* Program Status Word.  */
+-  -1, -1,
+-  /* General Purpose Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* Access Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* Floating Point Control Word.  */
+-  0x00,
+-  /* Floating Point Registers.  */
+-  0x08, 0x10, 0x18, 0x20,
+-  0x28, 0x30, 0x38, 0x40,
+-  0x48, 0x50, 0x58, 0x60,
+-  0x68, 0x70, 0x78, 0x80,
+-  /* GPR Uppper Halves.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* GNU/Linux-specific optional "registers".  */
+-  -1, -1, -1,
+-};
++const short s390_regmap_fpregset[] =
++  {
++    0x00, S390_FPC_REGNUM,
++    0x08, S390_F0_REGNUM,
++    0x10, S390_F1_REGNUM,
++    0x18, S390_F2_REGNUM,
++    0x20, S390_F3_REGNUM,
++    0x28, S390_F4_REGNUM,
++    0x30, S390_F5_REGNUM,
++    0x38, S390_F6_REGNUM,
++    0x40, S390_F7_REGNUM,
++    0x48, S390_F8_REGNUM,
++    0x50, S390_F9_REGNUM,
++    0x58, S390_F10_REGNUM,
++    0x60, S390_F11_REGNUM,
++    0x68, S390_F12_REGNUM,
++    0x70, S390_F13_REGNUM,
++    0x78, S390_F14_REGNUM,
++    0x80, S390_F15_REGNUM,
++    -1, -1
++  };
+ 
+-int s390_regmap_upper[S390_NUM_REGS] =
+-{
+-  /* Program Status Word.  */
+-  -1, -1,
+-  /* General Purpose Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* Access Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* Floating Point Control Word.  */
+-  -1,
+-  /* Floating Point Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* GPR Uppper Halves.  */
+-  0x00, 0x04, 0x08, 0x0c,
+-  0x10, 0x14, 0x18, 0x1c,
+-  0x20, 0x24, 0x28, 0x2c,
+-  0x30, 0x34, 0x38, 0x3c,
+-  /* GNU/Linux-specific optional "registers".  */
+-  -1, -1, -1,
+-};
++const short s390_regmap_upper[] =
++  {
++    0x00, S390_R0_UPPER_REGNUM,
++    0x04, S390_R1_UPPER_REGNUM,
++    0x08, S390_R2_UPPER_REGNUM,
++    0x0c, S390_R3_UPPER_REGNUM,
++    0x10, S390_R4_UPPER_REGNUM,
++    0x14, S390_R5_UPPER_REGNUM,
++    0x18, S390_R6_UPPER_REGNUM,
++    0x1c, S390_R7_UPPER_REGNUM,
++    0x20, S390_R8_UPPER_REGNUM,
++    0x24, S390_R9_UPPER_REGNUM,
++    0x28, S390_R10_UPPER_REGNUM,
++    0x2c, S390_R11_UPPER_REGNUM,
++    0x30, S390_R12_UPPER_REGNUM,
++    0x34, S390_R13_UPPER_REGNUM,
++    0x38, S390_R14_UPPER_REGNUM,
++    0x3c, S390_R15_UPPER_REGNUM,
++    -1, -1
++  };
+ 
+-int s390_regmap_last_break[S390_NUM_REGS] =
+-{
+-  /* Program Status Word.  */
+-  -1, -1,
+-  /* General Purpose Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* Access Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* Floating Point Control Word.  */
+-  -1,
+-  /* Floating Point Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* GPR Uppper Halves.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* GNU/Linux-specific optional "registers".  */
+-  -1, 4, -1,
+-};
++const short s390_regmap_last_break[] =
++  {
++    0x04, S390_LAST_BREAK_REGNUM,
++    -1, -1
++  };
++
++const short s390x_regmap_last_break[] =
++  {
++    0x00, S390_LAST_BREAK_REGNUM,
++    -1, -1
++  };
++
++const short s390_regmap_system_call[] =
++  {
++    0x00, S390_SYSTEM_CALL_REGNUM,
++    -1, -1
++  };
+ 
+-int s390x_regmap_last_break[S390_NUM_REGS] =
+-{
+-  /* Program Status Word.  */
+-  -1, -1,
+-  /* General Purpose Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* Access Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* Floating Point Control Word.  */
+-  -1,
+-  /* Floating Point Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* GPR Uppper Halves.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* GNU/Linux-specific optional "registers".  */
+-  -1, 0, -1,
+-};
+ 
+-int s390_regmap_system_call[S390_NUM_REGS] =
+-{
+-  /* Program Status Word.  */
+-  -1, -1,
+-  /* General Purpose Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* Access Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* Floating Point Control Word.  */
+-  -1,
+-  /* Floating Point Registers.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* GPR Uppper Halves.  */
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  -1, -1, -1, -1, -1, -1, -1, -1,
+-  /* GNU/Linux-specific optional "registers".  */
+-  -1, -1, 0,
+-};
+ 
+ /* Supply register REGNUM from the register set REGSET to register cache 
+    REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
+@@ -585,14 +576,10 @@ static void
+ s390_supply_regset (const struct regset *regset, struct regcache *regcache,
+ 		    int regnum, const void *regs, size_t len)
+ {
+-  const int *offset = regset->descr;
+-  int i;
+-
+-  for (i = 0; i < S390_NUM_REGS; i++)
+-    {
+-      if ((regnum == i || regnum == -1) && offset[i] != -1)
+-	regcache_raw_supply (regcache, i, (const char *)regs + offset[i]);
+-    }
++  const short *map;
++  for (map = regset->descr; map[0] >= 0; map += 2)
++    if (regnum == -1 || regnum == map[1])
++      regcache_raw_supply (regcache, map[1], (const char *)regs + map[0]);
+ }
+ 
+ /* Collect register REGNUM from the register cache REGCACHE and store
+@@ -604,14 +591,10 @@ s390_collect_regset (const struct regset
+ 		     const struct regcache *regcache,
+ 		     int regnum, void *regs, size_t len)
+ {
+-  const int *offset = regset->descr;
+-  int i;
+-
+-  for (i = 0; i < S390_NUM_REGS; i++)
+-    {
+-      if ((regnum == i || regnum == -1) && offset[i] != -1)
+-	regcache_raw_collect (regcache, i, (char *)regs + offset[i]);
+-    }
++  const short *map;
++  for (map = regset->descr; map[0] >= 0; map += 2)
++    if (regnum == -1 || regnum == map[1])
++      regcache_raw_collect (regcache, map[1], (char *)regs + map[0]);
+ }
+ 
+ static const struct regset s390_gregset = {
+@@ -1718,9 +1701,7 @@ s390_unwind_pseudo_register (struct fram
+ 
+   /* Unwind full GPRs to show at least the lower halves (as the
+      upper halves are undefined).  */
+-  if (tdep->gpr_full_regnum != -1
+-      && regnum >= tdep->gpr_full_regnum
+-      && regnum < tdep->gpr_full_regnum + 16)
++  if (regnum_is_gpr_full (tdep, regnum))
+     {
+       int reg = regnum - tdep->gpr_full_regnum;
+       struct value *val;
+Index: gdb-7.6.1/gdb/s390-tdep.h
+===================================================================
+--- gdb-7.6.1.orig/gdb/s390-tdep.h
++++ gdb-7.6.1/gdb/s390-tdep.h
+@@ -106,16 +106,24 @@
+ #define S390_RETADDR_REGNUM S390_R14_REGNUM
+ #define S390_FRAME_REGNUM S390_R11_REGNUM
+ 
++#define S390_IS_GREGSET_REGNUM(i)					\
++  (((i) >= S390_PSWM_REGNUM && (i) <= S390_A15_REGNUM)			\
++   || ((i) >= S390_R0_UPPER_REGNUM && (i) <= S390_R15_UPPER_REGNUM)	\
++   || (i) == S390_ORIG_R2_REGNUM)
++
++#define S390_IS_FPREGSET_REGNUM(i)			\
++  ((i) >= S390_FPC_REGNUM && (i) <= S390_F15_REGNUM)
++
+ /* Core file register sets, defined in s390-tdep.c.  */
+ #define s390_sizeof_gregset 0x90
+-extern int s390_regmap_gregset[S390_NUM_REGS];
++extern const short s390_regmap_gregset[];
+ #define s390x_sizeof_gregset 0xd8
+-extern int s390x_regmap_gregset[S390_NUM_REGS];
++extern const short s390x_regmap_gregset[];
+ #define s390_sizeof_fpregset 0x88
+-extern int s390_regmap_fpregset[S390_NUM_REGS];
+-extern int s390_regmap_last_break[S390_NUM_REGS];
+-extern int s390x_regmap_last_break[S390_NUM_REGS];
+-extern int s390_regmap_system_call[S390_NUM_REGS];
++extern const short s390_regmap_fpregset[];
++extern const short s390_regmap_last_break[];
++extern const short s390x_regmap_last_break[];
++extern const short s390_regmap_system_call[];
+ 
+ /* GNU/Linux target descriptions.  */
+ extern struct target_desc *tdesc_s390_linux32;
diff --git a/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-2of9.patch b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-2of9.patch
new file mode 100644
index 0000000..2087e2b
--- /dev/null
+++ b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-2of9.patch
@@ -0,0 +1,22 @@
+commit 9b44a3a57d17ea2d35823780007a38daeeaec6a4
+Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
+Date:   Tue May 13 14:55:53 2014 +0200
+
+    S390: Fix erroneous offset in fill_gregset.
+    
+    This fixes a bug that leads to various failures when debugging a
+    31-bit inferior with a 64-bit gdb on s390x.
+
+Index: gdb-7.6.1/gdb/s390-nat.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/s390-nat.c
++++ gdb-7.6.1/gdb/s390-nat.c
+@@ -167,7 +167,7 @@ fill_gregset (const struct regcache *reg
+ 		  memset (p, 0, 4);
+ 		  p += 4;
+ 		}
+-	      regcache_raw_collect (regcache, reg, p + 4);
++	      regcache_raw_collect (regcache, reg, p);
+ 	    }
+ 	}
+ 
diff --git a/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-3of9.patch b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-3of9.patch
new file mode 100644
index 0000000..ac325db
--- /dev/null
+++ b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-3of9.patch
@@ -0,0 +1,1398 @@
+From 4ac33720d6022079e8b038e795e40f0e06a4012c Mon Sep 17 00:00:00 2001
+From: Ulrich Weigand <uweigand@de.ibm.com>
+Date: Fri, 13 Sep 2013 14:17:31 +0000
+Subject: [PATCH 3/3] gdb/ChangeLog: 2013-09-13  Andreas Arnez 
+ <arnez@linux.vnet.ibm.com>
+
+	* NEWS: Mention TDB support.
+	* features/s390-tdb.xml: New file.
+	* features/s390-te-linux64.xml: New file.
+	* features/s390x-te-linux64.xml: New file.
+	* features/Makefile (WHICH): Add new tdescs above.
+	(s390-te-linux64-expedite): Set.
+	(s390x-te-linux64-expedite): Set.
+	* features/s390-te-linux64.c: New file (generated).
+	* features/s390x-te-linux64.c: New file (generated).
+	* regformats/s390-te-linux64.dat: New file (generated).
+	* regformats/s390x-te-linux64.dat: New file (generated).
+	* s390-tdep.h (HWCAP_S390_HIGH_GPRS): Define.
+	(HWCAP_S390_TE): Likewise.
+	(S390_TDB_DWORD0_REGNUM): Likewise.
+	(S390_TDB_DWORD0_REGNUM): Likewise.
+	(S390_TDB_ABORT_CODE_REGNUM): Likewise.
+	(S390_TDB_CONFLICT_TOKEN_REGNUM): Likewise.
+	(S390_TDB_ATIA_REGNUM): Likewise.
+	(S390_TDB_R0_REGNUM): Likewise.
+	(S390_TDB_R1_REGNUM): Likewise.
+	(S390_TDB_R2_REGNUM): Likewise.
+	(S390_TDB_R3_REGNUM): Likewise.
+	(S390_TDB_R4_REGNUM): Likewise.
+	(S390_TDB_R5_REGNUM): Likewise.
+	(S390_TDB_R6_REGNUM): Likewise.
+	(S390_TDB_R7_REGNUM): Likewise.
+	(S390_TDB_R8_REGNUM): Likewise.
+	(S390_TDB_R9_REGNUM): Likewise.
+	(S390_TDB_R10_REGNUM): Likewise.
+	(S390_TDB_R11_REGNUM): Likewise.
+	(S390_TDB_R12_REGNUM): Likewise.
+	(S390_TDB_R13_REGNUM): Likewise.
+	(S390_TDB_R14_REGNUM): Likewise.
+	(S390_TDB_R15_REGNUM): Likewise.
+	(S390_NUM_REGS): Increase.
+	(S390_IS_TDBREGSET_REGNUM): New macro.
+	(s390_regmap_tdb): Declare.
+	(s390_sizeof_tdbregset): Define.
+	(tdesc_s390_te_linux64): Declare.
+	(tdesc_s390x_te_linux64): Likewise.
+	* s390-tdep.c: Add includes for "auxv.h", <elf.h>,
+	"features/s390-te-linux64.c", and "features/s390x-te-linux64.c".
+	(s390_regmap_tdb): New regmap.
+	(s390_supply_tdb_regset): New function.
+	(s390_tdb_regset): New regset.
+	(s390_linux64v2_regset_sections): Add TDB regset to list.
+	(s390x_linux64v2_regset_sections): Likewise.
+	(s390_regset_from_core_section): Recognize TDB core note section.
+	(s390_core_read_description): If HWCAP indicates TE support,
+	select tdesc_s390_te_linux64 or tdesc_s390_s390x_te_linux64.
+	(s390_gdbarch_init): Handle TDB regset.
+	(_initialize_s390_tdep): Initialize new tdescs.
+	* s390-nat.c (HWCAP_S390_HIGH_GPRS): Remove define.
+	(have_regset_tdb): New variable.
+	(s390_native_supply): Support register invalidation.
+	(fetch_regset): Invalidate registers if ptrace yields ENODATA.
+	(check_regset): Treat ENODATA as "regset exists".
+	(s390_linux_fetch_inferior_registers): Add TDB.
+	(s390_read_description): Check for TDB existence and select
+	appropriate tdesc.
+	* gdbserver/Makefile.in (clean): Add removal of new makefile
+	targets.
+	(s390-te-linux64.c): New makefile target.
+	(s390x-te-linux64.c): Likewise.
+	* gdbserver/configure.srv (srv_regobj): Append new objects
+	s390-te-linux64.o and s390x-te-linux64.o.
+	(srv_xmlfiles): Append new files s390-te-linux64.xml,
+	s390x-te-linux64.xml, and s390-tdb.xml.
+	* gdbserver/linux-s390-low.c (init_registers_s390_te_linux64): New
+	declaration.
+	(tdesc_s390_te_linux64): Likewise.
+	(init_registers_s390x_te_linux64): Likewise.
+	(tdesc_s390x_te_linux64): Likewise.
+	(s390_check_regset): Treat ENODATA as "regset exists".
+	(s390_arch_setup): Add TDB regset support.
+	(initialize_low_arch): Initialize registers for new tdescs.
+
+gdb/doc/ChangeLog:
+2013-09-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
+
+	* gdb.texinfo (Decimal Floating Point format): Mention S/390.
+	(Standard Target Features): Add new node to menu.
+	(S/390 and System z Features): New node.
+
+gdb/testsuite/ChangeLog:
+2013-09-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
+
+	* gdb.arch/s390-tdbregs.c: New file.
+	* gdb.arch/s390-tdbregs.exp: New file.
+---
+ gdb/ChangeLog                           |  79 +++++++++++++++++++++
+ gdb/NEWS                                |   4 ++
+ gdb/doc/ChangeLog                       |   6 ++
+ gdb/doc/gdb.texinfo                     |  38 +++++++++-
+ gdb/features/Makefile                   |   3 +
+ gdb/features/s390-tdb.xml               |  30 ++++++++
+ gdb/features/s390-te-linux64.c          | 118 ++++++++++++++++++++++++++++++++
+ gdb/features/s390-te-linux64.xml        |  25 +++++++
+ gdb/features/s390x-te-linux64.c         | 102 +++++++++++++++++++++++++++
+ gdb/features/s390x-te-linux64.xml       |  24 +++++++
+ gdb/gdbserver/Makefile.in               |   7 ++
+ gdb/gdbserver/configure.srv             |   5 ++
+ gdb/gdbserver/linux-s390-low.c          |  25 +++++--
+ gdb/regformats/s390-te-linux64.dat      |  94 +++++++++++++++++++++++++
+ gdb/regformats/s390x-te-linux64.dat     |  78 +++++++++++++++++++++
+ gdb/s390-nat.c                          |  37 ++++++----
+ gdb/s390-tdep.c                         |  85 ++++++++++++++++++++++-
+ gdb/s390-tdep.h                         |  40 ++++++++++-
+ gdb/testsuite/ChangeLog                 |   5 ++
+ gdb/testsuite/gdb.arch/s390-tdbregs.c   |  64 +++++++++++++++++
+ gdb/testsuite/gdb.arch/s390-tdbregs.exp |  75 ++++++++++++++++++++
+ 21 files changed, 921 insertions(+), 23 deletions(-)
+ create mode 100644 gdb/features/s390-tdb.xml
+ create mode 100644 gdb/features/s390-te-linux64.c
+ create mode 100644 gdb/features/s390-te-linux64.xml
+ create mode 100644 gdb/features/s390x-te-linux64.c
+ create mode 100644 gdb/features/s390x-te-linux64.xml
+ create mode 100644 gdb/regformats/s390-te-linux64.dat
+ create mode 100644 gdb/regformats/s390x-te-linux64.dat
+ create mode 100644 gdb/testsuite/gdb.arch/s390-tdbregs.c
+ create mode 100644 gdb/testsuite/gdb.arch/s390-tdbregs.exp
+
+Index: gdb-7.6.1/gdb/NEWS
+===================================================================
+--- gdb-7.6.1.orig/gdb/NEWS
++++ gdb-7.6.1/gdb/NEWS
+@@ -14,6 +14,10 @@ add-auto-load-scripts-directory director
+ 
+   ** Frame filters and frame decorators have been added.
+ 
++* On S/390 targets that provide the transactional-execution feature,
++  the program interruption transaction diagnostic block (TDB) is now
++  represented as a number of additional "registers" in GDB.
++
+ * New remote packets
+ 
+ qXfer:libraries-svr4:read's annex
+Index: gdb-7.6.1/gdb/doc/gdb.texinfo
+===================================================================
+--- gdb-7.6.1.orig/gdb/doc/gdb.texinfo
++++ gdb-7.6.1/gdb/doc/gdb.texinfo
+@@ -13737,8 +13737,8 @@ specified by the extension to support de
+ 
+ There are two encodings in use, depending on the architecture: BID (Binary
+ Integer Decimal) for x86 and x86-64, and DPD (Densely Packed Decimal) for
+-PowerPC.  @value{GDBN} will use the appropriate encoding for the configured
+-target.
++PowerPC and S/390.  @value{GDBN} will use the appropriate encoding for the
++configured target.
+ 
+ Because of a limitation in @file{libdecnumber}, the library used by @value{GDBN}
+ to manipulate decimal floating point numbers, it is not possible to convert
+@@ -42082,6 +42082,7 @@ registers using the capitalization used
+ * MIPS Features::
+ * M68K Features::
+ * PowerPC Features::
++* S/390 and System z Features::
+ * TIC6x Features::
+ @end menu
+ 
+@@ -42261,6 +42262,39 @@ contain registers @samp{ev0h} through @s
+ these to present registers @samp{ev0} through @samp{ev31} to the
+ user.
+ 
++@node S/390 and System z Features
++@subsection S/390 and System z Features
++@cindex target descriptions, S/390 features
++@cindex target descriptions, System z features
++
++The @samp{org.gnu.gdb.s390.core} feature is required for S/390 and
++System z targets.  It should contain the PSW and the 16 general
++registers.  In particular, System z targets should provide the 64-bit
++registers @samp{pswm}, @samp{pswa}, and @samp{r0} through @samp{r15}.
++S/390 targets should provide the 32-bit versions of these registers.
++A System z target that runs in 31-bit addressing mode should provide
++32-bit versions of @samp{pswm} and @samp{pswa}, as well as the general
++register's upper halves @samp{r0h} through @samp{r15h}, and their
++lower halves @samp{r0l} through @samp{r15l}.
++
++The @samp{org.gnu.gdb.s390.fpr} feature is required.  It should
++contain the 64-bit registers @samp{f0} through @samp{f15}, and
++@samp{fpc}.
++
++The @samp{org.gnu.gdb.s390.acr} feature is required.  It should
++contain the 32-bit registers @samp{acr0} through @samp{acr15}.
++
++The @samp{org.gnu.gdb.s390.linux} feature is optional.  It should
++contain the register @samp{orig_r2}, which is 64-bit wide on System z
++targets and 32-bit otherwise.  In addition, the feature may contain
++the @samp{last_break} register, whose width depends on the addressing
++mode, as well as the @samp{system_call} register, which is always
++32-bit wide.
++
++The @samp{org.gnu.gdb.s390.tdb} feature is optional.  It should
++contain the 64-bit registers @samp{tdb0}, @samp{tac}, @samp{tct},
++@samp{atia}, and @samp{tr0} through @samp{tr15}.
++
+ @node TIC6x Features
+ @subsection TMS320C6x Features
+ @cindex target descriptions, TIC6x features
+Index: gdb-7.6.1/gdb/features/Makefile
+===================================================================
+--- gdb-7.6.1.orig/gdb/features/Makefile
++++ gdb-7.6.1/gdb/features/Makefile
+@@ -49,6 +49,7 @@ WHICH = aarch64 aarch64-without-fpu \
+ 	s390-linux32 s390-linux64 s390x-linux64 \
+ 	s390-linux32v1 s390-linux64v1 s390x-linux64v1 \
+ 	s390-linux32v2 s390-linux64v2 s390x-linux64v2 \
++	s390-te-linux64 s390x-te-linux64 \
+ 	tic6x-c64xp tic6x-c64x tic6x-c62x \
+ 	tic6x-c64xp-linux tic6x-c64x-linux tic6x-c62x-linux
+ 
+@@ -82,9 +83,11 @@ s390-linux32v2-expedite = r14,r15,pswa
+ s390-linux64-expedite = r14l,r15l,pswa
+ s390-linux64v1-expedite = r14l,r15l,pswa
+ s390-linux64v2-expedite = r14l,r15l,pswa
++s390-te-linux64-expedite = r14,r15,pswa
+ s390x-linux64-expedite = r14,r15,pswa
+ s390x-linux64v1-expedite = r14,r15,pswa
+ s390x-linux64v2-expedite = r14,r15,pswa
++s390x-te-linux64-expedite = r14,r15,pswa
+ tic6x-c64xp-expedite = A15,PC
+ tic6x-c64x-expedite = A15,PC
+ tic6x-c62x-expedite = A15,PC
+Index: gdb-7.6.1/gdb/features/s390-tdb.xml
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/features/s390-tdb.xml
+@@ -0,0 +1,30 @@
++<?xml version="1.0"?>
++<!-- Copyright (C) 2010-2013 Free Software Foundation, Inc.
++
++     Copying and distribution of this file, with or without modification,
++     are permitted in any medium without royalty provided the copyright
++     notice and this notice are preserved.  -->
++
++<!DOCTYPE feature SYSTEM "gdb-target.dtd">
++<feature name="org.gnu.gdb.s390.tdb">
++  <reg name="tdb0" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tac" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tct" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="atia" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr0" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr1" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr2" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr3" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr4" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr5" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr6" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr7" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr8" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr9" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr10" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr11" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr12" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr13" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr14" bitsize="64" type="uint64" group="tdb"/>
++  <reg name="tr15" bitsize="64" type="uint64" group="tdb"/>
++</feature>
+Index: gdb-7.6.1/gdb/features/s390-te-linux64.c
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/features/s390-te-linux64.c
+@@ -0,0 +1,118 @@
++/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
++  Original: s390-te-linux64.xml */
++
++#include "defs.h"
++#include "osabi.h"
++#include "target-descriptions.h"
++
++struct target_desc *tdesc_s390_te_linux64;
++static void
++initialize_tdesc_s390_te_linux64 (void)
++{
++  struct target_desc *result = allocate_target_description ();
++  struct tdesc_feature *feature;
++
++  set_tdesc_architecture (result, bfd_scan_arch ("s390:31-bit"));
++
++  feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core");
++  tdesc_create_reg (feature, "pswm", 0, 1, "psw", 32, "uint32");
++  tdesc_create_reg (feature, "pswa", 1, 1, "psw", 32, "uint32");
++  tdesc_create_reg (feature, "r0h", 2, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r0l", 3, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r1h", 4, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r1l", 5, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r2h", 6, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r2l", 7, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r3h", 8, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r3l", 9, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r4h", 10, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r4l", 11, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r5h", 12, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r5l", 13, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r6h", 14, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r6l", 15, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r7h", 16, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r7l", 17, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r8h", 18, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r8l", 19, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r9h", 20, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r9l", 21, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r10h", 22, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r10l", 23, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r11h", 24, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r11l", 25, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r12h", 26, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r12l", 27, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r13h", 28, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r13l", 29, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r14h", 30, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r14l", 31, 1, "lower", 32, "uint32");
++  tdesc_create_reg (feature, "r15h", 32, 1, "upper", 32, "uint32");
++  tdesc_create_reg (feature, "r15l", 33, 1, "lower", 32, "uint32");
++
++  feature = tdesc_create_feature (result, "org.gnu.gdb.s390.acr");
++  tdesc_create_reg (feature, "acr0", 34, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr1", 35, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr2", 36, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr3", 37, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr4", 38, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr5", 39, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr6", 40, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr7", 41, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr8", 42, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr9", 43, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr10", 44, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr11", 45, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr12", 46, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr13", 47, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr14", 48, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr15", 49, 1, "access", 32, "uint32");
++
++  feature = tdesc_create_feature (result, "org.gnu.gdb.s390.fpr");
++  tdesc_create_reg (feature, "fpc", 50, 1, "float", 32, "uint32");
++  tdesc_create_reg (feature, "f0", 51, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f1", 52, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f2", 53, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f3", 54, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f4", 55, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f5", 56, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f6", 57, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f7", 58, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f8", 59, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f9", 60, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f10", 61, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f11", 62, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f12", 63, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f13", 64, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f14", 65, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f15", 66, 1, "float", 64, "ieee_double");
++
++  feature = tdesc_create_feature (result, "org.gnu.gdb.s390.linux");
++  tdesc_create_reg (feature, "orig_r2", 67, 1, "system", 32, "uint32");
++  tdesc_create_reg (feature, "last_break", 68, 0, "system", 32, "code_ptr");
++  tdesc_create_reg (feature, "system_call", 69, 1, "system", 32, "uint32");
++
++  feature = tdesc_create_feature (result, "org.gnu.gdb.s390.tdb");
++  tdesc_create_reg (feature, "tdb0", 70, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tac", 71, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tct", 72, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "atia", 73, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr0", 74, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr1", 75, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr2", 76, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr3", 77, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr4", 78, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr5", 79, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr6", 80, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr7", 81, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr8", 82, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr9", 83, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr10", 84, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr11", 85, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr12", 86, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr13", 87, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr14", 88, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr15", 89, 1, "tdb", 64, "uint64");
++
++  tdesc_s390_te_linux64 = result;
++}
+Index: gdb-7.6.1/gdb/features/s390-te-linux64.xml
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/features/s390-te-linux64.xml
+@@ -0,0 +1,25 @@
++<?xml version="1.0"?>
++<!-- Copyright (C) 2010-2013 Free Software Foundation, Inc.
++
++     Copying and distribution of this file, with or without modification,
++     are permitted in any medium without royalty provided the copyright
++     notice and this notice are preserved.  -->
++
++<!-- S/390 31-bit user-level code on a machine operating
++     in z/Architecture mode.  -->
++
++<!DOCTYPE target SYSTEM "gdb-target.dtd">
++<target>
++  <architecture>s390:31-bit</architecture>
++  <xi:include href="s390-core64.xml"/>
++  <xi:include href="s390-acr.xml"/>
++  <xi:include href="s390-fpr.xml"/>
++
++  <feature name="org.gnu.gdb.s390.linux">
++    <reg name="orig_r2" bitsize="32" type="uint32" group="system"/>
++    <reg name="last_break" bitsize="32" type="code_ptr" group="system" save-restore="no"/>
++    <reg name="system_call" bitsize="32" type="uint32" group="system"/>
++  </feature>
++
++  <xi:include href="s390-tdb.xml"/>
++</target>
+Index: gdb-7.6.1/gdb/features/s390x-te-linux64.c
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/features/s390x-te-linux64.c
+@@ -0,0 +1,102 @@
++/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
++  Original: s390x-te-linux64.xml */
++
++#include "defs.h"
++#include "osabi.h"
++#include "target-descriptions.h"
++
++struct target_desc *tdesc_s390x_te_linux64;
++static void
++initialize_tdesc_s390x_te_linux64 (void)
++{
++  struct target_desc *result = allocate_target_description ();
++  struct tdesc_feature *feature;
++
++  set_tdesc_architecture (result, bfd_scan_arch ("s390:64-bit"));
++
++  feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core");
++  tdesc_create_reg (feature, "pswm", 0, 1, "psw", 64, "uint64");
++  tdesc_create_reg (feature, "pswa", 1, 1, "psw", 64, "uint64");
++  tdesc_create_reg (feature, "r0", 2, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r1", 3, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r2", 4, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r3", 5, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r4", 6, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r5", 7, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r6", 8, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r7", 9, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r8", 10, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r9", 11, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r10", 12, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r11", 13, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r12", 14, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r13", 15, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r14", 16, 1, "general", 64, "uint64");
++  tdesc_create_reg (feature, "r15", 17, 1, "general", 64, "uint64");
++
++  feature = tdesc_create_feature (result, "org.gnu.gdb.s390.acr");
++  tdesc_create_reg (feature, "acr0", 18, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr1", 19, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr2", 20, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr3", 21, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr4", 22, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr5", 23, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr6", 24, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr7", 25, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr8", 26, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr9", 27, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr10", 28, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr11", 29, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr12", 30, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr13", 31, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr14", 32, 1, "access", 32, "uint32");
++  tdesc_create_reg (feature, "acr15", 33, 1, "access", 32, "uint32");
++
++  feature = tdesc_create_feature (result, "org.gnu.gdb.s390.fpr");
++  tdesc_create_reg (feature, "fpc", 34, 1, "float", 32, "uint32");
++  tdesc_create_reg (feature, "f0", 35, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f1", 36, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f2", 37, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f3", 38, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f4", 39, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f5", 40, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f6", 41, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f7", 42, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f8", 43, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f9", 44, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f10", 45, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f11", 46, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f12", 47, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f13", 48, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f14", 49, 1, "float", 64, "ieee_double");
++  tdesc_create_reg (feature, "f15", 50, 1, "float", 64, "ieee_double");
++
++  feature = tdesc_create_feature (result, "org.gnu.gdb.s390.linux");
++  tdesc_create_reg (feature, "orig_r2", 51, 1, "system", 64, "uint64");
++  tdesc_create_reg (feature, "last_break", 52, 0, "system", 64, "code_ptr");
++  tdesc_create_reg (feature, "system_call", 53, 1, "system", 32, "uint32");
++
++  feature = tdesc_create_feature (result, "org.gnu.gdb.s390.tdb");
++  tdesc_create_reg (feature, "tdb0", 54, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tac", 55, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tct", 56, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "atia", 57, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr0", 58, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr1", 59, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr2", 60, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr3", 61, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr4", 62, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr5", 63, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr6", 64, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr7", 65, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr8", 66, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr9", 67, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr10", 68, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr11", 69, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr12", 70, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr13", 71, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr14", 72, 1, "tdb", 64, "uint64");
++  tdesc_create_reg (feature, "tr15", 73, 1, "tdb", 64, "uint64");
++
++  tdesc_s390x_te_linux64 = result;
++}
+Index: gdb-7.6.1/gdb/features/s390x-te-linux64.xml
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/features/s390x-te-linux64.xml
+@@ -0,0 +1,24 @@
++<?xml version="1.0"?>
++<!-- Copyright (C) 2010-2013 Free Software Foundation, Inc.
++
++     Copying and distribution of this file, with or without modification,
++     are permitted in any medium without royalty provided the copyright
++     notice and this notice are preserved.  -->
++
++<!-- S/390 64-bit user-level code.  -->
++
++<!DOCTYPE target SYSTEM "gdb-target.dtd">
++<target>
++  <architecture>s390:64-bit</architecture>
++  <xi:include href="s390x-core64.xml"/>
++  <xi:include href="s390-acr.xml"/>
++  <xi:include href="s390-fpr.xml"/>
++
++  <feature name="org.gnu.gdb.s390.linux">
++    <reg name="orig_r2" bitsize="64" type="uint64" group="system"/>
++    <reg name="last_break" bitsize="64" type="code_ptr" group="system" save-restore="no"/>
++    <reg name="system_call" bitsize="32" type="uint32" group="system"/>
++  </feature>
++
++  <xi:include href="s390-tdb.xml"/>
++</target>
+Index: gdb-7.6.1/gdb/gdbserver/Makefile.in
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbserver/Makefile.in
++++ gdb-7.6.1/gdb/gdbserver/Makefile.in
+@@ -329,6 +329,9 @@ clean:
+ 	rm -f powerpc-isa205-altivec32l.c powerpc-isa205-vsx32l.c powerpc-isa205-altivec64l.c
+ 	rm -f powerpc-isa205-vsx64l.c
+ 	rm -f s390-linux32.c s390-linux64.c s390x-linux64.c
++	rm -f s390-linux32v1.c s390-linux32v2.c s390-linux64v1.c
++	rm -f s390-linux64v2.c s390x-linux64v1.c s390x-linux64v2.c
++	rm -f s390-te-linux32.c s390-te-linux64.c
+ 	rm -f tic6x-c64xp-linux.c tic6x-c64x-linux.c tic6x-c62x-linux.c
+ 	rm -f xml-builtin.c stamp-xml
+ 	rm -f i386-avx.c i386-avx-linux.c
+@@ -658,12 +661,16 @@ s390-linux64v1.c : $(srcdir)/../regforma
+ 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390-linux64v1.dat s390-linux64v1.c
+ s390-linux64v2.c : $(srcdir)/../regformats/s390-linux64v2.dat $(regdat_sh)
+ 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390-linux64v2.dat s390-linux64v2.c
++s390-te-linux64.c : $(srcdir)/../regformats/s390-te-linux64.dat $(regdat_sh)
++	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390-te-linux64.dat s390-te-linux64.c
+ s390x-linux64.c : $(srcdir)/../regformats/s390x-linux64.dat $(regdat_sh)
+ 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390x-linux64.dat s390x-linux64.c
+ s390x-linux64v1.c : $(srcdir)/../regformats/s390x-linux64v1.dat $(regdat_sh)
+ 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390x-linux64v1.dat s390x-linux64v1.c
+ s390x-linux64v2.c : $(srcdir)/../regformats/s390x-linux64v2.dat $(regdat_sh)
+ 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390x-linux64v2.dat s390x-linux64v2.c
++s390x-te-linux64.c : $(srcdir)/../regformats/s390x-te-linux64.dat $(regdat_sh)
++	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/s390x-te-linux64.dat s390x-te-linux64.c
+ 
+ tic6x-c64xp-linux.c : $(srcdir)/../regformats/tic6x-c64xp-linux.dat $(regdat_sh)
+ 	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/tic6x-c64xp-linux.dat tic6x-c64xp-linux.c
+Index: gdb-7.6.1/gdb/gdbserver/configure.srv
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbserver/configure.srv
++++ gdb-7.6.1/gdb/gdbserver/configure.srv
+@@ -259,9 +259,11 @@ case "${target}" in
+ 			srv_regobj="${srv_regobj} s390-linux64.o"
+ 			srv_regobj="${srv_regobj} s390-linux64v1.o"
+ 			srv_regobj="${srv_regobj} s390-linux64v2.o"
++			srv_regobj="${srv_regobj} s390-te-linux64.o"
+ 			srv_regobj="${srv_regobj} s390x-linux64.o"
+ 			srv_regobj="${srv_regobj} s390x-linux64v1.o"
+ 			srv_regobj="${srv_regobj} s390x-linux64v2.o"
++			srv_regobj="${srv_regobj} s390x-te-linux64.o"
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-s390-low.o linux-procfs.o"
+ 			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_xmlfiles="s390-linux32.xml"
+@@ -270,14 +272,17 @@ case "${target}" in
+ 			srv_xmlfiles="${srv_xmlfiles} s390-linux64.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} s390-linux64v1.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} s390-linux64v2.xml"
++			srv_xmlfiles="${srv_xmlfiles} s390-te-linux64.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} s390x-linux64.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} s390x-linux64v1.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} s390x-linux64v2.xml"
++			srv_xmlfiles="${srv_xmlfiles} s390x-te-linux64.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} s390-core32.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} s390-core64.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} s390x-core64.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} s390-acr.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} s390-fpr.xml"
++			srv_xmlfiles="${srv_xmlfiles} s390-tdb.xml"
+ 			srv_linux_usrregs=yes
+ 			srv_linux_regsets=yes
+ 			srv_linux_thread_db=yes
+Index: gdb-7.6.1/gdb/gdbserver/linux-s390-low.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbserver/linux-s390-low.c
++++ gdb-7.6.1/gdb/gdbserver/linux-s390-low.c
+@@ -59,6 +59,12 @@ void init_registers_s390x_linux64v1 (voi
+ /* Defined in auto-generated file s390x-linux64v2.c.  */
+ void init_registers_s390x_linux64v2 (void);
+ 
++/* Defined in auto-generated file s390x-te-linux64.c.  */
++void init_registers_s390x_te_linux64 (void);
++
++/* Defined in auto-generated file s390-te-linux64.c.  */
++void init_registers_s390_te_linux64 (void);
++
+ #define s390_num_regs 52
+ 
+ static int s390_regmap[] = {
+@@ -365,10 +371,10 @@ s390_check_regset (int pid, int regset,
+   iov.iov_base = buf;
+   iov.iov_len = regsize;
+ 
+-  if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) < 0)
+-    return 0;
+-  else
++  if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) >= 0
++      || errno == ENODATA)
+     return 1;
++  return 0;
+ }
+ 
+ static void
+@@ -382,6 +388,7 @@ s390_arch_setup (void)
+     = s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
+   int have_regset_system_call
+     = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
++  int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256);
+ 
+   /* Update target_regsets according to available register sets.  */
+   for (regset = target_regsets; regset->fill_function != NULL; regset++)
+@@ -394,6 +401,8 @@ s390_arch_setup (void)
+ 	case NT_S390_SYSTEM_CALL:
+ 	  regset->size = have_regset_system_call? 4 : 0;
+ 	  break;
++	case NT_S390_TDB:
++	  regset->size = have_regset_tdb ? 256 : 0;
+ 	default:
+ 	  break;
+ 	}
+@@ -421,6 +430,8 @@ s390_arch_setup (void)
+ 
+     if (pswm & 1)
+       {
++	if (have_regset_tdb)
++	  init_registers_s390x_te_linux64 ();
+ 	if (have_regset_system_call)
+ 	  init_registers_s390x_linux64v2 ();
+ 	else if (have_regset_last_break)
+@@ -433,6 +444,8 @@ s390_arch_setup (void)
+        using the full 64-bit GPRs.  */
+     else if (s390_get_hwcap () & HWCAP_S390_HIGH_GPRS)
+       {
++	if (have_regset_tdb)
++	  init_registers_s390_te_linux64 ();
+ 	if (have_regset_system_call)
+ 	  init_registers_s390_linux64v2 ();
+ 	else if (have_regset_last_break)
+Index: gdb-7.6.1/gdb/regformats/s390-te-linux64.dat
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/regformats/s390-te-linux64.dat
+@@ -0,0 +1,94 @@
++# DO NOT EDIT: generated from s390-te-linux64.xml
++name:s390_te_linux64
++xmltarget:s390-te-linux64.xml
++expedite:r14,r15,pswa
++32:pswm
++32:pswa
++32:r0h
++32:r0l
++32:r1h
++32:r1l
++32:r2h
++32:r2l
++32:r3h
++32:r3l
++32:r4h
++32:r4l
++32:r5h
++32:r5l
++32:r6h
++32:r6l
++32:r7h
++32:r7l
++32:r8h
++32:r8l
++32:r9h
++32:r9l
++32:r10h
++32:r10l
++32:r11h
++32:r11l
++32:r12h
++32:r12l
++32:r13h
++32:r13l
++32:r14h
++32:r14l
++32:r15h
++32:r15l
++32:acr0
++32:acr1
++32:acr2
++32:acr3
++32:acr4
++32:acr5
++32:acr6
++32:acr7
++32:acr8
++32:acr9
++32:acr10
++32:acr11
++32:acr12
++32:acr13
++32:acr14
++32:acr15
++32:fpc
++64:f0
++64:f1
++64:f2
++64:f3
++64:f4
++64:f5
++64:f6
++64:f7
++64:f8
++64:f9
++64:f10
++64:f11
++64:f12
++64:f13
++64:f14
++64:f15
++32:orig_r2
++32:last_break
++32:system_call
++64:tdb0
++64:tac
++64:tct
++64:atia
++64:tr0
++64:tr1
++64:tr2
++64:tr3
++64:tr4
++64:tr5
++64:tr6
++64:tr7
++64:tr8
++64:tr9
++64:tr10
++64:tr11
++64:tr12
++64:tr13
++64:tr14
++64:tr15
+Index: gdb-7.6.1/gdb/regformats/s390x-te-linux64.dat
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/regformats/s390x-te-linux64.dat
+@@ -0,0 +1,78 @@
++# DO NOT EDIT: generated from s390x-te-linux64.xml
++name:s390x_te_linux64
++xmltarget:s390x-te-linux64.xml
++expedite:r14,r15,pswa
++64:pswm
++64:pswa
++64:r0
++64:r1
++64:r2
++64:r3
++64:r4
++64:r5
++64:r6
++64:r7
++64:r8
++64:r9
++64:r10
++64:r11
++64:r12
++64:r13
++64:r14
++64:r15
++32:acr0
++32:acr1
++32:acr2
++32:acr3
++32:acr4
++32:acr5
++32:acr6
++32:acr7
++32:acr8
++32:acr9
++32:acr10
++32:acr11
++32:acr12
++32:acr13
++32:acr14
++32:acr15
++32:fpc
++64:f0
++64:f1
++64:f2
++64:f3
++64:f4
++64:f5
++64:f6
++64:f7
++64:f8
++64:f9
++64:f10
++64:f11
++64:f12
++64:f13
++64:f14
++64:f15
++64:orig_r2
++64:last_break
++32:system_call
++64:tdb0
++64:tac
++64:tct
++64:atia
++64:tr0
++64:tr1
++64:tr2
++64:tr3
++64:tr4
++64:tr5
++64:tr6
++64:tr7
++64:tr8
++64:tr9
++64:tr10
++64:tr11
++64:tr12
++64:tr13
++64:tr14
++64:tr15
+Index: gdb-7.6.1/gdb/s390-nat.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/s390-nat.c
++++ gdb-7.6.1/gdb/s390-nat.c
+@@ -37,10 +37,6 @@
+ #include <sys/ucontext.h>
+ #include <elf.h>
+ 
+-#ifndef HWCAP_S390_HIGH_GPRS
+-#define HWCAP_S390_HIGH_GPRS 512
+-#endif
+-
+ #ifndef PTRACE_GETREGSET
+ #define PTRACE_GETREGSET 0x4204
+ #endif
+@@ -51,6 +47,7 @@
+ 
+ static int have_regset_last_break = 0;
+ static int have_regset_system_call = 0;
++static int have_regset_tdb = 0;
+ 
+ /* Map registers to gregset/ptrace offsets.
+    These arrays are defined in s390-tdep.c.  */
+@@ -72,7 +69,7 @@ s390_native_supply (struct regcache *reg
+ 		    const gdb_byte *regp)
+ {
+   for (; map[0] >= 0; map += 2)
+-    regcache_raw_supply (regcache, map[1], regp + map[0]);
++    regcache_raw_supply (regcache, map[1], regp ? regp + map[0] : NULL);
+ }
+ 
+ /* Collect the register REGNO out of the regset described by MAP from
+@@ -315,9 +312,14 @@ fetch_regset (struct regcache *regcache,
+   iov.iov_len = regsize;
+ 
+   if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
+-    perror_with_name (_("Couldn't get register set"));
+-
+-  s390_native_supply (regcache, regmap, buf);
++    {
++      if (errno == ENODATA)
++	s390_native_supply (regcache, regmap, NULL);
++      else
++	perror_with_name (_("Couldn't get register set"));
++    }
++  else
++    s390_native_supply (regcache, regmap, buf);
+ }
+ 
+ /* Store all registers in the kernel's register set whose number is REGSET,
+@@ -353,10 +355,10 @@ check_regset (int tid, int regset, int r
+   iov.iov_base = buf;
+   iov.iov_len = regsize;
+ 
+-  if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0)
+-    return 0;
+-  else
++  if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) >= 0
++      || errno == ENODATA)
+     return 1;
++  return 0;
+ }
+ 
+ /* Fetch register REGNUM from the child process.  If REGNUM is -1, do
+@@ -383,6 +385,11 @@ s390_linux_fetch_inferior_registers (str
+     if (regnum == -1 || regnum == S390_SYSTEM_CALL_REGNUM)
+       fetch_regset (regcache, tid, NT_S390_SYSTEM_CALL, 4,
+ 		    s390_regmap_system_call);
++
++  if (have_regset_tdb)
++    if (regnum == -1 || S390_IS_TDBREGSET_REGNUM (regnum))
++      fetch_regset (regcache, tid, NT_S390_TDB, s390_sizeof_tdbregset,
++		    s390_regmap_tdb);
+ }
+ 
+ /* Store register REGNUM back into the child process.  If REGNUM is
+@@ -625,6 +632,8 @@ s390_read_description (struct target_ops
+     = check_regset (tid, NT_S390_LAST_BREAK, 8);
+   have_regset_system_call
+     = check_regset (tid, NT_S390_SYSTEM_CALL, 4);
++  have_regset_tdb
++    = check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset);
+ 
+ #ifdef __s390x__
+   /* If GDB itself is compiled as 64-bit, we are running on a machine in
+@@ -634,12 +643,14 @@ s390_read_description (struct target_ops
+      that mode, report s390 architecture with 64-bit GPRs.  */
+ 
+   if (s390_target_wordsize () == 8)
+-    return (have_regset_system_call? tdesc_s390x_linux64v2 :
++    return (have_regset_tdb ? tdesc_s390x_te_linux64 :
++	    have_regset_system_call? tdesc_s390x_linux64v2 :
+ 	    have_regset_last_break? tdesc_s390x_linux64v1 :
+ 	    tdesc_s390x_linux64);
+ 
+   if (s390_get_hwcap () & HWCAP_S390_HIGH_GPRS)
+-    return (have_regset_system_call? tdesc_s390_linux64v2 :
++    return (have_regset_tdb ? tdesc_s390_te_linux64 :
++	    have_regset_system_call? tdesc_s390_linux64v2 :
+ 	    have_regset_last_break? tdesc_s390_linux64v1 :
+ 	    tdesc_s390_linux64);
+ #endif
+Index: gdb-7.6.1/gdb/s390-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/s390-tdep.c
++++ gdb-7.6.1/gdb/s390-tdep.c
+@@ -44,6 +44,7 @@
+ #include "prologue-value.h"
+ #include "linux-tdep.h"
+ #include "s390-tdep.h"
++#include "auxv.h"
+ 
+ #include "stap-probe.h"
+ #include "ax.h"
+@@ -51,6 +52,7 @@
+ #include "user-regs.h"
+ #include "cli/cli-utils.h"
+ #include <ctype.h>
++#include <elf.h>
+ 
+ #include "features/s390-linux32.c"
+ #include "features/s390-linux32v1.c"
+@@ -58,9 +60,11 @@
+ #include "features/s390-linux64.c"
+ #include "features/s390-linux64v1.c"
+ #include "features/s390-linux64v2.c"
++#include "features/s390-te-linux64.c"
+ #include "features/s390x-linux64.c"
+ #include "features/s390x-linux64v1.c"
+ #include "features/s390x-linux64v2.c"
++#include "features/s390x-te-linux64.c"
+ 
+ /* The tdep structure.  */
+ 
+@@ -568,6 +572,30 @@ const short s390_regmap_system_call[] =
+     -1, -1
+   };
+ 
++const short s390_regmap_tdb[] =
++  {
++    0x00, S390_TDB_DWORD0_REGNUM,
++    0x08, S390_TDB_ABORT_CODE_REGNUM,
++    0x10, S390_TDB_CONFLICT_TOKEN_REGNUM,
++    0x18, S390_TDB_ATIA_REGNUM,
++    0x80, S390_TDB_R0_REGNUM,
++    0x88, S390_TDB_R1_REGNUM,
++    0x90, S390_TDB_R2_REGNUM,
++    0x98, S390_TDB_R3_REGNUM,
++    0xa0, S390_TDB_R4_REGNUM,
++    0xa8, S390_TDB_R5_REGNUM,
++    0xb0, S390_TDB_R6_REGNUM,
++    0xb8, S390_TDB_R7_REGNUM,
++    0xc0, S390_TDB_R8_REGNUM,
++    0xc8, S390_TDB_R9_REGNUM,
++    0xd0, S390_TDB_R10_REGNUM,
++    0xd8, S390_TDB_R11_REGNUM,
++    0xe0, S390_TDB_R12_REGNUM,
++    0xe8, S390_TDB_R13_REGNUM,
++    0xf0, S390_TDB_R14_REGNUM,
++    0xf8, S390_TDB_R15_REGNUM,
++    -1, -1
++  };
+ 
+ 
+ /* Supply register REGNUM from the register set REGSET to register cache 
+@@ -579,7 +607,25 @@ s390_supply_regset (const struct regset
+   const short *map;
+   for (map = regset->descr; map[0] >= 0; map += 2)
+     if (regnum == -1 || regnum == map[1])
+-      regcache_raw_supply (regcache, map[1], (const char *)regs + map[0]);
++      regcache_raw_supply (regcache, map[1],
++			   regs ? (const char *)regs + map[0] : NULL);
++}
++
++/* Supply the TDB regset.  Like s390_supply_regset, but invalidate the
++   TDB registers unless the TDB format field is valid.  */
++
++static void
++s390_supply_tdb_regset (const struct regset *regset, struct regcache *regcache,
++		    int regnum, const void *regs, size_t len)
++{
++  ULONGEST tdw;
++  enum register_status ret;
++  int i;
++
++  s390_supply_regset (regset, regcache, regnum, regs, len);
++  ret = regcache_cooked_read_unsigned (regcache, S390_TDB_DWORD0_REGNUM, &tdw);
++  if (ret != REG_VALID || (tdw >> 56) != 1)
++    s390_supply_regset (regset, regcache, regnum, NULL, len);
+ }
+ 
+ /* Collect register REGNUM from the register cache REGCACHE and store
+@@ -639,6 +685,12 @@ static const struct regset s390_system_c
+   s390_collect_regset
+ };
+ 
++static const struct regset s390_tdb_regset = {
++  s390_regmap_tdb,
++  s390_supply_tdb_regset,
++  s390_collect_regset
++};
++
+ static struct core_regset_section s390_linux32_regset_sections[] =
+ {
+   { ".reg", s390_sizeof_gregset, "general-purpose" },
+@@ -687,6 +739,7 @@ static struct core_regset_section s390_l
+   { ".reg-s390-high-gprs", 16*4, "s390 GPR upper halves" },
+   { ".reg-s390-last-break", 8, "s930 last-break address" },
+   { ".reg-s390-system-call", 4, "s390 system-call" },
++  { ".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB" },
+   { NULL, 0}
+ };
+ 
+@@ -711,6 +764,7 @@ static struct core_regset_section s390x_
+   { ".reg2", s390_sizeof_fpregset, "floating-point" },
+   { ".reg-s390-last-break", 8, "s930 last-break address" },
+   { ".reg-s390-system-call", 4, "s390 system-call" },
++  { ".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB" },
+   { NULL, 0}
+ };
+ 
+@@ -739,6 +793,9 @@ s390_regset_from_core_section (struct gd
+   if (strcmp (sect_name, ".reg-s390-system-call") == 0 && sect_size >= 4)
+     return &s390_system_call_regset;
+ 
++  if (strcmp (sect_name, ".reg-s390-tdb") == 0 && sect_size >= 256)
++    return &s390_tdb_regset;
++
+   return NULL;
+ }
+ 
+@@ -750,6 +807,9 @@ s390_core_read_description (struct gdbar
+   asection *v1 = bfd_get_section_by_name (abfd, ".reg-s390-last-break");
+   asection *v2 = bfd_get_section_by_name (abfd, ".reg-s390-system-call");
+   asection *section = bfd_get_section_by_name (abfd, ".reg");
++  CORE_ADDR hwcap = 0;
++
++  target_auxv_search (target, AT_HWCAP, &hwcap);
+   if (!section)
+     return NULL;
+ 
+@@ -757,14 +817,16 @@ s390_core_read_description (struct gdbar
+     {
+     case s390_sizeof_gregset:
+       if (high_gprs)
+-	return (v2? tdesc_s390_linux64v2 :
++	return ((hwcap & HWCAP_S390_TE) ? tdesc_s390_te_linux64 :
++		v2? tdesc_s390_linux64v2 :
+ 		v1? tdesc_s390_linux64v1 : tdesc_s390_linux64);
+       else
+ 	return (v2? tdesc_s390_linux32v2 :
+ 		v1? tdesc_s390_linux32v1 : tdesc_s390_linux32);
+ 
+     case s390x_sizeof_gregset:
+-      return (v2? tdesc_s390x_linux64v2 :
++      return ((hwcap & HWCAP_S390_TE) ? tdesc_s390x_te_linux64 :
++	      v2? tdesc_s390x_linux64v2 :
+ 	      v1? tdesc_s390x_linux64v1 : tdesc_s390x_linux64);
+ 
+     default:
+@@ -3011,6 +3073,11 @@ s390_gdbarch_init (struct gdbarch_info i
+ 	"r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
+ 	"r8h", "r9h", "r10h", "r11h", "r12h", "r13h", "r14h", "r15h"
+       };
++      static const char *const tdb_regs[] = {
++	"tdb0", "tac", "tct", "atia",
++	"tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7",
++	"tr8", "tr9", "tr10", "tr11", "tr12", "tr13", "tr14", "tr15"
++      };
+       const struct tdesc_feature *feature;
+       int i, valid_p = 1;
+ 
+@@ -3088,6 +3155,16 @@ s390_gdbarch_init (struct gdbarch_info i
+ 	    valid_p = 0;
+ 	}
+ 
++      /* Transaction diagnostic block.  */
++      feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.tdb");
++      if (feature)
++	{
++	  for (i = 0; i < ARRAY_SIZE (tdb_regs); i++)
++	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
++						S390_TDB_DWORD0_REGNUM + i,
++						tdb_regs[i]);
++	}
++
+       if (!valid_p)
+ 	{
+ 	  tdesc_data_cleanup (tdesc_data);
+@@ -3304,7 +3381,9 @@ _initialize_s390_tdep (void)
+   initialize_tdesc_s390_linux64 ();
+   initialize_tdesc_s390_linux64v1 ();
+   initialize_tdesc_s390_linux64v2 ();
++  initialize_tdesc_s390_te_linux64 ();
+   initialize_tdesc_s390x_linux64 ();
+   initialize_tdesc_s390x_linux64v1 ();
+   initialize_tdesc_s390x_linux64v2 ();
++  initialize_tdesc_s390x_te_linux64 ();
+ }
+Index: gdb-7.6.1/gdb/s390-tdep.h
+===================================================================
+--- gdb-7.6.1.orig/gdb/s390-tdep.h
++++ gdb-7.6.1/gdb/s390-tdep.h
+@@ -19,6 +19,16 @@
+ #ifndef S390_TDEP_H
+ #define S390_TDEP_H
+ 
++/* Hardware capabilities. */
++
++#ifndef HWCAP_S390_HIGH_GPRS
++#define HWCAP_S390_HIGH_GPRS 512
++#endif
++
++#ifndef HWCAP_S390_TE
++#define HWCAP_S390_TE 1024
++#endif
++
+ /* Register information.  */
+ 
+ /* Program Status Word.  */
+@@ -98,8 +108,29 @@
+ #define S390_ORIG_R2_REGNUM 67
+ #define S390_LAST_BREAK_REGNUM 68
+ #define S390_SYSTEM_CALL_REGNUM 69
++/* Transaction diagnostic block.  */
++#define S390_TDB_DWORD0_REGNUM 70
++#define S390_TDB_ABORT_CODE_REGNUM 71
++#define S390_TDB_CONFLICT_TOKEN_REGNUM 72
++#define S390_TDB_ATIA_REGNUM 73
++#define S390_TDB_R0_REGNUM 74
++#define S390_TDB_R1_REGNUM 75
++#define S390_TDB_R2_REGNUM 76
++#define S390_TDB_R3_REGNUM 77
++#define S390_TDB_R4_REGNUM 78
++#define S390_TDB_R5_REGNUM 79
++#define S390_TDB_R6_REGNUM 80
++#define S390_TDB_R7_REGNUM 81
++#define S390_TDB_R8_REGNUM 82
++#define S390_TDB_R9_REGNUM 83
++#define S390_TDB_R10_REGNUM 84
++#define S390_TDB_R11_REGNUM 85
++#define S390_TDB_R12_REGNUM 86
++#define S390_TDB_R13_REGNUM 87
++#define S390_TDB_R14_REGNUM 88
++#define S390_TDB_R15_REGNUM 89
+ /* Total.  */
+-#define S390_NUM_REGS 70
++#define S390_NUM_REGS 90
+ 
+ /* Special register usage.  */
+ #define S390_SP_REGNUM S390_R15_REGNUM
+@@ -114,6 +145,9 @@
+ #define S390_IS_FPREGSET_REGNUM(i)			\
+   ((i) >= S390_FPC_REGNUM && (i) <= S390_F15_REGNUM)
+ 
++#define S390_IS_TDBREGSET_REGNUM(i)				\
++  ((i) >= S390_TDB_DWORD0_REGNUM && (i) <= S390_TDB_R15_REGNUM)
++
+ /* Core file register sets, defined in s390-tdep.c.  */
+ #define s390_sizeof_gregset 0x90
+ extern const short s390_regmap_gregset[];
+@@ -124,6 +158,8 @@ extern const short s390_regmap_fpregset[
+ extern const short s390_regmap_last_break[];
+ extern const short s390x_regmap_last_break[];
+ extern const short s390_regmap_system_call[];
++extern const short s390_regmap_tdb[];
++#define s390_sizeof_tdbregset 0x100
+ 
+ /* GNU/Linux target descriptions.  */
+ extern struct target_desc *tdesc_s390_linux32;
+@@ -132,9 +168,11 @@ extern struct target_desc *tdesc_s390_li
+ extern struct target_desc *tdesc_s390_linux64;
+ extern struct target_desc *tdesc_s390_linux64v1;
+ extern struct target_desc *tdesc_s390_linux64v2;
++extern struct target_desc *tdesc_s390_te_linux64;
+ extern struct target_desc *tdesc_s390x_linux64;
+ extern struct target_desc *tdesc_s390x_linux64v1;
+ extern struct target_desc *tdesc_s390x_linux64v2;
++extern struct target_desc *tdesc_s390x_te_linux64;
+ 
+ #endif
+ 
+Index: gdb-7.6.1/gdb/testsuite/gdb.arch/s390-tdbregs.c
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.arch/s390-tdbregs.c
+@@ -0,0 +1,64 @@
++/* Copyright 2008-2013 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   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/>.  */
++
++#include <stdio.h>
++
++static void
++my_tbegin ()
++{
++  __asm__ volatile
++    ( "1:  .byte 0xe5,0x60,0x00,0x00,0xff,0x00\n"
++      "    jnz 1b"
++      : /* no return value */
++      : /* no inputs */
++      : "cc", "memory" );
++}
++
++static void
++my_tend ()
++{
++  __asm__ volatile
++    ( "    .byte 0xb2,0xf8,0x00,0x00"
++      : /* no return value */
++      : /* no inputs */
++      : "cc", "memory" );
++}
++
++void
++try_transaction (void)
++{
++  my_tbegin ();
++  my_tend ();
++}
++
++void
++crash_in_transaction (void)
++{
++  volatile char *p = 0;
++
++  my_tbegin ();
++  *p = 5;			/* FAULT */
++  my_tend ();
++}
++
++int
++main (int argc, char *argv[])
++{
++  try_transaction ();
++  crash_in_transaction ();
++  return 0;
++}
+Index: gdb-7.6.1/gdb/testsuite/gdb.arch/s390-tdbregs.exp
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.arch/s390-tdbregs.exp
+@@ -0,0 +1,75 @@
++# Copyright 2004-2013 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/>.
++
++# Please email any bugs, comments, and/or additions to this file to:
++# bug-gdb@gnu.org
++
++# This file is part of the gdb testsuite.
++
++
++if { ![istarget s390-*-*] && ![istarget s390x-*-* ] } {
++    verbose "Skipping s390 TDB register tests."
++    return
++}
++
++set testfile "s390-tdbregs"
++set srcfile ${testfile}.c
++set binfile ${objdir}/${subdir}/${testfile}
++
++if { [get_compiler_info] } {
++    return -1
++}
++
++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
++      executable [list debug]] != "" } {
++    fail "compile failed"
++    return
++}
++
++gdb_exit
++gdb_start
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_load ${binfile}
++
++if { ![runto_main] } then {
++    gdb_suppress_tests
++}
++
++gdb_test_multiple "next" "check for TE support" {
++    -re "Program received signal SIGILL,.*\r\n$gdb_prompt $" {
++	unsupported "No TE support."
++	return
++    }
++    -re "\[0-9\]+.*\r\n$gdb_prompt $" {
++	pass "TE support available"
++    }
++    -re "$gdb_prompt $" {
++	unsupported "No TE support (unknown error)."
++	return
++    }
++}
++
++set crashline [gdb_get_line_number "FAULT"]
++
++gdb_test "print \$tdb0" "\\\$\[0-9\]+ = <unavailable>" "tdb0 unavailable"
++gdb_test "print \$tr0" "\\\$\[0-9\]+ = <unavailable>" "tr0 unavailable"
++gdb_test "next" \
++    "Program received signal SIGSEGV, .*" \
++    "crash in transaction"
++gdb_test "print/x \$tdb0" "\\\$\[0-9\]+ = 0x1.*" "tdb0 available"
++gdb_test "set print symbol-filename" "" "set print symbol-filename"
++gdb_test "print/a \$atia" \
++    "<crash_in_transaction.*:$crashline>" \
++    "ATIA points to crash"
diff --git a/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-4of9.patch b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-4of9.patch
new file mode 100644
index 0000000..4b19bb2
--- /dev/null
+++ b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-4of9.patch
@@ -0,0 +1,148 @@
+From 6682d9595ed8d9b9bba5470bfd7fd1ccd378f19a Mon Sep 17 00:00:00 2001
+From: Andreas Arnez <arnez at linux dot vnet dot ibm dot com>
+Date: Tue, 5 Nov 2013 18:43:50 +0100
+Subject: [PATCH] S390: Fix TDB regset recognition
+
+When checking for the presence of the TDB regset, the current code
+interprets ENODATA from PTRACE_GETREGSET as an indication that the TDB
+regset *could* occur on this system, but the inferior stopped outside
+a transaction.  However, the Linux kernel actually reports ENODATA
+even on systems without the transactional execution facility.  Thus
+the logic is now changed to check the TE field in the HWCAP as well.
+
+This version also checks the existence of the TDB regset -- just to be
+on the safe side when running on TE-enabled hardware with a kernel
+that does not offer the TDB regset for some reason.
+
+gdb/
+	* s390-linux-nat.c (s390_read_description): Consider the TE field
+	in the HWCAP for determining 'have_regset_tdb'.
+
+gdbserver/
+	* linux-s390-low.c (HWCAP_S390_TE): New define.
+	(s390_arch_setup): Consider the TE field in the HWCAP for
+	determining 'have_regset_tdb'.
+---
+ gdb/ChangeLog                  |  5 +++++
+ gdb/gdbserver/ChangeLog        |  6 ++++++
+ gdb/gdbserver/linux-s390-low.c | 48 ++++++++++++++++++++++++++----------------
+ gdb/s390-linux-nat.c           |  5 +++--
+ 4 files changed, 44 insertions(+), 20 deletions(-)
+
+Index: gdb-7.6.1/gdb/gdbserver/linux-s390-low.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbserver/linux-s390-low.c
++++ gdb-7.6.1/gdb/gdbserver/linux-s390-low.c
+@@ -32,6 +32,10 @@
+ #define HWCAP_S390_HIGH_GPRS 512
+ #endif
+ 
++#ifndef HWCAP_S390_TE
++#define HWCAP_S390_TE 1024
++#endif
++
+ #ifndef PTRACE_GETREGSET
+ #define PTRACE_GETREGSET 0x4204
+ #endif
+@@ -390,23 +394,6 @@ s390_arch_setup (void)
+     = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
+   int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256);
+ 
+-  /* Update target_regsets according to available register sets.  */
+-  for (regset = target_regsets; regset->fill_function != NULL; regset++)
+-    if (regset->get_request == PTRACE_GETREGSET)
+-      switch (regset->nt_type)
+-	{
+-	case NT_S390_LAST_BREAK:
+-	  regset->size = have_regset_last_break? 8 : 0;
+-	  break;
+-	case NT_S390_SYSTEM_CALL:
+-	  regset->size = have_regset_system_call? 4 : 0;
+-	  break;
+-	case NT_S390_TDB:
+-	  regset->size = have_regset_tdb ? 256 : 0;
+-	default:
+-	  break;
+-	}
+-
+   /* Assume 31-bit inferior process.  */
+   if (have_regset_system_call)
+     init_registers_s390_linux32v2 ();
+@@ -424,6 +411,7 @@ s390_arch_setup (void)
+   {
+     unsigned int pswm;
+     struct regcache *regcache = new_register_cache ();
++
+     fetch_inferior_registers (regcache, find_regno ("pswm"));
+     collect_register_by_name (regcache, "pswm", &pswm);
+     free_register_cache (regcache);
+@@ -431,8 +419,12 @@ s390_arch_setup (void)
+     if (pswm & 1)
+       {
+ 	if (have_regset_tdb)
++	  have_regset_tdb =
++	    (s390_get_hwcap () & HWCAP_S390_TE) != 0;
++
++	if (have_regset_tdb)
+ 	  init_registers_s390x_te_linux64 ();
+-	if (have_regset_system_call)
++	else if (have_regset_system_call)
+ 	  init_registers_s390x_linux64v2 ();
+ 	else if (have_regset_last_break)
+ 	  init_registers_s390x_linux64v1 ();
+@@ -445,6 +437,9 @@ s390_arch_setup (void)
+     else if (s390_get_hwcap () & HWCAP_S390_HIGH_GPRS)
+       {
+ 	if (have_regset_tdb)
++	  have_regset_tdb = (s390_get_hwcap () & HWCAP_S390_TE) != 0;
++
++	if (have_regset_tdb)
+ 	  init_registers_s390_te_linux64 ();
+ 	if (have_regset_system_call)
+ 	  init_registers_s390_linux64v2 ();
+@@ -458,6 +453,22 @@ s390_arch_setup (void)
+       }
+   }
+ #endif
++  /* Update target_regsets according to available register sets.  */
++  for (regset = target_regsets; regset->fill_function != NULL; regset++)
++    if (regset->get_request == PTRACE_GETREGSET)
++      switch (regset->nt_type)
++	{
++	case NT_S390_LAST_BREAK:
++	  regset->size = have_regset_last_break? 8 : 0;
++	  break;
++	case NT_S390_SYSTEM_CALL:
++	  regset->size = have_regset_system_call? 4 : 0;
++	  break;
++	case NT_S390_TDB:
++	  regset->size = have_regset_tdb ? 256 : 0;
++	default:
++	  break;
++	}
+ }
+ 
+ 
+Index: gdb-7.6.1/gdb/s390-nat.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/s390-nat.c
++++ gdb-7.6.1/gdb/s390-nat.c
+@@ -632,8 +632,6 @@ s390_read_description (struct target_ops
+     = check_regset (tid, NT_S390_LAST_BREAK, 8);
+   have_regset_system_call
+     = check_regset (tid, NT_S390_SYSTEM_CALL, 4);
+-  have_regset_tdb
+-    = check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset);
+ 
+ #ifdef __s390x__
+   /* If GDB itself is compiled as 64-bit, we are running on a machine in
+@@ -642,6 +640,9 @@ s390_read_description (struct target_ops
+      addressing mode, but the kernel supports using 64-bit registers in
+      that mode, report s390 architecture with 64-bit GPRs.  */
+ 
++  have_regset_tdb = (s390_get_hwcap () & HWCAP_S390_TE) ?
++    check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset) : 0;
++
+   if (s390_target_wordsize () == 8)
+     return (have_regset_tdb ? tdesc_s390x_te_linux64 :
+ 	    have_regset_system_call? tdesc_s390x_linux64v2 :
diff --git a/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-5of9.patch b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-5of9.patch
new file mode 100644
index 0000000..11abcbb
--- /dev/null
+++ b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-5of9.patch
@@ -0,0 +1,68 @@
+From 098dbe61246fd65ea5e3825d77afb31d52c43153 Mon Sep 17 00:00:00 2001
+From: Andreas Arnez <arnez@linux.vnet.ibm.com>
+Date: Fri, 12 Dec 2014 14:14:20 +0100
+Subject: [PATCH 7/9] gdbserver: Prevent stale/random values in register cache
+
+When fetch_inferior_registers does not update all registers, this
+patch assures that no stale register values remain in the register
+cache.  On Linux platforms using the regsets interface, when one of
+the ptrace calls used for fetching the register values returns an
+error, this patch also avoids copying the random data returned from
+ptrace into the register cache.  All unfetched registers are marked
+"unavailable" instead.
+
+gdb/gdbserver/ChangeLog:
+
+	* linux-low.c (regsets_fetch_inferior_registers): Do not invoke
+	the regset's store function when ptrace returned an error.
+	* regcache.c (get_thread_regcache): Invalidate register cache
+	before fetching inferior's registers.
+---
+ gdb/gdbserver/ChangeLog   |  7 +++++++
+ gdb/gdbserver/linux-low.c | 11 ++++++-----
+ gdb/gdbserver/regcache.c  |  3 +++
+ 3 files changed, 16 insertions(+), 5 deletions(-)
+
+Index: gdb-7.6.1/gdb/gdbserver/linux-low.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbserver/linux-low.c
++++ gdb-7.6.1/gdb/gdbserver/linux-low.c
+@@ -4080,8 +4080,6 @@ regsets_fetch_inferior_registers (struct
+ 	      /* If we get EIO on a regset, do not try it again for
+ 		 this process.  */
+ 	      disabled_regsets[regset - target_regsets] = 1;
+-	      free (buf);
+-	      continue;
+ 	    }
+ 	  else
+ 	    {
+@@ -4091,9 +4089,12 @@ regsets_fetch_inferior_registers (struct
+ 	      perror (s);
+ 	    }
+ 	}
+-      else if (regset->type == GENERAL_REGS)
+-	saw_general_regs = 1;
+-      regset->store_function (regcache, buf);
++      else
++	{
++	  if (regset->type == GENERAL_REGS)
++	    saw_general_regs = 1;
++	  regset->store_function (regcache, buf);
++	}
+       regset ++;
+       free (buf);
+     }
+Index: gdb-7.6.1/gdb/gdbserver/regcache.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbserver/regcache.c
++++ gdb-7.6.1/gdb/gdbserver/regcache.c
+@@ -47,6 +47,9 @@ get_thread_regcache (struct thread_info
+       struct thread_info *saved_inferior = current_inferior;
+ 
+       current_inferior = thread;
++      /* Invalidate all registers, to prevent stale left-overs.  */
++      memset (regcache->register_status, REG_UNAVAILABLE,
++	      num_registers);
+       fetch_inferior_registers (regcache, -1);
+       current_inferior = saved_inferior;
+       regcache->registers_valid = 1;
diff --git a/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-6of9.patch b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-6of9.patch
new file mode 100644
index 0000000..397d40e
--- /dev/null
+++ b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-6of9.patch
@@ -0,0 +1,80 @@
+From feea5f36a9dd65a0ff279c71744423c419b77ada Mon Sep 17 00:00:00 2001
+From: Andreas Arnez <arnez@linux.vnet.ibm.com>
+Date: Fri, 12 Dec 2014 14:14:21 +0100
+Subject: [PATCH 8/9] gdbserver: Support read-only regsets in linux-low.c
+
+For GNU/Linux targets using the regsets interface, this change
+supports regsets that can be read but not written.  The S390 "last
+break" regset is an example.  So far it had been defined with
+regset->set_request == PTRACE_GETREGSET, such that the respective
+ptrace call does not cause any harm.  Now we just skip the whole
+read/modify/write sequence for regsets that do not define a
+fill_function.
+
+gdb/gdbserver/ChangeLog:
+
+	* linux-low.c (regsets_store_inferior_registers): Skip regsets
+	without a fill_function.
+	* linux-s390-low.c (s390_fill_last_break): Remove.
+	(s390_regsets): Set fill_function to NULL for NT_S390_LAST_BREAK.
+	(s390_arch_setup): Use regset's size instead of fill_function for
+	loop end condition.
+---
+ gdb/gdbserver/ChangeLog        |  9 +++++++++
+ gdb/gdbserver/linux-low.c      |  3 ++-
+ gdb/gdbserver/linux-s390-low.c | 14 ++++----------
+ 3 files changed, 15 insertions(+), 11 deletions(-)
+
+Index: gdb-7.6.1/gdb/gdbserver/linux-low.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbserver/linux-low.c
++++ gdb-7.6.1/gdb/gdbserver/linux-low.c
+@@ -4120,7 +4120,8 @@ regsets_store_inferior_registers (struct
+       void *buf, *data;
+       int nt_type, res;
+ 
+-      if (regset->size == 0 || disabled_regsets[regset - target_regsets])
++      if (regset->size == 0 || disabled_regsets[regset - target_regsets]
++	  || regset->fill_function == NULL)
+ 	{
+ 	  regset ++;
+ 	  continue;
+Index: gdb-7.6.1/gdb/gdbserver/linux-s390-low.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbserver/linux-s390-low.c
++++ gdb-7.6.1/gdb/gdbserver/linux-s390-low.c
+@@ -264,12 +264,6 @@ static void s390_fill_gregset (struct re
+ /* Fill and store functions for extended register sets.  */
+ 
+ static void
+-s390_fill_last_break (struct regcache *regcache, void *buf)
+-{
+-  /* Last break address is read-only.  */
+-}
+-
+-static void
+ s390_store_last_break (struct regcache *regcache, const void *buf)
+ {
+   supply_register_by_name (regcache, "last_break",
+@@ -290,9 +284,9 @@ s390_store_system_call (struct regcache
+ 
+ struct regset_info target_regsets[] = {
+   { 0, 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL },
+-  /* Last break address is read-only; do not attempt PTRACE_SETREGSET.  */
+-  { PTRACE_GETREGSET, PTRACE_GETREGSET, NT_S390_LAST_BREAK, 0,
+-    EXTENDED_REGS, s390_fill_last_break, s390_store_last_break },
++  /* Last break address is read-only; no fill function.  */
++  { PTRACE_GETREGSET, -1, NT_S390_LAST_BREAK, 0, EXTENDED_REGS,
++    NULL, s390_store_last_break },
+   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_SYSTEM_CALL, 0,
+     EXTENDED_REGS, s390_fill_system_call, s390_store_system_call },
+   { 0, 0, 0, -1, -1, NULL, NULL }
+@@ -454,7 +448,7 @@ s390_arch_setup (void)
+   }
+ #endif
+   /* Update target_regsets according to available register sets.  */
+-  for (regset = target_regsets; regset->fill_function != NULL; regset++)
++  for (regset = target_regsets; regset->size >= 0; regset++)
+     if (regset->get_request == PTRACE_GETREGSET)
+       switch (regset->nt_type)
+ 	{
diff --git a/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-7of9.patch b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-7of9.patch
new file mode 100644
index 0000000..fac2db6
--- /dev/null
+++ b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-7of9.patch
@@ -0,0 +1,76 @@
+From e5a9158d093d53f2bb1057359ac381dcdf6d4305 Mon Sep 17 00:00:00 2001
+From: Andreas Arnez <arnez@linux.vnet.ibm.com>
+Date: Fri, 12 Dec 2014 14:14:21 +0100
+Subject: [PATCH 9/9] S390: Fix gdbserver support for TDB
+
+This makes gdbserver actually provide values for the TDB registers
+when the inferior was stopped in a transaction.  The change in
+linux-low.c is needed to suppress the warning for an unavailable TDB.
+
+The test case 's390-tdbregs.exp' passes with this patch and fails
+without.
+
+gdb/gdbserver/ChangeLog:
+
+	* linux-low.c (regsets_fetch_inferior_registers): Suppress the
+	warning upon ENODATA from ptrace.
+	* linux-s390-low.c (s390_store_tdb): New.
+	(s390_regsets): Add regset for NT_S390_TDB.
+---
+ gdb/gdbserver/ChangeLog        |  7 +++++++
+ gdb/gdbserver/linux-low.c      |  6 ++++++
+ gdb/gdbserver/linux-s390-low.c | 17 +++++++++++++++++
+ 3 files changed, 30 insertions(+)
+
+Index: gdb-7.6.1/gdb/gdbserver/linux-low.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbserver/linux-low.c
++++ gdb-7.6.1/gdb/gdbserver/linux-low.c
+@@ -4183,6 +4183,12 @@ regsets_store_inferior_registers (struct
+ 	      free (buf);
+ 	      return 0;
+ 	    }
++	  else if (errno == ENODATA)
++	    {
++	      /* ENODATA may be returned if the regset is currently
++		 not "active".  This can happen in normal operation,
++		 so suppress the warning in this case.  */
++	    }
+ 	  else
+ 	    {
+ 	      perror ("Warning: ptrace(regsets_store_inferior_registers)");
+Index: gdb-7.6.1/gdb/gdbserver/linux-s390-low.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbserver/linux-s390-low.c
++++ gdb-7.6.1/gdb/gdbserver/linux-s390-low.c
+@@ -282,6 +282,20 @@ s390_store_system_call (struct regcache
+   supply_register_by_name (regcache, "system_call", buf);
+ }
+ 
++static void
++s390_store_tdb (struct regcache *regcache, const void *buf)
++{
++  int tdb0 = find_regno ("tdb0");
++  int tr0 = find_regno ("tr0");
++  int i;
++
++  for (i = 0; i < 4; i++)
++    supply_register (regcache, tdb0 + i, (const char *) buf + 8 * i);
++
++  for (i = 0; i < 16; i++)
++    supply_register (regcache, tr0 + i, (const char *) buf + 8 * (16 + i));
++}
++
+ struct regset_info target_regsets[] = {
+   { 0, 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL },
+   /* Last break address is read-only; no fill function.  */
+@@ -289,6 +303,9 @@ struct regset_info target_regsets[] = {
+     NULL, s390_store_last_break },
+   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_SYSTEM_CALL, 0,
+     EXTENDED_REGS, s390_fill_system_call, s390_store_system_call },
++  /* TDB is read-only.  */
++  { PTRACE_GETREGSET, -1, NT_S390_TDB, 0, EXTENDED_REGS,
++    NULL, s390_store_tdb },
+   { 0, 0, 0, -1, -1, NULL, NULL }
+ };
+ 
diff --git a/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-8of9.patch b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-8of9.patch
new file mode 100644
index 0000000..9288bcf
--- /dev/null
+++ b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-8of9.patch
@@ -0,0 +1,44 @@
+From d5552aabd6c68147421819577108b51ff25ea064 Mon Sep 17 00:00:00 2001
+From: Andreas Arnez <arnez@linux.vnet.ibm.com>
+Date: Tue, 2 Dec 2014 10:47:30 +0100
+Subject: [PATCH] S390: Fix 'expedite' for s390-te-linux64
+
+Fix a typo in the expedited registers for s390-te-linux64.
+
+gdb/ChangeLog:
+
+	* features/Makefile (s390-te-linux64-expedite): Replace
+	non-existant r14 and r15 by r14l and r15l, respectively.
+	* regformats/s390-te-linux64.dat: Regenerate.
+---
+ gdb/ChangeLog                      | 6 ++++++
+ gdb/features/Makefile              | 2 +-
+ gdb/regformats/s390-te-linux64.dat | 2 +-
+ 3 files changed, 8 insertions(+), 2 deletions(-)
+
+Index: gdb-7.6.1/gdb/features/Makefile
+===================================================================
+--- gdb-7.6.1.orig/gdb/features/Makefile
++++ gdb-7.6.1/gdb/features/Makefile
+@@ -83,7 +83,7 @@ s390-linux32v2-expedite = r14,r15,pswa
+ s390-linux64-expedite = r14l,r15l,pswa
+ s390-linux64v1-expedite = r14l,r15l,pswa
+ s390-linux64v2-expedite = r14l,r15l,pswa
+-s390-te-linux64-expedite = r14,r15,pswa
++s390-te-linux64-expedite = r14l,r15l,pswa
+ s390x-linux64-expedite = r14,r15,pswa
+ s390x-linux64v1-expedite = r14,r15,pswa
+ s390x-linux64v2-expedite = r14,r15,pswa
+Index: gdb-7.6.1/gdb/regformats/s390-te-linux64.dat
+===================================================================
+--- gdb-7.6.1.orig/gdb/regformats/s390-te-linux64.dat
++++ gdb-7.6.1/gdb/regformats/s390-te-linux64.dat
+@@ -1,7 +1,7 @@
+ # DO NOT EDIT: generated from s390-te-linux64.xml
+ name:s390_te_linux64
+ xmltarget:s390-te-linux64.xml
+-expedite:r14,r15,pswa
++expedite:r14l,r15l,pswa
+ 32:pswm
+ 32:pswa
+ 32:r0h
diff --git a/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-9of9.patch b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-9of9.patch
new file mode 100644
index 0000000..2dfd2c5
--- /dev/null
+++ b/SOURCES/gdb-rhbz1105165-ibm-tdb-support-system-z-9of9.patch
@@ -0,0 +1,69 @@
+commit 2492f0d005f0390eabb3deb58aa7db7fcd716763
+Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
+Date:   Fri May 8 12:50:47 2015 +0200
+
+    S390: Fix for inadvertently setting 24-bit mode in fill_gregset
+    
+    On 64-bit S390 platforms, for programs compiled with -m31, it could
+    happen that GDB inadvertently cleared the inferior's 31-bit addressing
+    mode bit and left the inferior running in 24-bit addressing mode.  In
+    particular this occurred with checkpoint.exp, when the "restore"
+    command needed to create a new regcache copy: At the time when the
+    PSWM register was copied over, the addressing mode bit was taken from
+    the PSWA register, which was still zero since it had not been copied
+    yet.  And when the PSWA register was copied, the addressing mode was
+    not updated again.
+    
+    The fix affects fill_gregset, where the bits "belonging" to each of
+    the PSWA and PSWM registers are now carefully separated.  The
+    addressing mode bit is no longer touched when writing PSWM, and --
+    more importantly -- it *is* written when writing PSWA.
+    
+    gdb/ChangeLog:
+    
+    	* s390-linux-nat.c (fill_gregset): Avoid relying on the PSWA
+    	register in the regcache when treating the PSWM register, and vice
+    	versa.
+
+Index: gdb-7.6.1/gdb/s390-nat.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/s390-nat.c
++++ gdb-7.6.1/gdb/s390-nat.c
+@@ -174,19 +174,28 @@ fill_gregset (const struct regcache *reg
+ 	  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ 	  ULONGEST pswa, pswm;
+ 	  gdb_byte buf[4];
++	  gdb_byte *pswm_p = (gdb_byte *) regp + 0;
++	  gdb_byte *pswa_p = (gdb_byte *) regp + 8;
+ 
+-	  regcache_raw_collect (regcache, S390_PSWM_REGNUM, buf);
+-	  pswm = extract_unsigned_integer (buf, 4, byte_order);
+-	  regcache_raw_collect (regcache, S390_PSWA_REGNUM, buf);
+-	  pswa = extract_unsigned_integer (buf, 4, byte_order);
++	  pswm = extract_unsigned_integer (pswm_p, 8, byte_order);
+ 
+ 	  if (regno == -1 || regno == S390_PSWM_REGNUM)
+-	    store_unsigned_integer (psw_p[0], 8, byte_order,
+-				    ((pswm & 0xfff7ffff) << 32) |
+-				    (pswa & 0x80000000));
++	    {
++	      pswm &= 0x80000000;
++	      regcache_raw_collect (regcache, S390_PSWM_REGNUM, buf);
++	      pswm |= (extract_unsigned_integer (buf, 4, byte_order)
++		       & 0xfff7ffff) << 32;
++	    }
+ 	  if (regno == -1 || regno == S390_PSWA_REGNUM)
+-	    store_unsigned_integer (psw_p[1], 8, byte_order,
+-				    pswa & 0x7fffffff);
++	    {
++	      regcache_raw_collect (regcache, S390_PSWA_REGNUM, buf);
++	      pswa = extract_unsigned_integer (buf, 4, byte_order);
++	      pswm ^= (pswm ^ pswa) & 0x80000000;
++	      pswa &= 0x7fffffff;
++	      store_unsigned_integer (pswa_p, 8, byte_order, pswa);
++	    }
++
++	  store_unsigned_integer (pswm_p, 8, byte_order, pswm);
+ 	}
+       return;
+     }
diff --git a/SOURCES/gdb-rhbz1149207-catch-syscall-after-fork.patch b/SOURCES/gdb-rhbz1149207-catch-syscall-after-fork.patch
new file mode 100644
index 0000000..8345b18
--- /dev/null
+++ b/SOURCES/gdb-rhbz1149207-catch-syscall-after-fork.patch
@@ -0,0 +1,136 @@
+  NOTE: This patch has been forwardported from RHEL-6.7.
+
+URL: <https://sourceware.org/ml/gdb-patches/2013-05/msg00364.html>
+Message-ID: <1368136582.30058.7.camel@soleil>
+
+  From: Philippe Waroquiers <philippe dot waroquiers at skynet dot be>
+  To: gdb-patches at sourceware dot org
+  Subject: RFA: fix gdb_assert caused by 'catch signal ...' and fork
+  Date: Thu, 09 May 2013 23:56:22 +0200
+
+  The attached patch fixes a gdb_assert caused by the combination of catch
+  signal and fork:
+    break-catch-sig.c:152: internal-error: signal_catchpoint_remove_location: Assertion `signal_catch_counts[iter] > 0' failed.
+
+  The problem is that the signal_catch_counts is decremented by detach_breakpoints.
+  The fix consists in not detaching breakpoint locations of type bp_loc_other.
+  The patch introduces a new test.
+
+Comments by Sergio Durigan Junior:
+
+  I addded a specific testcase for this patch, which tests exactly the
+  issue that the customer is facing.  This patch does not solve the
+  whole problem of catching a syscall and forking (for more details,
+  see <https://sourceware.org/bugzilla/show_bug.cgi?id=13457>,
+  specifically comment #3), but it solves the issue reported by the
+  customer.
+
+  I also removed the original testcase of this patch, because it
+  relied on "catch signal", which is a command that is not implemented
+  in this version of GDB.
+
+commit bd9673a4ded96ea5c108601501c8e59003ea1be6
+Author: Philippe Waroquiers <philippe@sourceware.org>
+Date:   Tue May 21 18:47:05 2013 +0000
+
+    Fix internal error caused by interaction between catch signal and fork
+
+Index: gdb-7.6.1/gdb/breakpoint.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/breakpoint.c
++++ gdb-7.6.1/gdb/breakpoint.c
+@@ -3542,6 +3542,15 @@ detach_breakpoints (ptid_t ptid)
+     if (bl->pspace != inf->pspace)
+       continue;
+ 
++    /* This function must physically remove breakpoints locations
++       from the specified ptid, without modifying the breakpoint
++       package's state.  Locations of type bp_loc_other are only
++       maintained at GDB side.  So, there is no need to remove
++       these bp_loc_other locations.  Moreover, removing these
++       would modify the breakpoint package's state.  */
++    if (bl->loc_type == bp_loc_other)
++      continue;
++
+     if (bl->inserted)
+       val |= remove_breakpoint_1 (bl, mark_inserted);
+   }
+Index: gdb-7.6.1/gdb/testsuite/gdb.base/gdb-rhbz1149207-catch-syscall-fork.c
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.base/gdb-rhbz1149207-catch-syscall-fork.c
+@@ -0,0 +1,11 @@
++#include <stdio.h>
++#include <unistd.h>
++
++int
++main (int argc, char **argv)
++{
++  if (fork () == 0)
++    sleep (1);
++  chdir (".");
++  return 0;
++}
+Index: gdb-7.6.1/gdb/testsuite/gdb.base/gdb-rhbz1149207-catch-syscall-fork.exp
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.base/gdb-rhbz1149207-catch-syscall-fork.exp
+@@ -0,0 +1,58 @@
++# Copyright 2015 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/>.
++
++if { [is_remote target] || ![isnative] } then {
++    continue
++}
++
++set testfile "gdb-rhbz1149207-catch-syscall-fork"
++set srcfile ${testfile}.c
++set binfile ${objdir}/${subdir}/${testfile}
++
++# Until "catch syscall" is implemented on other targets...
++if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then {
++    continue
++}
++
++# This shall be updated whenever 'catch syscall' is implemented
++# on some architecture.
++#if { ![istarget "i\[34567\]86-*-linux*"]
++if { ![istarget "x86_64-*-linux*"] && ![istarget "i\[34567\]86-*-linux*"]
++     && ![istarget "powerpc-*-linux*"] && ![istarget "powerpc64-*-linux*"]
++     && ![istarget "sparc-*-linux*"] && ![istarget "sparc64-*-linux*"] } {
++     continue
++}
++
++if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
++    untested ${testfile}.exp
++    return -1
++}
++
++gdb_exit
++gdb_start
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_load $binfile
++
++if { ![runto_main] } {
++    return -1
++}
++
++gdb_test "catch syscall chdir" \
++  "Catchpoint $decimal \\\(syscall (.)?chdir(.)? \\\[$decimal\\\]\\\)" \
++  "catch syscall chdir"
++
++gdb_test "continue" \
++  "Continuing\.\r\n.*\r\nCatchpoint $decimal \\\(call to syscall .?chdir.?.*" \
++  "continue from catch syscall after fork"
diff --git a/SOURCES/gdb-rhbz1184724-gdb-internal-error-num-lwps.patch b/SOURCES/gdb-rhbz1184724-gdb-internal-error-num-lwps.patch
new file mode 100644
index 0000000..8526288
--- /dev/null
+++ b/SOURCES/gdb-rhbz1184724-gdb-internal-error-num-lwps.patch
@@ -0,0 +1,568 @@
+From 6681535d2cecea1f67255c140f11b217518a2f4e Mon Sep 17 00:00:00 2001
+From: Pedro Alves <palves@redhat.com>
+Date: Wed, 17 Jun 2015 20:41:05 +0100
+Subject: [PATCH] Fix BZ1184724 - gdb output a internal-error: Assertion
+ `num_lwps (GET_PID (inferior_ptid)) == 1'
+
+The real issue with this bug is in the ptrace error:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  (gdb) c
+  Continuing.
+  netcfStateCleanup () at interface/interface_backend_netcf.c:116
+  116	}
+  ptrace: No such process.
+  ^^^^^^^^^^^^^^^^^^^^^^^^
+  (gdb) quit
+	  Inferior 1 [process 11205] will be detached.
+  Quit anyway? (y or n) y
+  [Thread 0x7fefdf322880 (LWP 11205) exited]
+
+  ../../gdb/linux-nat.c:1869: internal-error: linux_nat_detach: Assertion `num_lwps (GET_PID (inferior_ptid)) == 1' failed.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The assertion is just a consequence.
+
+So the main fix is to backport the GDB [1] bits of upstream 23f238d3
+(Fix race exposed by gdb.threads/killed.exp).  That makes
+linux_resume_one_lwp detect when the LWP being resumed disappears.
+However, we need to backport also part of 8a99810d (linux-nat.c: clean
+up pending status checking and resuming LWPs), which is what
+introduced the centralized linux_resume_one_lwp in the first place,
+and also one bit from 8817a6f2 (PR gdb/15713 - errors from
+i386_linux_resume lead to lock-up), which makes linux_nat_resume not
+clear the leader LWP's lwp->stopped flag too early, otherwise we'd hit
+the new assertion in check_ptrace_stopped_lwp_gone.
+
+The test is new (not a backport), and without the fix triggers the
+"detach" assertion shown above.
+
+[1] - The equivalent GDBserver bits are harder to backport, as they
+rely on GDB exceptions, which GDBserver 7.6.1 doesn't support yet.
+Fortunately, GDBserver already handles ESRCH from within its
+linux_resume_one_lwp, so doesn't trigger this particular bug and
+passes the test.
+
+gdb/ChangeLog:
+2015-06-17  Pedro Alves  <palves@redhat.com>
+
+	* common/linux-procfs.c (linux_proc_pid_is_trace_stopped): New
+	function.
+	* common/linux-procfs.h (linux_proc_pid_is_trace_stopped): New
+	declaration.
+	* linux-nat.c (linux_resume_one_lwp_throw, check_ptrace_stopped_lwp_gone)
+	(linux_resume_one_lwp): New functions.
+	(resume_lwp): Use linux_resume_one_lwp.
+	(linux_nat_resume_callback): Skip if LWP is the same as the passed
+	in data pointer.
+	(linux_nat_resume): Don't clear the selected LWP's stopped flag
+	before resuming the sibling LWPs.  Instead pass LWP to
+	linux_nat_resume_callback.  Use linux_resume_one_lwp.
+	(linux_handle_extended_wait, linux_nat_filter_event)
+	(linux_nat_wait_1): Use linux_resume_one_lwp.
+	(resume_stopped_resumed_lwps): Try register reads in TRY/CATCH and
+	swallows errors if the LWP is gone.  Use
+	linux_resume_one_lwp_throw instead of linux_resume_one_lwp.
+
+gdb/testsuite/ChangeLog:
+2015-06-17  Pedro Alves  <palves@redhat.com>
+
+	* gdb.threads/thread-kills-process.c: New file.
+	* gdb.threads/thread-kills-process.exp: New file.
+---
+ gdb/ChangeLog                                      |  13 ++
+ gdb/common/linux-procfs.c                          |   6 +
+ gdb/common/linux-procfs.h                          |   2 +
+ gdb/linux-nat.c                                    | 200 +++++++++++++--------
+ gdb/testsuite/gdb.threads/thread-kills-process.c   |  62 +++++++
+ gdb/testsuite/gdb.threads/thread-kills-process.exp |  70 ++++++++
+ 6 files changed, 277 insertions(+), 76 deletions(-)
+ create mode 100644 gdb/testsuite/gdb.threads/thread-kills-process.c
+ create mode 100644 gdb/testsuite/gdb.threads/thread-kills-process.exp
+
+Index: gdb-7.6.1/gdb/common/linux-procfs.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/common/linux-procfs.c
++++ gdb-7.6.1/gdb/common/linux-procfs.c
+@@ -111,6 +111,12 @@ linux_proc_pid_is_stopped (pid_t pid)
+   return linux_proc_pid_has_state (pid, "T (stopped)");
+ }
+ 
++int
++linux_proc_pid_is_trace_stopped (pid_t pid)
++{
++  return linux_proc_pid_has_state (pid, "T (tracing stop)");
++}
++
+ /* See linux-procfs.h declaration.  */
+ 
+ int
+Index: gdb-7.6.1/gdb/common/linux-procfs.h
+===================================================================
+--- gdb-7.6.1.orig/gdb/common/linux-procfs.h
++++ gdb-7.6.1/gdb/common/linux-procfs.h
+@@ -36,6 +36,8 @@ extern pid_t linux_proc_get_tracerpid (p
+ 
+ extern int linux_proc_pid_is_stopped (pid_t pid);
+ 
++extern int linux_proc_pid_is_trace_stopped (pid_t pid);
++
+ /* Return non-zero if PID is a zombie.  */
+ 
+ extern int linux_proc_pid_is_zombie (pid_t pid);
+Index: gdb-7.6.1/gdb/linux-nat.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/linux-nat.c
++++ gdb-7.6.1/gdb/linux-nat.c
+@@ -1928,6 +1928,85 @@ linux_nat_detach (struct target_ops *ops
+     linux_ops->to_detach (ops, args, from_tty);
+ }
+ 
++/* Resume execution of the inferior process.  If STEP is nonzero,
++   single-step it.  If SIGNAL is nonzero, give it that signal.  */
++
++static void
++linux_resume_one_lwp_throw (struct lwp_info *lp, int step,
++			    enum gdb_signal signo)
++{
++  ptid_t ptid;
++
++  lp->step = step;
++
++  if (linux_nat_prepare_to_resume != NULL)
++    linux_nat_prepare_to_resume (lp);
++
++  ptid = pid_to_ptid (GET_LWP (lp->ptid));
++  linux_ops->to_resume (linux_ops, ptid, step, signo);
++
++  /* Successfully resumed.  Clear state that no longer makes sense,
++     and mark the LWP as running.  Must not do this before resuming
++     otherwise if that fails other code will be confused.  E.g., we'd
++     later try to stop the LWP and hang forever waiting for a stop
++     status.  Note that we must not throw after this is cleared,
++     otherwise handle_zombie_lwp_error would get confused.  */
++  lp->stopped = 0;
++  lp->stopped_by_watchpoint = 0;
++  registers_changed_ptid (lp->ptid);
++}
++
++/* Called when we try to resume a stopped LWP and that errors out.  If
++   the LWP is no longer in ptrace-stopped state (meaning it's zombie,
++   or about to become), discard the error, clear any pending status
++   the LWP may have, and return true (we'll collect the exit status
++   soon enough).  Otherwise, return false.  */
++
++static int
++check_ptrace_stopped_lwp_gone (struct lwp_info *lp)
++{
++  /* If we get an error after resuming the LWP successfully, we'd
++     confuse !T state for the LWP being gone.  */
++  gdb_assert (lp->stopped);
++
++  /* We can't just check whether the LWP is in 'Z (Zombie)' state,
++     because even if ptrace failed with ESRCH, the tracee may be "not
++     yet fully dead", but already refusing ptrace requests.  In that
++     case the tracee has 'R (Running)' state for a little bit
++     (observed in Linux 3.18).  See also the note on ESRCH in the
++     ptrace(2) man page.  Instead, check whether the LWP has any state
++     other than ptrace-stopped.  */
++
++  /* Don't assume anything if /proc/PID/status can't be read.  */
++  if (linux_proc_pid_is_trace_stopped (ptid_get_lwp (lp->ptid)) == 0)
++    {
++      lp->status = 0;
++      lp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
++      lp->stopped_by_watchpoint = 0;
++      return 1;
++    }
++  return 0;
++}
++
++/* Like linux_resume_one_lwp_throw, but no error is thrown if the LWP
++   disappears while we try to resume it.  */
++
++static void
++linux_resume_one_lwp (struct lwp_info *lp, int step, enum gdb_signal signo)
++{
++  volatile struct gdb_exception ex;
++
++  TRY_CATCH (ex, RETURN_MASK_ERROR)
++    {
++      linux_resume_one_lwp_throw (lp, step, signo);
++    }
++  if (ex.reason < 0)
++    {
++      if (!check_ptrace_stopped_lwp_gone (lp))
++	throw_exception (ex);
++    }
++}
++
+ /* Resume LP.  */
+ 
+ static void
+@@ -1956,14 +2035,7 @@ resume_lwp (struct lwp_info *lp, int ste
+ 				 : "0"),
+ 				step ? "step" : "resume");
+ 
+-	  if (linux_nat_prepare_to_resume != NULL)
+-	    linux_nat_prepare_to_resume (lp);
+-	  linux_ops->to_resume (linux_ops,
+-				pid_to_ptid (GET_LWP (lp->ptid)),
+-				step, signo);
+-	  lp->stopped = 0;
+-	  lp->step = step;
+-	  lp->stopped_by_watchpoint = 0;
++	  linux_resume_one_lwp (lp, step, signo);
+ 	}
+       else
+ 	{
+@@ -1982,13 +2054,17 @@ resume_lwp (struct lwp_info *lp, int ste
+     }
+ }
+ 
+-/* Resume LWP, with the last stop signal, if it is in pass state.  */
++/* Callback for iterate_over_lwps.  If LWP is EXCEPT, do nothing.
++   Resume LWP with the last stop signal, if it is in pass state.  */
+ 
+ static int
+-linux_nat_resume_callback (struct lwp_info *lp, void *data)
++linux_nat_resume_callback (struct lwp_info *lp, void *except)
+ {
+   enum gdb_signal signo = GDB_SIGNAL_0;
+ 
++  if (lp == except)
++    return 0;
++
+   if (lp->stopped)
+     {
+       struct thread_info *thread;
+@@ -2108,20 +2184,10 @@ linux_nat_resume (struct target_ops *ops
+       return;
+     }
+ 
+-  /* Mark LWP as not stopped to prevent it from being continued by
+-     linux_nat_resume_callback.  */
+-  lp->stopped = 0;
+-
+   if (resume_many)
+-    iterate_over_lwps (ptid, linux_nat_resume_callback, NULL);
++    iterate_over_lwps (ptid, linux_nat_resume_callback, lp);
+ 
+-  /* Convert to something the lower layer understands.  */
+-  ptid = pid_to_ptid (GET_LWP (lp->ptid));
+-
+-  if (linux_nat_prepare_to_resume != NULL)
+-    linux_nat_prepare_to_resume (lp);
+-  linux_ops->to_resume (linux_ops, ptid, step, signo);
+-  lp->stopped_by_watchpoint = 0;
++  linux_resume_one_lwp (lp, step, signo);
+ 
+   if (debug_linux_nat)
+     fprintf_unfiltered (gdb_stdlog,
+@@ -2287,11 +2353,7 @@ linux_handle_syscall_trap (struct lwp_in
+ 
+   /* Note that gdbarch_get_syscall_number may access registers, hence
+      fill a regcache.  */
+-  registers_changed ();
+-  if (linux_nat_prepare_to_resume != NULL)
+-    linux_nat_prepare_to_resume (lp);
+-  linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
+-			lp->step, GDB_SIGNAL_0);
++  linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
+   return 1;
+ }
+ 
+@@ -2486,22 +2548,15 @@ linux_handle_extended_wait (struct lwp_i
+ 		    fprintf_unfiltered (gdb_stdlog,
+ 					"LHEW: resuming new LWP %ld\n",
+ 					GET_LWP (new_lp->ptid));
+-		  if (linux_nat_prepare_to_resume != NULL)
+-		    linux_nat_prepare_to_resume (new_lp);
+-		  linux_ops->to_resume (linux_ops, pid_to_ptid (new_pid),
+-					0, GDB_SIGNAL_0);
+-		  new_lp->stopped = 0;
++
++		  linux_resume_one_lwp (new_lp, 0, GDB_SIGNAL_0);
+ 		}
+ 	    }
+ 
+ 	  if (debug_linux_nat)
+ 	    fprintf_unfiltered (gdb_stdlog,
+ 				"LHEW: resuming parent LWP %d\n", pid);
+-	  if (linux_nat_prepare_to_resume != NULL)
+-	    linux_nat_prepare_to_resume (lp);
+-	  linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
+-				0, GDB_SIGNAL_0);
+-
++	  linux_resume_one_lwp (lp, 0, GDB_SIGNAL_0);
+ 	  return 1;
+ 	}
+ 
+@@ -3382,12 +3437,7 @@ linux_nat_filter_event (int lwpid, int s
+ 	{
+ 	  /* This is a delayed SIGSTOP.  */
+ 
+-	  registers_changed ();
+-
+-	  if (linux_nat_prepare_to_resume != NULL)
+-	    linux_nat_prepare_to_resume (lp);
+-	  linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
+-			    lp->step, GDB_SIGNAL_0);
++	  linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
+ 	  if (debug_linux_nat)
+ 	    fprintf_unfiltered (gdb_stdlog,
+ 				"LLW: %s %s, 0, 0 (discard SIGSTOP)\n",
+@@ -3395,7 +3445,6 @@ linux_nat_filter_event (int lwpid, int s
+ 				"PTRACE_SINGLESTEP" : "PTRACE_CONT",
+ 				target_pid_to_str (lp->ptid));
+ 
+-	  lp->stopped = 0;
+ 	  gdb_assert (lp->resumed);
+ 
+ 	  /* Discard the event.  */
+@@ -3416,11 +3465,7 @@ linux_nat_filter_event (int lwpid, int s
+       /* This is a delayed SIGINT.  */
+       lp->ignore_sigint = 0;
+ 
+-      registers_changed ();
+-      if (linux_nat_prepare_to_resume != NULL)
+-	linux_nat_prepare_to_resume (lp);
+-      linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
+-			    lp->step, GDB_SIGNAL_0);
++      linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
+       if (debug_linux_nat)
+ 	fprintf_unfiltered (gdb_stdlog,
+ 			    "LLW: %s %s, 0, 0 (discard SIGINT)\n",
+@@ -3428,7 +3473,6 @@ linux_nat_filter_event (int lwpid, int s
+ 			    "PTRACE_SINGLESTEP" : "PTRACE_CONT",
+ 			    target_pid_to_str (lp->ptid));
+ 
+-      lp->stopped = 0;
+       gdb_assert (lp->resumed);
+ 
+       /* Discard the event.  */
+@@ -3796,11 +3840,7 @@ retry:
+ 	     other threads to run.  On the other hand, not resuming
+ 	     newly attached threads may cause an unwanted delay in
+ 	     getting them running.  */
+-	  registers_changed ();
+-	  if (linux_nat_prepare_to_resume != NULL)
+-	    linux_nat_prepare_to_resume (lp);
+-	  linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
+-				lp->step, signo);
++	  linux_resume_one_lwp (lp, lp->step, signo);
+ 	  if (debug_linux_nat)
+ 	    fprintf_unfiltered (gdb_stdlog,
+ 				"LLW: %s %s, %s (preempt 'handle')\n",
+@@ -3810,7 +3850,6 @@ retry:
+ 				(signo != GDB_SIGNAL_0
+ 				 ? strsignal (gdb_signal_to_host (signo))
+ 				 : "0"));
+-	  lp->stopped = 0;
+ 	  goto retry;
+ 	}
+ 
+@@ -3935,32 +3974,41 @@ resume_stopped_resumed_lwps (struct lwp_
+     {
+       struct regcache *regcache = get_thread_regcache (lp->ptid);
+       struct gdbarch *gdbarch = get_regcache_arch (regcache);
+-      CORE_ADDR pc = regcache_read_pc (regcache);
++      volatile struct gdb_exception ex;
+ 
+       gdb_assert (is_executing (lp->ptid));
+ 
+-      /* Don't bother if there's a breakpoint at PC that we'd hit
+-	 immediately, and we're not waiting for this LWP.  */
+-      if (!ptid_match (lp->ptid, *wait_ptid_p))
++      TRY_CATCH (ex, RETURN_MASK_ERROR)
+ 	{
+-	  if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
+-	    return 0;
+-	}
++	  CORE_ADDR pc = regcache_read_pc (regcache);
++	  int leave_stopped = 0;
+ 
+-      if (debug_linux_nat)
+-	fprintf_unfiltered (gdb_stdlog,
+-			    "RSRL: resuming stopped-resumed LWP %s at %s: step=%d\n",
+-			    target_pid_to_str (lp->ptid),
+-			    paddress (gdbarch, pc),
+-			    lp->step);
++	  /* Don't bother if there's a breakpoint at PC that we'd hit
++	     immediately, and we're not waiting for this LWP.  */
++	  if (!ptid_match (lp->ptid, *wait_ptid_p))
++	    {
++	      if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
++		leave_stopped = 1;
++	    }
+ 
+-      registers_changed ();
+-      if (linux_nat_prepare_to_resume != NULL)
+-	linux_nat_prepare_to_resume (lp);
+-      linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
+-			    lp->step, GDB_SIGNAL_0);
+-      lp->stopped = 0;
+-      lp->stopped_by_watchpoint = 0;
++	  if (!leave_stopped)
++	    {
++	      if (debug_linux_nat)
++		fprintf_unfiltered (gdb_stdlog,
++				    "RSRL: resuming stopped-resumed LWP %s at "
++				    "%s: step=%d\n",
++				    target_pid_to_str (lp->ptid),
++				    paddress (gdbarch, pc),
++				    lp->step);
++
++	      linux_resume_one_lwp_throw (lp, lp->step, GDB_SIGNAL_0);
++	    }
++	}
++      if (ex.reason < 0)
++	{
++	  if (!check_ptrace_stopped_lwp_gone (lp))
++	    throw_exception (ex);
++	}
+     }
+ 
+   return 0;
+Index: gdb-7.6.1/gdb/testsuite/gdb.threads/thread-kills-process.c
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.threads/thread-kills-process.c
+@@ -0,0 +1,62 @@
++/* Copyright 2015 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   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/>.  */
++
++#include <pthread.h>
++#include <unistd.h>
++
++volatile int call_exit;
++static pthread_barrier_t barrier;
++#define NUMTHREADS 256
++
++void *
++thread_function (void *arg)
++{
++  pthread_barrier_wait (&barrier);
++
++  while (!call_exit)
++    usleep (1);
++
++  _exit (0);
++  return NULL;
++}
++
++void
++all_threads_started (void)
++{
++  call_exit = 1;
++}
++
++int
++main (int argc, char **argv)
++{
++  pthread_t threads[NUMTHREADS];
++  int i;
++
++  pthread_barrier_init (&barrier, NULL, NUMTHREADS + 1);
++
++  for (i = 0; i < NUMTHREADS; ++i)
++    pthread_create (&threads[i], NULL, thread_function, NULL);
++
++  pthread_barrier_wait (&barrier);
++
++  all_threads_started ();
++
++  for (i = 0; i < NUMTHREADS; ++i)
++    pthread_join (threads[i], NULL);
++
++  return 0;
++}
+Index: gdb-7.6.1/gdb/testsuite/gdb.threads/thread-kills-process.exp
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.threads/thread-kills-process.exp
+@@ -0,0 +1,70 @@
++# Copyright (C) 2015 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/>.
++
++standard_testfile
++
++if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
++    return -1
++}
++
++clean_restart ${binfile}
++if {![runto_main]} {
++    fail "Couldn't run to main"
++    return
++}
++
++gdb_breakpoint "all_threads_started"
++
++gdb_continue_to_breakpoint "all_threads_started"
++
++# Update the thread list, otherwise when testing against GDBserver,
++# GDB won't know about thread 2.  (Only necessary with GDB < 7.9.)
++gdb_test "info threads" ".*"
++
++# Select any thread but the leader.
++gdb_test "thread 2" ".*" "switch to non-leader thread"
++
++# Delete breakpoints so that GDB doesn't switch back the to leader to
++# step over its breakpoint.
++delete_breakpoints
++
++# Let threads exit the process on next resume.
++gdb_test "p call_exit = 0" " = 0"
++
++# While GDB is busy resuming all threads one by one, one of the
++# threads should manage to exit the process.  GDB should handle that
++# gracefully instead of erroring out.
++#
++# gdb_continue_to_end doesn't work with GDBserver until the
++# introduction of the "exit_is_reliable" board variable
++# (b477a5e649150) in GDB 7.7.
++#gdb_continue_to_end "" continue 1
++gdb_test "continue" "$inferior_exited_re normally.*"
++
++# On the buggy GDB where the "continue" above would error out, a
++# subsequent "detach" (e.g., the user tries to quit GDB, and quit
++# offers to detach) would hit this assertion:
++#
++#   linux-nat.c:1869: internal-error: linux_nat_detach: Assertion `num_lwps (GET_PID (inferior_ptid)) == 1' failed.
++
++# That was a consequence of the original bug, but let's make sure that
++# even when "continue" is handled properly, detach doesn't stumble on
++# anything stale.
++gdb_test "detach" "The program is not being run\\." \
++    "detach after exit"
++
++# Likewise "continue".
++gdb_test "continue" "The program is not being run\\." \
++    "continue after exit"
diff --git a/SOURCES/gdb-rhbz1190506-segv-in-ko-ppc64.patch b/SOURCES/gdb-rhbz1190506-segv-in-ko-ppc64.patch
new file mode 100644
index 0000000..6ae16d5
--- /dev/null
+++ b/SOURCES/gdb-rhbz1190506-segv-in-ko-ppc64.patch
@@ -0,0 +1,220 @@
+commit 80c570537e380c1b8e48754c0ddbce2abcde2d00
+Author: Jan Kratochvil <jan.kratochvil@redhat.com>
+Date:   Thu Feb 26 14:08:01 2015 +0100
+
+    SEGV in ppc64_elf_get_synthetic_symtab reading a separate debug file
+    
+    The attached patch fixes the SEGV and lets GDB successfully
+    load all kernel modules installed by default on RHEL 7.
+    
+    Valgrind on F-21 x86_64 host has shown me more clear what is the problem:
+    
+    Reading symbols from /home/jkratoch/t/cordic.ko...Reading symbols from
+    /home/jkratoch/t/cordic.ko.debug...=================================================================
+    ==22763==ERROR: AddressSanitizer: heap-use-after-free on address 0x6120000461c8 at pc 0x150cdbd bp 0x7fffffffc7e0 sp 0x7fffffffc7d0
+    READ of size 8 at 0x6120000461c8 thread T0
+        #0 0x150cdbc in ppc64_elf_get_synthetic_symtab /home/jkratoch/redhat/gdb-test-asan/bfd/elf64-ppc.c:3282
+        #1 0x8c5274 in elf_read_minimal_symbols /home/jkratoch/redhat/gdb-test-asan/gdb/elfread.c:1205
+        #2 0x8c55e7 in elf_symfile_read /home/jkratoch/redhat/gdb-test-asan/gdb/elfread.c:1268
+    [...]
+    0x6120000461c8 is located 264 bytes inside of 288-byte region [0x6120000460c0,0x6120000461e0)
+    freed by thread T0 here:
+        #0 0x7ffff715454f in __interceptor_free (/lib64/libasan.so.1+0x5754f)
+        #1 0xde9cde in xfree common/common-utils.c:98
+        #2 0x9a04f7 in do_my_cleanups common/cleanups.c:155
+        #3 0x9a05d3 in do_cleanups common/cleanups.c:177
+        #4 0x8c538a in elf_read_minimal_symbols /home/jkratoch/redhat/gdb-test-asan/gdb/elfread.c:1229
+        #5 0x8c55e7 in elf_symfile_read /home/jkratoch/redhat/gdb-test-asan/gdb/elfread.c:1268
+    [...]
+    previously allocated by thread T0 here:
+        #0 0x7ffff71547c7 in malloc (/lib64/libasan.so.1+0x577c7)
+        #1 0xde9b95 in xmalloc common/common-utils.c:41
+        #2 0x8c4da2 in elf_read_minimal_symbols /home/jkratoch/redhat/gdb-test-asan/gdb/elfread.c:1147
+        #3 0x8c55e7 in elf_symfile_read /home/jkratoch/redhat/gdb-test-asan/gdb/elfread.c:1268
+    [...]
+    SUMMARY: AddressSanitizer: heap-use-after-free /home/jkratoch/redhat/gdb-test-asan/bfd/elf64-ppc.c:3282 ppc64_elf_get_synthetic_symtab
+    [...]
+    ==22763==ABORTING
+    
+    A similar case a few lines later I have fixed in 2010 by:
+            https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=3f1eff0a2c7f0e7078f011f55b8e7f710aae0cc2
+    
+    My testcase does not always reproduce it but at least a bit:
+     * GDB without ppc64 target (even as a secondary one) is reported as "untested"
+     * ASAN-built GDB with ppc64 target always crashes (and PASSes with this fix)
+     * unpatched non-ASAN-built GDB with ppc64 target crashes from commandline
+     * unpatched non-ASAN-built GDB with ppc64 target PASSes from runtest (?)
+    
+    gdb/ChangeLog
+    2015-02-26  Jan Kratochvil  <jan.kratochvil@redhat.com>
+    
+    	* elfread.c (elf_read_minimal_symbols): Use bfd_alloc for
+    	bfd_canonicalize_symtab.
+    
+    gdb/testsuite/ChangeLog
+    2015-02-26  Jan Kratochvil  <jan.kratochvil@redhat.com>
+    
+    	* gdb.arch/cordic.ko.bz2: New file.
+    	* gdb.arch/cordic.ko.debug.bz2: New file.
+    	* gdb.arch/ppc64-symtab-cordic.exp: New file.
+
+Index: gdb-7.6.1/gdb/elfread.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/elfread.c
++++ gdb-7.6.1/gdb/elfread.c
+@@ -2308,8 +2308,10 @@ elf_symfile_read (struct objfile *objfil
+ 
+   if (storage_needed > 0)
+     {
+-      symbol_table = (asymbol **) xmalloc (storage_needed);
+-      make_cleanup (xfree, symbol_table);
++      /* Memory gets permanently referenced from ABFD after
++	 bfd_canonicalize_symtab so it must not get freed before ABFD gets.  */
++
++      symbol_table = bfd_alloc (abfd, storage_needed);
+       symcount = bfd_canonicalize_symtab (objfile->obfd, symbol_table);
+ 
+       if (symcount < 0)
+Index: gdb-7.6.1/gdb/testsuite/gdb.arch/ppc64-symtab-cordic.exp
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.arch/ppc64-symtab-cordic.exp
+@@ -0,0 +1,51 @@
++# Copyright 2015 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/>.
++
++standard_testfile
++
++set kobz2uufile ${srcdir}/${subdir}/cordic.ko.bz2.uu
++set kofile ${objdir}/${subdir}/cordic.ko
++set kodebugbz2uufile ${srcdir}/${subdir}/cordic.ko.debug.bz2.uu
++set kodebugfile ${objdir}/${subdir}/cordic.ko.debug
++
++if {[catch "system \"uudecode -o - ${kobz2uufile} | bzip2 -dc >${kofile}\""] != 0} {
++    untested "failed bzip2 for ${kobz2uufile}"
++    return -1
++}
++if {[catch "system \"uudecode -o - ${kodebugbz2uufile} | bzip2 -dc >${kodebugfile}\""] != 0} {
++    untested "failed bzip2 for ${kodebugbz2uufile}"
++    return -1
++}
++
++gdb_exit
++gdb_start
++gdb_reinitialize_dir $srcdir/$subdir
++
++# This test won't work properly if system debuginfo is installed.
++# Test message is suppressed by "" as otherwise we could print PASS+UNTESTED
++# result to gdb.sum making a false feeling the issue has been tested.
++gdb_test_no_output "set debug-file-directory" ""
++
++gdb_load ${kofile}
++
++set test "show architecture"
++gdb_test_multiple $test $test {
++    -re "\r\nThe target architecture is set automatically \\(currently powerpc:common64\\)\r\n$gdb_prompt $" {
++	pass $test
++    }
++    -re "\r\nThe target architecture is set automatically \\(currently .*\\)\r\n$gdb_prompt $" {
++	untested "powerpc:common64 is not supported"
++    }
++}
+Index: gdb-7.6.1/gdb/testsuite/gdb.arch/cordic.ko.bz2.uu
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.arch/cordic.ko.bz2.uu
+@@ -0,0 +1,53 @@
++begin 664 cordic.ko.bz2.uu
++M0EIH.3%!62936:QR$J<`!:7____________^___________]__O_U__]_N]]
++M__?W__Z[T`88O`VP73FU<<H&'2AJ(()E/3U1Y,IXIY1M3)HR#:CT0,ADTVID
++MT`#(!M31B`!H:-J#30R!B&3T@:`TT:#)H::`#$]0T:-&F@Q#3"#330BC14]/
++M1&IZ::F:GHGZD-'H-JC":8]0GZD]0&0T\IIZFF)IZ3)Z9(,`C33"`#:@`/4`
++M#U-&(TR,`C(8AB-,0&C$TTT`-#U!H@28)DT`T%,I[32F)Y)IIZAZ3U,0`-,C
++M$>IZADTR`/4]0#(T,U&@]0#0`9`,FC33&IM(S4!M30`:``:-&@`TT0`````&
++M@```!H#(`````````-``-&@`````````:&@-```R:`2)(2GHIYI,F%-E/4T&
++M@&U&:FU#Q3TGJ-#0T:'J&AH!IM1H&1H/2,@`#U,AH&@`:`#0`:``:``````#
++M(U?UGYM5,T:_>+G'N@2C!1`YAHM*$?TZ#1VWC-*HMEMC`L[FZ949K<@VVOMY
++MU)8$>DL`F?4./0/$L*"![J$&9GBD5L68$)"T^%J\L*M>Y6]*.ZV?-,M+74MS
++M7X1*XFVMS`GJ:<:C<>QUJ_';N$*3SYGC0I2/;CC),,OZ-<IY73[N/O.B0;R?
++MI/<85F@2'*0F)SQA``1&4A'*N[QK=YH`SFJ0@+C:ZLY_13B02;8DJ+[6G`Y7
++MK,PS@W976]9?+U>.I9"LJNAL9IU>5*1JOU=!B=\KO8P"K$KJZ@,&_@O]-`%Q
++M1"!+@F22E`B(B(@&PPF@)2B(@!#;?@NJE`@OH($-@%RQ&,9BF;=PFGNYNN:]
++M1K+-8+.R,EQTLVUO+WYI(QK5X:^84TW9M(`M6"/LM(AH5ZP0%:Q(T[0KMI%)
++MK'8N$JP[&$L?9VM]HM)E94:/1MLZAN$17YE)SG=9KFW(7T\)"%!;##C5+>4R
++M+&1/XU>[&0[7.2$D6]MR[.4/('!2/<'"D!H!-4U+CBQA3B#6<O!T]78?U:\N
++MLI#K(]1D:\SL[(IBPJH=FQ8C(RP)C<,HB.4G@PV%$F1\%"4!I+!"A)!.P&T4
++M.&$:BJD2B!36Y"492"LSL84J4J(CD&2>>9V[R5=#84J#]Y?XUP#19NF-!"]]
++MX_SK#=\A1G\0*HM7:I&QL4I3$C,G<F3G,;<TA!9=Y`K!B"3U)&8EQ4N)[68N
++M-1Z65F5HZYG)V,+.LP)3CS^O3B7\]W3\.8Z/K=-+<<.!'\/[6EJA`T`0_/([
++M"**0\\*JEO1KGAC=YE57IB5?(PN*0`!Z"KV<;"91^G$G;Q-Z0[H?\83QQR2!
++M&2SD18CG':Y>5,]\X`ACXR-CR8>6HC1/&?-/$G_7L%R3..'6)YM[Y+VR5V9@
++M2Y>@7D>:F^&RN0<IR!XYSY%NLW*I@$:XP;THVYN93]\]&I%M9'.*B6;=J.VM
++M^=S.I1XC#*5*25-&`18$T'(BF!;1&`@,/+9IL''"/5\#9$]H:^!=0[#[HM&P
++M78=YV;:7C,=:YYUJ5J)3'KW&<O,X7*X-_J8,G3KWD3E:3?3HAJ.<L6IF`,.O
++MWC7[B9OY\0#++GY+:(/"1^#CN2P<4Z+A;^PO\06VXMY(,";SL-KS1RDNK)4)
++MQ,$VS*+XS4N/!":4L-:SS1K4YH"62]$2[GN9NS>-`,\AXMIV$:@$3N<4D<S@
++M(A,OL*OZSTWNL?:G/AU]9"Y+599T$SH)8X`\;/#4@"]J(7GKU2A*@?U+0;0I
++M-08^,8B(3)P&ILNM28QTA+7*&@?M:E*.#C]F@)/J)$5M0I^<C<3NBB&6/:5F
++MXN&AS@$?P2#G_A'I9H?Q+6PW1->N9049W"\_/7-IY&R65X)I4Q-F@8VBEF@*
++M2GT.9G)TIA2EFR449J7+31?[-I>_N+>]O;TK_]Z++'W8)0:4[C0(@1SIU1;6
++MR61G=;D\6<;;6L]O66.,1>-&K5+O61ZG%00&>8%2K2K4JDQ7<EB43@V>K$04
++MX0V/:9#BX'_EBFQ2RA2<,L[,X82(-+!@L-S).E+:14JL6#4*`O3:#L""$LFP
++ML6XHO((,4$J_%NGA(G!-`/E`OT*I%?LI>VE0.T&E3,.D5DU77T%K3SE84QM4
++M$Z7R$'][%^7LT7^N;%L,*@M0%QKZ=EAF"6DBJT1D3)*O1J//3L3!/"Y1ME[Z
++M;X#WO\Q#AF/8,0P(F$_,)1B7`PF#AEAA'-^RO3K/65R$&64,K9P@T904AC%D
++M0DYNK'=<]Y\B><\2GZ*(!ZXD9I)%_5]P'EOE,)W&A)$+"D("%PAH1,B+EFDI
++M!,)F/LQ1>WRLFH;:IH<2$*#V)$9#%O.HL&6)@RP)U[0)RL9S4(0;B)T#H5"X
++M&Z`6P3@'37WRBX^=+*>0?3)D!K;W>WTTBC,"$.MX6MVUWV)^U1P?[LI/6A$8
++M#^333)CO]9Z/55B?/R5TR?-./&C+(&A[):L7T-MT:"JPH.M@Z)$TTB$NC^Z1
++M$FHE%T(C1-:Y93\]R_U&6A-O.3_)/0K&;LK]9Z%>?Q>4_L&TM>J:2S3BFC/>
++MN^\3B,#<PZV<LO.Z!9BF?OY:8RR^%ISMVQD_"U[#U6?EMF'RW??JVVC#?E@Z
++MZ-F1!4;VZ*,I9R]E_G.KW;'I]'V58XOT$]I3K#6/S!8NT#`R($`[HXM(SI'G
++M-VR6DNW`-506)H:YC&P$2IW-,_-JO^N-]0X[,*V2WP_LXN#R8#C@`#C@YSN2
++M!9&`Y*AH4IGB:&=NNOQL5/M+M0V.QH62$W-+B1HD(9$=`BV@*IKV[Q`U/A0>
++MA6QOQMY*]TJV12V[4+J+-P=Q?/MV=Q2Y%@*"\<12OVLPHS(E+340BRPFZI/$
++M,;[5&:J8,\D"&@9CK"#&OP@<"A!3ND%9S*EA'6D3JLC"T6<9:`!E;3O(&G94
++MIT-`CL3%A?;_(NKY1#S-PYZ#Q/58AEZZY4LG'0B(3B$`4$0P0_XNY(IPH2%8
++#Y"5.
++`
++end
+Index: gdb-7.6.1/gdb/testsuite/gdb.arch/cordic.ko.debug.bz2.uu
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.arch/cordic.ko.debug.bz2.uu
+@@ -0,0 +1,24 @@
++begin 664 cordic.ko.debug.bz2.uu
++M0EIH.3%!62936;;3U;4``^=______^==:W]63^U^1+_O_V"H4V#`)$A@F@90
++M"D$!"""2P`,!Q0-*1AHB-4])ZGI-#3U`T:8C0``-``-`:-#0`:#T@!IH-&@-
++M!HA$\D](])E)Z(V@)A#30TT,1@`C-`)@(!H8"8!,--!!@``````````$P```
++M`$8``F``2)$FF@FDVIZGJ>BFF1A-/-)HVJ'J8`#U3,H:#"-D@'H:@8CT&("]
++M???6F=%1'FNGCPP"I4HL6ZE@2>=E(>L$@&5?>9ZJAI%`&%I2P2MAW226F58=
++M!Z[0:D$@C,S$%$*-\ZZF[U##1Q9M=6V$MAXS#$,A5@8IA,-^8#:S#*JAEJUA
++M.ZJWN+EH.Z>`5$02]B/^B\^*GMP%%$,#,BH!`%2&""YD(Z$``3/9]@Y;'/LR
++M6_C%]&YT&1HR5[H(&VQ`9U[/&/_IX]&CA3,4BW\%WK:>,KF?AA?;I0M)HJHA
++M))0E$!$-PFTDHB!1$`@;;*T0".1!";2&QM!L,.,TDA*LQ:G*A?T5HS.EQQ-^
++MXX9F.PV"$H]V,TTRF$T%@NHPIQ2[]T6@8*!#(2$CYW1@8Y(S,WQ[.UM[GKY.
++M"Y^V=].A<UFI,NGU92)29WV1.9)H:[UE)0D)4,"\PS?KC;T(3=0U#]C`"0J4
++MLR"24H($(R60S'.$.0^K9F@,AZ&K`@I92T5.3:4H@=-7S'#/C,1QSD%>INN_
++MT#7-^3M?A9*J-8-<-'1M[-.*2H<Y0M)B'-Y(3XMHL#)[--X-<BGOA\YO#T,(
++M,AEB@'L$[^WOL#7!:ID4FH5S_!;7O`M!KRV?T3%):X7H+A!38."$$X!D+S@4
++MP3/-VM<9?0%-"Z.(MVYY(FE7$V?"QM'CX*6-4;^9,4A1\1$4<"4GCOX3S(:1
++MY[`HM?>82JW<$8<LTV:J##D"KBRIUZS2>`0=$2U,`K^AD\-A$N6%@!,)D\40
++MG+A5S!8)K\D>T%$6+5VX1Q3?#S@85E<O5&TQ;KCX)9$]Y54IR%L'KW<C)87T
++M718+9P'1>LW\N1-;@7B98=FRJ21(E>-R[9:8#GQ6&((U`"<&M?(D**&1(`:P
++MAXD/K49))+)4^H3%*:%H4QQ2+J4.>B,&7.N<`R,SB0A!LB3&(`J?03!*`8:!
++M$Z0H8&G/30D@`M$O`Z5)%-CU'QCR@Z6&_RJIJ@M5&8H8&$O*6ESP4],\P7^+
++*N2*<*$A;:>K:@```
++`
++end
diff --git a/SOURCES/gdb-rhbz1197665-fix-applyframefilter-backport.patch b/SOURCES/gdb-rhbz1197665-fix-applyframefilter-backport.patch
new file mode 100644
index 0000000..fb90df2
--- /dev/null
+++ b/SOURCES/gdb-rhbz1197665-fix-applyframefilter-backport.patch
@@ -0,0 +1,285 @@
+commit 21909fa1c6d934bfa0c7ad3ef95909db48f6f756
+Author: Tom Tromey <tromey@redhat.com>
+Date:   Wed Jan 22 08:10:01 2014 -0700
+
+    fix crash in frame filters
+    
+    apply_frame_filter calls ensure_python_env before computing the
+    gdbarch to use.  This means that python_gdbarch can be NULL while in
+    Python code, and if a frame filter depends on this somehow (easy to
+    do), gdb will crash.
+    
+    The fix is to compute the gdbarch first.
+    
+    Built and regtested on x86-64 Fedora 18.
+    New test case included.
+    
+    2014-01-23  Tom Tromey  <tromey@redhat.com>
+    
+    	PR python/16491:
+    	* python/py-framefilter.c (apply_frame_filter): Call
+    	ensure_python_env after computing gdbarch.
+    
+    2014-01-23  Tom Tromey  <tromey@redhat.com>
+    
+    	PR python/16491:
+    	* gdb.python/py-framefilter.py (Reverse_Function.function): Read a
+    	string from an inferior frame.
+    	* gdb.python/py-framefilter-mi.exp: Update.
+
+Index: gdb-7.6.1/gdb/python/py-framefilter.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/python/py-framefilter.c
++++ gdb-7.6.1/gdb/python/py-framefilter.c
+@@ -1468,18 +1468,18 @@ apply_frame_filter (struct frame_info *f
+   PyObject *item;
+   htab_t levels_printed;
+ 
+-  cleanups = ensure_python_env (gdbarch, current_language);
+-
+   TRY_CATCH (except, RETURN_MASK_ALL)
+     {
+       gdbarch = get_frame_arch (frame);
+     }
+   if (except.reason < 0)
+     {
+-      gdbpy_convert_exception (except);
+-      goto error;
++      /* Let gdb try to print the stack trace.  */
++      return PY_BT_NO_FILTERS;
+     }
+ 
++  cleanups = ensure_python_env (gdbarch, current_language);
++
+   iterable = bootstrap_python_frame_filters (frame, frame_low, frame_high);
+ 
+   if (iterable == NULL)
+Index: gdb-7.6.1/gdb/testsuite/gdb.python/py-framefilter-mi.exp
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/gdb.python/py-framefilter-mi.exp
++++ gdb-7.6.1/gdb/testsuite/gdb.python/py-framefilter-mi.exp
+@@ -66,10 +66,10 @@ mi_continue_to_line [gdb_get_line_number
+   "step to breakpoint"
+ 
+ mi_gdb_test "-stack-list-frames" \
+-    "\\^done,stack=\\\[frame={level=\"0\",addr=\"$hex\",func=\"cnuf_dne\".*},frame={level=\"1\",addr=\"$hex\",func=\"acnuf\".*},frame={level=\"2\",addr=\"$hex\",func=\"bcnuf\".*},frame={level=\"3\",addr=\"$hex\",func=\"acnuf\".*},frame={level=\"22\",addr=\"$hex\",func=\"1cnuf\".*,children=\\\[frame={level=\"23\",addr=\"$hex\",func=\"func2\".*}\\\]},frame={level=\"24\",addr=\"$hex\",func=\"3cnuf\".*},frame={level=\"27\",addr=\"$hex\",func=\"niam\".*}\\\].*" \
++    "\\^done,stack=\\\[frame={level=\"0\",addr=\"$hex\",func=\"cnuf_dne.*\".*},frame={level=\"1\",addr=\"$hex\",func=\"acnuf\".*},frame={level=\"2\",addr=\"$hex\",func=\"bcnuf\".*},frame={level=\"3\",addr=\"$hex\",func=\"acnuf\".*},frame={level=\"22\",addr=\"$hex\",func=\"1cnuf\".*,children=\\\[frame={level=\"23\",addr=\"$hex\",func=\"func2\".*}\\\]},frame={level=\"24\",addr=\"$hex\",func=\"3cnuf\".*},frame={level=\"27\",addr=\"$hex\",func=\"niam\".*}\\\].*" \
+     "filtered stack listing"
+ mi_gdb_test "-stack-list-frames 0 3" \
+-    "\\^done,stack=\\\[frame={level=\"0\",addr=\"$hex\",func=\"cnuf_dne\".*},frame={level=\"1\",addr=\"$hex\",func=\"acnuf\".*},frame={level=\"2\",addr=\"$hex\",func=\"bcnuf\".*},frame={level=\"3\",addr=\"$hex\",func=\"acnuf\".*}\\\]" \
++    "\\^done,stack=\\\[frame={level=\"0\",addr=\"$hex\",func=\"cnuf_dne.*\".*},frame={level=\"1\",addr=\"$hex\",func=\"acnuf\".*},frame={level=\"2\",addr=\"$hex\",func=\"bcnuf\".*},frame={level=\"3\",addr=\"$hex\",func=\"acnuf\".*}\\\]" \
+     "filtered stack list 0 3"
+ mi_gdb_test "-stack-list-frames 22 24" \
+     "\\^done,stack=\\\[frame={level=\"22\",addr=\"$hex\",func=\"1cnuf\".*,children=\\\[frame={level=\"23\",addr=\"$hex\",func=\"func2\".*}\\\]},frame={level=\"24\",addr=\"$hex\",func=\"3cnuf\".*}\\\]" \
+Index: gdb-7.6.1/gdb/testsuite/gdb.python/py-framefilter.py
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/gdb.python/py-framefilter.py
++++ gdb-7.6.1/gdb/testsuite/gdb.python/py-framefilter.py
+@@ -30,8 +30,11 @@ class Reverse_Function (FrameDecorator):
+         fname = str (self.fobj.function())
+         if (fname == None or fname == ""):
+             return None
++        if fname == 'end_func':
++            extra = self.fobj.inferior_frame().read_var('str').string()
+         else:
+-            fname = fname[::-1]
++            extra = ''
++        fname = fname[::-1] + extra
+         return fname
+ 
+ class Dummy (FrameDecorator):
+Index: gdb-7.6.1/gdb/testsuite/gdb.python/rhbz1197665-apply-frame-filter-segv-gdb.py.in
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.python/rhbz1197665-apply-frame-filter-segv-gdb.py.in
+@@ -0,0 +1,48 @@
++# Copyright (C) 2013 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 file is part of the GDB testsuite.  It tests Python-based
++# frame-filters.
++import gdb
++import itertools
++from gdb.FrameDecorator import FrameDecorator
++
++
++class FrameObjFile ():
++
++    def __init__ (self):
++        self.name = "Filter1"
++        self.priority = 1
++        self.enabled = False
++        gdb.current_progspace().frame_filters ["Progspace" + self.name] = self
++        gdb.current_objfile().frame_filters ["ObjectFile" + self.name] = self
++
++    def filter (self, frame_iter):
++        return frame_iter
++
++class FrameObjFile2 ():
++
++    def __init__ (self):
++        self.name = "Filter2"
++        self.priority = 100
++        self.enabled = True
++        gdb.current_progspace().frame_filters ["Progspace" + self.name] = self
++        gdb.current_objfile().frame_filters ["ObjectFile" + self.name] = self
++
++    def filter (self, frame_iter):
++        return frame_iter
++
++FrameObjFile()
++FrameObjFile2()
+Index: gdb-7.6.1/gdb/testsuite/gdb.python/rhbz1197665-apply-frame-filter-segv.exp
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.python/rhbz1197665-apply-frame-filter-segv.exp
+@@ -0,0 +1,76 @@
++# Copyright (C) 2013-2015 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 file is part of the GDB testsuite.  It tests Python-based
++# frame-filters.
++
++# This test is specifically crafted for RH BZ 1197665.
++
++load_lib gdb-python.exp
++
++standard_testfile py-framefilter.c
++
++# We cannot use prepare_for_testing as we have to set the safe-patch
++# to check objfile and progspace printers.
++if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} {
++    return -1
++}
++
++# Start with a fresh gdb.
++gdb_exit
++gdb_start
++
++# Skip all tests if Python scripting is not enabled.
++if { [skip_python_tests] } { continue }
++
++# Make the -gdb.py script available to gdb, it is automagically loaded by gdb.
++# Care is taken to put it in the same directory as the binary so that
++# gdb will find it.
++set remote_obj_python_file \
++    [remote_download \
++	 host ${srcdir}/${subdir}/${testfile}-gdb.py.in \
++	 ${subdir}/${testfile}-gdb.py]
++
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_test_no_output "set auto-load safe-path ${remote_obj_python_file}" \
++    "set auto-load safe-path"
++gdb_load ${binfile}
++# Verify gdb loaded the script.
++gdb_test "info auto-load python-scripts" "Yes.*/${testfile}-gdb.py.*" \
++    "Test auto-load had loaded python scripts"
++
++if ![runto_main] then {
++    perror "couldn't run to breakpoint"
++    return
++}
++gdb_test_no_output "set python print-stack full" \
++    "Set python print-stack to full"
++
++# Load global frame-filters
++set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py]
++gdb_test_no_output "python execfile ('${remote_python_file}')" \
++    "Load python file"
++
++gdb_breakpoint [gdb_get_line_number "Backtrace end breakpoint"]
++gdb_breakpoint [gdb_get_line_number "Inner test breakpoint"]
++gdb_continue_to_breakpoint "Inner test breakpoint"
++
++# Test multiple local blocks.
++gdb_test "bt full no-filters" \
++    ".*#0.*end_func.*h = 9.*f = 42.*g = 19.*bar = $hex \"Inside block x2\".*d = 15.*e = 14.*foo = $hex \"Inside block\".*str = $hex \"The End\".*st2 = $hex \"Is Near\".*b = 12.*c = 5.*" \
++    "bt full no-filters"
++gdb_test "bt full" \
++    ".*#0.*cnuf_dne.*h = 9.*f = 42.*g = 19.*bar = $hex \"Inside block x2\".*d = 15.*e = 14.*foo = $hex \"Inside block\".*str = $hex \"The End\".*st2 = $hex \"Is Near\".*b = 12.*c = 5.*" \
++    "bt full with filters"
+Index: gdb-7.6.1/gdb/testsuite/gdb.python/rhbz1197665-apply-frame-filter-segv.py
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.python/rhbz1197665-apply-frame-filter-segv.py
+@@ -0,0 +1,56 @@
++# Copyright (C) 2013-2015 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 file is part of the GDB testsuite.  It tests Python-based
++# frame-filters.
++
++# This test is specifically crafted for RH BZ 1197665.
++
++import gdb
++import itertools
++from gdb.FrameDecorator import FrameDecorator
++import copy
++
++class Reverse_Function (FrameDecorator):
++
++    def __init__(self, fobj):
++        super(Reverse_Function, self).__init__(fobj)
++        self.fobj = fobj
++
++    def function (self):
++        # This function call should not fail.
++        gdb.target_charset ()
++
++        fname = str (self.fobj.function())
++        if (fname == None or fname == ""):
++            return None
++        else:
++            fname = fname[::-1]
++        return fname
++
++class FrameFilter ():
++
++    def __init__ (self):
++        self.name = "Reverse"
++        self.priority = 100
++        self.enabled = True
++        gdb.frame_filters [self.name] = self
++
++    def filter (self, frame_iter):
++        frame_iter = itertools.imap (Reverse_Function,
++                                     frame_iter)
++        return frame_iter
++
++FrameFilter()
diff --git a/SOURCES/gdb-rhbz1210135-internal-error-linux_nat_post_attach_wait.patch b/SOURCES/gdb-rhbz1210135-internal-error-linux_nat_post_attach_wait.patch
new file mode 100644
index 0000000..0d23bdb
--- /dev/null
+++ b/SOURCES/gdb-rhbz1210135-internal-error-linux_nat_post_attach_wait.patch
@@ -0,0 +1,158 @@
+  NOTE: This patch has been forwardported to RHEL-7.2.  It is originally
+  from RHEL-6.7.
+
+  Message-ID: <54E37CE7.50703@redhat.com>
+  Date: Tue, 17 Feb 2015 17:39:51 +0000
+  From: Pedro Alves <palves@redhat.com>
+  To: Sergio Durigan Junior <sergiodj@redhat.com>
+  Subject: [debug-list] [PATCH] RH BZ #1162264 - gdb/linux-nat.c:1411:
+   internal-error:,
+   linux_nat_post_attach_wait: Assertion `pid == new_pid' failed.
+
+  Hi.
+
+  Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1162264
+
+  So I spend a few more hours today trying to reproduce the
+  EACCES, to no avail.  Also, unfortunately, none of the attach
+  bugs exposed by attach-many-short-lived-threads.exp test
+  can explain this.
+
+  It seems to be that really the best we can do is cope with
+  the error, like in the patch below.
+
+  Note that the backtrace at
+
+   https://bugzilla.redhat.com/show_bug.cgi?id=1162264#c3 :
+
+  shows that this triggers for the main thread already:
+
+  ...
+  #6  0x000000000044fd2e in linux_nat_post_attach_wait (ptid=..., first=1, cloned=0x1d84368,
+  ...
+
+  (note "first=1").
+
+  For upstream, I think linux_nat_attach should be adjusted to work
+  like gdbserver -- that is, leave the initial waitpid to the main
+  wait code, like all other events, instead of synchronously
+  doing waitpid(PID).  That'll get rid of linux_nat_post_attach_wait
+  altogether.  But that's too invasive for a bug fix.
+
+  >From 072c61aeb9adc64e1eb45c120061b85fbf6f4d25 Mon Sep 17 00:00:00 2001
+  From: Pedro Alves <palves@redhat.com>
+  Date: Tue, 17 Feb 2015 17:11:05 +0000
+  Subject: [PATCH] RH BZ #1162264 - gdb/linux-nat.c:1411: internal-error:
+   linux_nat_post_attach_wait: Assertion `pid == new_pid' failed.
+
+  According to BZ #1162264, it can happen that we manage to attach to a
+  process, but then waitpid on it fails with EACCES.  That's unexpected,
+  and gdb hits an assertion.  But given this is an error that is out of
+  our control, we should handle it gracefully.  I wasn't able to
+  reproduce the EACCES, but hacking in the error, like:
+
+  |  --- a/gdb/linux-nat.c
+  |  +++ b/gdb/linux-nat.c
+  |  @@ -1409,7 +1409,7 @@ linux_nat_post_attach_wait (ptid_t ptid, int first, int *cloned,
+  | 	   *cloned = 1;
+  | 	 }
+  | 
+  |  -  if (new_pid != pid)
+  |  +  if (new_pid != pid || 1)
+  | 	 {
+  | 	   int saved_errno = errno;
+  | 
+  |  @@ -1423,6 +1423,7 @@ linux_nat_post_attach_wait (ptid_t ptid, int first, int *cloned,
+  | 	   ptrace (PTRACE_DETACH, pid, 0, 0);
+  | 
+  | 	   errno = saved_errno;
+  |  +      errno = EACCES;
+  | 	   perror_with_name (_("waitpid"));
+  | 	 }
+
+  ... I could confirm that the error handling works properly.  On the
+  EACCES case, we get:
+
+   (gdb) attach 1202
+   Attaching to process 1202
+   Unable to attach: waitpid: Permission denied.
+   (gdb) info inferiors
+     Num  Description       Executable
+   * 1    <null>
+   (gdb)
+
+  No test because the conditions that lead to the waitpid error are
+  unknown.
+
+  gdb/ChangeLog:
+  2015-02-17  Pedro Alves  <palves@redhat.com>
+
+	  * linux-nat.c: Include "exceptions.h".
+	  (linux_nat_post_attach_wait): If waitpid returns an excepted
+	  result, detach and error out instead of asserting.
+	  (linux_nat_attach): Wrap linux_nat_post_attach_wait in TRY_CATCH.
+	  Mourn inferior and rethrow in case of error while waiting for the
+	  initial stop.
+---
+ gdb/linux-nat.c | 34 +++++++++++++++++++++++++++++++---
+ 1 file changed, 31 insertions(+), 3 deletions(-)
+
+Index: gdb-7.6.1/gdb/linux-nat.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/linux-nat.c
++++ gdb-7.6.1/gdb/linux-nat.c
+@@ -1397,7 +1397,22 @@ linux_nat_post_attach_wait (ptid_t ptid,
+       *cloned = 1;
+     }
+ 
+-  gdb_assert (pid == new_pid);
++  if (new_pid != pid)
++    {
++      int saved_errno = errno;
++
++      /* Unexpected waitpid result.  EACCES has been observed on RHEL
++	 6.5 (RH BZ #1162264).  This is most likely a kernel bug, thus
++	 out of our control, so treat it as invalid input.  The LWP's
++	 state is indeterminate at this point, so best we can do is
++	 error out, otherwise we'd probably end up wedged later on.
++
++	 In case we're still attached.  */
++      ptrace (PTRACE_DETACH, pid, 0, 0);
++
++      errno = saved_errno;
++      perror_with_name (_("waitpid"));
++    }
+ 
+   if (!WIFSTOPPED (status))
+     {
+@@ -1621,7 +1636,7 @@ static void
+ linux_nat_attach (struct target_ops *ops, char *args, int from_tty)
+ {
+   struct lwp_info *lp;
+-  int status;
++  int status = 0;
+   ptid_t ptid;
+   volatile struct gdb_exception ex;
+ 
+@@ -1659,8 +1674,19 @@ linux_nat_attach (struct target_ops *ops
+   /* Add the initial process as the first LWP to the list.  */
+   lp = add_initial_lwp (ptid);
+ 
+-  status = linux_nat_post_attach_wait (lp->ptid, 1, &lp->cloned,
+-				       &lp->signalled);
++  TRY_CATCH (ex, RETURN_MASK_ERROR)
++    {
++      status = linux_nat_post_attach_wait (lp->ptid, 1, &lp->cloned,
++					   &lp->signalled);
++    }
++  if (ex.reason < 0)
++    {
++      target_terminal_ours ();
++      target_mourn_inferior ();
++
++      error (_("Unable to attach: %s"), ex.message);
++    }
++
+   if (!WIFSTOPPED (status))
+     {
+       if (WIFEXITED (status))
diff --git a/SOURCES/gdb-rhbz1210889-thread-call-clone.patch b/SOURCES/gdb-rhbz1210889-thread-call-clone.patch
new file mode 100644
index 0000000..5ea2e02
--- /dev/null
+++ b/SOURCES/gdb-rhbz1210889-thread-call-clone.patch
@@ -0,0 +1,236 @@
+  NOTE: This patch has been forwardported from RHEL-6.7.
+
+  From: Pedro Alves <palves@redhat.com>
+  Date: Fri, 20 Feb 2015 19:10:08 +0000
+  Subject: [PATCH] PR18006: internal error if threaded program calls
+   clone(CLONE_VM)
+
+  On GNU/Linux, if a pthreaded program has a thread call clone(CLONE_VM)
+  directly, and then that clone LWP hits a debug event (breakpoint,
+  etc.) GDB internal errors.  Threaded programs shouldn't really be
+  calling clone directly, but GDB shouldn't crash either.
+
+  The crash looks like this:
+
+  (gdb) break clone_fn
+   Breakpoint 1 at 0x4007d8: file clone-thread_db.c, line 35.
+   (gdb) r
+   ...
+   [Thread debugging using libthread_db enabled]
+   ...
+   [New Thread 0x7ffff7fc2700 (LWP 3886)]
+   ../../gdb/linux-thread-db.c:437: internal-error: thread_get_info_callback: Assertion `inout->thread_info != NULL' failed.
+   A problem internal to GDB has been detected,
+   further debugging may prove unreliable.
+
+  The problem is that 'clone' ends up clearing the parent thread's tid
+  field in glibc's thread data structure.  For x86_64, the glibc code in
+  question is here:
+
+    sysdeps/unix/sysv/linux/x86_64/clone.S:
+
+     ...
+	    testq   $CLONE_THREAD, %rdi
+	    jne     1f
+	    testq   $CLONE_VM, %rdi
+	    movl    $-1, %eax            <----
+	    jne     2f
+	    movl    $SYS_ify(getpid), %eax
+	    syscall
+    2:      movl    %eax, %fs:PID
+	    movl    %eax, %fs:TID        <----
+    1:
+
+  When GDB refreshes the thread list out of libthread_db, it finds a
+  thread with LWP with pid -1 (the clone's parent), which naturally
+  isn't yet on the thread list.  GDB then tries to attach to that bogus
+  LWP id, that fails, and then GDB gets confused.
+
+  The fix is to detect the bad PID early.
+
+  Tested on x86-64 Fedora 20.  GDBserver doesn't need any fix.
+
+  gdb/ChangeLog:
+  2015-02-20  Pedro Alves  <palves@redhat.com>
+
+	  PR threads/18006
+	  * linux-thread-db.c (thread_get_info_callback): Return early if
+	  the thread's lwp id is -1.
+	  (check_event): On TD_DEATH, if the thread is not on the thread
+	  list, warn instead of erroring out.
+
+  gdb/testsuite/ChangeLog:
+  2015-02-20  Pedro Alves  <palves@redhat.com>
+
+	  PR threads/18006
+	  * gdb.threads/clone-thread_db.c: New file.
+	  * gdb.threads/clone-thread_db.exp: New file.
+---
+ gdb/linux-thread-db.c                         | 14 +++--
+ gdb/testsuite/gdb.threads/clone-thread_db.c   | 73 +++++++++++++++++++++++++++
+ gdb/testsuite/gdb.threads/clone-thread_db.exp | 44 ++++++++++++++++
+ 3 files changed, 128 insertions(+), 3 deletions(-)
+ create mode 100644 gdb/testsuite/gdb.threads/clone-thread_db.c
+ create mode 100644 gdb/testsuite/gdb.threads/clone-thread_db.exp
+
+Index: gdb-7.6.1/gdb/linux-thread-db.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/linux-thread-db.c
++++ gdb-7.6.1/gdb/linux-thread-db.c
+@@ -422,6 +422,14 @@ thread_get_info_callback (const td_thrha
+     error (_("thread_get_info_callback: cannot get thread info: %s"),
+ 	   thread_db_err_str (err));
+ 
++  if (ti.ti_lid == -1)
++    {
++      /* We'll get this if a threaded program has a thread call clone
++	 with CLONE_VM.  `clone' sets the pthread LID of the new LWP
++	 to -1, which ends up clearing the parent thread's LID.  */
++      return 0;
++    }
++
+   /* Fill the cache.  */
+   thread_ptid = ptid_build (info->pid, ti.ti_lid, 0);
+   inout->thread_info = find_thread_ptid (thread_ptid);
+@@ -1454,9 +1462,9 @@ check_event (ptid_t ptid)
+ 	case TD_DEATH:
+ 
+ 	  if (!in_thread_list (ptid))
+-	    error (_("Spurious thread death event."));
+-
+-	  detach_thread (ptid);
++	    warning (_("Spurious thread death event."));
++	  else
++	    detach_thread (ptid);
+ 
+ 	  break;
+ 
+Index: gdb-7.6.1/gdb/testsuite/gdb.threads/clone-thread_db.c
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.threads/clone-thread_db.c
+@@ -0,0 +1,75 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++   Copyright 2015 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/>.
++
++   Test that GDB doesn't lose an event for a thread it didn't know
++   about, until an event is reported for it.  */
++
++#define _GNU_SOURCE
++#include <sched.h>
++#include <assert.h>
++#include <stdlib.h>
++#include <sys/types.h>
++#include <sys/wait.h>
++#include <unistd.h>
++#include <pthread.h>
++
++#define STACK_SIZE 0x1000
++
++int clone_pid;
++
++static int
++clone_fn (void *unused)
++{
++  return 0;
++}
++
++void *
++thread_fn (void *arg)
++{
++  unsigned char *stack;
++  int res;
++
++  stack = malloc (STACK_SIZE);
++  assert (stack != NULL);
++
++#ifdef __ia64__
++  clone_pid = __clone2 (clone_fn, stack, STACK_SIZE, CLONE_VM, NULL);
++#else
++  clone_pid = clone (clone_fn, stack + STACK_SIZE, CLONE_VM, NULL);
++#endif
++
++  assert (clone_pid > 0);
++
++  /* Wait for child.  */
++  res = waitpid (clone_pid, NULL, __WCLONE);
++  assert (res != -1);
++
++  return NULL;
++}
++
++int
++main (int argc, char **argv)
++{
++  pthread_t child;
++
++  alarm (300);
++
++  pthread_create (&child, NULL, thread_fn, NULL);
++  pthread_join (child, NULL);
++
++  return 0;
++}
+Index: gdb-7.6.1/gdb/testsuite/gdb.threads/clone-thread_db.exp
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.threads/clone-thread_db.exp
+@@ -0,0 +1,44 @@
++# This testcase is part of GDB, the GNU debugger.
++
++# Copyright 2015 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 only works on targets with the Linux kernel.
++if ![istarget *-*-linux*] {
++    return
++}
++
++set testfile "clone-thread_db"
++set srcfile ${testfile}.c
++set binfile ${objdir}/${subdir}/${testfile}
++
++if  { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
++    untested $testfile.exp
++    return -1
++}
++
++gdb_start
++gdb_reinitialize_dir $srcdir/$subdir
++gdb_load ${binfile}
++
++if ![runto_main] {
++    untested "could not run to main"
++    return -1
++}
++
++gdb_test "break clone_fn" "Breakpoint.*at.*file.*$srcfile.*line.*"
++gdb_test "continue" "clone_fn .* at .*" "continue to clone_fn"
++
++gdb_test "continue" "exited normally.*" "continue to end"
diff --git a/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-1of7.patch b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-1of7.patch
new file mode 100644
index 0000000..cd55b33
--- /dev/null
+++ b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-1of7.patch
@@ -0,0 +1,418 @@
+  Date: Mon, 15 Apr 2013 11:04:10 -0700
+  Message-ID: <CADPb22TTQCsFsuNtjTiUUQU_FN8R6cxfPeCRvNp_Ad2XS6XUag@mail.gmail.com>
+  Subject: Re: [RFA] Fix solib-precsave.exp,solib-reverse.exp
+  From: Doug Evans <dje at google dot com>
+  To: Pedro Alves <palves at redhat dot com>
+  Cc: gdb-patches <gdb-patches at sourceware dot org>
+
+  On Mon, Apr 15, 2013 at 10:33 AM, Pedro Alves <palves@redhat.com> wrote:
+  > On 04/13/2013 12:13 AM, Doug Evans wrote:
+  >> Hi.
+  >>
+  >> These two tests are failing for me.
+  >> They make the assumption that debug info for libc isn't installed.
+  >>
+  >> To fix this I've created a library of wrappers for the affected libc
+  >> functions and compiled it without debug info.
+  >>
+  >> Ok to check in?
+  >
+  > This the certainly the right idea for fixing the problem, but it took me a
+  > while to realize that the fact that the functions currently called are
+  > printf and sleep, and that the new library has wrappers for those has no
+  > importance.  They really are just used as proxy for "functions in library
+  > with no debug info".  Not even the output of printf is used.  I think that
+  > calling the library a syscall wrapper makes it prone to causing such doubt
+  > and confusion in other readers (of either the patch or the resulting code
+  > in the tree), as it has caused me.
+  >
+  > How about we just call it "shr1", and have it export some non-libc related
+  > functions like e.g., "shr1_foo" and "shr1_bar"?
+
+  Blech.  That's how I originally had it.
+  The original code used printf and sleep and I figured someone would
+  want to keep them.
+  I don't have a preference for either way.  Anyone else?
+  In any case we need to document that one cannot call libc functions
+  (or similar) as is.
+
+  >>  int main ()
+  >> @@ -27,16 +31,25 @@ int main ()
+  >>    char* cptr = "String 1";
+  >>    int b[2] = {5,8};
+  >>
+  >> +  /* Call these functions once before we start testing so that they get
+  >> +     resolved by the dynamic loader.  If the system has debug info for
+  >> +     the dynamic loader installed, reverse-stepping for the first call
+  >> +     will otherwise record being in the dynamic loader, which is not what
+  >
+  > reverse-stepping doesn't record.  Did you mean "report", or even
+  > "reverse-stepping the first call will otherwise stop in the
+  > dynamic loader", perhaps?
+
+  Yeah.
+
+commit c2a96e8cafeeda6132399e9ea94dafad6366ccc5
+Author: Doug Evans <dje@google.com>
+Date:   Mon May 6 22:07:13 2013 +0000
+
+    	* gdb.reverse/shr.h: New file.
+    	* gdb.reverse/shr1.c: New file.
+    	* gdb.reverse/shr2.c: #include "shr.h".
+    	* gdb.reverse/solib-reverse.c: Remove #include <stdio.h>.
+    	#include "shr.h".  Replace calls to printf,sleep to call shr1 instead.
+    	* gdb.reverse/solib-precsave.exp: Build shr2.sl.
+    	Update tests using sleep/printf to use shr2.sl instead.
+    	* gdb.reverse/solib-reverse.exp: Ditt.o
+
+Index: gdb-7.6.1/gdb/testsuite/gdb.reverse/shr1.c
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.reverse/shr1.c
+@@ -0,0 +1,24 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++   Copyright 2013 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/>.  */
++
++#include "shr.h"
++
++void
++shr1 (const char *s)
++{
++  /* nothing to do */
++}
+Index: gdb-7.6.1/gdb/testsuite/gdb.reverse/shr2.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/gdb.reverse/shr2.c
++++ gdb-7.6.1/gdb/testsuite/gdb.reverse/shr2.c
+@@ -15,6 +15,8 @@
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
++#include "shr.h"
++
+ #ifdef PROTOTYPES
+ int shr2(int x)
+ #else
+Index: gdb-7.6.1/gdb/testsuite/gdb.reverse/shr.h
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.reverse/shr.h
+@@ -0,0 +1,24 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++   Copyright 2013 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/>.  */
++
++#ifndef GDB_REVERSE_SHR_H
++#define GDB_REVERSE_SHR_H
++
++extern void shr1 (const char *);
++extern int shr2 (int);
++
++#endif /* GDB_REVERSE_SHR_H */
+Index: gdb-7.6.1/gdb/testsuite/gdb.reverse/solib-precsave.exp
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/gdb.reverse/solib-precsave.exp
++++ gdb-7.6.1/gdb/testsuite/gdb.reverse/solib-precsave.exp
+@@ -26,20 +26,30 @@ if {[skip_shlib_tests]} {
+ 
+ standard_testfile solib-reverse.c
+ set precsave [standard_output_file solib.precsave]
+-set libfile  "shr2"
+-set libsrc   ${libfile}.c
+-set library  [standard_output_file ${libfile}.sl]
++set lib1file "shr1"
++set lib1src  ${lib1file}.c
++set library1 [standard_output_file ${lib1file}.sl]
++set lib2file "shr2"
++set lib2src  ${lib2file}.c
++set library2 [standard_output_file ${lib2file}.sl]
+ 
+ if [get_compiler_info] {
+     return -1
+ }
+ 
+-if { [gdb_compile_shlib ${srcdir}/${subdir}/${libsrc} ${library} "debug"] != "" } {
+-    untested "Could not compile shared library."
++# Compile the first without debug info so that
++# stepping and reverse stepping doesn't end up inside them.
++if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib1src} ${library1} ""] != "" } {
++    untested "Could not compile shared library1."
+     return -1
+ }
+ 
+-set exec_opts [list debug shlib=${library}]
++if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib2src} ${library2} "debug"] != "" } {
++    untested "Could not compile shared library2."
++    return -1
++}
++
++set exec_opts [list debug shlib=${library1} shlib=${library2}]
+ 
+ # Attempt to prevent -Wl,-z,relro which may happen by default with some
+ # toolchain configurations.  Due to PR corefiles/11804 GDB will then produce
+@@ -57,12 +67,17 @@ if { [gdb_compile ${srcdir}/${subdir}/${
+ gdb_exit
+ gdb_start
+ 
+-# Clear it to never find any separate system debug infos.
+-gdb_test_no_output "set debug-file-directory"
++# Note: The test previously did "set debug-file-directory" to (try to)
++# ensure the debug info for the dynamic loader and libc weren't found.
++# This doesn't work if the debug info is in the .debug subdirectory.
++# Avoiding debug info for system libraries is not germaine to this test
++# and is no longer attempted.  Instead, the test does not make assumptions
++# about whether the debug info is present or not.
+ 
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+-gdb_load_shlibs $library
++gdb_load_shlibs $library1
++gdb_load_shlibs $library2
+ 
+ runto main
+ 
+@@ -99,15 +114,10 @@ set end_part_one [gdb_get_line_number "
+ set end_part_two [gdb_get_line_number " end part two" "$srcfile"]
+ gdb_test "until $end_part_one" " end part one.*" "run until end part one"
+ 
+-gdb_test "reverse-step" " sleep three .*" "reverse-step third sleep"
+-gdb_test "reverse-step" " sleep two .*"   "reverse-step second sleep"
+-gdb_test "reverse-step" " sleep one .*"   \
+-		    "reverse-step first sleep, dynsym resolve"
+-
+-gdb_test "reverse-step" " printf three .*" "reverse-step third printf"
+-gdb_test "reverse-step" " printf two .*"   "reverse-step second printf"
+-gdb_test "reverse-step" " printf one .*"   \
+-		    "reverse-step first printf, dynsym resolve"
++gdb_test "reverse-step" " shr1 three .*" "reverse-step third shr1"
++gdb_test "reverse-step" " shr1 two .*"   "reverse-step second shr1"
++gdb_test "reverse-step" " shr1 one .*"   "reverse-step first shr1"
++
+ gdb_test "reverse-step" " generic statement.*" "reverse-step generic"
+ 
+ 
+@@ -119,15 +129,10 @@ gdb_test "reverse-step" " generic statem
+ 
+ gdb_test "until $end_part_one" " end part one.*" "forward to end part one"
+ 
+-gdb_test "reverse-next" " sleep three .*" "reverse-next third sleep"
+-gdb_test "reverse-next" " sleep two .*"   "reverse-next second sleep"
+-gdb_test "reverse-next" " sleep one .*"   \
+-		    "reverse-next first sleep, dynsym resolve"
+-
+-gdb_test "reverse-next" " printf three .*" "reverse-next third printf"
+-gdb_test "reverse-next" " printf two .*"   "reverse-next second printf"
+-gdb_test "reverse-next" " printf one .*"   \
+-		    "reverse-next first printf, dynsym resolve"
++gdb_test "reverse-next" " shr1 three .*" "reverse-next third shr1"
++gdb_test "reverse-next" " shr1 two .*"   "reverse-next second shr1"
++gdb_test "reverse-next" " shr1 one .*"   "reverse-next first shr1"
++
+ gdb_test "reverse-next" " generic statement.*" "reverse-next generic"
+ 
+ 
+@@ -135,11 +140,11 @@ gdb_test "reverse-next" " generic statem
+ # Test reverse-step into debuggable solib function
+ #
+ 
+-gdb_test "reverse-step" "${libsrc}.*" "reverse-step into solib function one"
++gdb_test "reverse-step" "${lib2src}.*" "reverse-step into solib function one"
+ gdb_test "reverse-step" "return 2.x.*" "reverse-step within solib function one"
+ gdb_test "reverse-step" " middle part two.*" "reverse-step back to main one"
+ 
+-gdb_test "reverse-step" "${libsrc}.*" "reverse-step into solib function two"
++gdb_test "reverse-step" "${lib2src}.*" "reverse-step into solib function two"
+ gdb_test "reverse-step" "return 2.x.*" "reverse-step within solib function two"
+ gdb_test "reverse-step" " begin part two.*" "reverse-step back to main two"
+ 
+Index: gdb-7.6.1/gdb/testsuite/gdb.reverse/solib-reverse.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/gdb.reverse/solib-reverse.c
++++ gdb-7.6.1/gdb/testsuite/gdb.reverse/solib-reverse.c
+@@ -15,28 +15,33 @@
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+ 
+-/* Test reverse debugging of shared libraries.  */
++/* Test reverse debugging of shared libraries.
+ 
+-#include <stdio.h>
++   N.B. Do not call system routines here, we don't want to have to deal with
++   whether or not there is debug info present for them.  */
+ 
+-/* Shared library function */
+-extern int shr2(int);
++#include "shr.h"
+ 
+ int main ()
+ {
+   char* cptr = "String 1";
+   int b[2] = {5,8};
+ 
++  /* Call these functions once before we start testing so that they get
++     resolved by the dynamic loader.  If the system has debug info for
++     the dynamic loader installed, reverse-stepping for the first call
++     will otherwise stop in the dynamic loader, which is not what we want.  */
++  shr1 ("");
++  shr2 (0);
++
+   b[0] = shr2(12);		/* begin part two */
+   b[1] = shr2(17);		/* middle part two */
+ 
+   b[0] = 6;   b[1] = 9;		/* generic statement, end part two */
+-  printf ("message 1\n");	/* printf one */
+-  printf ("message 2\n");	/* printf two */
+-  printf ("message 3\n");	/* printf three */
+-  sleep (0);			/* sleep one */
+-  sleep (0);			/* sleep two */
+-  sleep (0);			/* sleep three */
++
++  shr1 ("message 1\n");		/* shr1 one */
++  shr1 ("message 2\n");		/* shr1 two */
++  shr1 ("message 3\n");		/* shr1 three */
+ 
+   return 0;			/* end part one */
+ } /* end of main */
+Index: gdb-7.6.1/gdb/testsuite/gdb.reverse/solib-reverse.exp
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/gdb.reverse/solib-reverse.exp
++++ gdb-7.6.1/gdb/testsuite/gdb.reverse/solib-reverse.exp
+@@ -24,20 +24,30 @@ if {[skip_shlib_tests]} {
+ }
+ 
+ standard_testfile
+-set libfile  "shr2"
+-set libsrc   ${libfile}.c
+-set library  [standard_output_file ${libfile}.sl]
++set lib1file "shr1"
++set lib1src  ${lib1file}.c
++set library1 [standard_output_file ${lib1file}.sl]
++set lib2file "shr2"
++set lib2src  ${lib2file}.c
++set library2 [standard_output_file ${lib2file}.sl]
+ 
+ if [get_compiler_info] {
+     return -1
+ }
+ 
+-if { [gdb_compile_shlib ${srcdir}/${subdir}/${libsrc} ${library} "debug"] != "" } {
+-    untested "Could not compile shared library."
++# Compile the first without debug info so that
++# stepping and reverse stepping doesn't end up inside them.
++if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib1src} ${library1} ""] != "" } {
++    untested "Could not compile shared library1."
+     return -1
+ }
+ 
+-set exec_opts [list debug shlib=${library}]
++if { [gdb_compile_shlib ${srcdir}/${subdir}/${lib2src} ${library2} "debug"] != "" } {
++    untested "Could not compile shared library2."
++    return -1
++}
++
++set exec_opts [list debug shlib=${library1} shlib=${library2}]
+ 
+ if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable $exec_opts] != "" } {
+     untested "Could not compile $binfile."
+@@ -49,12 +59,17 @@ if { [gdb_compile ${srcdir}/${subdir}/${
+ gdb_exit
+ gdb_start
+ 
+-# Clear it to never find any separate system debug infos.
+-gdb_test_no_output "set debug-file-directory"
++# Note: The test previously did "set debug-file-directory" to (try to)
++# ensure the debug info for the dynamic loader and libc weren't found.
++# This doesn't work if the debug info is in the .debug subdirectory.
++# Avoiding debug info for system libraries is not germaine to this test
++# and is no longer attempted.  Instead, the test does not make assumptions
++# about whether the debug info is present or not.
+ 
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+-gdb_load_shlibs $library
++gdb_load_shlibs $library1
++gdb_load_shlibs $library2
+ 
+ runto main
+ 
+@@ -73,15 +88,10 @@ set end_part_one [gdb_get_line_number "
+ set end_part_two [gdb_get_line_number " end part two" "$srcfile"]
+ gdb_test "until $end_part_one" " end part one.*" "run until end part one"
+ 
+-gdb_test "reverse-step" " sleep three .*" "reverse-step third sleep"
+-gdb_test "reverse-step" " sleep two .*"   "reverse-step second sleep"
+-gdb_test "reverse-step" " sleep one .*"   \
+-		    "reverse-step first sleep, dynsym resolve"
+-
+-gdb_test "reverse-step" " printf three .*" "reverse-step third printf"
+-gdb_test "reverse-step" " printf two .*"   "reverse-step second printf"
+-gdb_test "reverse-step" " printf one .*"   \
+-		    "reverse-step first printf, dynsym resolve"
++gdb_test "reverse-step" " shr1 three .*" "reverse-step third shr1"
++gdb_test "reverse-step" " shr1 two .*"   "reverse-step second shr1"
++gdb_test "reverse-step" " shr1 one .*"   "reverse-step first shr1"
++
+ gdb_test "reverse-step" " generic statement.*" "reverse-step generic"
+ 
+ 
+@@ -93,15 +103,10 @@ gdb_test "reverse-step" " generic statem
+ 
+ gdb_test "until $end_part_one" " end part one.*" "forward to end part one"
+ 
+-gdb_test "reverse-next" " sleep three .*" "reverse-next third sleep"
+-gdb_test "reverse-next" " sleep two .*"   "reverse-next second sleep"
+-gdb_test "reverse-next" " sleep one .*"   \
+-		    "reverse-next first sleep, dynsym resolve"
+-
+-gdb_test "reverse-next" " printf three .*" "reverse-next third printf"
+-gdb_test "reverse-next" " printf two .*"   "reverse-next second printf"
+-gdb_test "reverse-next" " printf one .*"   \
+-		    "reverse-next first printf, dynsym resolve"
++gdb_test "reverse-next" " shr1 three .*" "reverse-next third shr1"
++gdb_test "reverse-next" " shr1 two .*"   "reverse-next second shr1"
++gdb_test "reverse-next" " shr1 one .*"   "reverse-next first shr1"
++
+ gdb_test "reverse-next" " generic statement.*" "reverse-next generic"
+ 
+ 
+@@ -109,11 +114,11 @@ gdb_test "reverse-next" " generic statem
+ # Test reverse-step into debuggable solib function
+ #
+ 
+-gdb_test "reverse-step" "${libsrc}.*" "reverse-step into solib function one"
++gdb_test "reverse-step" "${lib2src}.*" "reverse-step into solib function one"
+ gdb_test "reverse-step" "return 2.x.*" "reverse-step within solib function one"
+ gdb_test "reverse-step" " middle part two.*" "reverse-step back to main one"
+ 
+-gdb_test "reverse-step" "${libsrc}.*" "reverse-step into solib function two"
++gdb_test "reverse-step" "${lib2src}.*" "reverse-step into solib function two"
+ gdb_test "reverse-step" "return 2.x.*" "reverse-step within solib function two"
+ gdb_test "reverse-step" " begin part two.*" "reverse-step back to main two"
+ 
diff --git a/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-2of7.patch b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-2of7.patch
new file mode 100644
index 0000000..0ef08f3
--- /dev/null
+++ b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-2of7.patch
@@ -0,0 +1,459 @@
+  NOTE: The testcase part of this patch has been removed.
+
+commit 5ce0145de764dc9c6e92daf2f843fa6e496c49d0
+Author: Pedro Alves <palves@redhat.com>
+Date:   Tue Dec 17 20:47:36 2013 +0000
+
+    "tfind" across unavailable-stack frames.
+    
+    Like when stepping, the current stack frame location is expected to be
+    printed as result of tfind command, if that results in moving to a
+    different function.  In tfind_1 we see:
+    
+      if (from_tty
+          && (has_stack_frames () || traceframe_number >= 0))
+        {
+          enum print_what print_what;
+    
+          /* NOTE: in imitation of the step command, try to determine
+             whether we have made a transition from one function to
+             another.  If so, we'll print the "stack frame" (ie. the new
+             function and it's arguments) -- otherwise we'll just show the
+             new source line.  */
+    
+          if (frame_id_eq (old_frame_id,
+                           get_frame_id (get_current_frame ())))
+            print_what = SRC_LINE;
+          else
+            print_what = SRC_AND_LOC;
+    
+          print_stack_frame (get_selected_frame (NULL), 1, print_what, 1);
+          do_displays ();
+        }
+    
+    However, when we haven't collected any registers in the tracepoint
+    (collect $regs), that doesn't actually work:
+    
+     (gdb) tstart
+     (gdb) info tracepoints
+     Num     Type           Disp Enb Address    What
+     1       tracepoint     keep y   0x080483b7 in func0
+                                                at ../.././../git/gdb/testsuite/gdb.trace/circ.c:28
+             collect testload
+         installed on target
+     2       tracepoint     keep y   0x080483bc in func1
+                                                at ../.././../git/gdb/testsuite/gdb.trace/circ.c:32
+             collect testload
+         installed on target
+     (gdb) c
+     Continuing.
+    
+     Breakpoint 3, end () at ../.././../git/gdb/testsuite/gdb.trace/circ.c:72
+     72    }
+     (gdb) tstop
+     (gdb) tfind start
+     Found trace frame 0, tracepoint 1
+     #0  func0 () at ../.././../git/gdb/testsuite/gdb.trace/circ.c:28
+     28    }
+     (gdb) tfind
+     Found trace frame 1, tracepoint 2
+     32    }
+     (gdb)
+    
+    When we don't have info about the stack available
+    (UNWIND_UNAVAILABLE), frames end up with outer_frame_id as frame ID.
+    And in the scenario above, the issue is that both frames before and
+    after the second tfind (the frames for func0 an func1) have the same
+    id (outer_frame_id), so the frame_id_eq check returns false, even
+    though the frames were of different functions.  GDB knows that,
+    because the PC is inferred from the tracepoint's address, even if no
+    registers were collected.
+    
+    To fix this, this patch adds support for frame ids with a valid code
+    address, but <unavailable> stack address, and then makes the unwinders
+    use that instead of the catch-all outer_frame_id for such frames.  The
+    frame_id_eq check in tfind_1 then automatically does the right thing
+    as expected.
+    
+    I tested with --directory=gdb.trace/ , before/after the patch, and
+    compared the resulting gdb.logs, then adjusted the tests to expect the
+    extra output that came out.  Turns out that was only circ.exp, the
+    original test that actually brought this issue to light.
+    
+    Tested on x86_64 Fedora 17, native and gdbserver.
+    
+    gdb/
+    2013-12-17  Pedro Alves  <palves@redhat.com>
+    
+    	* frame.h (enum frame_id_stack_status): New enum.
+    	(struct frame_id) <stack_addr>: Adjust comment.
+    	<stack_addr_p>: Delete field, replaced with ...
+    	<stack_status>: ... this new field.
+    	(frame_id_build_unavailable_stack): Declare.
+    	* frame.c (frame_addr_hash, fprint_field, outer_frame_id)
+    	(frame_id_build_special): Adjust.
+    	(frame_id_build_unavailable_stack): New function.
+    	(frame_id_build, frame_id_build_wild): Adjust.
+    	(frame_id_p, frame_id_eq, frame_id_inner): Adjust to take into
+    	account frames with unavailable stack.
+    
+    	* amd64-tdep.c (amd64_frame_this_id)
+    	(amd64_sigtramp_frame_this_id, amd64_epilogue_frame_this_id): Use
+    	frame_id_build_unavailable_stack.
+    	* dwarf2-frame.c (dwarf2_frame_this_id): Likewise.
+    	* i386-tdep.c (i386_frame_this_id, i386_epilogue_frame_this_id)
+    	(i386_sigtramp_frame_this_id):  Likewise.
+    
+    gdb/testsuite/
+    2013-12-17  Pedro Alves  <palves@redhat.com>
+    
+    	* gdb.trace/circ.exp: Expect frame info to be printed when
+    	switching between frames with unavailable stack, but different
+    	functions.
+
+Index: gdb-7.6.1/gdb/amd64-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/amd64-tdep.c
++++ gdb-7.6.1/gdb/amd64-tdep.c
+@@ -2403,15 +2403,16 @@ amd64_frame_this_id (struct frame_info *
+   struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
+ 
+   if (!cache->base_p)
+-    return;
+-
+-  /* This marks the outermost frame.  */
+-  if (cache->base == 0)
+-    return;
+-
+-  /* Detect OS dependent outermost frames; such as `clone'.  */
+-  if (tdep->outermost_frame_p && tdep->outermost_frame_p (this_frame))
+-    return;
++    (*this_id) = frame_id_build_unavailable_stack (cache->pc);
++  else if (cache->base == 0)
++    {
++      /* This marks the outermost frame.  */
++      return;
++    }
++  else
++    /* Detect OS dependent outermost frames; such as `clone'.  */
++    if (tdep->outermost_frame_p && tdep->outermost_frame_p (this_frame))
++      return;
+ 
+   (*this_id) = frame_id_build (cache->base + 16, cache->pc);
+ }
+@@ -2528,9 +2529,14 @@ amd64_sigtramp_frame_this_id (struct fra
+     amd64_sigtramp_frame_cache (this_frame, this_cache);
+ 
+   if (!cache->base_p)
+-    return;
+-
+-  (*this_id) = frame_id_build (cache->base + 16, get_frame_pc (this_frame));
++    (*this_id) = frame_id_build_unavailable_stack (get_frame_pc (this_frame));
++  else if (cache->base == 0)
++    {
++      /* This marks the outermost frame.  */
++      return;
++    }
++  else
++    (*this_id) = frame_id_build (cache->base + 16, get_frame_pc (this_frame));
+ }
+ 
+ static struct value *
+@@ -2699,9 +2705,9 @@ amd64_epilogue_frame_this_id (struct fra
+ 							       this_cache);
+ 
+   if (!cache->base_p)
+-    return;
+-
+-  (*this_id) = frame_id_build (cache->base + 8, cache->pc);
++    (*this_id) = frame_id_build_unavailable_stack (cache->pc);
++  else
++    (*this_id) = frame_id_build (cache->base + 8, cache->pc);
+ }
+ 
+ static const struct frame_unwind amd64_epilogue_frame_unwind =
+Index: gdb-7.6.1/gdb/dwarf2-frame.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/dwarf2-frame.c
++++ gdb-7.6.1/gdb/dwarf2-frame.c
+@@ -1265,12 +1265,11 @@ dwarf2_frame_this_id (struct frame_info
+     dwarf2_frame_cache (this_frame, this_cache);
+ 
+   if (cache->unavailable_retaddr)
++    (*this_id) = frame_id_build_unavailable_stack (get_frame_func (this_frame));
++  else if (cache->undefined_retaddr)
+     return;
+-
+-  if (cache->undefined_retaddr)
+-    return;
+-
+-  (*this_id) = frame_id_build (cache->cfa, get_frame_func (this_frame));
++  else
++    (*this_id) = frame_id_build (cache->cfa, get_frame_func (this_frame));
+ }
+ 
+ static struct value *
+Index: gdb-7.6.1/gdb/frame.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/frame.c
++++ gdb-7.6.1/gdb/frame.c
+@@ -147,10 +147,11 @@ frame_addr_hash (const void *ap)
+   const struct frame_id f_id = frame->this_id.value;
+   hashval_t hash = 0;
+ 
+-  gdb_assert (f_id.stack_addr_p || f_id.code_addr_p
++  gdb_assert (f_id.stack_status != FID_STACK_INVALID
++	      || f_id.code_addr_p
+ 	      || f_id.special_addr_p);
+ 
+-  if (f_id.stack_addr_p)
++  if (f_id.stack_status == FID_STACK_VALID)
+     hash = iterative_hash (&f_id.stack_addr,
+ 			   sizeof (f_id.stack_addr), hash);
+   if (f_id.code_addr_p)
+@@ -290,13 +291,23 @@ void
+ fprint_frame_id (struct ui_file *file, struct frame_id id)
+ {
+   fprintf_unfiltered (file, "{");
+-  fprint_field (file, "stack", id.stack_addr_p, id.stack_addr);
++
++  if (id.stack_status == FID_STACK_INVALID)
++    fprintf_unfiltered (file, "!stack");
++  else if (id.stack_status == FID_STACK_UNAVAILABLE)
++    fprintf_unfiltered (file, "stack=<unavailable>");
++  else
++    fprintf_unfiltered (file, "stack=%s", hex_string (id.stack_addr));
+   fprintf_unfiltered (file, ",");
++
+   fprint_field (file, "code", id.code_addr_p, id.code_addr);
+   fprintf_unfiltered (file, ",");
++
+   fprint_field (file, "special", id.special_addr_p, id.special_addr);
++
+   if (id.artificial_depth)
+     fprintf_unfiltered (file, ",artificial=%d", id.artificial_depth);
++
+   fprintf_unfiltered (file, "}");
+ }
+ 
+@@ -446,7 +457,7 @@ frame_unwind_caller_id (struct frame_inf
+ }
+ 
+ const struct frame_id null_frame_id; /* All zeros.  */
+-const struct frame_id outer_frame_id = { 0, 0, 0, 0, 0, 1, 0 };
++const struct frame_id outer_frame_id = { 0, 0, 0, FID_STACK_INVALID, 0, 1, 0 };
+ 
+ struct frame_id
+ frame_id_build_special (CORE_ADDR stack_addr, CORE_ADDR code_addr,
+@@ -455,7 +466,7 @@ frame_id_build_special (CORE_ADDR stack_
+   struct frame_id id = null_frame_id;
+ 
+   id.stack_addr = stack_addr;
+-  id.stack_addr_p = 1;
++  id.stack_status = FID_STACK_VALID;
+   id.code_addr = code_addr;
+   id.code_addr_p = 1;
+   id.special_addr = special_addr;
+@@ -463,13 +474,26 @@ frame_id_build_special (CORE_ADDR stack_
+   return id;
+ }
+ 
++/* See frame.h.  */
++
++struct frame_id
++frame_id_build_unavailable_stack (CORE_ADDR code_addr)
++{
++  struct frame_id id = null_frame_id;
++
++  id.stack_status = FID_STACK_UNAVAILABLE;
++  id.code_addr = code_addr;
++  id.code_addr_p = 1;
++  return id;
++}
++
+ struct frame_id
+ frame_id_build (CORE_ADDR stack_addr, CORE_ADDR code_addr)
+ {
+   struct frame_id id = null_frame_id;
+ 
+   id.stack_addr = stack_addr;
+-  id.stack_addr_p = 1;
++  id.stack_status = FID_STACK_VALID;
+   id.code_addr = code_addr;
+   id.code_addr_p = 1;
+   return id;
+@@ -481,7 +505,7 @@ frame_id_build_wild (CORE_ADDR stack_add
+   struct frame_id id = null_frame_id;
+ 
+   id.stack_addr = stack_addr;
+-  id.stack_addr_p = 1;
++  id.stack_status = FID_STACK_VALID;
+   return id;
+ }
+ 
+@@ -491,7 +515,7 @@ frame_id_p (struct frame_id l)
+   int p;
+ 
+   /* The frame is valid iff it has a valid stack address.  */
+-  p = l.stack_addr_p;
++  p = l.stack_status != FID_STACK_INVALID;
+   /* outer_frame_id is also valid.  */
+   if (!p && memcmp (&l, &outer_frame_id, sizeof (l)) == 0)
+     p = 1;
+@@ -518,19 +542,20 @@ frame_id_eq (struct frame_id l, struct f
+ {
+   int eq;
+ 
+-  if (!l.stack_addr_p && l.special_addr_p
+-      && !r.stack_addr_p && r.special_addr_p)
++  if (l.stack_status == FID_STACK_INVALID && l.special_addr_p
++      && r.stack_status == FID_STACK_INVALID && r.special_addr_p)
+     /* The outermost frame marker is equal to itself.  This is the
+        dodgy thing about outer_frame_id, since between execution steps
+        we might step into another function - from which we can't
+        unwind either.  More thought required to get rid of
+        outer_frame_id.  */
+     eq = 1;
+-  else if (!l.stack_addr_p || !r.stack_addr_p)
++  else if (l.stack_status == FID_STACK_INVALID
++	   || r.stack_status == FID_STACK_INVALID)
+     /* Like a NaN, if either ID is invalid, the result is false.
+        Note that a frame ID is invalid iff it is the null frame ID.  */
+     eq = 0;
+-  else if (l.stack_addr != r.stack_addr)
++  else if (l.stack_status != r.stack_status || l.stack_addr != r.stack_addr)
+     /* If .stack addresses are different, the frames are different.  */
+     eq = 0;
+   else if (l.code_addr_p && r.code_addr_p && l.code_addr != r.code_addr)
+@@ -597,8 +622,9 @@ frame_id_inner (struct gdbarch *gdbarch,
+ {
+   int inner;
+ 
+-  if (!l.stack_addr_p || !r.stack_addr_p)
+-    /* Like NaN, any operation involving an invalid ID always fails.  */
++  if (l.stack_status != FID_STACK_VALID || r.stack_status != FID_STACK_VALID)
++    /* Like NaN, any operation involving an invalid ID always fails.
++       Likewise if either ID has an unavailable stack address.  */
+     inner = 0;
+   else if (l.artificial_depth > r.artificial_depth
+ 	   && l.stack_addr == r.stack_addr
+Index: gdb-7.6.1/gdb/frame.h
+===================================================================
+--- gdb-7.6.1.orig/gdb/frame.h
++++ gdb-7.6.1/gdb/frame.h
+@@ -76,6 +76,23 @@ struct block;
+ struct gdbarch;
+ struct ui_file;
+ 
++/* Status of a given frame's stack.  */
++
++enum frame_id_stack_status
++{
++  /* Stack address is invalid.  E.g., this frame is the outermost
++     (i.e., _start), and the stack hasn't been setup yet.  */
++  FID_STACK_INVALID = 0,
++
++  /* Stack address is valid, and is found in the stack_addr field.  */
++  FID_STACK_VALID = 1,
++
++  /* Stack address is unavailable.  I.e., there's a valid stack, but
++     we don't know where it is (because memory or registers we'd
++     compute it from were not collected).  */
++  FID_STACK_UNAVAILABLE = -1
++};
++
+ /* The frame object.  */
+ 
+ struct frame_info;
+@@ -97,8 +114,9 @@ struct frame_id
+      function pointer register or stack pointer register.  They are
+      wrong.
+ 
+-     This field is valid only if stack_addr_p is true.  Otherwise, this
+-     frame represents the null frame.  */
++     This field is valid only if frame_id.stack_status is
++     FID_STACK_VALID.  It will be 0 for other
++     FID_STACK_... statuses.  */
+   CORE_ADDR stack_addr;
+ 
+   /* The frame's code address.  This shall be constant through out the
+@@ -129,7 +147,7 @@ struct frame_id
+   CORE_ADDR special_addr;
+ 
+   /* Flags to indicate the above fields have valid contents.  */
+-  unsigned int stack_addr_p : 1;
++  ENUM_BITFIELD(frame_id_stack_status) stack_status : 2;
+   unsigned int code_addr_p : 1;
+   unsigned int special_addr_p : 1;
+ 
+@@ -169,6 +187,12 @@ extern struct frame_id frame_id_build_sp
+ 					       CORE_ADDR code_addr,
+ 					       CORE_ADDR special_addr);
+ 
++/* Construct a frame ID representing a frame where the stack address
++   exists, but is unavailable.  CODE_ADDR is the frame's constant code
++   address (typically the entry point).  The special identifier
++   address is set to indicate a wild card.  */
++extern struct frame_id frame_id_build_unavailable_stack (CORE_ADDR code_addr);
++
+ /* Construct a wild card frame ID.  The parameter is the frame's constant
+    stack address (typically the outer-bound).  The code address as well
+    as the special identifier address are set to indicate wild cards.  */
+Index: gdb-7.6.1/gdb/i386-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/i386-tdep.c
++++ gdb-7.6.1/gdb/i386-tdep.c
+@@ -1846,12 +1846,17 @@ i386_frame_this_id (struct frame_info *t
+ {
+   struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
+ 
+-  /* This marks the outermost frame.  */
+-  if (cache->base == 0)
+-    return;
+-
+-  /* See the end of i386_push_dummy_call.  */
+-  (*this_id) = frame_id_build (cache->base + 8, cache->pc);
++  if (!cache->base_p)
++    (*this_id) = frame_id_build_unavailable_stack (cache->pc);
++  else if (cache->base == 0)
++    {
++      /* This marks the outermost frame.  */
++    }
++  else
++    {
++      /* See the end of i386_push_dummy_call.  */
++      (*this_id) = frame_id_build (cache->base + 8, cache->pc);
++    }
+ }
+ 
+ static enum unwind_stop_reason
+@@ -2032,9 +2037,9 @@ i386_epilogue_frame_this_id (struct fram
+     i386_epilogue_frame_cache (this_frame, this_cache);
+ 
+   if (!cache->base_p)
+-    return;
+-
+-  (*this_id) = frame_id_build (cache->base + 8, cache->pc);
++    (*this_id) = frame_id_build_unavailable_stack (cache->pc);
++  else
++    (*this_id) = frame_id_build (cache->base + 8, cache->pc);
+ }
+ 
+ static struct value *
+@@ -2226,10 +2231,12 @@ i386_sigtramp_frame_this_id (struct fram
+     i386_sigtramp_frame_cache (this_frame, this_cache);
+ 
+   if (!cache->base_p)
+-    return;
+-
+-  /* See the end of i386_push_dummy_call.  */
+-  (*this_id) = frame_id_build (cache->base + 8, get_frame_pc (this_frame));
++    (*this_id) = frame_id_build_unavailable_stack (get_frame_pc (this_frame));
++  else
++    {
++      /* See the end of i386_push_dummy_call.  */
++      (*this_id) = frame_id_build (cache->base + 8, get_frame_pc (this_frame));
++    }
+ }
+ 
+ static struct value *
diff --git a/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-3of7.patch b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-3of7.patch
new file mode 100644
index 0000000..3b426d2
--- /dev/null
+++ b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-3of7.patch
@@ -0,0 +1,176 @@
+  Message-ID: <548343C8.1020109@gmail.com>
+  Date: Sun, 07 Dec 2014 01:58:32 +0800
+  From: Wei-cheng Wang <cole945 at gmail dot com>
+  To: uweigand at de dot ibm dot com, gdb-patches at sourceware dot org
+  Subject: Re: [PATCH 1/3 v2] Process record support for PowerPC
+
+  2014-12-06  Wei-cheng Wang  <cole945@gmail.com>
+
+	      * rs6000-tdep.c (rs6000_in_function_epilogue_p): Rename to
+	      rs6000_in_function_epilogue_frame_p and add an argument
+	      for frame_info.
+	      (rs6000_epilogue_frame_cache, rs6000_epilogue_frame_this_id,
+	      rs6000_epilogue_frame_prev_register, rs6000_epilogue_frame_sniffer):
+	      New functions.
+	      (rs6000_epilogue_frame_unwind): New.
+	      (rs6000_gdbarch_init): Append epilogue unwinder.
+
+
+commit 2608dbf8a3ee666ac0a7d5d7c45611d489edcda5
+Author: Wei-cheng Wang <cole945@gmail.com>
+Date:   Sat Jan 17 14:29:16 2015 +0800
+
+    Epilogue unwinder for PowerPC.
+
+Index: gdb-7.6.1/gdb/rs6000-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/rs6000-tdep.c
++++ gdb-7.6.1/gdb/rs6000-tdep.c
+@@ -873,14 +873,14 @@ insn_changes_sp_or_jumps (unsigned long
+            limit for the size of an epilogue.  */
+ 
+ static int
+-rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
++rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm,
++				     struct gdbarch *gdbarch, CORE_ADDR pc)
+ {
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+   bfd_byte insn_buf[PPC_INSN_SIZE];
+   CORE_ADDR scan_pc, func_start, func_end, epilogue_start, epilogue_end;
+   unsigned long insn;
+-  struct frame_info *curfrm;
+ 
+   /* Find the search limits based on function boundaries and hard limit.  */
+ 
+@@ -893,8 +893,6 @@ rs6000_in_function_epilogue_p (struct gd
+   epilogue_end = pc + PPC_MAX_EPILOGUE_INSTRUCTIONS * PPC_INSN_SIZE;
+   if (epilogue_end > func_end) epilogue_end = func_end;
+ 
+-  curfrm = get_current_frame ();
+-
+   /* Scan forward until next 'blr'.  */
+ 
+   for (scan_pc = pc; scan_pc < epilogue_end; scan_pc += PPC_INSN_SIZE)
+@@ -935,6 +933,15 @@ rs6000_in_function_epilogue_p (struct gd
+   return 0;
+ }
+ 
++/* Implementation of gdbarch_in_function_epilogue_p.  */
++
++static int
++rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
++{
++  return rs6000_in_function_epilogue_frame_p (get_current_frame (),
++					      gdbarch, pc);
++}
++
+ /* Get the ith function argument for the current function.  */
+ static CORE_ADDR
+ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi, 
+@@ -3388,6 +3395,89 @@ static const struct frame_unwind rs6000_
+   NULL,
+   default_frame_sniffer
+ };
++
++static struct rs6000_frame_cache *
++rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
++{
++  volatile struct gdb_exception ex;
++  struct rs6000_frame_cache *cache;
++  struct gdbarch *gdbarch = get_frame_arch (this_frame);
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++  CORE_ADDR sp;
++
++  if (*this_cache)
++    return *this_cache;
++
++  cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache);
++  (*this_cache) = cache;
++  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
++
++  TRY_CATCH (ex, RETURN_MASK_ERROR)
++    {
++      /* At this point the stack looks as if we just entered the
++	 function, and the return address is stored in LR.  */
++      CORE_ADDR sp, lr;
++
++      sp = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
++      lr = get_frame_register_unsigned (this_frame, tdep->ppc_lr_regnum);
++
++      cache->base = sp;
++      cache->initial_sp = sp;
++
++      trad_frame_set_value (cache->saved_regs,
++			    gdbarch_pc_regnum (gdbarch), lr);
++    }
++  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
++    throw_exception (ex);
++
++  return cache;
++}
++
++static void
++rs6000_epilogue_frame_this_id (struct frame_info *this_frame,
++			       void **this_cache, struct frame_id *this_id)
++{
++  CORE_ADDR pc;
++  struct rs6000_frame_cache *info =
++    rs6000_epilogue_frame_cache (this_frame, this_cache);
++
++  pc = get_frame_func (this_frame);
++  if (info->base == 0)
++    (*this_id) = frame_id_build_unavailable_stack (pc);
++  else
++    (*this_id) = frame_id_build (info->base, pc);
++}
++
++static struct value *
++rs6000_epilogue_frame_prev_register (struct frame_info *this_frame,
++				     void **this_cache, int regnum)
++{
++  struct rs6000_frame_cache *info =
++    rs6000_epilogue_frame_cache (this_frame, this_cache);
++  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
++}
++
++static int
++rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
++			       struct frame_info *this_frame,
++			       void **this_prologue_cache)
++{
++  if (frame_relative_level (this_frame) == 0)
++    return rs6000_in_function_epilogue_frame_p (this_frame,
++						get_frame_arch (this_frame),
++						get_frame_pc (this_frame));
++  else
++    return 0;
++}
++
++static const struct frame_unwind rs6000_epilogue_frame_unwind =
++{
++  NORMAL_FRAME,
++  default_frame_unwind_stop_reason,
++  rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register,
++  NULL,
++  rs6000_epilogue_frame_sniffer
++};
+ 
+ 
+ static CORE_ADDR
+@@ -4207,6 +4297,7 @@ rs6000_gdbarch_init (struct gdbarch_info
+     case GDB_OSABI_NETBSD_ELF:
+     case GDB_OSABI_UNKNOWN:
+       set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
++      frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
+       frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
+       set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
+       frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
+@@ -4215,6 +4306,7 @@ rs6000_gdbarch_init (struct gdbarch_info
+       set_gdbarch_believe_pcc_promotion (gdbarch, 1);
+ 
+       set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
++      frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
+       frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
+       set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
+       frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
diff --git a/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-4of7.patch b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-4of7.patch
new file mode 100644
index 0000000..c65490b
--- /dev/null
+++ b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-4of7.patch
@@ -0,0 +1,2248 @@
+  Message-ID: <549C48EA.9060206@gmail.com>
+  Date: Fri, 26 Dec 2014 01:27:06 +0800
+  From: Wei-cheng Wang <cole945 at gmail dot com>
+  To: Ulrich Weigand <uweigand at de dot ibm dot com>
+  CC: gdb-patches at sourceware dot org
+  Subject: Re: [PATCH 2/3 v4] Process record support for PowerPC
+
+  On 12/18/2014 2:41 AM, Ulrich Weigand wrote:
+  > you seem to have removed all the 32-bit struct sizes here.  Your last
+  > iteration had different values for many of those structs for wordsize 4
+  > vs. wordsize 8, and I think we need to keep them.
+
+     Oops, this is a mistake.  I'm sorry.
+     Fixed now :)
+
+  Thanks,
+  Wei-cheng
+
+  --
+
+  2014-12-06  Wei-cheng Wang  <cole945@gmail.com>
+		  Ulrich Weigand  <uweigand@de.ibm.com>
+
+		  * configure.tgt (powerpc*-*-linux): Add linux-record.o to
+		  gdb_target_obs.
+		  (ppc_linux_record_tdep, ppc64_linux_record_tdep): New for linux syscall
+		  record.
+		  (ppc_canonicalize_syscall, ppc_linux_syscall_record,
+		  ppc_linux_record_signal, ppc_init_linux_record_tdep): New functions.
+		  (ppc_linux_init_abi): Set process_record, process_record_signal.
+		  * ppc-tdep.h (struct gdbarch_tdep): Add ppc_syscall_record and
+		  ppc_linux_record_tdep to gdbarch_tdep.
+		  (ppc_process_record): New declaration.
+		  * rs6000-tdep.c (ppc_record_vsr, ppc_process_record_op4,
+		  ppc_process_record_op19, ppc_process_record_op31,
+		  ppc_process_record_op59, ppc_process_record_op60,
+		  ppc_process_record_op63, ppc_process_record): New functions.
+
+  changelog for testsuite
+
+  2014-12-06  Wei-cheng Wang  <cole945@gmail.com>
+
+	      * lib/gdb.exp (supports_process_record): Return true for
+	      powerpc*-*-linux*.
+	      (supports_reverse): Likewise.
+
+
+commit b4cdae6fe51e532e0b1069c6960b14a610182d14
+Author: Wei-cheng Wang <cole945@gmail.com>
+Date:   Sat Jan 17 14:30:33 2015 +0800
+
+    Reverse debugging for PowerPC.
+
+Index: gdb-7.6.1/gdb/configure.tgt
+===================================================================
+--- gdb-7.6.1.orig/gdb/configure.tgt
++++ gdb-7.6.1/gdb/configure.tgt
+@@ -428,7 +428,8 @@ powerpc*-*-linux*)
+ 			ppc64-tdep.o solib-svr4.o solib-spu.o \
+ 			spu-multiarch.o \
+ 			glibc-tdep.o symfile-mem.o linux-tdep.o \
+-			ravenscar-thread.o ppc-ravenscar-thread.o"
++			ravenscar-thread.o ppc-ravenscar-thread.o \
++			linux-record.o "
+ 	gdb_sim=../sim/ppc/libsim.a
+ 	build_gdbserver=yes
+ 	;;
+Index: gdb-7.6.1/gdb/ppc-linux-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/ppc-linux-tdep.c
++++ gdb-7.6.1/gdb/ppc-linux-tdep.c
+@@ -50,6 +50,8 @@
+ #include "spu-tdep.h"
+ #include "xml-syscall.h"
+ #include "linux-tdep.h"
++#include "linux-record.h"
++#include "record-full.h"
+ 
+ #include "stap-probe.h"
+ #include "ax.h"
+@@ -812,6 +814,167 @@ ppc_linux_get_syscall_number (struct gdb
+   return ret;
+ }
+ 
++/* PPC process record-replay */
++
++static struct linux_record_tdep ppc_linux_record_tdep;
++static struct linux_record_tdep ppc64_linux_record_tdep;
++
++static enum gdb_syscall
++ppc_canonicalize_syscall (int syscall)
++{
++  /* See arch/powerpc/include/uapi/asm/unistd.h */
++
++  if (syscall <= 165)
++    return syscall;
++  else if (syscall >= 167 && syscall <= 190)	/* Skip query_module 166 */
++    return syscall + 1;
++  else if (syscall >= 192 && syscall <= 197)	/* mmap2 */
++    return syscall;
++  else if (syscall == 208)			/* tkill */
++    return gdb_sys_tkill;
++  else if (syscall >= 207 && syscall <= 220)	/* gettid */
++    return syscall + 224 - 207;
++  else if (syscall >= 234 && syscall <= 239)	/* exit_group */
++    return syscall + 252 - 234;
++  else if (syscall >= 240 && syscall <=248)	/* timer_create */
++    return syscall += 259 - 240;
++  else if (syscall >= 250 && syscall <=251)	/* tgkill */
++    return syscall + 270 - 250;
++  else if (syscall == 336)
++    return gdb_sys_recv;
++  else if (syscall == 337)
++    return gdb_sys_recvfrom;
++  else if (syscall == 342)
++    return gdb_sys_recvmsg;
++  return -1;
++}
++
++static int
++ppc_linux_syscall_record (struct regcache *regcache)
++{
++  struct gdbarch *gdbarch = get_regcache_arch (regcache);
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++  ULONGEST scnum;
++  enum gdb_syscall syscall_gdb;
++  int ret;
++  int i;
++
++  regcache_raw_read_unsigned (regcache, tdep->ppc_gp0_regnum, &scnum);
++  syscall_gdb = ppc_canonicalize_syscall (scnum);
++
++  if (syscall_gdb < 0)
++    {
++      printf_unfiltered (_("Process record and replay target doesn't "
++			   "support syscall number %d\n"), (int) scnum);
++      return 0;
++    }
++
++  if (syscall_gdb == gdb_sys_sigreturn
++      || syscall_gdb == gdb_sys_rt_sigreturn)
++   {
++     int i, j;
++     int regsets[] = { tdep->ppc_gp0_regnum,
++		       tdep->ppc_fp0_regnum,
++		       tdep->ppc_vr0_regnum,
++		       tdep->ppc_vsr0_upper_regnum };
++
++     for (j = 0; j < 4; j++)
++       {
++	 if (regsets[j] == -1)
++	   continue;
++	 for (i = 0; i < 32; i++)
++	   {
++	     if (record_full_arch_list_add_reg (regcache, regsets[j] + i))
++	       return -1;
++	   }
++       }
++
++     if (record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum))
++       return -1;
++     if (record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum))
++       return -1;
++     if (record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum))
++       return -1;
++     if (record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum))
++       return -1;
++
++     return 0;
++   }
++
++  if (tdep->wordsize == 8)
++    ret = record_linux_system_call (syscall_gdb, regcache,
++				    &ppc64_linux_record_tdep);
++  else
++    ret = record_linux_system_call (syscall_gdb, regcache,
++				    &ppc_linux_record_tdep);
++
++  if (ret != 0)
++    return ret;
++
++  /* Record registers clobbered during syscall.  */
++  for (i = 3; i <= 12; i++)
++    {
++      if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + i))
++	return -1;
++    }
++  if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + 0))
++    return -1;
++  if (record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum))
++    return -1;
++  if (record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum))
++    return -1;
++  if (record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum))
++    return -1;
++
++  return 0;
++}
++
++static int
++ppc_linux_record_signal (struct gdbarch *gdbarch, struct regcache *regcache,
++			 enum gdb_signal signal)
++{
++  /* See handle_rt_signal64 in arch/powerpc/kernel/signal_64.c
++	 handle_rt_signal32 in arch/powerpc/kernel/signal_32.c
++	 arch/powerpc/include/asm/ptrace.h
++     for details.  */
++  const int SIGNAL_FRAMESIZE = 128;
++  const int sizeof_rt_sigframe = 1440 * 2 + 8 * 2 + 4 * 6 + 8 + 8 + 128 + 512;
++  ULONGEST sp;
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++  int i;
++
++  for (i = 3; i <= 12; i++)
++    {
++      if (record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + i))
++	return -1;
++    }
++
++  if (record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum))
++    return -1;
++  if (record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum))
++    return -1;
++  if (record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum))
++    return -1;
++  if (record_full_arch_list_add_reg (regcache, gdbarch_pc_regnum (gdbarch)))
++    return -1;
++  if (record_full_arch_list_add_reg (regcache, gdbarch_sp_regnum (gdbarch)))
++    return -1;
++
++  /* Record the change in the stack.
++     frame-size = sizeof (struct rt_sigframe) + SIGNAL_FRAMESIZE  */
++  regcache_raw_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch), &sp);
++  sp -= SIGNAL_FRAMESIZE;
++  sp -= sizeof_rt_sigframe;
++
++  if (record_full_arch_list_add_mem (sp, SIGNAL_FRAMESIZE + sizeof_rt_sigframe))
++    return -1;
++
++  if (record_full_arch_list_add_end ())
++    return -1;
++
++  return 0;
++}
++
+ static void
+ ppc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
+ {
+@@ -1287,6 +1450,234 @@ static const struct frame_unwind ppu2spu
+   ppu2spu_prev_arch,
+ };
+ 
++/* Initialize linux_record_tdep if not initialized yet.  */
++
++static void
++ppc_init_linux_record_tdep (struct linux_record_tdep *record_tdep,
++			    int wordsize)
++{
++  /* Simply return if it had been initialized.  */
++  if (record_tdep->size_pointer != 0)
++    return;
++
++  /* These values are the size of the type that will be used in a system
++     call.  They are obtained from Linux Kernel source.  */
++
++  if (wordsize == 8)
++    {
++      record_tdep->size_pointer = 8;
++      record_tdep->size__old_kernel_stat = 32;
++      record_tdep->size_tms = 32;
++      record_tdep->size_loff_t = 8;
++      record_tdep->size_flock = 32;
++      record_tdep->size_oldold_utsname = 45;
++      record_tdep->size_ustat = 32;
++      record_tdep->size_old_sigaction = 152;
++      record_tdep->size_old_sigset_t = 128;
++      record_tdep->size_rlimit = 16;
++      record_tdep->size_rusage = 144;
++      record_tdep->size_timeval = 16;
++      record_tdep->size_timezone = 8;
++      record_tdep->size_old_gid_t = 4;
++      record_tdep->size_old_uid_t = 4;
++      record_tdep->size_fd_set = 128;
++      record_tdep->size_dirent = 280;
++      record_tdep->size_dirent64 = 280;
++      record_tdep->size_statfs = 120;
++      record_tdep->size_statfs64 = 120;
++      record_tdep->size_sockaddr = 16;
++      record_tdep->size_int = 4;
++      record_tdep->size_long = 8;
++      record_tdep->size_ulong = 8;
++      record_tdep->size_msghdr = 56;
++      record_tdep->size_itimerval = 32;
++      record_tdep->size_stat = 144;
++      record_tdep->size_old_utsname = 325;
++      record_tdep->size_sysinfo = 112;
++      record_tdep->size_msqid_ds = 120;
++      record_tdep->size_shmid_ds = 112;
++      record_tdep->size_new_utsname = 390;
++      record_tdep->size_timex = 208;
++      record_tdep->size_mem_dqinfo = 24;
++      record_tdep->size_if_dqblk = 72;
++      record_tdep->size_fs_quota_stat = 80;
++      record_tdep->size_timespec = 16;
++      record_tdep->size_pollfd = 8;
++      record_tdep->size_NFS_FHSIZE = 32;
++      record_tdep->size_knfsd_fh = 132;
++      record_tdep->size_TASK_COMM_LEN = 32;
++      record_tdep->size_sigaction = 152;
++      record_tdep->size_sigset_t = 128;
++      record_tdep->size_siginfo_t = 128;
++      record_tdep->size_cap_user_data_t = 8;
++      record_tdep->size_stack_t = 24;
++      record_tdep->size_off_t = 8;
++      record_tdep->size_stat64 = 104;
++      record_tdep->size_gid_t = 4;
++      record_tdep->size_uid_t = 4;
++      record_tdep->size_PAGE_SIZE = 0x10000;	/* 64KB */
++      record_tdep->size_flock64 = 32;
++      record_tdep->size_io_event = 32;
++      record_tdep->size_iocb = 64;
++      record_tdep->size_epoll_event = 16;
++      record_tdep->size_itimerspec = 32;
++      record_tdep->size_mq_attr = 64;
++      record_tdep->size_siginfo = 128;
++      record_tdep->size_termios = 44;
++      record_tdep->size_pid_t = 4;
++      record_tdep->size_winsize = 8;
++      record_tdep->size_serial_struct = 72;
++      record_tdep->size_serial_icounter_struct = 80;
++      record_tdep->size_size_t = 8;
++      record_tdep->size_iovec = 16;
++    }
++  else if (wordsize == 4)
++    {
++      record_tdep->size_pointer = 4;
++      record_tdep->size__old_kernel_stat = 32;
++      record_tdep->size_tms = 16;
++      record_tdep->size_loff_t = 8;
++      record_tdep->size_flock = 16;
++      record_tdep->size_oldold_utsname = 45;
++      record_tdep->size_ustat = 20;
++      record_tdep->size_old_sigaction = 152;
++      record_tdep->size_old_sigset_t = 128;
++      record_tdep->size_rlimit = 8;
++      record_tdep->size_rusage = 72;
++      record_tdep->size_timeval = 8;
++      record_tdep->size_timezone = 8;
++      record_tdep->size_old_gid_t = 4;
++      record_tdep->size_old_uid_t = 4;
++      record_tdep->size_fd_set = 128;
++      record_tdep->size_dirent = 268;
++      record_tdep->size_dirent64 = 280;
++      record_tdep->size_statfs = 64;
++      record_tdep->size_statfs64 = 88;
++      record_tdep->size_sockaddr = 16;
++      record_tdep->size_int = 4;
++      record_tdep->size_long = 4;
++      record_tdep->size_ulong = 4;
++      record_tdep->size_msghdr = 28;
++      record_tdep->size_itimerval = 16;
++      record_tdep->size_stat = 88;
++      record_tdep->size_old_utsname = 325;
++      record_tdep->size_sysinfo = 64;
++      record_tdep->size_msqid_ds = 68;
++      record_tdep->size_shmid_ds = 60;
++      record_tdep->size_new_utsname = 390;
++      record_tdep->size_timex = 128;
++      record_tdep->size_mem_dqinfo = 24;
++      record_tdep->size_if_dqblk = 72;
++      record_tdep->size_fs_quota_stat = 80;
++      record_tdep->size_timespec = 8;
++      record_tdep->size_pollfd = 8;
++      record_tdep->size_NFS_FHSIZE = 32;
++      record_tdep->size_knfsd_fh = 132;
++      record_tdep->size_TASK_COMM_LEN = 32;
++      record_tdep->size_sigaction = 140;
++      record_tdep->size_sigset_t = 128;
++      record_tdep->size_siginfo_t = 128;
++      record_tdep->size_cap_user_data_t = 4;
++      record_tdep->size_stack_t = 12;
++      record_tdep->size_off_t = 4;
++      record_tdep->size_stat64 = 104;
++      record_tdep->size_gid_t = 4;
++      record_tdep->size_uid_t = 4;
++      record_tdep->size_PAGE_SIZE = 0x10000;	/* 64KB */
++      record_tdep->size_flock64 = 32;
++      record_tdep->size_io_event = 32;
++      record_tdep->size_iocb = 64;
++      record_tdep->size_epoll_event = 16;
++      record_tdep->size_itimerspec = 16;
++      record_tdep->size_mq_attr = 32;
++      record_tdep->size_siginfo = 128;
++      record_tdep->size_termios = 44;
++      record_tdep->size_pid_t = 4;
++      record_tdep->size_winsize = 8;
++      record_tdep->size_serial_struct = 60;
++      record_tdep->size_serial_icounter_struct = 80;
++      record_tdep->size_size_t = 4;
++      record_tdep->size_iovec = 8;
++    }
++  else
++    internal_error (__FILE__, __LINE__, _("unexpected wordsize"));
++
++  /* These values are the second argument of system call "sys_fcntl"
++     and "sys_fcntl64".  They are obtained from Linux Kernel source.  */
++  record_tdep->fcntl_F_GETLK = 5;
++  record_tdep->fcntl_F_GETLK64 = 12;
++  record_tdep->fcntl_F_SETLK64 = 13;
++  record_tdep->fcntl_F_SETLKW64 = 14;
++
++  record_tdep->arg1 = PPC_R0_REGNUM + 3;
++  record_tdep->arg2 = PPC_R0_REGNUM + 4;
++  record_tdep->arg3 = PPC_R0_REGNUM + 5;
++  record_tdep->arg4 = PPC_R0_REGNUM + 6;
++  record_tdep->arg5 = PPC_R0_REGNUM + 7;
++  record_tdep->arg6 = PPC_R0_REGNUM + 8;
++
++  /* These values are the second argument of system call "sys_ioctl".
++     They are obtained from Linux Kernel source.
++     See arch/powerpc/include/uapi/asm/ioctls.h.  */
++  record_tdep->ioctl_TCGETS = 0x403c7413;
++  record_tdep->ioctl_TCSETS = 0x803c7414;
++  record_tdep->ioctl_TCSETSW = 0x803c7415;
++  record_tdep->ioctl_TCSETSF = 0x803c7416;
++  record_tdep->ioctl_TCGETA = 0x40147417;
++  record_tdep->ioctl_TCSETA = 0x80147418;
++  record_tdep->ioctl_TCSETAW = 0x80147419;
++  record_tdep->ioctl_TCSETAF = 0x8014741c;
++  record_tdep->ioctl_TCSBRK = 0x2000741d;
++  record_tdep->ioctl_TCXONC = 0x2000741e;
++  record_tdep->ioctl_TCFLSH = 0x2000741f;
++  record_tdep->ioctl_TIOCEXCL = 0x540c;
++  record_tdep->ioctl_TIOCNXCL = 0x540d;
++  record_tdep->ioctl_TIOCSCTTY = 0x540e;
++  record_tdep->ioctl_TIOCGPGRP = 0x40047477;
++  record_tdep->ioctl_TIOCSPGRP = 0x80047476;
++  record_tdep->ioctl_TIOCOUTQ = 0x40047473;
++  record_tdep->ioctl_TIOCSTI = 0x5412;
++  record_tdep->ioctl_TIOCGWINSZ = 0x40087468;
++  record_tdep->ioctl_TIOCSWINSZ = 0x80087467;
++  record_tdep->ioctl_TIOCMGET = 0x5415;
++  record_tdep->ioctl_TIOCMBIS = 0x5416;
++  record_tdep->ioctl_TIOCMBIC = 0x5417;
++  record_tdep->ioctl_TIOCMSET = 0x5418;
++  record_tdep->ioctl_TIOCGSOFTCAR = 0x5419;
++  record_tdep->ioctl_TIOCSSOFTCAR = 0x541a;
++  record_tdep->ioctl_FIONREAD = 0x4004667f;
++  record_tdep->ioctl_TIOCINQ = 0x4004667f;
++  record_tdep->ioctl_TIOCLINUX = 0x541c;
++  record_tdep->ioctl_TIOCCONS = 0x541d;
++  record_tdep->ioctl_TIOCGSERIAL = 0x541e;
++  record_tdep->ioctl_TIOCSSERIAL = 0x541f;
++  record_tdep->ioctl_TIOCPKT = 0x5420;
++  record_tdep->ioctl_FIONBIO = 0x8004667e;
++  record_tdep->ioctl_TIOCNOTTY = 0x5422;
++  record_tdep->ioctl_TIOCSETD = 0x5423;
++  record_tdep->ioctl_TIOCGETD = 0x5424;
++  record_tdep->ioctl_TCSBRKP = 0x5425;
++  record_tdep->ioctl_TIOCSBRK = 0x5427;
++  record_tdep->ioctl_TIOCCBRK = 0x5428;
++  record_tdep->ioctl_TIOCGSID = 0x5429;
++  record_tdep->ioctl_TIOCGPTN = 0x40045430;
++  record_tdep->ioctl_TIOCSPTLCK = 0x80045431;
++  record_tdep->ioctl_FIONCLEX = 0x20006602;
++  record_tdep->ioctl_FIOCLEX = 0x20006601;
++  record_tdep->ioctl_FIOASYNC = 0x8004667d;
++  record_tdep->ioctl_TIOCSERCONFIG = 0x5453;
++  record_tdep->ioctl_TIOCSERGWILD = 0x5454;
++  record_tdep->ioctl_TIOCSERSWILD = 0x5455;
++  record_tdep->ioctl_TIOCGLCKTRMIOS = 0x5456;
++  record_tdep->ioctl_TIOCSLCKTRMIOS = 0x5457;
++  record_tdep->ioctl_TIOCSERGSTRUCT = 0x5458;
++  record_tdep->ioctl_TIOCSERGETLSR = 0x5459;
++  record_tdep->ioctl_TIOCSERGETMULTI = 0x545a;
++  record_tdep->ioctl_TIOCSERSETMULTI = 0x545b;
++  record_tdep->ioctl_TIOCMIWAIT = 0x545c;
++  record_tdep->ioctl_TIOCGICOUNT = 0x545d;
++  record_tdep->ioctl_FIOQSIZE = 0x40086680;
++}
+ 
+ static void
+ ppc_linux_init_abi (struct gdbarch_info info,
+@@ -1486,6 +1877,14 @@ ppc_linux_init_abi (struct gdbarch_info
+     }
+ 
+   set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
++
++  /* Support reverse debugging.  */
++  set_gdbarch_process_record (gdbarch, ppc_process_record);
++  set_gdbarch_process_record_signal (gdbarch, ppc_linux_record_signal);
++  tdep->ppc_syscall_record = ppc_linux_syscall_record;
++
++  ppc_init_linux_record_tdep (&ppc_linux_record_tdep, 4);
++  ppc_init_linux_record_tdep (&ppc64_linux_record_tdep, 8);
+ }
+ 
+ /* Provide a prototype to silence -Wmissing-prototypes.  */
+Index: gdb-7.6.1/gdb/ppc-tdep.h
+===================================================================
+--- gdb-7.6.1.orig/gdb/ppc-tdep.h
++++ gdb-7.6.1/gdb/ppc-tdep.h
+@@ -259,6 +259,8 @@ struct gdbarch_tdep
+     /* ISA-specific types.  */
+     struct type *ppc_builtin_type_vec64;
+     struct type *ppc_builtin_type_vec128;
++
++    int (*ppc_syscall_record) (struct regcache *regcache);
+ };
+ 
+ 
+@@ -318,6 +320,9 @@ extern CORE_ADDR ppc_insn_d_field (unsig
+ 
+ extern CORE_ADDR ppc_insn_ds_field (unsigned int insn);
+ 
++extern int ppc_process_record (struct gdbarch *gdbarch,
++			       struct regcache *regcache, CORE_ADDR addr);
++
+ /* Instruction size.  */
+ #define PPC_INSN_SIZE 4
+ 
+Index: gdb-7.6.1/gdb/rs6000-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/rs6000-tdep.c
++++ gdb-7.6.1/gdb/rs6000-tdep.c
+@@ -39,6 +39,8 @@
+ #include "dwarf2-frame.h"
+ #include "target-descriptions.h"
+ #include "user-regs.h"
++#include "record-full.h"
++#include "auxv.h"
+ 
+ #include "libbfd.h"		/* for bfd_default_set_arch_mach */
+ #include "coff/internal.h"	/* for libcoff.h */
+@@ -3682,6 +3684,1689 @@ bfd_uses_spe_extensions (bfd *abfd)
+   return success;
+ }
+ 
++/* These are macros for parsing instruction fields (I.1.6.28)  */
++
++#define PPC_FIELD(value, from, len) \
++	(((value) >> (32 - (from) - (len))) & ((1 << (len)) - 1))
++#define PPC_SEXT(v, bs) \
++	((((CORE_ADDR) (v) & (((CORE_ADDR) 1 << (bs)) - 1)) \
++	  ^ ((CORE_ADDR) 1 << ((bs) - 1))) \
++	 - ((CORE_ADDR) 1 << ((bs) - 1)))
++#define PPC_OP6(insn)	PPC_FIELD (insn, 0, 6)
++#define PPC_EXTOP(insn)	PPC_FIELD (insn, 21, 10)
++#define PPC_RT(insn)	PPC_FIELD (insn, 6, 5)
++#define PPC_RS(insn)	PPC_FIELD (insn, 6, 5)
++#define PPC_RA(insn)	PPC_FIELD (insn, 11, 5)
++#define PPC_RB(insn)	PPC_FIELD (insn, 16, 5)
++#define PPC_NB(insn)	PPC_FIELD (insn, 16, 5)
++#define PPC_VRT(insn)	PPC_FIELD (insn, 6, 5)
++#define PPC_FRT(insn)	PPC_FIELD (insn, 6, 5)
++#define PPC_SPR(insn)	(PPC_FIELD (insn, 11, 5) \
++			| (PPC_FIELD (insn, 16, 5) << 5))
++#define PPC_BO(insn)	PPC_FIELD (insn, 6, 5)
++#define PPC_T(insn)	PPC_FIELD (insn, 6, 5)
++#define PPC_D(insn)	PPC_SEXT (PPC_FIELD (insn, 16, 16), 16)
++#define PPC_DS(insn)	PPC_SEXT (PPC_FIELD (insn, 16, 14), 14)
++#define PPC_BIT(insn,n)	((insn & (1 << (31 - (n)))) ? 1 : 0)
++#define PPC_OE(insn)	PPC_BIT (insn, 21)
++#define PPC_RC(insn)	PPC_BIT (insn, 31)
++#define PPC_Rc(insn)	PPC_BIT (insn, 21)
++#define PPC_LK(insn)	PPC_BIT (insn, 31)
++#define PPC_TX(insn)	PPC_BIT (insn, 31)
++#define PPC_LEV(insn)	PPC_FIELD (insn, 20, 7)
++
++#define PPC_XT(insn)	((PPC_TX (insn) << 5) | PPC_T (insn))
++#define PPC_XER_NB(xer)	(xer & 0x7f)
++
++/* Record Vector-Scalar Registers.  */
++
++static int
++ppc_record_vsr (struct regcache *regcache, struct gdbarch_tdep *tdep, int vsr)
++{
++  if (vsr < 0 || vsr >= 64)
++    return -1;
++
++  if (vsr >= 32)
++    {
++      if (tdep->ppc_vr0_regnum >= 0)
++	record_full_arch_list_add_reg (regcache, tdep->ppc_vr0_regnum + vsr - 32);
++    }
++  else
++    {
++      if (tdep->ppc_fp0_regnum >= 0)
++	record_full_arch_list_add_reg (regcache, tdep->ppc_fp0_regnum + vsr);
++      if (tdep->ppc_vsr0_upper_regnum >= 0)
++	record_full_arch_list_add_reg (regcache,
++				       tdep->ppc_vsr0_upper_regnum + vsr);
++    }
++
++  return 0;
++}
++
++/* Parse instructions of primary opcode-4.  */
++
++static int
++ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
++			   CORE_ADDR addr, uint32_t insn)
++{
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++  int ext = PPC_FIELD (insn, 21, 11);
++
++  switch (ext & 0x3f)
++    {
++    case 32:		/* Vector Multiply-High-Add Signed Halfword Saturate */
++    case 33:		/* Vector Multiply-High-Round-Add Signed Halfword Saturate */
++    case 39:		/* Vector Multiply-Sum Unsigned Halfword Saturate */
++    case 41:		/* Vector Multiply-Sum Signed Halfword Saturate */
++      record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
++      /* FALL-THROUGH */
++    case 42:		/* Vector Select */
++    case 43:		/* Vector Permute */
++    case 44:		/* Vector Shift Left Double by Octet Immediate */
++    case 45:		/* Vector Permute and Exclusive-OR */
++    case 60:		/* Vector Add Extended Unsigned Quadword Modulo */
++    case 61:		/* Vector Add Extended & write Carry Unsigned Quadword */
++    case 62:		/* Vector Subtract Extended Unsigned Quadword Modulo */
++    case 63:		/* Vector Subtract Extended & write Carry Unsigned Quadword */
++    case 34:		/* Vector Multiply-Low-Add Unsigned Halfword Modulo */
++    case 36:		/* Vector Multiply-Sum Unsigned Byte Modulo */
++    case 37:		/* Vector Multiply-Sum Mixed Byte Modulo */
++    case 38:		/* Vector Multiply-Sum Unsigned Halfword Modulo */
++    case 40:		/* Vector Multiply-Sum Signed Halfword Modulo */
++    case 46:		/* Vector Multiply-Add Single-Precision */
++    case 47:		/* Vector Negative Multiply-Subtract Single-Precision */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
++      return 0;
++    }
++
++  switch ((ext & 0x1ff))
++    {
++			/* 5.16 Decimal Integer Arithmetic Instructions */
++    case 1:		/* Decimal Add Modulo */
++    case 65:		/* Decimal Subtract Modulo */
++
++      /* Bit-21 should be set.  */
++      if (!PPC_BIT (insn, 21))
++	break;
++
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      return 0;
++    }
++
++  /* Bit-21 is used for RC */
++  switch (ext & 0x3ff)
++    {
++    case 6:		/* Vector Compare Equal To Unsigned Byte */
++    case 70:		/* Vector Compare Equal To Unsigned Halfword */
++    case 134:		/* Vector Compare Equal To Unsigned Word */
++    case 199:		/* Vector Compare Equal To Unsigned Doubleword */
++    case 774:		/* Vector Compare Greater Than Signed Byte */
++    case 838:		/* Vector Compare Greater Than Signed Halfword */
++    case 902:		/* Vector Compare Greater Than Signed Word */
++    case 967:		/* Vector Compare Greater Than Signed Doubleword */
++    case 518:		/* Vector Compare Greater Than Unsigned Byte */
++    case 646:		/* Vector Compare Greater Than Unsigned Word */
++    case 582:		/* Vector Compare Greater Than Unsigned Halfword */
++    case 711:		/* Vector Compare Greater Than Unsigned Doubleword */
++    case 966:		/* Vector Compare Bounds Single-Precision */
++    case 198:		/* Vector Compare Equal To Single-Precision */
++    case 454:		/* Vector Compare Greater Than or Equal To Single-Precision */
++    case 710:		/* Vector Compare Greater Than Single-Precision */
++      if (PPC_Rc (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
++      return 0;
++    }
++
++  switch (ext)
++    {
++    case 142:		/* Vector Pack Unsigned Halfword Unsigned Saturate */
++    case 206:		/* Vector Pack Unsigned Word Unsigned Saturate */
++    case 270:		/* Vector Pack Signed Halfword Unsigned Saturate */
++    case 334:		/* Vector Pack Signed Word Unsigned Saturate */
++    case 398:		/* Vector Pack Signed Halfword Signed Saturate */
++    case 462:		/* Vector Pack Signed Word Signed Saturate */
++    case 1230:		/* Vector Pack Unsigned Doubleword Unsigned Saturate */
++    case 1358:		/* Vector Pack Signed Doubleword Unsigned Saturate */
++    case 1486:		/* Vector Pack Signed Doubleword Signed Saturate */
++    case 512:		/* Vector Add Unsigned Byte Saturate */
++    case 576:		/* Vector Add Unsigned Halfword Saturate */
++    case 640:		/* Vector Add Unsigned Word Saturate */
++    case 768:		/* Vector Add Signed Byte Saturate */
++    case 832:		/* Vector Add Signed Halfword Saturate */
++    case 896:		/* Vector Add Signed Word Saturate */
++    case 1536:		/* Vector Subtract Unsigned Byte Saturate */
++    case 1600:		/* Vector Subtract Unsigned Halfword Saturate */
++    case 1664:		/* Vector Subtract Unsigned Word Saturate */
++    case 1792:		/* Vector Subtract Signed Byte Saturate */
++    case 1856:		/* Vector Subtract Signed Halfword Saturate */
++    case 1920:		/* Vector Subtract Signed Word Saturate */
++
++    case 1544:		/* Vector Sum across Quarter Unsigned Byte Saturate */
++    case 1800:		/* Vector Sum across Quarter Signed Byte Saturate */
++    case 1608:		/* Vector Sum across Quarter Signed Halfword Saturate */
++    case 1672:		/* Vector Sum across Half Signed Word Saturate */
++    case 1928:		/* Vector Sum across Signed Word Saturate */
++    case 970:		/* Vector Convert To Signed Fixed-Point Word Saturate */
++    case 906:		/* Vector Convert To Unsigned Fixed-Point Word Saturate */
++      record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
++      /* FALL-THROUGH */
++    case 12:		/* Vector Merge High Byte */
++    case 14:		/* Vector Pack Unsigned Halfword Unsigned Modulo */
++    case 76:		/* Vector Merge High Halfword */
++    case 78:		/* Vector Pack Unsigned Word Unsigned Modulo */
++    case 140:		/* Vector Merge High Word */
++    case 268:		/* Vector Merge Low Byte */
++    case 332:		/* Vector Merge Low Halfword */
++    case 396:		/* Vector Merge Low Word */
++    case 526:		/* Vector Unpack High Signed Byte */
++    case 590:		/* Vector Unpack High Signed Halfword */
++    case 654:		/* Vector Unpack Low Signed Byte */
++    case 718:		/* Vector Unpack Low Signed Halfword */
++    case 782:		/* Vector Pack Pixel */
++    case 846:		/* Vector Unpack High Pixel */
++    case 974:		/* Vector Unpack Low Pixel */
++    case 1102:		/* Vector Pack Unsigned Doubleword Unsigned Modulo */
++    case 1614:		/* Vector Unpack High Signed Word */
++    case 1676:		/* Vector Merge Odd Word */
++    case 1742:		/* Vector Unpack Low Signed Word */
++    case 1932:		/* Vector Merge Even Word */
++    case 524:		/* Vector Splat Byte */
++    case 588:		/* Vector Splat Halfword */
++    case 652:		/* Vector Splat Word */
++    case 780:		/* Vector Splat Immediate Signed Byte */
++    case 844:		/* Vector Splat Immediate Signed Halfword */
++    case 908:		/* Vector Splat Immediate Signed Word */
++    case 452:		/* Vector Shift Left */
++    case 708:		/* Vector Shift Right */
++    case 1036:		/* Vector Shift Left by Octet */
++    case 1100:		/* Vector Shift Right by Octet */
++    case 0:		/* Vector Add Unsigned Byte Modulo */
++    case 64:		/* Vector Add Unsigned Halfword Modulo */
++    case 128:		/* Vector Add Unsigned Word Modulo */
++    case 192:		/* Vector Add Unsigned Doubleword Modulo */
++    case 256:		/* Vector Add Unsigned Quadword Modulo */
++    case 320:		/* Vector Add & write Carry Unsigned Quadword */
++    case 384:		/* Vector Add and Write Carry-Out Unsigned Word */
++    case 8:		/* Vector Multiply Odd Unsigned Byte */
++    case 72:		/* Vector Multiply Odd Unsigned Halfword */
++    case 136:		/* Vector Multiply Odd Unsigned Word */
++    case 264:		/* Vector Multiply Odd Signed Byte */
++    case 328:		/* Vector Multiply Odd Signed Halfword */
++    case 392:		/* Vector Multiply Odd Signed Word */
++    case 520:		/* Vector Multiply Even Unsigned Byte */
++    case 584:		/* Vector Multiply Even Unsigned Halfword */
++    case 648:		/* Vector Multiply Even Unsigned Word */
++    case 776:		/* Vector Multiply Even Signed Byte */
++    case 840:		/* Vector Multiply Even Signed Halfword */
++    case 904:		/* Vector Multiply Even Signed Word */
++    case 137:		/* Vector Multiply Unsigned Word Modulo */
++    case 1024:		/* Vector Subtract Unsigned Byte Modulo */
++    case 1088:		/* Vector Subtract Unsigned Halfword Modulo */
++    case 1152:		/* Vector Subtract Unsigned Word Modulo */
++    case 1216:		/* Vector Subtract Unsigned Doubleword Modulo */
++    case 1280:		/* Vector Subtract Unsigned Quadword Modulo */
++    case 1344:		/* Vector Subtract & write Carry Unsigned Quadword */
++    case 1408:		/* Vector Subtract and Write Carry-Out Unsigned Word */
++    case 1282:		/* Vector Average Signed Byte */
++    case 1346:		/* Vector Average Signed Halfword */
++    case 1410:		/* Vector Average Signed Word */
++    case 1026:		/* Vector Average Unsigned Byte */
++    case 1090:		/* Vector Average Unsigned Halfword */
++    case 1154:		/* Vector Average Unsigned Word */
++    case 258:		/* Vector Maximum Signed Byte */
++    case 322:		/* Vector Maximum Signed Halfword */
++    case 386:		/* Vector Maximum Signed Word */
++    case 450:		/* Vector Maximum Signed Doubleword */
++    case 2:		/* Vector Maximum Unsigned Byte */
++    case 66:		/* Vector Maximum Unsigned Halfword */
++    case 130:		/* Vector Maximum Unsigned Word */
++    case 194:		/* Vector Maximum Unsigned Doubleword */
++    case 770:		/* Vector Minimum Signed Byte */
++    case 834:		/* Vector Minimum Signed Halfword */
++    case 898:		/* Vector Minimum Signed Word */
++    case 962:		/* Vector Minimum Signed Doubleword */
++    case 514:		/* Vector Minimum Unsigned Byte */
++    case 578:		/* Vector Minimum Unsigned Halfword */
++    case 642:		/* Vector Minimum Unsigned Word */
++    case 706:		/* Vector Minimum Unsigned Doubleword */
++    case 1028:		/* Vector Logical AND */
++    case 1668:		/* Vector Logical Equivalent */
++    case 1092:		/* Vector Logical AND with Complement */
++    case 1412:		/* Vector Logical NAND */
++    case 1348:		/* Vector Logical OR with Complement */
++    case 1156:		/* Vector Logical OR */
++    case 1284:		/* Vector Logical NOR */
++    case 1220:		/* Vector Logical XOR */
++    case 4:		/* Vector Rotate Left Byte */
++    case 132:		/* Vector Rotate Left Word VX-form */
++    case 68:		/* Vector Rotate Left Halfword */
++    case 196:		/* Vector Rotate Left Doubleword */
++    case 260:		/* Vector Shift Left Byte */
++    case 388:		/* Vector Shift Left Word */
++    case 324:		/* Vector Shift Left Halfword */
++    case 1476:		/* Vector Shift Left Doubleword */
++    case 516:		/* Vector Shift Right Byte */
++    case 644:		/* Vector Shift Right Word */
++    case 580:		/* Vector Shift Right Halfword */
++    case 1732:		/* Vector Shift Right Doubleword */
++    case 772:		/* Vector Shift Right Algebraic Byte */
++    case 900:		/* Vector Shift Right Algebraic Word */
++    case 836:		/* Vector Shift Right Algebraic Halfword */
++    case 964:		/* Vector Shift Right Algebraic Doubleword */
++    case 10:		/* Vector Add Single-Precision */
++    case 74:		/* Vector Subtract Single-Precision */
++    case 1034:		/* Vector Maximum Single-Precision */
++    case 1098:		/* Vector Minimum Single-Precision */
++    case 842:		/* Vector Convert From Signed Fixed-Point Word */
++    case 778:		/* Vector Convert From Unsigned Fixed-Point Word */
++    case 714:		/* Vector Round to Single-Precision Integer toward -Infinity */
++    case 522:		/* Vector Round to Single-Precision Integer Nearest */
++    case 650:		/* Vector Round to Single-Precision Integer toward +Infinity */
++    case 586:		/* Vector Round to Single-Precision Integer toward Zero */
++    case 394:		/* Vector 2 Raised to the Exponent Estimate Floating-Point */
++    case 458:		/* Vector Log Base 2 Estimate Floating-Point */
++    case 266:		/* Vector Reciprocal Estimate Single-Precision */
++    case 330:		/* Vector Reciprocal Square Root Estimate Single-Precision */
++    case 1288:		/* Vector AES Cipher */
++    case 1289:		/* Vector AES Cipher Last */
++    case 1352:		/* Vector AES Inverse Cipher */
++    case 1353:		/* Vector AES Inverse Cipher Last */
++    case 1480:		/* Vector AES SubBytes */
++    case 1730:		/* Vector SHA-512 Sigma Doubleword */
++    case 1666:		/* Vector SHA-256 Sigma Word */
++    case 1032:		/* Vector Polynomial Multiply-Sum Byte */
++    case 1160:		/* Vector Polynomial Multiply-Sum Word */
++    case 1096:		/* Vector Polynomial Multiply-Sum Halfword */
++    case 1224:		/* Vector Polynomial Multiply-Sum Doubleword */
++    case 1292:		/* Vector Gather Bits by Bytes by Doubleword */
++    case 1794:		/* Vector Count Leading Zeros Byte */
++    case 1858:		/* Vector Count Leading Zeros Halfword */
++    case 1922:		/* Vector Count Leading Zeros Word */
++    case 1986:		/* Vector Count Leading Zeros Doubleword */
++    case 1795:		/* Vector Population Count Byte */
++    case 1859:		/* Vector Population Count Halfword */
++    case 1923:		/* Vector Population Count Word */
++    case 1987:		/* Vector Population Count Doubleword */
++    case 1356:		/* Vector Bit Permute Quadword */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
++      return 0;
++
++    case 1604:		/* Move To Vector Status and Control Register */
++      record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
++      return 0;
++    case 1540:		/* Move From Vector Status and Control Register */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
++      return 0;
++    }
++
++  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
++		      "%08x at %08lx, 4-%d.\n", insn, addr, ext);
++  return -1;
++}
++
++/* Parse instructions of primary opcode-19.  */
++
++static int
++ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
++			   CORE_ADDR addr, uint32_t insn)
++{
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++  int ext = PPC_EXTOP (insn);
++
++  switch (ext)
++    {
++    case 0:		/* Move Condition Register Field */
++    case 33:		/* Condition Register NOR */
++    case 129:		/* Condition Register AND with Complement */
++    case 193:		/* Condition Register XOR */
++    case 225:		/* Condition Register NAND */
++    case 257:		/* Condition Register AND */
++    case 289:		/* Condition Register Equivalent */
++    case 417:		/* Condition Register OR with Complement */
++    case 449:		/* Condition Register OR */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      return 0;
++
++    case 16:		/* Branch Conditional */
++    case 560:		/* Branch Conditional to Branch Target Address Register */
++      if ((PPC_BO (insn) & 0x4) == 0)
++	record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum);
++      /* FALL-THROUGH */
++    case 528:		/* Branch Conditional to Count Register */
++      if (PPC_LK (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
++      return 0;
++
++    case 150:		/* Instruction Synchronize */
++      /* Do nothing.  */
++      return 0;
++    }
++
++  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
++		      "%08x at %08lx, 19-%d.\n", insn, addr, ext);
++  return -1;
++}
++
++/* Parse instructions of primary opcode-31.  */
++
++static int
++ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
++			   CORE_ADDR addr, uint32_t insn)
++{
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++  int ext = PPC_EXTOP (insn);
++  int tmp, nr, nb, i;
++  CORE_ADDR at_dcsz, ea = 0;
++  ULONGEST rb, ra, xer;
++  int size = 0;
++
++  /* These instructions have OE bit.  */
++  switch (ext & 0x1ff)
++    {
++    /* These write RT and XER.  Update CR if RC is set.  */
++    case 8:		/* Subtract from carrying */
++    case 10:		/* Add carrying */
++    case 136:		/* Subtract from extended */
++    case 138:		/* Add extended */
++    case 200:		/* Subtract from zero extended */
++    case 202:		/* Add to zero extended */
++    case 232:		/* Subtract from minus one extended */
++    case 234:		/* Add to minus one extended */
++      /* CA is always altered, but SO/OV are only altered when OE=1.
++	 In any case, XER is always altered.  */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RT (insn));
++      return 0;
++
++    /* These write RT.  Update CR if RC is set and update XER if OE is set.  */
++    case 40:		/* Subtract from */
++    case 104:		/* Negate */
++    case 233:		/* Multiply low doubleword */
++    case 235:		/* Multiply low word */
++    case 266:		/* Add */
++    case 393:		/* Divide Doubleword Extended Unsigned */
++    case 395:		/* Divide Word Extended Unsigned */
++    case 425:		/* Divide Doubleword Extended */
++    case 427:		/* Divide Word Extended */
++    case 457:		/* Divide Doubleword Unsigned */
++    case 459:		/* Divide Word Unsigned */
++    case 489:		/* Divide Doubleword */
++    case 491:		/* Divide Word */
++      if (PPC_OE (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
++      /* FALL-THROUGH */
++    case 9:		/* Multiply High Doubleword Unsigned */
++    case 11:		/* Multiply High Word Unsigned */
++    case 73:		/* Multiply High Doubleword */
++    case 75:		/* Multiply High Word */
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RT (insn));
++      return 0;
++    }
++
++  if ((ext & 0x1f) == 15)
++    {
++      /* Integer Select. bit[16:20] is used for BC.  */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RT (insn));
++      return 0;
++    }
++
++  switch (ext)
++    {
++    case 78:		/* Determine Leftmost Zero Byte */
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RT (insn));
++      return 0;
++
++    /* These only write RT.  */
++    case 19:		/* Move from condition register */
++			/* Move From One Condition Register Field */
++    case 74:		/* Add and Generate Sixes */
++    case 74 | 0x200:	/* Add and Generate Sixes (bit-21 dont-care) */
++    case 302:		/* Move From Branch History Rolling Buffer */
++    case 339:		/* Move From Special Purpose Register */
++    case 371:		/* Move From Time Base [Phased-Out]  */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RT (insn));
++      return 0;
++
++    /* These only write to RA.  */
++    case 51:		/* Move From VSR Doubleword */
++    case 115:		/* Move From VSR Word and Zero */
++    case 122:		/* Population count bytes */
++    case 378:		/* Population count words */
++    case 506:		/* Population count doublewords */
++    case 154:		/* Parity Word */
++    case 186:		/* Parity Doubleword */
++    case 252:		/* Bit Permute Doubleword */
++    case 282:		/* Convert Declets To Binary Coded Decimal */
++    case 314:		/* Convert Binary Coded Decimal To Declets */
++    case 508:		/* Compare bytes */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RA (insn));
++      return 0;
++
++    /* These write CR and optional RA.  */
++    case 792:		/* Shift Right Algebraic Word */
++    case 794:		/* Shift Right Algebraic Doubleword */
++    case 824:		/* Shift Right Algebraic Word Immediate */
++    case 826:		/* Shift Right Algebraic Doubleword Immediate (413) */
++    case 826 | 1:	/* Shift Right Algebraic Doubleword Immediate (413) */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RA (insn));
++      /* FALL-THROUGH */
++    case 0:		/* Compare */
++    case 32:		/* Compare logical */
++    case 144:		/* Move To Condition Register Fields */
++			/* Move To One Condition Register Field */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      return 0;
++
++    /* These write to RT.  Update RA if 'update indexed.'  */
++    case 53:		/* Load Doubleword with Update Indexed */
++    case 119:		/* Load Byte and Zero with Update Indexed */
++    case 311:		/* Load Halfword and Zero with Update Indexed */
++    case 55:		/* Load Word and Zero with Update Indexed */
++    case 375:		/* Load Halfword Algebraic with Update Indexed */
++    case 373:		/* Load Word Algebraic with Update Indexed */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RA (insn));
++      /* FALL-THROUGH */
++    case 21:		/* Load Doubleword Indexed */
++    case 52:		/* Load Byte And Reserve Indexed */
++    case 116:		/* Load Halfword And Reserve Indexed */
++    case 20:		/* Load Word And Reserve Indexed */
++    case 84:		/* Load Doubleword And Reserve Indexed */
++    case 87:		/* Load Byte and Zero Indexed */
++    case 279:		/* Load Halfword and Zero Indexed */
++    case 23:		/* Load Word and Zero Indexed */
++    case 343:		/* Load Halfword Algebraic Indexed */
++    case 341:		/* Load Word Algebraic Indexed */
++    case 790:		/* Load Halfword Byte-Reverse Indexed */
++    case 534:		/* Load Word Byte-Reverse Indexed */
++    case 532:		/* Load Doubleword Byte-Reverse Indexed */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RT (insn));
++      return 0;
++
++    case 597:		/* Load String Word Immediate */
++    case 533:		/* Load String Word Indexed */
++      if (ext == 597)
++	{
++	nr = PPC_NB (insn);
++	if (nr == 0)
++	  nr = 32;
++	}
++      else
++	{
++	  regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &xer);
++	  nr = PPC_XER_NB (xer);
++	}
++
++      nr = (nr + 3) >> 2;
++
++      /* If n=0, the contents of register RT are undefined.  */
++      if (nr == 0)
++	nr = 1;
++
++      for (i = 0; i < nr; i++)
++	record_full_arch_list_add_reg (regcache,
++				       tdep->ppc_gp0_regnum
++				       + ((PPC_RT (insn) + i) & 0x1f));
++      return 0;
++
++    case 276:		/* Load Quadword And Reserve Indexed */
++      tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn) & ~1);
++      record_full_arch_list_add_reg (regcache, tmp);
++      record_full_arch_list_add_reg (regcache, tmp + 1);
++      return 0;
++
++    /* These write VRT.  */
++    case 6:		/* Load Vector for Shift Left Indexed */
++    case 38:		/* Load Vector for Shift Right Indexed */
++    case 7:		/* Load Vector Element Byte Indexed */
++    case 39:		/* Load Vector Element Halfword Indexed */
++    case 71:		/* Load Vector Element Word Indexed */
++    case 103:		/* Load Vector Indexed */
++    case 359:		/* Load Vector Indexed LRU */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_vr0_regnum + PPC_VRT (insn));
++      return 0;
++
++    /* These write FRT.  Update RA if 'update indexed.'  */
++    case 567:		/* Load Floating-Point Single with Update Indexed */
++    case 631:		/* Load Floating-Point Double with Update Indexed */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RA (insn));
++      /* FALL-THROUGH */
++    case 535:		/* Load Floating-Point Single Indexed */
++    case 599:		/* Load Floating-Point Double Indexed */
++    case 855:		/* Load Floating-Point as Integer Word Algebraic Indexed */
++    case 887:		/* Load Floating-Point as Integer Word and Zero Indexed */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      return 0;
++
++    case 791:		/* Load Floating-Point Double Pair Indexed */
++      tmp = tdep->ppc_fp0_regnum + (PPC_FRT (insn) & ~1);
++      record_full_arch_list_add_reg (regcache, tmp);
++      record_full_arch_list_add_reg (regcache, tmp + 1);
++      return 0;
++
++    case 179:		/* Move To VSR Doubleword */
++    case 211:		/* Move To VSR Word Algebraic */
++    case 243:		/* Move To VSR Word and Zero */
++    case 588:		/* Load VSX Scalar Doubleword Indexed */
++    case 524:		/* Load VSX Scalar Single-Precision Indexed */
++    case 76:		/* Load VSX Scalar as Integer Word Algebraic Indexed */
++    case 12:		/* Load VSX Scalar as Integer Word and Zero Indexed */
++    case 844:		/* Load VSX Vector Doubleword*2 Indexed */
++    case 332:		/* Load VSX Vector Doubleword & Splat Indexed */
++    case 780:		/* Load VSX Vector Word*4 Indexed */
++      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
++      return 0;
++
++    /* These write RA.  Update CR if RC is set.  */
++    case 24:		/* Shift Left Word */
++    case 26:		/* Count Leading Zeros Word */
++    case 27:		/* Shift Left Doubleword */
++    case 28:		/* AND */
++    case 58:		/* Count Leading Zeros Doubleword */
++    case 60:		/* AND with Complement */
++    case 124:		/* NOR */
++    case 284:		/* Equivalent */
++    case 316:		/* XOR */
++    case 476:		/* NAND */
++    case 412:		/* OR with Complement */
++    case 444:		/* OR */
++    case 536:		/* Shift Right Word */
++    case 539:		/* Shift Right Doubleword */
++    case 922:		/* Extend Sign Halfword */
++    case 954:		/* Extend Sign Byte */
++    case 986:		/* Extend Sign Word */
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RA (insn));
++      return 0;
++
++    /* Store memory.  */
++    case 181:		/* Store Doubleword with Update Indexed */
++    case 183:		/* Store Word with Update Indexed */
++    case 247:		/* Store Byte with Update Indexed */
++    case 439:		/* Store Half Word with Update Indexed */
++    case 695:		/* Store Floating-Point Single with Update Indexed */
++    case 759:		/* Store Floating-Point Double with Update Indexed */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RA (insn));
++      /* FALL-THROUGH */
++    case 135:		/* Store Vector Element Byte Indexed */
++    case 167:		/* Store Vector Element Halfword Indexed */
++    case 199:		/* Store Vector Element Word Indexed */
++    case 231:		/* Store Vector Indexed */
++    case 487:		/* Store Vector Indexed LRU */
++    case 716:		/* Store VSX Scalar Doubleword Indexed */
++    case 140:		/* Store VSX Scalar as Integer Word Indexed */
++    case 652:		/* Store VSX Scalar Single-Precision Indexed */
++    case 972:		/* Store VSX Vector Doubleword*2 Indexed */
++    case 908:		/* Store VSX Vector Word*4 Indexed */
++    case 149:		/* Store Doubleword Indexed */
++    case 151:		/* Store Word Indexed */
++    case 215:		/* Store Byte Indexed */
++    case 407:		/* Store Half Word Indexed */
++    case 694:		/* Store Byte Conditional Indexed */
++    case 726:		/* Store Halfword Conditional Indexed */
++    case 150:		/* Store Word Conditional Indexed */
++    case 214:		/* Store Doubleword Conditional Indexed */
++    case 182:		/* Store Quadword Conditional Indexed */
++    case 662:		/* Store Word Byte-Reverse Indexed */
++    case 918:		/* Store Halfword Byte-Reverse Indexed */
++    case 660:		/* Store Doubleword Byte-Reverse Indexed */
++    case 663:		/* Store Floating-Point Single Indexed */
++    case 727:		/* Store Floating-Point Double Indexed */
++    case 919:		/* Store Floating-Point Double Pair Indexed */
++    case 983:		/* Store Floating-Point as Integer Word Indexed */
++      if (ext == 694 || ext == 726 || ext == 150 || ext == 214 || ext == 182)
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++
++      ra = 0;
++      if (PPC_RA (insn) != 0)
++	regcache_raw_read_unsigned (regcache,
++				    tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
++      regcache_raw_read_unsigned (regcache,
++				  tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
++      ea = ra + rb;
++
++      switch (ext)
++	{
++	case 183:	/* Store Word with Update Indexed */
++	case 199:	/* Store Vector Element Word Indexed */
++	case 140:	/* Store VSX Scalar as Integer Word Indexed */
++	case 652:	/* Store VSX Scalar Single-Precision Indexed */
++	case 151:	/* Store Word Indexed */
++	case 150:	/* Store Word Conditional Indexed */
++	case 662:	/* Store Word Byte-Reverse Indexed */
++	case 663:	/* Store Floating-Point Single Indexed */
++	case 695:	/* Store Floating-Point Single with Update Indexed */
++	case 983:	/* Store Floating-Point as Integer Word Indexed */
++	  size = 4;
++	  break;
++	case 247:	/* Store Byte with Update Indexed */
++	case 135:	/* Store Vector Element Byte Indexed */
++	case 215:	/* Store Byte Indexed */
++	case 694:	/* Store Byte Conditional Indexed */
++	  size = 1;
++	  break;
++	case 439:	/* Store Halfword with Update Indexed */
++	case 167:	/* Store Vector Element Halfword Indexed */
++	case 407:	/* Store Halfword Indexed */
++	case 726:	/* Store Halfword Conditional Indexed */
++	case 918:	/* Store Halfword Byte-Reverse Indexed */
++	  size = 2;
++	  break;
++	case 181:	/* Store Doubleword with Update Indexed */
++	case 716:	/* Store VSX Scalar Doubleword Indexed */
++	case 149:	/* Store Doubleword Indexed */
++	case 214:	/* Store Doubleword Conditional Indexed */
++	case 660:	/* Store Doubleword Byte-Reverse Indexed */
++	case 727:	/* Store Floating-Point Double Indexed */
++	case 759:	/* Store Floating-Point Double with Update Indexed */
++	  size = 8;
++	  break;
++	case 972:	/* Store VSX Vector Doubleword*2 Indexed */
++	case 908:	/* Store VSX Vector Word*4 Indexed */
++	case 182:	/* Store Quadword Conditional Indexed */
++	case 231:	/* Store Vector Indexed */
++	case 487:	/* Store Vector Indexed LRU */
++	case 919:	/* Store Floating-Point Double Pair Indexed */
++	  size = 16;
++	  break;
++	default:
++	  gdb_assert (0);
++	}
++
++      /* Align address for Store Vector instructions.  */
++      switch (ext)
++	{
++	case 167:	/* Store Vector Element Halfword Indexed */
++	  addr = addr & ~0x1ULL;
++	  break;
++
++	case 199:	/* Store Vector Element Word Indexed */
++	  addr = addr & ~0x3ULL;
++	  break;
++
++	case 231:	/* Store Vector Indexed */
++	case 487:	/* Store Vector Indexed LRU */
++	  addr = addr & ~0xfULL;
++	  break;
++	}
++
++      if (record_full_arch_list_add_mem (addr, size) != 0)
++	return -1;
++      return 0;
++
++    case 725:		/* Store String Word Immediate */
++      ra = 0;
++      if (PPC_RA (insn) != 0)
++	regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra);
++      ea += ra;
++
++      nb = PPC_NB (insn);
++      if (nb == 0)
++	nb = 32;
++
++      if (record_full_arch_list_add_mem (ea, nb) != 0)
++	return -1;
++
++      return 0;
++
++    case 661:		/* Store String Word Indexed */
++      ra = 0;
++      if (PPC_RA (insn) != 0)
++	regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra);
++      ea += ra;
++
++      regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &xer);
++      nb = PPC_XER_NB (xer);
++
++      if (nb != 0)
++	{
++	  regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &rb);
++	  ea += rb;
++	  if (record_full_arch_list_add_mem (ea, nb) != 0)
++	    return -1;
++	}
++
++      return 0;
++
++    case 467:		/* Move To Special Purpose Register */
++      switch (PPC_SPR (insn))
++	{
++	case 1:			/* XER */
++	  record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
++	  return 0;
++	case 8:			/* LR */
++	  record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
++	  return 0;
++	case 9:			/* CTR */
++	  record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum);
++	  return 0;
++	case 256:		/* VRSAVE */
++	  record_full_arch_list_add_reg (regcache, tdep->ppc_vrsave_regnum);
++	  return 0;
++	}
++
++      goto UNKNOWN_OP;
++
++    case 147:		/* Move To Split Little Endian */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_ps_regnum);
++      return 0;
++
++    case 512:		/* Move to Condition Register from XER */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
++      return 0;
++
++    case 4:		/* Trap Word */
++    case 68:		/* Trap Doubleword */
++    case 430:		/* Clear BHRB */
++    case 598:		/* Synchronize */
++    case 62:		/* Wait for Interrupt */
++    case 22:		/* Instruction Cache Block Touch */
++    case 854:		/* Enforce In-order Execution of I/O */
++    case 246:		/* Data Cache Block Touch for Store */
++    case 54:		/* Data Cache Block Store */
++    case 86:		/* Data Cache Block Flush */
++    case 278:		/* Data Cache Block Touch */
++    case 758:		/* Data Cache Block Allocate */
++    case 982:		/* Instruction Cache Block Invalidate */
++      return 0;
++
++    case 654:		/* Transaction Begin */
++    case 686:		/* Transaction End */
++    case 718:		/* Transaction Check */
++    case 750:		/* Transaction Suspend or Resume */
++    case 782:		/* Transaction Abort Word Conditional */
++    case 814:		/* Transaction Abort Doubleword Conditional */
++    case 846:		/* Transaction Abort Word Conditional Immediate */
++    case 878:		/* Transaction Abort Doubleword Conditional Immediate */
++    case 910:		/* Transaction Abort */
++      fprintf_unfiltered (gdb_stdlog, "Cannot record Transaction instructions. "
++			  "%08x at %08lx, 31-%d.\n", insn, addr, ext);
++      return -1;
++
++    case 1014:		/* Data Cache Block set to Zero */
++      if (target_auxv_search (&current_target, AT_DCACHEBSIZE, &at_dcsz) <= 0
++	  || at_dcsz == 0)
++	at_dcsz = 128; /* Assume 128-byte cache line size (POWER8)  */
++
++      ra = 0;
++      if (PPC_RA (insn) != 0)
++	regcache_raw_read_unsigned (regcache,
++				    tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
++      regcache_raw_read_unsigned (regcache,
++				  tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
++      ea = (ra + rb) & ~((ULONGEST) (at_dcsz - 1));
++      if (record_full_arch_list_add_mem (ea, at_dcsz) != 0)
++	return -1;
++      return 0;
++    }
++
++UNKNOWN_OP:
++  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
++		      "%08x at %08lx, 31-%d.\n", insn, addr, ext);
++  return -1;
++}
++
++/* Parse instructions of primary opcode-59.  */
++
++static int
++ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
++			   CORE_ADDR addr, uint32_t insn)
++{
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++  int ext = PPC_EXTOP (insn);
++
++  switch (ext & 0x1f)
++    {
++    case 18:		/* Floating Divide */
++    case 20:		/* Floating Subtract */
++    case 21:		/* Floating Add */
++    case 22:		/* Floating Square Root */
++    case 24:		/* Floating Reciprocal Estimate */
++    case 25:		/* Floating Multiply */
++    case 26:		/* Floating Reciprocal Square Root Estimate */
++    case 28:		/* Floating Multiply-Subtract */
++    case 29:		/* Floating Multiply-Add */
++    case 30:		/* Floating Negative Multiply-Subtract */
++    case 31:		/* Floating Negative Multiply-Add */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++
++      return 0;
++    }
++
++  switch (ext)
++    {
++    case 2:		/* DFP Add */
++    case 3:		/* DFP Quantize */
++    case 34:		/* DFP Multiply */
++    case 35:		/* DFP Reround */
++    case 67:		/* DFP Quantize Immediate */
++    case 99:		/* DFP Round To FP Integer With Inexact */
++    case 227:		/* DFP Round To FP Integer Without Inexact */
++    case 258:		/* DFP Convert To DFP Long! */
++    case 290:		/* DFP Convert To Fixed */
++    case 514:		/* DFP Subtract */
++    case 546:		/* DFP Divide */
++    case 770:		/* DFP Round To DFP Short! */
++    case 802:		/* DFP Convert From Fixed */
++    case 834:		/* DFP Encode BCD To DPD */
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++      return 0;
++
++    case 130:		/* DFP Compare Ordered */
++    case 162:		/* DFP Test Exponent */
++    case 194:		/* DFP Test Data Class */
++    case 226:		/* DFP Test Data Group */
++    case 642:		/* DFP Compare Unordered */
++    case 674:		/* DFP Test Significance */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++      return 0;
++
++    case 66:		/* DFP Shift Significand Left Immediate */
++    case 98:		/* DFP Shift Significand Right Immediate */
++    case 322:		/* DFP Decode DPD To BCD */
++    case 354:		/* DFP Extract Biased Exponent */
++    case 866:		/* DFP Insert Biased Exponent */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      return 0;
++
++    case 846:		/* Floating Convert From Integer Doubleword Single */
++    case 974:		/* Floating Convert From Integer Doubleword Unsigned
++			   Single */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++
++      return 0;
++    }
++
++  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
++		      "%08x at %08lx, 59-%d.\n", insn, addr, ext);
++  return -1;
++}
++
++/* Parse instructions of primary opcode-60.  */
++
++static int
++ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
++			   CORE_ADDR addr, uint32_t insn)
++{
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++  int ext = PPC_EXTOP (insn);
++  int tmp;
++
++  switch (ext >> 2)
++    {
++    case 0:		/* VSX Scalar Add Single-Precision */
++    case 32:		/* VSX Scalar Add Double-Precision */
++    case 24:		/* VSX Scalar Divide Single-Precision */
++    case 56:		/* VSX Scalar Divide Double-Precision */
++    case 176:		/* VSX Scalar Copy Sign Double-Precision */
++    case 33:		/* VSX Scalar Multiply-Add Double-Precision */
++    case 41:		/* ditto */
++    case 1:		/* VSX Scalar Multiply-Add Single-Precision */
++    case 9:		/* ditto */
++    case 160:		/* VSX Scalar Maximum Double-Precision */
++    case 168:		/* VSX Scalar Minimum Double-Precision */
++    case 49:		/* VSX Scalar Multiply-Subtract Double-Precision */
++    case 57:		/* ditto */
++    case 17:		/* VSX Scalar Multiply-Subtract Single-Precision */
++    case 25:		/* ditto */
++    case 48:		/* VSX Scalar Multiply Double-Precision */
++    case 16:		/* VSX Scalar Multiply Single-Precision */
++    case 161:		/* VSX Scalar Negative Multiply-Add Double-Precision */
++    case 169:		/* ditto */
++    case 129:		/* VSX Scalar Negative Multiply-Add Single-Precision */
++    case 137:		/* ditto */
++    case 177:		/* VSX Scalar Negative Multiply-Subtract Double-Precision */
++    case 185:		/* ditto */
++    case 145:		/* VSX Scalar Negative Multiply-Subtract Single-Precision */
++    case 153:		/* ditto */
++    case 40:		/* VSX Scalar Subtract Double-Precision */
++    case 8:		/* VSX Scalar Subtract Single-Precision */
++    case 96:		/* VSX Vector Add Double-Precision */
++    case 64:		/* VSX Vector Add Single-Precision */
++    case 120:		/* VSX Vector Divide Double-Precision */
++    case 88:		/* VSX Vector Divide Single-Precision */
++    case 97:		/* VSX Vector Multiply-Add Double-Precision */
++    case 105:		/* ditto */
++    case 65:		/* VSX Vector Multiply-Add Single-Precision */
++    case 73:		/* ditto */
++    case 224:		/* VSX Vector Maximum Double-Precision */
++    case 192:		/* VSX Vector Maximum Single-Precision */
++    case 232:		/* VSX Vector Minimum Double-Precision */
++    case 200:		/* VSX Vector Minimum Single-Precision */
++    case 113:		/* VSX Vector Multiply-Subtract Double-Precision */
++    case 121:		/* ditto */
++    case 81:		/* VSX Vector Multiply-Subtract Single-Precision */
++    case 89:		/* ditto */
++    case 112:		/* VSX Vector Multiply Double-Precision */
++    case 80:		/* VSX Vector Multiply Single-Precision */
++    case 225:		/* VSX Vector Negative Multiply-Add Double-Precision */
++    case 233:		/* ditto */
++    case 193:		/* VSX Vector Negative Multiply-Add Single-Precision */
++    case 201:		/* ditto */
++    case 241:		/* VSX Vector Negative Multiply-Subtract Double-Precision */
++    case 249:		/* ditto */
++    case 209:		/* VSX Vector Negative Multiply-Subtract Single-Precision */
++    case 217:		/* ditto */
++    case 104:		/* VSX Vector Subtract Double-Precision */
++    case 72:		/* VSX Vector Subtract Single-Precision */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++    case 240:		/* VSX Vector Copy Sign Double-Precision */
++    case 208:		/* VSX Vector Copy Sign Single-Precision */
++    case 130:		/* VSX Logical AND */
++    case 138:		/* VSX Logical AND with Complement */
++    case 186:		/* VSX Logical Equivalence */
++    case 178:		/* VSX Logical NAND */
++    case 170:		/* VSX Logical OR with Complement */
++    case 162:		/* VSX Logical NOR */
++    case 146:		/* VSX Logical OR */
++    case 154:		/* VSX Logical XOR */
++    case 18:		/* VSX Merge High Word */
++    case 50:		/* VSX Merge Low Word */
++    case 10:		/* VSX Permute Doubleword Immediate (DM=0) */
++    case 10 | 0x20:	/* VSX Permute Doubleword Immediate (DM=1) */
++    case 10 | 0x40:	/* VSX Permute Doubleword Immediate (DM=2) */
++    case 10 | 0x60:	/* VSX Permute Doubleword Immediate (DM=3) */
++    case 2:		/* VSX Shift Left Double by Word Immediate (SHW=0) */
++    case 2 | 0x20:	/* VSX Shift Left Double by Word Immediate (SHW=1) */
++    case 2 | 0x40:	/* VSX Shift Left Double by Word Immediate (SHW=2) */
++    case 2 | 0x60:	/* VSX Shift Left Double by Word Immediate (SHW=3) */
++      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
++      return 0;
++
++    case 61:		/* VSX Scalar Test for software Divide Double-Precision */
++    case 125:		/* VSX Vector Test for software Divide Double-Precision */
++    case 93:		/* VSX Vector Test for software Divide Single-Precision */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      return 0;
++
++    case 35:		/* VSX Scalar Compare Unordered Double-Precision */
++    case 43:		/* VSX Scalar Compare Ordered Double-Precision */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++      return 0;
++    }
++
++  switch ((ext >> 2) & 0x7f) /* Mask out Rc-bit.  */
++    {
++    case 99:		/* VSX Vector Compare Equal To Double-Precision */
++    case 67:		/* VSX Vector Compare Equal To Single-Precision */
++    case 115:		/* VSX Vector Compare Greater Than or
++			   Equal To Double-Precision */
++    case 83:		/* VSX Vector Compare Greater Than or
++			   Equal To Single-Precision */
++    case 107:		/* VSX Vector Compare Greater Than Double-Precision */
++    case 75:		/* VSX Vector Compare Greater Than Single-Precision */
++      if (PPC_Rc (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
++      return 0;
++    }
++
++  switch (ext >> 1)
++    {
++    case 265:		/* VSX Scalar round Double-Precision to
++			   Single-Precision and Convert to
++			   Single-Precision format */
++    case 344:		/* VSX Scalar truncate Double-Precision to
++			   Integer and Convert to Signed Integer
++			   Doubleword format with Saturate */
++    case 88:		/* VSX Scalar truncate Double-Precision to
++			   Integer and Convert to Signed Integer Word
++			   Format with Saturate */
++    case 328:		/* VSX Scalar truncate Double-Precision integer
++			   and Convert to Unsigned Integer Doubleword
++			   Format with Saturate */
++    case 72:		/* VSX Scalar truncate Double-Precision to
++			   Integer and Convert to Unsigned Integer Word
++			   Format with Saturate */
++    case 329:		/* VSX Scalar Convert Single-Precision to
++			   Double-Precision format */
++    case 376:		/* VSX Scalar Convert Signed Integer
++			   Doubleword to floating-point format and
++			   Round to Double-Precision format */
++    case 312:		/* VSX Scalar Convert Signed Integer
++			   Doubleword to floating-point format and
++			   round to Single-Precision */
++    case 360:		/* VSX Scalar Convert Unsigned Integer
++			   Doubleword to floating-point format and
++			   Round to Double-Precision format */
++    case 296:		/* VSX Scalar Convert Unsigned Integer
++			   Doubleword to floating-point format and
++			   Round to Single-Precision */
++    case 73:		/* VSX Scalar Round to Double-Precision Integer
++			   Using Round to Nearest Away */
++    case 107:		/* VSX Scalar Round to Double-Precision Integer
++			   Exact using Current rounding mode */
++    case 121:		/* VSX Scalar Round to Double-Precision Integer
++			   Using Round toward -Infinity */
++    case 105:		/* VSX Scalar Round to Double-Precision Integer
++			   Using Round toward +Infinity */
++    case 89:		/* VSX Scalar Round to Double-Precision Integer
++			   Using Round toward Zero */
++    case 90:		/* VSX Scalar Reciprocal Estimate Double-Precision */
++    case 26:		/* VSX Scalar Reciprocal Estimate Single-Precision */
++    case 281:		/* VSX Scalar Round to Single-Precision */
++    case 74:		/* VSX Scalar Reciprocal Square Root Estimate
++			   Double-Precision */
++    case 10:		/* VSX Scalar Reciprocal Square Root Estimate
++			   Single-Precision */
++    case 75:		/* VSX Scalar Square Root Double-Precision */
++    case 11:		/* VSX Scalar Square Root Single-Precision */
++    case 393:		/* VSX Vector round Double-Precision to
++			   Single-Precision and Convert to
++			   Single-Precision format */
++    case 472:		/* VSX Vector truncate Double-Precision to
++			   Integer and Convert to Signed Integer
++			   Doubleword format with Saturate */
++    case 216:		/* VSX Vector truncate Double-Precision to
++			   Integer and Convert to Signed Integer Word
++			   Format with Saturate */
++    case 456:		/* VSX Vector truncate Double-Precision to
++			   Integer and Convert to Unsigned Integer
++			   Doubleword format with Saturate */
++    case 200:		/* VSX Vector truncate Double-Precision to
++			   Integer and Convert to Unsigned Integer Word
++			   Format with Saturate */
++    case 457:		/* VSX Vector Convert Single-Precision to
++			   Double-Precision format */
++    case 408:		/* VSX Vector truncate Single-Precision to
++			   Integer and Convert to Signed Integer
++			   Doubleword format with Saturate */
++    case 152:		/* VSX Vector truncate Single-Precision to
++			   Integer and Convert to Signed Integer Word
++			   Format with Saturate */
++    case 392:		/* VSX Vector truncate Single-Precision to
++			   Integer and Convert to Unsigned Integer
++			   Doubleword format with Saturate */
++    case 136:		/* VSX Vector truncate Single-Precision to
++			   Integer and Convert to Unsigned Integer Word
++			   Format with Saturate */
++    case 504:		/* VSX Vector Convert and round Signed Integer
++			   Doubleword to Double-Precision format */
++    case 440:		/* VSX Vector Convert and round Signed Integer
++			   Doubleword to Single-Precision format */
++    case 248:		/* VSX Vector Convert Signed Integer Word to
++			   Double-Precision format */
++    case 184:		/* VSX Vector Convert and round Signed Integer
++			   Word to Single-Precision format */
++    case 488:		/* VSX Vector Convert and round Unsigned
++			   Integer Doubleword to Double-Precision format */
++    case 424:		/* VSX Vector Convert and round Unsigned
++			   Integer Doubleword to Single-Precision format */
++    case 232:		/* VSX Vector Convert and round Unsigned
++			   Integer Word to Double-Precision format */
++    case 168:		/* VSX Vector Convert and round Unsigned
++			   Integer Word to Single-Precision format */
++    case 201:		/* VSX Vector Round to Double-Precision
++			   Integer using round to Nearest Away */
++    case 235:		/* VSX Vector Round to Double-Precision
++			   Integer Exact using Current rounding mode */
++    case 249:		/* VSX Vector Round to Double-Precision
++			   Integer using round toward -Infinity */
++    case 233:		/* VSX Vector Round to Double-Precision
++			   Integer using round toward +Infinity */
++    case 217:		/* VSX Vector Round to Double-Precision
++			   Integer using round toward Zero */
++    case 218:		/* VSX Vector Reciprocal Estimate Double-Precision */
++    case 154:		/* VSX Vector Reciprocal Estimate Single-Precision */
++    case 137:		/* VSX Vector Round to Single-Precision Integer
++			   Using Round to Nearest Away */
++    case 171:		/* VSX Vector Round to Single-Precision Integer
++			   Exact Using Current rounding mode */
++    case 185:		/* VSX Vector Round to Single-Precision Integer
++			   Using Round toward -Infinity */
++    case 169:		/* VSX Vector Round to Single-Precision Integer
++			   Using Round toward +Infinity */
++    case 153:		/* VSX Vector Round to Single-Precision Integer
++			   Using round toward Zero */
++    case 202:		/* VSX Vector Reciprocal Square Root Estimate
++			   Double-Precision */
++    case 138:		/* VSX Vector Reciprocal Square Root Estimate
++			   Single-Precision */
++    case 203:		/* VSX Vector Square Root Double-Precision */
++    case 139:		/* VSX Vector Square Root Single-Precision */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++    case 345:		/* VSX Scalar Absolute Value Double-Precision */
++    case 267:		/* VSX Scalar Convert Scalar Single-Precision to
++			   Vector Single-Precision format Non-signalling */
++    case 331:		/* VSX Scalar Convert Single-Precision to
++			   Double-Precision format Non-signalling */
++    case 361:		/* VSX Scalar Negative Absolute Value Double-Precision */
++    case 377:		/* VSX Scalar Negate Double-Precision */
++    case 473:		/* VSX Vector Absolute Value Double-Precision */
++    case 409:		/* VSX Vector Absolute Value Single-Precision */
++    case 489:		/* VSX Vector Negative Absolute Value Double-Precision */
++    case 425:		/* VSX Vector Negative Absolute Value Single-Precision */
++    case 505:		/* VSX Vector Negate Double-Precision */
++    case 441:		/* VSX Vector Negate Single-Precision */
++    case 164:		/* VSX Splat Word */
++      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
++      return 0;
++
++    case 106:		/* VSX Scalar Test for software Square Root
++			   Double-Precision */
++    case 234:		/* VSX Vector Test for software Square Root
++			   Double-Precision */
++    case 170:		/* VSX Vector Test for software Square Root
++			   Single-Precision */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      return 0;
++    }
++
++  if (((ext >> 3) & 0x3) == 3)	/* VSX Select */
++    {
++      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
++      return 0;
++    }
++
++  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
++		      "%08x at %08lx, 60-%d.\n", insn, addr, ext);
++  return -1;
++}
++
++/* Parse instructions of primary opcode-63.  */
++
++static int
++ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
++			   CORE_ADDR addr, uint32_t insn)
++{
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++  int ext = PPC_EXTOP (insn);
++  int tmp;
++
++  switch (ext & 0x1f)
++    {
++    case 18:		/* Floating Divide */
++    case 20:		/* Floating Subtract */
++    case 21:		/* Floating Add */
++    case 22:		/* Floating Square Root */
++    case 24:		/* Floating Reciprocal Estimate */
++    case 25:		/* Floating Multiply */
++    case 26:		/* Floating Reciprocal Square Root Estimate */
++    case 28:		/* Floating Multiply-Subtract */
++    case 29:		/* Floating Multiply-Add */
++    case 30:		/* Floating Negative Multiply-Subtract */
++    case 31:		/* Floating Negative Multiply-Add */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++      return 0;
++
++    case 23:		/* Floating Select */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++    }
++
++  switch (ext)
++    {
++    case 2:		/* DFP Add Quad */
++    case 3:		/* DFP Quantize Quad */
++    case 34:		/* DFP Multiply Quad */
++    case 35:		/* DFP Reround Quad */
++    case 67:		/* DFP Quantize Immediate Quad */
++    case 99:		/* DFP Round To FP Integer With Inexact Quad */
++    case 227:		/* DFP Round To FP Integer Without Inexact Quad */
++    case 258:		/* DFP Convert To DFP Extended Quad */
++    case 514:		/* DFP Subtract Quad */
++    case 546:		/* DFP Divide Quad */
++    case 770:		/* DFP Round To DFP Long Quad */
++    case 802:		/* DFP Convert From Fixed Quad */
++    case 834:		/* DFP Encode BCD To DPD Quad */
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      tmp = tdep->ppc_fp0_regnum + (PPC_FRT (insn) & ~1);
++      record_full_arch_list_add_reg (regcache, tmp);
++      record_full_arch_list_add_reg (regcache, tmp + 1);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++      return 0;
++
++    case 130:		/* DFP Compare Ordered Quad */
++    case 162:		/* DFP Test Exponent Quad */
++    case 194:		/* DFP Test Data Class Quad */
++    case 226:		/* DFP Test Data Group Quad */
++    case 642:		/* DFP Compare Unordered Quad */
++    case 674:		/* DFP Test Significance Quad */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++      return 0;
++
++    case 66:		/* DFP Shift Significand Left Immediate Quad */
++    case 98:		/* DFP Shift Significand Right Immediate Quad */
++    case 322:		/* DFP Decode DPD To BCD Quad */
++    case 866:		/* DFP Insert Biased Exponent Quad */
++      tmp = tdep->ppc_fp0_regnum + (PPC_FRT (insn) & ~1);
++      record_full_arch_list_add_reg (regcache, tmp);
++      record_full_arch_list_add_reg (regcache, tmp + 1);
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      return 0;
++
++    case 290:		/* DFP Convert To Fixed Quad */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++      break;
++
++    case 354:		/* DFP Extract Biased Exponent Quad */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      return 0;
++
++    case 12:		/* Floating Round to Single-Precision */
++    case 14:		/* Floating Convert To Integer Word */
++    case 15:		/* Floating Convert To Integer Word
++			   with round toward Zero */
++    case 142:		/* Floating Convert To Integer Word Unsigned */
++    case 143:		/* Floating Convert To Integer Word Unsigned
++			   with round toward Zero */
++    case 392:		/* Floating Round to Integer Nearest */
++    case 424:		/* Floating Round to Integer Toward Zero */
++    case 456:		/* Floating Round to Integer Plus */
++    case 488:		/* Floating Round to Integer Minus */
++    case 814:		/* Floating Convert To Integer Doubleword */
++    case 815:		/* Floating Convert To Integer Doubleword
++			   with round toward Zero */
++    case 846:		/* Floating Convert From Integer Doubleword */
++    case 942:		/* Floating Convert To Integer Doubleword Unsigned */
++    case 943:		/* Floating Convert To Integer Doubleword Unsigned
++			   with round toward Zero */
++    case 974:		/* Floating Convert From Integer Doubleword Unsigned */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++      return 0;
++
++    case 583:		/* Move From FPSCR */
++    case 8:		/* Floating Copy Sign */
++    case 40:		/* Floating Negate */
++    case 72:		/* Floating Move Register */
++    case 136:		/* Floating Negative Absolute Value */
++    case 264:		/* Floating Absolute Value */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      return 0;
++
++    case 838:		/* Floating Merge Odd Word */
++    case 966:		/* Floating Merge Even Word */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      return 0;
++
++    case 38:		/* Move To FPSCR Bit 1 */
++    case 70:		/* Move To FPSCR Bit 0 */
++    case 134:		/* Move To FPSCR Field Immediate */
++    case 711:		/* Move To FPSCR Fields */
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++      break;
++
++    case 0:		/* Floating Compare Unordered */
++    case 32:		/* Floating Compare Ordered */
++    case 64:		/* Move to Condition Register from FPSCR */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
++      /* FALL-THROUGH */
++    case 128:		/* Floating Test for software Divide */
++    case 160:		/* Floating Test for software Square Root */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      return 0;
++
++    }
++
++  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
++		      "%08x at %08lx, 59-%d.\n", insn, addr, ext);
++  return -1;
++}
++
++/* Parse the current instruction and record the values of the registers and
++   memory that will be changed in current instruction to "record_arch_list".
++   Return -1 if something wrong.  */
++
++int
++ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
++		      CORE_ADDR addr)
++{
++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
++  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
++  uint32_t insn;
++  int op6, tmp, i;
++
++  insn = read_memory_unsigned_integer (addr, 4, byte_order);
++  op6 = PPC_OP6 (insn);
++
++  switch (op6)
++    {
++    case 2:		/* Trap Doubleword Immediate */
++    case 3:		/* Trap Word Immediate */
++      /* Do nothing.  */
++      break;
++
++    case 4:
++      if (ppc_process_record_op4 (gdbarch, regcache, addr, insn) != 0)
++	return -1;
++      break;
++
++    case 17:		/* System call */
++      if (PPC_LEV (insn) != 0)
++	goto UNKNOWN_OP;
++
++      if (tdep->ppc_syscall_record != NULL)
++	{
++	  if (tdep->ppc_syscall_record (regcache) != 0)
++	    return -1;
++	}
++      else
++	{
++	  printf_unfiltered (_("no syscall record support\n"));
++	  return -1;
++	}
++      break;
++
++    case 7:		/* Multiply Low Immediate */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RT (insn));
++      break;
++
++    case 8:		/* Subtract From Immediate Carrying */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RT (insn));
++      break;
++
++    case 10:		/* Compare Logical Immediate  */
++    case 11:		/* Compare Immediate */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      break;
++
++    case 13:		/* Add Immediate Carrying and Record */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      /* FALL-THROUGH */
++    case 12:		/* Add Immediate Carrying */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
++      /* FALL-THROUGH */
++    case 14:		/* Add Immediate */
++    case 15:		/* Add Immediate Shifted */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RT (insn));
++      break;
++
++    case 16:		/* Branch Conditional */
++      if ((PPC_BO (insn) & 0x4) == 0)
++	record_full_arch_list_add_reg (regcache, tdep->ppc_ctr_regnum);
++      /* FALL-THROUGH */
++    case 18:		/* Branch */
++      if (PPC_LK (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
++      break;
++
++    case 19:
++      if (ppc_process_record_op19 (gdbarch, regcache, addr, insn) != 0)
++	return -1;
++      break;
++
++    case 20:		/* Rotate Left Word Immediate then Mask Insert */
++    case 21:		/* Rotate Left Word Immediate then AND with Mask */
++    case 23:		/* Rotate Left Word then AND with Mask */
++    case 30:		/* Rotate Left Doubleword Immediate then Clear Left */
++			/* Rotate Left Doubleword Immediate then Clear Right */
++			/* Rotate Left Doubleword Immediate then Clear */
++			/* Rotate Left Doubleword then Clear Left */
++			/* Rotate Left Doubleword then Clear Right */
++			/* Rotate Left Doubleword Immediate then Mask Insert */
++      if (PPC_RC (insn))
++	record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RA (insn));
++      break;
++
++    case 28:		/* AND Immediate */
++    case 29:		/* AND Immediate Shifted */
++      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
++      /* FALL-THROUGH */
++    case 24:		/* OR Immediate */
++    case 25:		/* OR Immediate Shifted */
++    case 26:		/* XOR Immediate */
++    case 27:		/* XOR Immediate Shifted */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RA (insn));
++      break;
++
++    case 31:
++      if (ppc_process_record_op31 (gdbarch, regcache, addr, insn) != 0)
++	return -1;
++      break;
++
++    case 33:		/* Load Word and Zero with Update */
++    case 35:		/* Load Byte and Zero with Update */
++    case 41:		/* Load Halfword and Zero with Update */
++    case 43:		/* Load Halfword Algebraic with Update */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RA (insn));
++      /* FALL-THROUGH */
++    case 32:		/* Load Word and Zero */
++    case 34:		/* Load Byte and Zero */
++    case 40:		/* Load Halfword and Zero */
++    case 42:		/* Load Halfword Algebraic */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RT (insn));
++      break;
++
++    case 46:		/* Load Multiple Word */
++      for (i = PPC_RT (insn); i < 32; i++)
++	record_full_arch_list_add_reg (regcache, tdep->ppc_gp0_regnum + i);
++      break;
++
++    case 56:		/* Load Quadword */
++      tmp = tdep->ppc_gp0_regnum + (PPC_RT (insn) & ~1);
++      record_full_arch_list_add_reg (regcache, tmp);
++      record_full_arch_list_add_reg (regcache, tmp + 1);
++      break;
++
++    case 49:		/* Load Floating-Point Single with Update */
++    case 51:		/* Load Floating-Point Double with Update */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RA (insn));
++      /* FALL-THROUGH */
++    case 48:		/* Load Floating-Point Single */
++    case 50:		/* Load Floating-Point Double */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_fp0_regnum + PPC_FRT (insn));
++      break;
++
++    case 47:		/* Store Multiple Word */
++	{
++	  ULONGEST addr = 0;
++
++	  if (PPC_RA (insn) != 0)
++	    regcache_raw_read_unsigned (regcache,
++					tdep->ppc_gp0_regnum + PPC_RA (insn),
++					&addr);
++
++	  addr += PPC_D (insn);
++	  if (record_full_arch_list_add_mem (addr, 4 * (32 - PPC_RS (insn))) != 0)
++	    return -1;
++	}
++      break;
++
++    case 37:		/* Store Word with Update */
++    case 39:		/* Store Byte with Update */
++    case 45:		/* Store Halfword with Update */
++    case 53:		/* Store Floating-Point Single with Update */
++    case 55:		/* Store Floating-Point Double with Update */
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RA (insn));
++      /* FALL-THROUGH */
++    case 36:		/* Store Word */
++    case 38:		/* Store Byte */
++    case 44:		/* Store Halfword */
++    case 52:		/* Store Floating-Point Single */
++    case 54:		/* Store Floating-Point Double */
++	{
++	  ULONGEST addr = 0;
++	  int size = -1;
++
++	  if (PPC_RA (insn) != 0)
++	    regcache_raw_read_unsigned (regcache,
++					tdep->ppc_gp0_regnum + PPC_RA (insn),
++					&addr);
++	  addr += PPC_D (insn);
++
++	  if (op6 == 36 || op6 == 37 || op6 == 52 || op6 == 53)
++	    size = 4;
++	  else if (op6 == 54 || op6 == 55)
++	    size = 8;
++	  else if (op6 == 44 || op6 == 45)
++	    size = 2;
++	  else if (op6 == 38 || op6 == 39)
++	    size = 1;
++	  else
++	    gdb_assert (0);
++
++	  if (record_full_arch_list_add_mem (addr, size) != 0)
++	    return -1;
++	}
++      break;
++
++    case 57:		/* Load Floating-Point Double Pair */
++      if (PPC_FIELD (insn, 30, 2) != 0)
++	goto UNKNOWN_OP;
++      tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1);
++      record_full_arch_list_add_reg (regcache, tmp);
++      record_full_arch_list_add_reg (regcache, tmp + 1);
++      break;
++
++    case 58:		/* Load Doubleword */
++			/* Load Doubleword with Update */
++			/* Load Word Algebraic */
++      if (PPC_FIELD (insn, 30, 2) > 2)
++	goto UNKNOWN_OP;
++
++      record_full_arch_list_add_reg (regcache,
++				     tdep->ppc_gp0_regnum + PPC_RT (insn));
++      if (PPC_BIT (insn, 31))
++	record_full_arch_list_add_reg (regcache,
++				       tdep->ppc_gp0_regnum + PPC_RA (insn));
++      break;
++
++    case 59:
++      if (ppc_process_record_op59 (gdbarch, regcache, addr, insn) != 0)
++	return -1;
++      break;
++
++    case 60:
++      if (ppc_process_record_op60 (gdbarch, regcache, addr, insn) != 0)
++	return -1;
++      break;
++
++    case 61:		/* Store Floating-Point Double Pair */
++    case 62:		/* Store Doubleword */
++			/* Store Doubleword with Update */
++			/* Store Quadword with Update */
++	{
++	  ULONGEST addr = 0;
++	  int size;
++	  int sub2 = PPC_FIELD (insn, 30, 2);
++
++	  if ((op6 == 61 && sub2 != 0) || (op6 == 62 && sub2 > 2))
++	    goto UNKNOWN_OP;
++
++	  if (PPC_RA (insn) != 0)
++	    regcache_raw_read_unsigned (regcache,
++					tdep->ppc_gp0_regnum + PPC_RA (insn),
++					&addr);
++
++	  size = ((op6 == 61) || sub2 == 2) ? 16 : 8;
++
++	  addr += PPC_DS (insn) << 2;
++	  if (record_full_arch_list_add_mem (addr, size) != 0)
++	    return -1;
++
++	  if (op6 == 62 && sub2 == 1)
++	    record_full_arch_list_add_reg (regcache,
++					   tdep->ppc_gp0_regnum +
++					   PPC_RA (insn));
++
++	  break;
++	}
++
++    case 63:
++      if (ppc_process_record_op63 (gdbarch, regcache, addr, insn) != 0)
++	return -1;
++      break;
++
++    default:
++UNKNOWN_OP:
++      fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
++			  "%08x at %08lx, %d.\n", insn, addr, op6);
++      return -1;
++    }
++
++  if (record_full_arch_list_add_reg (regcache, PPC_PC_REGNUM))
++    return -1;
++  if (record_full_arch_list_add_end ())
++    return -1;
++  return 0;
++}
++
+ /* Initialize the current architecture based on INFO.  If possible, re-use an
+    architecture from ARCHES, which is a list of architectures already created
+    during this debugging session.
+Index: gdb-7.6.1/gdb/testsuite/lib/gdb.exp
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/lib/gdb.exp
++++ gdb-7.6.1/gdb/testsuite/lib/gdb.exp
+@@ -1784,7 +1784,8 @@ proc supports_process_record {} {
+ 	return [target_info gdb,use_precord]
+     }
+ 
+-    if { [istarget "x86_64-*-linux*"] || [istarget "i\[34567\]86-*-linux*"] } {
++    if { [istarget "x86_64-*-linux*"] || [istarget "i\[34567\]86-*-linux*"]
++         || [istarget "powerpc*-*-linux*"] } {
+ 	return 1
+     }
+ 
+@@ -1799,7 +1800,8 @@ proc supports_reverse {} {
+ 	return [target_info gdb,can_reverse]
+     }
+ 
+-    if { [istarget "x86_64-*-linux*"] || [istarget "i\[34567\]86-*-linux*"] } {
++    if { [istarget "x86_64-*-linux*"] || [istarget "i\[34567\]86-*-linux*"]
++         || [istarget "powerpc*-*-linux*"] } {
+ 	return 1
+     }
+ 
diff --git a/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-5of7.patch b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-5of7.patch
new file mode 100644
index 0000000..ac43ca4
--- /dev/null
+++ b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-5of7.patch
@@ -0,0 +1,252 @@
+  Message-ID: <5491BE7E.2060708@gmail.com>
+  Date: Thu, 18 Dec 2014 01:33:50 +0800
+  From: Wei-cheng Wang <cole945 at gmail dot com>
+  To: Ulrich Weigand <uweigand at de dot ibm dot com>
+  CC: gdb-patches at sourceware dot org
+  Subject: Re: [PATCH 3/3 v2] Process record support for PowerPC
+
+  On 2014/12/9 上午 03:13, Ulrich Weigand wrote:
+  > Wei-cheng Wang wrote:
+  >> 	    * ppc-linux-tdep.c (powerpc_linux_in_dynsym_resolve_code):
+  >> 	    Scan PLT stub backward for reverse debugging.
+  >> 	    (ppc_linux_init_abi): set powerpc_linux_in_dynsym_resolve_code
+  >> 	    for both 32-bit and 64-bit.
+  >
+  > As I said in the reply to the 0/3 mail, I really think it would be
+  > better to handle this within the PPC skip_trampoline_code implementation,
+  > instead of having in_dynsym_resolve_code suddenly also cover the
+  > trampolines ...
+
+     Hi,
+
+     See the new patch, I moved the for-loop into skip_trampoline_code,
+     and removed in_dynsym_resolve_code.
+
+  > It seems odd to have in_dynsym_resolve_code call into
+  > skip_trampoline_code.  Is there a reason why the skip_trampoline_code
+  > implementation cannot accept a PC in the middle of the sequence?
+
+     I thought skip-trampoline is used to find the target address for
+     inserting step-resume breakpoint, so it doesn't make sense for
+     reverse-stepping, because we are just stepping from the target address.
+     And for forward-stepping, when we reach the very first instruction of
+     trampoline code, we can just skip the resolving code by inserting
+     a step-resume breakpoint, so we don't have to step through the resolving
+     code and check whether we are in the middle of trampoline code.
+
+     in_dynsym_resolve_code is used to check whether we are in (the middle of)
+     the resolving code, so we can keep going to step though the resolving code.
+     Therefor I thought in_dynsym_resolve_code is the proper place to implement.
+
+     Since skip-trampoline-code had implemented the plt-stub pattern-match code
+     we need, by calling it in in-dynsym-resolve-code, we don't need to have
+     duplicate pattern-match code in both functions.
+
+  Wei-cheng,
+  Thanks
+
+  --
+
+  2014-12-06  Wei-cheng Wang  <cole945@gmail.com>
+
+	      * ppc-linux-tdep.c (ppc_skip_trampoline_code):
+	      Scan PLT stub backward for reverse debugging.
+	      * ppc64-tdep.c (ppc64_skip_trampoline_code): Likewise.
+
+
+commit cf90fd9a07e8998540bf74f293d348a6653ac120
+Author: Wei-cheng Wang <cole945@gmail.com>
+Date:   Sat Jan 17 14:30:59 2015 +0800
+
+    Skip-trampoline for PowerPC reverse-stepping.
+
+Index: gdb-7.6.1/gdb/ppc64-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/ppc64-tdep.c
++++ gdb-7.6.1/gdb/ppc64-tdep.c
+@@ -20,6 +20,7 @@
+ #include "defs.h"
+ #include "frame.h"
+ #include "gdbcore.h"
++#include "inferior.h"
+ #include "ppc-tdep.h"
+ #include "ppc64-tdep.h"
+ #include "elf-bfd.h"
+@@ -464,35 +465,66 @@ ppc64_skip_trampoline_code (struct frame
+ 				    ARRAY_SIZE (ppc64_standard_linkage8))))
+ 		     - 1];
+   CORE_ADDR target;
++  int scan_limit, i;
+ 
+-  if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns))
+-    pc = ppc64_standard_linkage4_target (frame, pc, insns);
+-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7, insns))
+-    pc = ppc64_standard_linkage3_target (frame, pc, insns);
+-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6, insns))
+-    pc = ppc64_standard_linkage4_target (frame, pc, insns);
+-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5, insns)
+-	   && (insns[8] != 0 || insns[9] != 0))
+-    pc = ppc64_standard_linkage3_target (frame, pc, insns);
+-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4, insns)
+-	   && (insns[9] != 0 || insns[10] != 0))
+-    pc = ppc64_standard_linkage4_target (frame, pc, insns);
+-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns)
+-	   && (insns[8] != 0 || insns[9] != 0))
+-    pc = ppc64_standard_linkage3_target (frame, pc, insns);
+-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns)
+-	   && (insns[10] != 0 || insns[11] != 0))
+-    pc = ppc64_standard_linkage2_target (frame, pc, insns);
+-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1, insns))
+-    pc = ppc64_standard_linkage1_target (frame, pc, insns);
+-  else
+-    return 0;
+-
+-  /* The PLT descriptor will either point to the already resolved target
+-     address, or else to a glink stub.  As the latter carry synthetic @plt
+-     symbols, find_solib_trampoline_target should be able to resolve them.  */
+-  target = find_solib_trampoline_target (frame, pc);
+-  return target ? target : pc;
++  scan_limit = 1;
++  /* When reverse-debugging, scan backward to check whether we are
++     in the middle of trampoline code.  */
++  if (execution_direction == EXEC_REVERSE)
++    scan_limit = ARRAY_SIZE (insns) - 1;
++
++  for (i = 0; i < scan_limit; i++)
++    {
++      if (i < ARRAY_SIZE (ppc64_standard_linkage8) - 1
++	  && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns))
++	pc = ppc64_standard_linkage4_target (frame, pc, insns);
++      else if (i < ARRAY_SIZE (ppc64_standard_linkage7) - 1
++	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7,
++					   insns))
++	pc = ppc64_standard_linkage3_target (frame, pc, insns);
++      else if (i < ARRAY_SIZE (ppc64_standard_linkage6) - 1
++	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6,
++					   insns))
++	pc = ppc64_standard_linkage4_target (frame, pc, insns);
++      else if (i < ARRAY_SIZE (ppc64_standard_linkage5) - 1
++	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5,
++					   insns)
++	       && (insns[8] != 0 || insns[9] != 0))
++	pc = ppc64_standard_linkage3_target (frame, pc, insns);
++      else if (i < ARRAY_SIZE (ppc64_standard_linkage4) - 1
++	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4,
++					   insns)
++	       && (insns[9] != 0 || insns[10] != 0))
++	pc = ppc64_standard_linkage4_target (frame, pc, insns);
++      else if (i < ARRAY_SIZE (ppc64_standard_linkage3) - 1
++	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3,
++					   insns)
++	       && (insns[8] != 0 || insns[9] != 0))
++	pc = ppc64_standard_linkage3_target (frame, pc, insns);
++      else if (i < ARRAY_SIZE (ppc64_standard_linkage2) - 1
++	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2,
++					   insns)
++	       && (insns[10] != 0 || insns[11] != 0))
++	pc = ppc64_standard_linkage2_target (frame, pc, insns);
++      else if (i < ARRAY_SIZE (ppc64_standard_linkage1) - 1
++	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1,
++					   insns))
++	pc = ppc64_standard_linkage1_target (frame, pc, insns);
++      else
++	{
++	  /* Scan backward one more instructions if doesn't match.  */
++	  pc -= 4;
++	  continue;
++	}
++
++      /* The PLT descriptor will either point to the already resolved target
++         address, or else to a glink stub.  As the latter carry synthetic @plt
++         symbols, find_solib_trampoline_target should be able to resolve them.  */
++      target = find_solib_trampoline_target (frame, pc);
++      return target ? target : pc;
++  }
++
++  return 0;
+ }
+ 
+ /* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC64
+Index: gdb-7.6.1/gdb/ppc-linux-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/ppc-linux-tdep.c
++++ gdb-7.6.1/gdb/ppc-linux-tdep.c
+@@ -52,6 +52,7 @@
+ #include "linux-tdep.h"
+ #include "linux-record.h"
+ #include "record-full.h"
++#include "inferior.h"
+ 
+ #include "stap-probe.h"
+ #include "ax.h"
+@@ -362,31 +363,50 @@ ppc_skip_trampoline_code (struct frame_i
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+   CORE_ADDR target = 0;
++  int scan_limit, i;
+ 
+-  if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf))
+-    {
+-      /* Insn pattern is
+-		lis   r11, xxxx
+-		lwz   r11, xxxx(r11)
+-	 Branch target is in r11.  */
+-
+-      target = (ppc_insn_d_field (insnbuf[0]) << 16)
+-	| ppc_insn_d_field (insnbuf[1]);
+-      target = read_memory_unsigned_integer (target, 4, byte_order);
+-    }
++  scan_limit = 1;
++  /* When reverse-debugging, scan backward to check whether we are
++     in the middle of trampoline code.  */
++  if (execution_direction == EXEC_REVERSE)
++    scan_limit = 4;	/* At more 4 instructions.  */
+ 
+-  if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so, insnbuf))
++  for (i = 0; i < scan_limit; i++)
+     {
+-      /* Insn pattern is
+-		lwz   r11, xxxx(r30)
+-	 Branch target is in r11.  */
+-
+-      target = get_frame_register_unsigned (frame, tdep->ppc_gp0_regnum + 30)
+-	       + ppc_insn_d_field (insnbuf[0]);
+-      target = read_memory_unsigned_integer (target, 4, byte_order);
++      if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf))
++	{
++	  /* Insn pattern is
++	     lis   r11, xxxx
++	     lwz   r11, xxxx(r11)
++	     Branch target is in r11.  */
++
++	  target = (ppc_insn_d_field (insnbuf[0]) << 16)
++		   | ppc_insn_d_field (insnbuf[1]);
++	  target = read_memory_unsigned_integer (target, 4, byte_order);
++	}
++      else if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so,
++					insnbuf))
++	{
++	  /* Insn pattern is
++	     lwz   r11, xxxx(r30)
++	     Branch target is in r11.  */
++
++	  target = get_frame_register_unsigned (frame,
++						tdep->ppc_gp0_regnum + 30)
++		   + ppc_insn_d_field (insnbuf[0]);
++	  target = read_memory_unsigned_integer (target, 4, byte_order);
++	}
++      else
++	{
++	  /* Scan backward one more instructions if doesn't match.  */
++	  pc -= 4;
++	  continue;
++	}
++
++      return target;
+     }
+ 
+-  return target;
++  return 0;
+ }
+ 
+ /* Wrappers to handle Linux-only registers.  */
diff --git a/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-6of7.patch b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-6of7.patch
new file mode 100644
index 0000000..f8e3ff3
--- /dev/null
+++ b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-6of7.patch
@@ -0,0 +1,131 @@
+  Message-ID: <54BB676B.2090101@gmail.com>
+  Date: Sun, 18 Jan 2015 15:57:31 +0800
+  From: Wei-cheng Wang <cole945 at gmail dot com>
+  To: Jan Kratochvil <jan dot kratochvil at redhat dot com>
+  CC: Ulrich Weigand <uweigand at de dot ibm dot com>, gdb-patches at sourceware dot org,  Joel Brobecker <brobecker at adacore dot com>
+  Subject: Re: Broken build: rs6000-tdep.c: 32-bit host --enable-targets=all --enable-64-bit-bfd  [Re: [PATCH 2/3 v4] Process record support for PowerPC]
+
+  On 2015/1/18 下午 02:59, Jan Kratochvil wrote:
+  > GDB has paddress(), core_addr_to_string() and hex_string() instead while the
+  > codebase uses these three interchangeably.  But the codebase uses even the
+  > %lx+long form.
+
+  Using %s+paddress instead of %lx+long in this patch.
+
+  Thanks,
+  Wei-cheng
+
+
+commit 810c102655475827a3174fb64b5e14beaa57ec3f
+Author: Wei-cheng Wang <cole945@gmail.com>
+Date:   Sun Jan 18 15:20:46 2015 +0800
+
+    Fix format warning in rs6000t-dep.c
+
+Index: gdb-7.6.1/gdb/rs6000-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/rs6000-tdep.c
++++ gdb-7.6.1/gdb/rs6000-tdep.c
+@@ -3405,7 +3405,6 @@ rs6000_epilogue_frame_cache (struct fram
+   struct rs6000_frame_cache *cache;
+   struct gdbarch *gdbarch = get_frame_arch (this_frame);
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+-  CORE_ADDR sp;
+ 
+   if (*this_cache)
+     return *this_cache;
+@@ -4006,8 +4005,8 @@ ppc_process_record_op4 (struct gdbarch *
+       return 0;
+     }
+ 
+-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+-		      "%08x at %08lx, 4-%d.\n", insn, addr, ext);
++  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
++		      "at %s, 4-%d.\n", insn, paddress (gdbarch, addr), ext);
+   return -1;
+ }
+ 
+@@ -4049,8 +4048,8 @@ ppc_process_record_op19 (struct gdbarch
+       return 0;
+     }
+ 
+-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+-		      "%08x at %08lx, 19-%d.\n", insn, addr, ext);
++  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
++		      "at %s, 19-%d.\n", insn, paddress (gdbarch, addr), ext);
+   return -1;
+ }
+ 
+@@ -4507,7 +4506,8 @@ ppc_process_record_op31 (struct gdbarch
+     case 878:		/* Transaction Abort Doubleword Conditional Immediate */
+     case 910:		/* Transaction Abort */
+       fprintf_unfiltered (gdb_stdlog, "Cannot record Transaction instructions. "
+-			  "%08x at %08lx, 31-%d.\n", insn, addr, ext);
++			  "%08x at %s, 31-%d.\n",
++			  insn, paddress (gdbarch, addr), ext);
+       return -1;
+ 
+     case 1014:		/* Data Cache Block set to Zero */
+@@ -4526,8 +4526,8 @@ ppc_process_record_op31 (struct gdbarch
+     }
+ 
+ UNKNOWN_OP:
+-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+-		      "%08x at %08lx, 31-%d.\n", insn, addr, ext);
++  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
++		      "at %s, 31-%d.\n", insn, paddress (gdbarch, addr), ext);
+   return -1;
+ }
+ 
+@@ -4618,8 +4618,8 @@ ppc_process_record_op59 (struct gdbarch
+       return 0;
+     }
+ 
+-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+-		      "%08x at %08lx, 59-%d.\n", insn, addr, ext);
++  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
++		      "at %s, 59-%d.\n", insn, paddress (gdbarch, addr), ext);
+   return -1;
+ }
+ 
+@@ -4631,7 +4631,6 @@ ppc_process_record_op60 (struct gdbarch
+ {
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+   int ext = PPC_EXTOP (insn);
+-  int tmp;
+ 
+   switch (ext >> 2)
+     {
+@@ -4901,8 +4900,8 @@ ppc_process_record_op60 (struct gdbarch
+       return 0;
+     }
+ 
+-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+-		      "%08x at %08lx, 60-%d.\n", insn, addr, ext);
++  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
++		      "at %s, 60-%d.\n", insn, paddress (gdbarch, addr), ext);
+   return -1;
+ }
+ 
+@@ -5067,8 +5066,8 @@ ppc_process_record_op63 (struct gdbarch
+ 
+     }
+ 
+-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+-		      "%08x at %08lx, 59-%d.\n", insn, addr, ext);
++  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
++		      "at %s, 59-%d.\n", insn, paddress (gdbarch, addr), ext);
+   return -1;
+ }
+ 
+@@ -5347,8 +5346,8 @@ ppc_process_record (struct gdbarch *gdba
+ 
+     default:
+ UNKNOWN_OP:
+-      fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
+-			  "%08x at %08lx, %d.\n", insn, addr, op6);
++      fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
++			  "at %s, %d.\n", insn, paddress (gdbarch, addr), op6);
+       return -1;
+     }
+ 
diff --git a/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-7of7.patch b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-7of7.patch
new file mode 100644
index 0000000..4922423
--- /dev/null
+++ b/SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-7of7.patch
@@ -0,0 +1,284 @@
+  Message-ID: <54BD2C4B.7010102@gmail.com>
+  Date: Tue, 20 Jan 2015 00:09:47 +0800
+  From: Wei-cheng Wang <cole945 at gmail dot com>
+  To: Joel Brobecker <brobecker at adacore dot com>
+  CC: Ulrich Weigand <uweigand at de dot ibm dot com>, gdb-patches at sourceware dot org
+  Subject: Re: [PATCH 2/3 v4] Process record support for PowerPC
+
+  On 2015/1/19 下午 03:48, Joel Brobecker wrote:
+  >> Using %s+paddress instead of %lx+long in this patch.
+  > The change looks fine to me, but there is no ChangeLog.
+
+  Hi Joel,
+
+  ChangeLog is in my last mail.  Re-post below for your review.
+
+  2015-01-18  Wei-cheng Wang  <cole945@gmail.com>
+
+	      * rs6000-tdep.c (ppc_process_record_op4, ppc_process_record_op19,
+	      ppc_process_record_op31, ppc_process_record_op59,
+	      ppc_process_record_op60, ppc_process_record_op63,
+	      ppc_process_record): Fix -Wformat warning.
+	      * rs6000-tdep.c (rs6000_epilogue_frame_cache, ppc_process_record_op60):
+	      Remove unused variables.
+
+  > Also, I ended glancing at some of the patches you recently pushed,
+  > and noticed that you added a lot of new functions for which there
+  > is no introductory comment describing the function's behavior and
+  > arguments. It is now mandatory that all new functions, no matter
+  > how trivial, have such introductory comment. Would you mind going
+  > back over your patches, and send a patch that adds the missing
+  > comments, please?
+
+  I've added the missing comments.  See below.
+
+  Thanks,
+  Wei-cheng
+
+
+  2015-01-18  Wei-cheng Wang  <cole945@gmail.com>
+
+	      * ppc-linux-tdep.c (ppc_skip_trampoline_code,
+	      ppc_canonicalize_syscall, ppc_linux_syscall_record,
+	      ppc_linux_record_signal, ppc_init_linux_record_tdep): Add comments.
+	      * ppc64-tdep.c (ppc64_skip_trampoline_code): Likewise.
+	      * rs6000-tdep.c (rs6000_epilogue_frame_cache,
+	      rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register,
+	      rs6000_epilogue_frame_sniffer, ppc_record_vsr, ppc_process_record_op4,
+	      ppc_process_record_op19, ppc_process_record_op31,
+	      ppc_process_record_op59, ppc_process_record_op60,
+	      ppc_process_record_op63): Likewise.
+
+commit ddeca1dffbe346eea03b893bf3c5bc46e4439e93
+Author: Wei-cheng Wang <cole945@gmail.com>
+Date:   Mon Jan 19 23:34:07 2015 +0800
+
+    Add missing comments in rs6000-tdep.c, ppc64-tdep.c and ppc-linux-tdep.c.
+    
+    gdb/ChangeLog:
+    
+    	* ppc-linux-tdep.c (ppc_skip_trampoline_code,
+    	ppc_canonicalize_syscall, ppc_linux_syscall_record,
+    	ppc_linux_record_signal, ppc_init_linux_record_tdep): Add comments.
+    	* ppc64-tdep.c (ppc64_skip_trampoline_code): Likewise.
+    	* rs6000-tdep.c (rs6000_epilogue_frame_cache,
+    	rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register,
+    	rs6000_epilogue_frame_sniffer, ppc_record_vsr, ppc_process_record_op4,
+    	ppc_process_record_op19, ppc_process_record_op31,
+    	ppc_process_record_op59, ppc_process_record_op60,
+    	ppc_process_record_op63): Likewise.
+
+Index: gdb-7.6.1/gdb/ppc64-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/ppc64-tdep.c
++++ gdb-7.6.1/gdb/ppc64-tdep.c
+@@ -449,7 +449,10 @@ ppc64_standard_linkage4_target (struct f
+ 
+ 
+ /* Given that we've begun executing a call trampoline at PC, return
+-   the entry point of the function the trampoline will go to.  */
++   the entry point of the function the trampoline will go to.
++
++   When the execution direction is EXEC_REVERSE, scan backward to
++   check whether we are in the middle of a PLT stub.  */
+ 
+ CORE_ADDR
+ ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+Index: gdb-7.6.1/gdb/ppc-linux-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/ppc-linux-tdep.c
++++ gdb-7.6.1/gdb/ppc-linux-tdep.c
+@@ -353,7 +353,12 @@ powerpc_linux_in_dynsym_resolve_code (CO
+   return 0;
+ }
+ 
+-/* Follow PLT stub to actual routine.  */
++/* Follow PLT stub to actual routine.
++
++   When the execution direction is EXEC_REVERSE, scan backward to
++   check whether we are in the middle of a PLT stub.  Currently,
++   we only look-behind at most 4 instructions (the max length of PLT
++   stub sequence.  */
+ 
+ static CORE_ADDR
+ ppc_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+@@ -839,11 +844,16 @@ ppc_linux_get_syscall_number (struct gdb
+ static struct linux_record_tdep ppc_linux_record_tdep;
+ static struct linux_record_tdep ppc64_linux_record_tdep;
+ 
++/* ppc_canonicalize_syscall maps from the native PowerPC Linux set of
++   syscall ids into a canonical set of syscall ids used by process
++   record.  (See arch/powerpc/include/uapi/asm/unistd.h in kernel tree.)
++   Return -1 if this system call is not supported by process record.
++   Otherwise, return the syscall number for preocess reocrd of given
++   SYSCALL.  */
++
+ static enum gdb_syscall
+ ppc_canonicalize_syscall (int syscall)
+ {
+-  /* See arch/powerpc/include/uapi/asm/unistd.h */
+-
+   if (syscall <= 165)
+     return syscall;
+   else if (syscall >= 167 && syscall <= 190)	/* Skip query_module 166 */
+@@ -869,6 +879,9 @@ ppc_canonicalize_syscall (int syscall)
+   return -1;
+ }
+ 
++/* Record registers which might be clobbered during system call.
++   Return 0 if successful.  */
++
+ static int
+ ppc_linux_syscall_record (struct regcache *regcache)
+ {
+@@ -949,6 +962,9 @@ ppc_linux_syscall_record (struct regcach
+   return 0;
+ }
+ 
++/* Record registers which might be clobbered during signal handling.
++   Return 0 if successful.  */
++
+ static int
+ ppc_linux_record_signal (struct gdbarch *gdbarch, struct regcache *regcache,
+ 			 enum gdb_signal signal)
+@@ -1470,7 +1486,9 @@ static const struct frame_unwind ppu2spu
+   ppu2spu_prev_arch,
+ };
+ 
+-/* Initialize linux_record_tdep if not initialized yet.  */
++/* Initialize linux_record_tdep if not initialized yet.
++   WORDSIZE is 4 or 8 for 32- or 64-bit PowerPC Linux respectively.
++   Sizes of data structures are initialized accordingly.  */
+ 
+ static void
+ ppc_init_linux_record_tdep (struct linux_record_tdep *record_tdep,
+Index: gdb-7.6.1/gdb/rs6000-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/rs6000-tdep.c
++++ gdb-7.6.1/gdb/rs6000-tdep.c
+@@ -3398,6 +3398,9 @@ static const struct frame_unwind rs6000_
+   default_frame_sniffer
+ };
+ 
++/* Allocate and initialize a frame cache for an epilogue frame.
++   SP is restored and prev-PC is stored in LR.  */
++
+ static struct rs6000_frame_cache *
+ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
+ {
+@@ -3434,6 +3437,9 @@ rs6000_epilogue_frame_cache (struct fram
+   return cache;
+ }
+ 
++/* Implementation of frame_unwind.this_id, as defined in frame_unwind.h.
++   Return the frame ID of an epilogue frame.  */
++
+ static void
+ rs6000_epilogue_frame_this_id (struct frame_info *this_frame,
+ 			       void **this_cache, struct frame_id *this_id)
+@@ -3449,6 +3455,9 @@ rs6000_epilogue_frame_this_id (struct fr
+     (*this_id) = frame_id_build (info->base, pc);
+ }
+ 
++/* Implementation of frame_unwind.prev_register, as defined in frame_unwind.h.
++   Return the register value of REGNUM in previous frame.  */
++
+ static struct value *
+ rs6000_epilogue_frame_prev_register (struct frame_info *this_frame,
+ 				     void **this_cache, int regnum)
+@@ -3458,6 +3467,9 @@ rs6000_epilogue_frame_prev_register (str
+   return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
+ }
+ 
++/* Implementation of frame_unwind.sniffer, as defined in frame_unwind.h.
++   Check whether this an epilogue frame.  */
++
+ static int
+ rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
+ 			       struct frame_info *this_frame,
+@@ -3471,6 +3483,9 @@ rs6000_epilogue_frame_sniffer (const str
+     return 0;
+ }
+ 
++/* Frame unwinder for epilogue frame.  This is required for reverse step-over
++   a function without debug information.  */
++
+ static const struct frame_unwind rs6000_epilogue_frame_unwind =
+ {
+   NORMAL_FRAME,
+@@ -3717,7 +3732,9 @@ bfd_uses_spe_extensions (bfd *abfd)
+ #define PPC_XT(insn)	((PPC_TX (insn) << 5) | PPC_T (insn))
+ #define PPC_XER_NB(xer)	(xer & 0x7f)
+ 
+-/* Record Vector-Scalar Registers.  */
++/* Record Vector-Scalar Registers.
++   For VSR less than 32, it's represented by an FPR and an VSR-upper register.
++   Otherwise, it's just a VR register.  Record them accordingly.  */
+ 
+ static int
+ ppc_record_vsr (struct regcache *regcache, struct gdbarch_tdep *tdep, int vsr)
+@@ -3742,11 +3759,12 @@ ppc_record_vsr (struct regcache *regcach
+   return 0;
+ }
+ 
+-/* Parse instructions of primary opcode-4.  */
++/* Parse and record instructions primary opcode-4 at ADDR.
++   Return 0 if successful.  */
+ 
+ static int
+ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
+-			   CORE_ADDR addr, uint32_t insn)
++			CORE_ADDR addr, uint32_t insn)
+ {
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+   int ext = PPC_FIELD (insn, 21, 11);
+@@ -4010,7 +4028,8 @@ ppc_process_record_op4 (struct gdbarch *
+   return -1;
+ }
+ 
+-/* Parse instructions of primary opcode-19.  */
++/* Parse and record instructions of primary opcode-19 at ADDR.
++   Return 0 if successful.  */
+ 
+ static int
+ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
+@@ -4053,7 +4072,8 @@ ppc_process_record_op19 (struct gdbarch
+   return -1;
+ }
+ 
+-/* Parse instructions of primary opcode-31.  */
++/* Parse and record instructions of primary opcode-31 at ADDR.
++   Return 0 if successful.  */
+ 
+ static int
+ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
+@@ -4531,7 +4551,8 @@ UNKNOWN_OP:
+   return -1;
+ }
+ 
+-/* Parse instructions of primary opcode-59.  */
++/* Parse and record instructions of primary opcode-59 at ADDR.
++   Return 0 if successful.  */
+ 
+ static int
+ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
+@@ -4623,7 +4644,8 @@ ppc_process_record_op59 (struct gdbarch
+   return -1;
+ }
+ 
+-/* Parse instructions of primary opcode-60.  */
++/* Parse and record instructions of primary opcode-60 at ADDR.
++   Return 0 if successful.  */
+ 
+ static int
+ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
+@@ -4905,7 +4927,8 @@ ppc_process_record_op60 (struct gdbarch
+   return -1;
+ }
+ 
+-/* Parse instructions of primary opcode-63.  */
++/* Parse and record instructions of primary opcode-63 at ADDR.
++   Return 0 if successful.  */
+ 
+ static int
+ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
diff --git a/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-1of8.patch b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-1of8.patch
new file mode 100644
index 0000000..76107e7
--- /dev/null
+++ b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-1of8.patch
@@ -0,0 +1,257 @@
+commit 1ec56e88aa9b052ab10b806d82fbdbc8d153d977
+Author: Pedro Alves <palves@redhat.com>
+Date:   Fri Nov 22 13:17:46 2013 +0000
+
+    Eliminate dwarf2_frame_cache recursion, don't unwind from the dwarf2 sniffer (move dwarf2_tailcall_sniffer_first elsewhere).
+    
+    Two rationales, same patch.
+    
+    TL;DR 1:
+    
+     dwarf2_frame_cache recursion is evil.  dwarf2_frame_cache calls
+     dwarf2_tailcall_sniffer_first which then recurses into
+     dwarf2_frame_cache.
+    
+    TL;DR 2:
+    
+     An unwinder trying to unwind is evil.  dwarf2_frame_sniffer calls
+     dwarf2_frame_cache which calls dwarf2_tailcall_sniffer_first which
+     then tries to unwind the PC of the previous frame.
+    
+    Avoid all that by deferring dwarf2_tailcall_sniffer_first until it's
+    really necessary.
+    
+    Rationale 1
+    ===========
+    
+    A frame sniffer should not try to unwind, because that bypasses all
+    the validation checks done by get_prev_frame.  The UNWIND_SAME_ID
+    scenario is one such case where GDB is currently broken because (in
+    part) of this (the next patch adds a test that would fail without
+    this).
+    
+    GDB goes into an infinite loop in value_fetch_lazy, here:
+    
+          while (VALUE_LVAL (new_val) == lval_register && value_lazy (new_val))
+    	{
+    	  frame = frame_find_by_id (VALUE_FRAME_ID (new_val));
+    ...
+    	  new_val = get_frame_register_value (frame, regnum);
+    	}
+    
+    (top-gdb) bt
+    #0  value_fetch_lazy (val=0x11516d0) at ../../src/gdb/value.c:3510
+    #1  0x0000000000584bd8 in value_optimized_out (value=0x11516d0) at ../../src/gdb/value.c:1096
+    #2  0x00000000006fe7a1 in frame_register_unwind (frame=0x1492600, regnum=16, optimizedp=0x7fffffffcdec, unavailablep=0x7fffffffcde8, lvalp=0x7fffffffcdd8, addrp=
+        0x7fffffffcde0, realnump=0x7fffffffcddc, bufferp=0x7fffffffce10 "@\316\377\377\377\177") at ../../src/gdb/frame.c:940
+    #3  0x00000000006fea3a in frame_unwind_register (frame=0x1492600, regnum=16, buf=0x7fffffffce10 "@\316\377\377\377\177") at ../../src/gdb/frame.c:990
+    #4  0x0000000000473b9b in i386_unwind_pc (gdbarch=0xf54660, next_frame=0x1492600) at ../../src/gdb/i386-tdep.c:1771
+    #5  0x0000000000601dfa in gdbarch_unwind_pc (gdbarch=0xf54660, next_frame=0x1492600) at ../../src/gdb/gdbarch.c:2870
+    #6  0x0000000000693db5 in dwarf2_tailcall_sniffer_first (this_frame=0x1492600, tailcall_cachep=0x14926f0, entry_cfa_sp_offsetp=0x7fffffffcf00)
+        at ../../src/gdb/dwarf2-frame-tailcall.c:389
+    #7  0x0000000000690928 in dwarf2_frame_cache (this_frame=0x1492600, this_cache=0x1492618) at ../../src/gdb/dwarf2-frame.c:1245
+    #8  0x0000000000690f46 in dwarf2_frame_sniffer (self=0x8e4980, this_frame=0x1492600, this_cache=0x1492618) at ../../src/gdb/dwarf2-frame.c:1423
+    #9  0x000000000070203b in frame_unwind_find_by_frame (this_frame=0x1492600, this_cache=0x1492618) at ../../src/gdb/frame-unwind.c:112
+    #10 0x00000000006fd681 in get_frame_id (fi=0x1492600) at ../../src/gdb/frame.c:408
+    #11 0x00000000007006c2 in get_prev_frame_1 (this_frame=0xdc1860) at ../../src/gdb/frame.c:1826
+    #12 0x0000000000700b7a in get_prev_frame (this_frame=0xdc1860) at ../../src/gdb/frame.c:2056
+    #13 0x0000000000514588 in frame_info_to_frame_object (frame=0xdc1860) at ../../src/gdb/python/py-frame.c:322
+    #14 0x000000000051784c in bootstrap_python_frame_filters (frame=0xdc1860, frame_low=0, frame_high=-1) at ../../src/gdb/python/py-framefilter.c:1396
+    #15 0x0000000000517a6f in apply_frame_filter (frame=0xdc1860, flags=7, args_type=CLI_SCALAR_VALUES, out=0xed7a90, frame_low=0, frame_high=-1)
+        at ../../src/gdb/python/py-framefilter.c:1492
+    #16 0x00000000005e77b0 in backtrace_command_1 (count_exp=0x0, show_locals=0, no_filters=0, from_tty=1) at ../../src/gdb/stack.c:1777
+    #17 0x00000000005e7c0f in backtrace_command (arg=0x0, from_tty=1) at ../../src/gdb/stack.c:1891
+    #18 0x00000000004e37a7 in do_cfunc (c=0xda4fa0, args=0x0, from_tty=1) at ../../src/gdb/cli/cli-decode.c:107
+    #19 0x00000000004e683c in cmd_func (cmd=0xda4fa0, args=0x0, from_tty=1) at ../../src/gdb/cli/cli-decode.c:1882
+    #20 0x00000000006f35ed in execute_command (p=0xcc66c2 "", from_tty=1) at ../../src/gdb/top.c:468
+    #21 0x00000000005f8853 in command_handler (command=0xcc66c0 "bt") at ../../src/gdb/event-top.c:435
+    #22 0x00000000005f8e12 in command_line_handler (rl=0xfe05f0 "@") at ../../src/gdb/event-top.c:632
+    #23 0x000000000074d2c6 in rl_callback_read_char () at ../../src/readline/callback.c:220
+    #24 0x00000000005f8375 in rl_callback_read_char_wrapper (client_data=0x0) at ../../src/gdb/event-top.c:164
+    #25 0x00000000005f876a in stdin_event_handler (error=0, client_data=0x0) at ../../src/gdb/event-top.c:375
+    #26 0x00000000005f72fa in handle_file_event (data=...) at ../../src/gdb/event-loop.c:768
+    #27 0x00000000005f67a3 in process_event () at ../../src/gdb/event-loop.c:342
+    #28 0x00000000005f686a in gdb_do_one_event () at ../../src/gdb/event-loop.c:406
+    #29 0x00000000005f68bb in start_event_loop () at ../../src/gdb/event-loop.c:431
+    #30 0x00000000005f83a7 in cli_command_loop (data=0x0) at ../../src/gdb/event-top.c:179
+    #31 0x00000000005eeed3 in current_interp_command_loop () at ../../src/gdb/interps.c:327
+    #32 0x00000000005ef8ff in captured_command_loop (data=0x0) at ../../src/gdb/main.c:267
+    #33 0x00000000005ed2f6 in catch_errors (func=0x5ef8e4 <captured_command_loop>, func_args=0x0, errstring=0x8b6554 "", mask=RETURN_MASK_ALL)
+        at ../../src/gdb/exceptions.c:524
+    #34 0x00000000005f0d21 in captured_main (data=0x7fffffffd9e0) at ../../src/gdb/main.c:1067
+    #35 0x00000000005ed2f6 in catch_errors (func=0x5efb9b <captured_main>, func_args=0x7fffffffd9e0, errstring=0x8b6554 "", mask=RETURN_MASK_ALL)
+        at ../../src/gdb/exceptions.c:524
+    #36 0x00000000005f0d57 in gdb_main (args=0x7fffffffd9e0) at ../../src/gdb/main.c:1076
+    #37 0x000000000045bb6a in main (argc=4, argv=0x7fffffffdae8) at ../../src/gdb/gdb.c:34
+    (top-gdb)
+    
+    GDB is trying to unwind the PC register of the previous frame (frame
+    #5 above), starting from the frame being sniffed (the THIS frame).
+    But the THIS frame's unwinder says the PC of the previous frame is
+    actually the same as the previous's frame's next frame (which is the
+    same frame we started with, the THIS frame), therefore it returns an
+    lval_register lazy value with frame set to THIS frame.  And so the
+    value_fetch_lazy loop never ends.
+    
+    
+    Rationale 2
+    ===========
+    
+    As an experiment, I tried making dwarf2-frame.c:read_addr_from_reg use
+    address_from_register.  That caused a bunch of regressions, but it
+    actually took me a long while to figure out what was going on.  Turns
+    out dwarf2-frame.c:read_addr_from_reg is called while computing the
+    frame's CFA, from within dwarf2_frame_cache.  address_from_register
+    wants to create a register with frame_id set to the frame being
+    constructed.  To create the frame id, we again call dwarf2_frame_cache,
+    which given:
+    
+    static struct dwarf2_frame_cache *
+    dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
+    {
+    ...
+      if (*this_cache)
+        return *this_cache;
+    
+    returns an incomplete object to the caller:
+    static void
+    dwarf2_frame_this_id (struct frame_info *this_frame, void **this_cache,
+    		      struct frame_id *this_id)
+    {
+      struct dwarf2_frame_cache *cache =
+        dwarf2_frame_cache (this_frame, this_cache);
+    ...
+     (*this_id) = frame_id_build (cache->cfa, get_frame_func (this_frame));
+    }
+    
+    As cache->cfa is still 0 (we were trying to compute it!), and
+    get_frame_id recalls this id from here on, we end up with a broken
+    frame id in recorded for this frame.  Later, when inspecting locals,
+    the dwarf machinery needs to know the selected frame's base, which
+    calls get_frame_base:
+    
+    CORE_ADDR
+    get_frame_base (struct frame_info *fi)
+    {
+      return get_frame_id (fi).stack_addr;
+    }
+    
+    which as seen above then returns 0 ...
+    
+    So I gave up using address_from_register.
+    
+    But, the pain of investigating this made me want to have GDB itself
+    assert that recursion never happens here.  So I wrote a patch to do
+    that.  But, it triggers on current mainline, because
+    dwarf2_tailcall_sniffer_first, called from dwarf2_frame_cache, unwinds
+    the this_frame.
+    
+    A sniffer shouldn't be trying to unwind, exactly because of this sort
+    of tricky issue.  The patch defers calling
+    dwarf2_tailcall_sniffer_first until it's really necessary, in
+    dwarf2_frame_prev_register (thus actually outside the sniffer path).
+    As this makes the call to dwarf2_frame_sniffer in dwarf2_frame_cache
+    unnecessary again, the patch removes that too.
+    
+    Tested on x86_64 Fedora 17.
+    
+    gdb/
+    2013-11-22  Pedro Alves  <palves@redhat.com>
+    
+    	PR 16155
+    	* dwarf2-frame.c (struct dwarf2_frame_cache)
+    	<checked_tailcall_bottom, entry_cfa_sp_offset,
+    	entry_cfa_sp_offset_p>: New fields.
+    	(dwarf2_frame_cache): Adjust to use the new cache fields instead
+    	of locals.  Don't call dwarf2_tailcall_sniffer_first here.
+    	(dwarf2_frame_prev_register): Call it here, but only once.
+
+Index: gdb-7.6.1/gdb/dwarf2-frame.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/dwarf2-frame.c
++++ gdb-7.6.1/gdb/dwarf2-frame.c
+@@ -984,12 +984,22 @@ struct dwarf2_frame_cache
+   /* The .text offset.  */
+   CORE_ADDR text_offset;
+ 
++  /* True if we already checked whether this frame is the bottom frame
++     of a virtual tail call frame chain.  */
++  int checked_tailcall_bottom;
++
+   /* If not NULL then this frame is the bottom frame of a TAILCALL_FRAME
+      sequence.  If NULL then it is a normal case with no TAILCALL_FRAME
+      involved.  Non-bottom frames of a virtual tail call frames chain use
+      dwarf2_tailcall_frame_unwind unwinder so this field does not apply for
+      them.  */
+   void *tailcall_cache;
++
++  /* The number of bytes to subtract from TAILCALL_FRAME frames frame
++     base to get the SP, to simulate the return address pushed on the
++     stack.  */
++  LONGEST entry_cfa_sp_offset;
++  int entry_cfa_sp_offset_p;
+ };
+ 
+ /* A cleanup that sets a pointer to NULL.  */
+@@ -1014,8 +1024,6 @@ dwarf2_frame_cache (struct frame_info *t
+   struct dwarf2_fde *fde;
+   volatile struct gdb_exception ex;
+   CORE_ADDR entry_pc;
+-  LONGEST entry_cfa_sp_offset;
+-  int entry_cfa_sp_offset_p = 0;
+   const gdb_byte *instr;
+ 
+   if (*this_cache)
+@@ -1080,8 +1088,8 @@ dwarf2_frame_cache (struct frame_info *t
+ 	  && (gdbarch_dwarf2_reg_to_regnum (gdbarch, fs->regs.cfa_reg)
+ 	      == gdbarch_sp_regnum (gdbarch)))
+ 	{
+-	  entry_cfa_sp_offset = fs->regs.cfa_offset;
+-	  entry_cfa_sp_offset_p = 1;
++	  cache->entry_cfa_sp_offset = fs->regs.cfa_offset;
++	  cache->entry_cfa_sp_offset_p = 1;
+ 	}
+     }
+   else
+@@ -1230,13 +1238,6 @@ incomplete CFI data; unspecified registe
+     cache->undefined_retaddr = 1;
+ 
+   do_cleanups (old_chain);
+-
+-  /* Try to find a virtual tail call frames chain with bottom (callee) frame
+-     starting at THIS_FRAME.  */
+-  dwarf2_tailcall_sniffer_first (this_frame, &cache->tailcall_cache,
+-				 (entry_cfa_sp_offset_p
+-				  ? &entry_cfa_sp_offset : NULL));
+-
+   discard_cleanups (reset_cache_cleanup);
+   return cache;
+ }
+@@ -1282,6 +1283,16 @@ dwarf2_frame_prev_register (struct frame
+   CORE_ADDR addr;
+   int realnum;
+ 
++  /* Check whether THIS_FRAME is the bottom frame of a virtual tail
++     call frame chain.  */
++  if (!cache->checked_tailcall_bottom)
++    {
++      cache->checked_tailcall_bottom = 1;
++      dwarf2_tailcall_sniffer_first (this_frame, &cache->tailcall_cache,
++				     (cache->entry_cfa_sp_offset_p
++				      ? &cache->entry_cfa_sp_offset : NULL));
++    }
++
+   /* Non-bottom frames of a virtual tail call frames chain use
+      dwarf2_tailcall_frame_unwind unwinder so this code does not apply for
+      them.  If dwarf2_tailcall_prev_register_first does not have specific value
+@@ -1408,10 +1419,6 @@ dwarf2_frame_sniffer (const struct frame
+   if (self->type != NORMAL_FRAME)
+     return 0;
+ 
+-  /* Preinitializa the cache so that TAILCALL_FRAME can find the record by
+-     dwarf2_tailcall_sniffer_first.  */
+-  dwarf2_frame_cache (this_frame, this_cache);
+-
+   return 1;
+ }
+ 
diff --git a/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-2of8.patch b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-2of8.patch
new file mode 100644
index 0000000..3dcafd2
--- /dev/null
+++ b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-2of8.patch
@@ -0,0 +1,819 @@
+commit 33f8fe58b9a55a0075a90cc9080a1716221a3f81
+Author: Pedro Alves <palves@redhat.com>
+Date:   Fri Nov 22 11:51:59 2013 +0000
+
+    Don't let two frames with the same id end up in the frame chain.
+    
+    The UNWIND_SAME_ID check is done between THIS_FRAME and the next frame
+    when we go try to unwind the previous frame.  But at this point, it's
+    already too late -- we ended up with two frames with the same ID in
+    the frame chain.  Each frame having its own ID is an invariant assumed
+    throughout GDB.  This patch applies the UNWIND_SAME_ID detection
+    earlier, right after the previous frame is unwound, discarding the dup
+    frame if a cycle is detected.
+    
+    The patch includes a new test that fails before the change.  Before
+    the patch, the test causes an infinite loop in GDB, after the patch,
+    the UNWIND_SAME_ID logic kicks in and makes the backtrace stop with:
+    
+      Backtrace stopped: previous frame identical to this frame (corrupt stack?)
+    
+    The test uses dwarf CFI to emulate a corrupted stack with a cycle.  It
+    has a function with registers marked DW_CFA_same_value (most
+    importantly RSP/RIP), so that GDB computes the same ID for that frame
+    and its caller.  IOW, something like this:
+    
+     #0 - frame_id_1
+     #1 - frame_id_2
+     #2 - frame_id_3
+     #3 - frame_id_4
+     #4 - frame_id_4  <<<< outermost (UNWIND_SAME_ID).
+    
+    (The test's code is just a copy of dw2-reg-undefined.S /
+    dw2-reg-undefined.c, adjusted to use DW_CFA_same_value instead of
+    DW_CFA_undefined, and to mark a different set of registers.)
+    
+    The infinite loop is here, in value_fetch_lazy:
+    
+          while (VALUE_LVAL (new_val) == lval_register && value_lazy (new_val))
+    	{
+    	  frame = frame_find_by_id (VALUE_FRAME_ID (new_val));
+    ...
+    	  new_val = get_frame_register_value (frame, regnum);
+    	}
+    
+    get_frame_register_value can return a lazy register value pointing to
+    the next frame.  This means that the register wasn't clobbered by
+    FRAME; the debugger should therefore retrieve its value from the next
+    frame.
+    
+    To be clear, get_frame_register_value unwinds the value in question
+    from the next frame:
+    
+     struct value *
+     get_frame_register_value (struct frame_info *frame, int regnum)
+     {
+       return frame_unwind_register_value (frame->next, regnum);
+                                           ^^^^^^^^^^^
+     }
+    
+    In other words, if we get a lazy lval_register, it should have the
+    frame ID of the _next_ frame, never of FRAME.
+    
+    At this point in value_fetch_lazy, the whole relevant chunk of the
+    stack up to frame #4 has already been unwound.  The loop always
+    "unlazies" lval_registers in the "next/innermost" direction, not in
+    the "prev/unwind further/outermost" direction.
+    
+    So say we're looking at frame #4.  get_frame_register_value in frame
+    #4 can return a lazy register value of frame #3.  So the next
+    iteration, frame_find_by_id tries to read the register from frame #3.
+    But, since frame #4 happens to have same id as frame #3,
+    frame_find_by_id returns frame #4 instead.  Rinse, repeat, and we have
+    an infinite loop.
+    
+    This is an old latent problem, exposed by the recent addition of the
+    frame stash.  Before we had a stash, frame_find_by_id(frame_id_4)
+    would walk over all frames starting at the current frame, and would
+    always find #3 first.  The stash happens to return #4 instead:
+    
+    struct frame_info *
+    frame_find_by_id (struct frame_id id)
+    {
+      struct frame_info *frame, *prev_frame;
+    
+    ...
+      /* Try using the frame stash first.  Finding it there removes the need
+         to perform the search by looping over all frames, which can be very
+         CPU-intensive if the number of frames is very high (the loop is O(n)
+         and get_prev_frame performs a series of checks that are relatively
+         expensive).  This optimization is particularly useful when this function
+         is called from another function (such as value_fetch_lazy, case
+         VALUE_LVAL (val) == lval_register) which already loops over all frames,
+         making the overall behavior O(n^2).  */
+      frame = frame_stash_find (id);
+      if (frame)
+        return frame;
+    
+      for (frame = get_current_frame (); ; frame = prev_frame)
+        {
+    
+    gdb/
+    2013-11-22  Pedro Alves  <palves@redhat.com>
+    
+    	PR 16155
+    	* frame.c (get_prev_frame_1): Do the UNWIND_SAME_ID check between
+    	this frame and the new previous frame, not between this frame and
+    	the next frame.
+    
+    gdb/testsuite/
+    2013-11-22  Pedro Alves  <palves@redhat.com>
+    
+    	PR 16155
+    	* gdb.dwarf2/dw2-dup-frame.S: New file.
+    	* gdb.dwarf2/dw2-dup-frame.c: New file.
+    	* gdb.dwarf2/dw2-dup-frame.exp: New file.
+
+Index: gdb-7.6.1/gdb/frame.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/frame.c
++++ gdb-7.6.1/gdb/frame.c
+@@ -1689,6 +1689,7 @@ get_prev_frame_1 (struct frame_info *thi
+ {
+   struct frame_id this_id;
+   struct gdbarch *gdbarch;
++  struct frame_info *prev_frame;
+ 
+   gdb_assert (this_frame != NULL);
+   gdbarch = get_frame_arch (this_frame);
+@@ -1790,22 +1791,6 @@ get_prev_frame_1 (struct frame_info *thi
+ 	}
+     }
+ 
+-  /* Check that this and the next frame are not identical.  If they
+-     are, there is most likely a stack cycle.  As with the inner-than
+-     test above, avoid comparing the inner-most and sentinel frames.  */
+-  if (this_frame->level > 0
+-      && frame_id_eq (this_id, get_frame_id (this_frame->next)))
+-    {
+-      if (frame_debug)
+-	{
+-	  fprintf_unfiltered (gdb_stdlog, "-> ");
+-	  fprint_frame (gdb_stdlog, NULL);
+-	  fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n");
+-	}
+-      this_frame->stop_reason = UNWIND_SAME_ID;
+-      return NULL;
+-    }
+-
+   /* Check that this and the next frame do not unwind the PC register
+      to the same memory location.  If they do, then even though they
+      have different frame IDs, the new frame will be bogus; two
+@@ -1853,7 +1838,31 @@ get_prev_frame_1 (struct frame_info *thi
+ 	}
+     }
+ 
+-  return get_prev_frame_raw (this_frame);
++  prev_frame = get_prev_frame_raw (this_frame);
++
++  /* Check that this and the prev frame are not identical.  If they
++     are, there is most likely a stack cycle.  Unlike the tests above,
++     we do this right after creating the prev frame, to avoid ever
++     ending up with two frames with the same id in the frame
++     chain.  */
++  if (prev_frame != NULL
++      && frame_id_eq (get_frame_id (prev_frame),
++		      get_frame_id (this_frame)))
++    {
++      if (frame_debug)
++	{
++	  fprintf_unfiltered (gdb_stdlog, "-> ");
++	  fprint_frame (gdb_stdlog, NULL);
++	  fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n");
++	}
++      this_frame->stop_reason = UNWIND_SAME_ID;
++      /* Unlink.  */
++      prev_frame->next = NULL;
++      this_frame->prev = NULL;
++      return NULL;
++    }
++
++  return prev_frame;
+ }
+ 
+ /* Construct a new "struct frame_info" and link it previous to
+Index: gdb-7.6.1/gdb/testsuite/gdb.dwarf2/dw2-dup-frame.S
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.dwarf2/dw2-dup-frame.S
+@@ -0,0 +1,540 @@
++/*
++   Copyright 2013 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/>.  */
++
++	/* The FDE entry for "stop_frame" in the .debug_frame section has
++	been hand modified to mark a set of registers as DW_CFA_same_value.
++	Otherwise this file is as generated by gcc 4.7.2 for x86_64.  */
++	.file	"dw2-dup-frame.c"
++	.text
++.Ltext0:
++	.globl	stop_frame
++	.type	stop_frame, @function
++stop_frame:
++.LFB0:
++	.file 1 "dw2-dup-frame.c"
++	.loc 1 19 0
++	pushq	%rbp
++.LCFI0:
++	movq	%rsp, %rbp
++.LCFI1:
++	.loc 1 22 0
++	popq	%rbp
++.LCFI2:
++	ret
++.LFE0:
++	.size	stop_frame, .-stop_frame
++	.globl	first_frame
++	.type	first_frame, @function
++first_frame:
++.LFB1:
++	.loc 1 26 0
++	pushq	%rbp
++.LCFI3:
++	movq	%rsp, %rbp
++.LCFI4:
++	.loc 1 27 0
++	movl	$0, %eax
++	call	stop_frame
++	.loc 1 28 0
++	popq	%rbp
++.LCFI5:
++	ret
++.LFE1:
++	.size	first_frame, .-first_frame
++	.globl	main
++	.type	main, @function
++main:
++.LFB2:
++	.loc 1 32 0
++	pushq	%rbp
++.LCFI6:
++	movq	%rsp, %rbp
++.LCFI7:
++	.loc 1 33 0
++	movl	$0, %eax
++	call	first_frame
++	.loc 1 35 0
++	movl	$0, %eax
++	.loc 1 36 0
++	popq	%rbp
++.LCFI8:
++	ret
++.LFE2:
++	.size	main, .-main
++	.section	.debug_frame,"",@progbits
++.Lframe0:
++	.long	.LECIE0-.LSCIE0
++.LSCIE0:
++	.long	0xffffffff
++	.byte	0x1
++	.string	""
++	.uleb128 0x1
++	.sleb128 -8
++	.byte	0x10
++	.byte	0xc
++	.uleb128 0x7
++	.uleb128 0x8
++	.byte	0x90
++	.uleb128 0x1
++	.align 8
++.LECIE0:
++	/* This FDE entry, for stop_frame was modified to mark
++	   registers 0 -> 16 (rax..ra/rip) as being DW_CFA_same_value.  */
++.LSFDE0:
++	.long	.LEFDE0-.LASFDE0
++.LASFDE0:
++	.long	.Lframe0
++	.quad	.LFB0
++	.quad	.LFE0-.LFB0
++
++		/* START OF NEW CONTENT.  */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0x0			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0x1			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0x2			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0x3			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0x4			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0x5			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0x6			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0x7			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0x8			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0x9			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0xa			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0xb			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0xc			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0xd			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0xe			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0xf			/*   ULEB128 register */
++	.byte	0x8			/* DW_CFA_same_value */
++	.uleb128 0x10			 /*   ULEB128 register */
++		/* END OF NEW CONTENT.  */
++
++	.byte	0x4
++	.long	.LCFI0-.LFB0
++	.byte	0xe
++	.uleb128 0x10
++	.byte	0x86
++	.uleb128 0x2
++	.byte	0x4
++	.long	.LCFI1-.LCFI0
++	.byte	0xd
++	.uleb128 0x6
++	.byte	0x4
++	.long	.LCFI2-.LCFI1
++	.byte	0xc
++	.uleb128 0x7
++	.uleb128 0x8
++	.align 8
++.LEFDE0:
++.LSFDE2:
++	.long	.LEFDE2-.LASFDE2
++.LASFDE2:
++	.long	.Lframe0
++	.quad	.LFB1
++	.quad	.LFE1-.LFB1
++	.byte	0x4
++	.long	.LCFI3-.LFB1
++	.byte	0xe
++	.uleb128 0x10
++	.byte	0x86
++	.uleb128 0x2
++	.byte	0x4
++	.long	.LCFI4-.LCFI3
++	.byte	0xd
++	.uleb128 0x6
++	.byte	0x4
++	.long	.LCFI5-.LCFI4
++	.byte	0xc
++	.uleb128 0x7
++	.uleb128 0x8
++	.align 8
++.LEFDE2:
++.LSFDE4:
++	.long	.LEFDE4-.LASFDE4
++.LASFDE4:
++	.long	.Lframe0
++	.quad	.LFB2
++	.quad	.LFE2-.LFB2
++	.byte	0x4
++	.long	.LCFI6-.LFB2
++	.byte	0xe
++	.uleb128 0x10
++	.byte	0x86
++	.uleb128 0x2
++	.byte	0x4
++	.long	.LCFI7-.LCFI6
++	.byte	0xd
++	.uleb128 0x6
++	.byte	0x4
++	.long	.LCFI8-.LCFI7
++	.byte	0xc
++	.uleb128 0x7
++	.uleb128 0x8
++	.align 8
++.LEFDE4:
++	.section	.eh_frame,"a",@progbits
++.Lframe1:
++	.long	.LECIE1-.LSCIE1
++.LSCIE1:
++	.long	0
++	.byte	0x1
++	.string	"zR"
++	.uleb128 0x1
++	.sleb128 -8
++	.byte	0x10
++	.uleb128 0x1
++	.byte	0x3
++	.byte	0xc
++	.uleb128 0x7
++	.uleb128 0x8
++	.byte	0x90
++	.uleb128 0x1
++	.align 8
++.LECIE1:
++.LSFDE7:
++	.long	.LEFDE7-.LASFDE7
++.LASFDE7:
++	.long	.LASFDE7-.Lframe1
++	.long	.LFB0
++	.long	.LFE0-.LFB0
++	.uleb128 0
++	.byte	0x4
++	.long	.LCFI0-.LFB0
++	.byte	0xe
++	.uleb128 0x10
++	.byte	0x86
++	.uleb128 0x2
++	.byte	0x4
++	.long	.LCFI1-.LCFI0
++	.byte	0xd
++	.uleb128 0x6
++	.byte	0x4
++	.long	.LCFI2-.LCFI1
++	.byte	0xc
++	.uleb128 0x7
++	.uleb128 0x8
++	.align 8
++.LEFDE7:
++.LSFDE9:
++	.long	.LEFDE9-.LASFDE9
++.LASFDE9:
++	.long	.LASFDE9-.Lframe1
++	.long	.LFB1
++	.long	.LFE1-.LFB1
++	.uleb128 0
++	.byte	0x4
++	.long	.LCFI3-.LFB1
++	.byte	0xe
++	.uleb128 0x10
++	.byte	0x86
++	.uleb128 0x2
++	.byte	0x4
++	.long	.LCFI4-.LCFI3
++	.byte	0xd
++	.uleb128 0x6
++	.byte	0x4
++	.long	.LCFI5-.LCFI4
++	.byte	0xc
++	.uleb128 0x7
++	.uleb128 0x8
++	.align 8
++.LEFDE9:
++.LSFDE11:
++	.long	.LEFDE11-.LASFDE11
++.LASFDE11:
++	.long	.LASFDE11-.Lframe1
++	.long	.LFB2
++	.long	.LFE2-.LFB2
++	.uleb128 0
++	.byte	0x4
++	.long	.LCFI6-.LFB2
++	.byte	0xe
++	.uleb128 0x10
++	.byte	0x86
++	.uleb128 0x2
++	.byte	0x4
++	.long	.LCFI7-.LCFI6
++	.byte	0xd
++	.uleb128 0x6
++	.byte	0x4
++	.long	.LCFI8-.LCFI7
++	.byte	0xc
++	.uleb128 0x7
++	.uleb128 0x8
++	.align 8
++.LEFDE11:
++	.text
++.Letext0:
++	.section	.debug_info,"",@progbits
++.Ldebug_info0:
++	.long	0x8c
++	.value	0x2
++	.long	.Ldebug_abbrev0
++	.byte	0x8
++	.uleb128 0x1
++	.long	.LASF2
++	.byte	0x1
++	.long	.LASF3
++	.long	.LASF4
++	.quad	.Ltext0
++	.quad	.Letext0
++	.long	.Ldebug_line0
++	.uleb128 0x2
++	.byte	0x1
++	.long	.LASF0
++	.byte	0x1
++	.byte	0x12
++	.quad	.LFB0
++	.quad	.LFE0
++	.long	.LLST0
++	.byte	0x1
++	.uleb128 0x3
++	.byte	0x1
++	.long	.LASF1
++	.byte	0x1
++	.byte	0x19
++	.quad	.LFB1
++	.quad	.LFE1
++	.long	.LLST1
++	.byte	0x1
++	.uleb128 0x4
++	.byte	0x1
++	.long	.LASF5
++	.byte	0x1
++	.byte	0x1f
++	.long	0x88
++	.quad	.LFB2
++	.quad	.LFE2
++	.long	.LLST2
++	.byte	0x1
++	.uleb128 0x5
++	.byte	0x4
++	.byte	0x5
++	.string	"int"
++	.byte	0
++	.section	.debug_abbrev,"",@progbits
++.Ldebug_abbrev0:
++	.uleb128 0x1
++	.uleb128 0x11
++	.byte	0x1
++	.uleb128 0x25
++	.uleb128 0xe
++	.uleb128 0x13
++	.uleb128 0xb
++	.uleb128 0x3
++	.uleb128 0xe
++	.uleb128 0x1b
++	.uleb128 0xe
++	.uleb128 0x11
++	.uleb128 0x1
++	.uleb128 0x12
++	.uleb128 0x1
++	.uleb128 0x10
++	.uleb128 0x6
++	.byte	0
++	.byte	0
++	.uleb128 0x2
++	.uleb128 0x2e
++	.byte	0
++	.uleb128 0x3f
++	.uleb128 0xc
++	.uleb128 0x3
++	.uleb128 0xe
++	.uleb128 0x3a
++	.uleb128 0xb
++	.uleb128 0x3b
++	.uleb128 0xb
++	.uleb128 0x11
++	.uleb128 0x1
++	.uleb128 0x12
++	.uleb128 0x1
++	.uleb128 0x40
++	.uleb128 0x6
++	.uleb128 0x2117
++	.uleb128 0xc
++	.byte	0
++	.byte	0
++	.uleb128 0x3
++	.uleb128 0x2e
++	.byte	0
++	.uleb128 0x3f
++	.uleb128 0xc
++	.uleb128 0x3
++	.uleb128 0xe
++	.uleb128 0x3a
++	.uleb128 0xb
++	.uleb128 0x3b
++	.uleb128 0xb
++	.uleb128 0x11
++	.uleb128 0x1
++	.uleb128 0x12
++	.uleb128 0x1
++	.uleb128 0x40
++	.uleb128 0x6
++	.uleb128 0x2116
++	.uleb128 0xc
++	.byte	0
++	.byte	0
++	.uleb128 0x4
++	.uleb128 0x2e
++	.byte	0
++	.uleb128 0x3f
++	.uleb128 0xc
++	.uleb128 0x3
++	.uleb128 0xe
++	.uleb128 0x3a
++	.uleb128 0xb
++	.uleb128 0x3b
++	.uleb128 0xb
++	.uleb128 0x49
++	.uleb128 0x13
++	.uleb128 0x11
++	.uleb128 0x1
++	.uleb128 0x12
++	.uleb128 0x1
++	.uleb128 0x40
++	.uleb128 0x6
++	.uleb128 0x2116
++	.uleb128 0xc
++	.byte	0
++	.byte	0
++	.uleb128 0x5
++	.uleb128 0x24
++	.byte	0
++	.uleb128 0xb
++	.uleb128 0xb
++	.uleb128 0x3e
++	.uleb128 0xb
++	.uleb128 0x3
++	.uleb128 0x8
++	.byte	0
++	.byte	0
++	.byte	0
++	.section	.debug_loc,"",@progbits
++.Ldebug_loc0:
++.LLST0:
++	.quad	.LFB0-.Ltext0
++	.quad	.LCFI0-.Ltext0
++	.value	0x2
++	.byte	0x77
++	.sleb128 8
++	.quad	.LCFI0-.Ltext0
++	.quad	.LCFI1-.Ltext0
++	.value	0x2
++	.byte	0x77
++	.sleb128 16
++	.quad	.LCFI1-.Ltext0
++	.quad	.LCFI2-.Ltext0
++	.value	0x2
++	.byte	0x76
++	.sleb128 16
++	.quad	.LCFI2-.Ltext0
++	.quad	.LFE0-.Ltext0
++	.value	0x2
++	.byte	0x77
++	.sleb128 8
++	.quad	0
++	.quad	0
++.LLST1:
++	.quad	.LFB1-.Ltext0
++	.quad	.LCFI3-.Ltext0
++	.value	0x2
++	.byte	0x77
++	.sleb128 8
++	.quad	.LCFI3-.Ltext0
++	.quad	.LCFI4-.Ltext0
++	.value	0x2
++	.byte	0x77
++	.sleb128 16
++	.quad	.LCFI4-.Ltext0
++	.quad	.LCFI5-.Ltext0
++	.value	0x2
++	.byte	0x76
++	.sleb128 16
++	.quad	.LCFI5-.Ltext0
++	.quad	.LFE1-.Ltext0
++	.value	0x2
++	.byte	0x77
++	.sleb128 8
++	.quad	0
++	.quad	0
++.LLST2:
++	.quad	.LFB2-.Ltext0
++	.quad	.LCFI6-.Ltext0
++	.value	0x2
++	.byte	0x77
++	.sleb128 8
++	.quad	.LCFI6-.Ltext0
++	.quad	.LCFI7-.Ltext0
++	.value	0x2
++	.byte	0x77
++	.sleb128 16
++	.quad	.LCFI7-.Ltext0
++	.quad	.LCFI8-.Ltext0
++	.value	0x2
++	.byte	0x76
++	.sleb128 16
++	.quad	.LCFI8-.Ltext0
++	.quad	.LFE2-.Ltext0
++	.value	0x2
++	.byte	0x77
++	.sleb128 8
++	.quad	0
++	.quad	0
++	.section	.debug_aranges,"",@progbits
++	.long	0x2c
++	.value	0x2
++	.long	.Ldebug_info0
++	.byte	0x8
++	.byte	0
++	.value	0
++	.value	0
++	.quad	.Ltext0
++	.quad	.Letext0-.Ltext0
++	.quad	0
++	.quad	0
++	.section	.debug_line,"",@progbits
++.Ldebug_line0:
++	.section	.debug_str,"MS",@progbits,1
++.LASF0:
++	.string	"stop_frame"
++.LASF3:
++	.string	"dw2-reg-undefined.c"
++.LASF2:
++	.string	"GNU C 4.7.2"
++.LASF1:
++	.string	"first_frame"
++.LASF5:
++	.string	"main"
++.LASF4:
++	.string	"/home/username/src/gdb/testsuite/gdb.dwarf2"
++	.ident	"GCC: (GNU) 4.7.2"
++	.section	.note.GNU-stack,"",@progbits
+Index: gdb-7.6.1/gdb/testsuite/gdb.dwarf2/dw2-dup-frame.c
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.dwarf2/dw2-dup-frame.c
+@@ -0,0 +1,36 @@
++/*
++   Copyright 2013 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/>.  */
++
++void
++stop_frame ()
++{
++  /* The debug information for this frame is modified in the accompanying
++     .S file, to mark a set of registers as being DW_CFA_same_value.  */
++}
++
++void
++first_frame ()
++{
++  stop_frame ();
++}
++
++int
++main ()
++{
++  first_frame ();
++
++  return 0;
++}
+Index: gdb-7.6.1/gdb/testsuite/gdb.dwarf2/dw2-dup-frame.exp
+===================================================================
+--- /dev/null
++++ gdb-7.6.1/gdb/testsuite/gdb.dwarf2/dw2-dup-frame.exp
+@@ -0,0 +1,44 @@
++# Copyright 2013 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/>.
++load_lib dwarf.exp
++
++# This test can only be run on targets which support DWARF-2 and use gas.
++if {![dwarf2_support]} {
++    return 0
++}
++
++# This test can only be run on x86_64 targets.
++if {![istarget "x86_64-*-*"] || ![is_lp64_target]} {
++    return 0
++}
++
++standard_testfile .S
++
++if { [prepare_for_testing $testfile.exp $testfile $srcfile {nodebug}] } {
++    return -1
++}
++
++if ![runto stop_frame] {
++    perror "Failed to stop in stop_frame"
++    return -1
++}
++
++gdb_test "bt" \
++    "#0  stop_frame \[^\r\n\]*\r\nBacktrace stopped: previous frame identical to this frame \\(corrupt stack\\?\\)" \
++    "backtrace from stop_frame"
++
++gdb_test "up" \
++    "Initial frame selected; you cannot go up\\\." \
++    "up from stop_frame"
diff --git a/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-3of8.patch b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-3of8.patch
new file mode 100644
index 0000000..23e70cc
--- /dev/null
+++ b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-3of8.patch
@@ -0,0 +1,246 @@
+commit 194cca41192efa65f710967e3149bbc813c12b22
+Author: Pedro Alves <palves@redhat.com>
+Date:   Thu Nov 21 15:20:09 2013 +0000
+
+    Make use of the frame stash to detect wider stack cycles.
+    
+    Given we already have the frame id stash, which holds the ids of all
+    frames in the chain, detecting corrupted stacks with wide stack cycles
+    with non-consecutive dup frame ids is just as cheap as just detecting
+    cycles in consecutive frames:
+    
+     #0 frame_id1
+     #1 frame_id2
+     #2 frame_id3
+     #3 frame_id1
+     #4 frame_id2
+     #5 frame_id3
+     #6 frame_id1
+     ... forever ...
+    
+    We just need to check whether the stash already knows about a given
+    frame id instead of comparing the ids of the previous/this frames.
+    
+    Tested on x86_64 Fedora 17.
+    
+    gdb/
+    2013-11-22  Pedro Alves  <palves@redhat.com>
+    	    Tom Tromey  <tromey@redhat.com>
+    
+    	* frame.c (frame_stash_add): Now returns whether a frame with the
+    	same ID was already known.
+    	(compute_frame_id): New function, factored out from get_frame_id.
+    	(get_frame_id): No longer lazilly compute the frame id here.
+    	(get_prev_frame_if_no_cycle): New function.  Detects wider stack
+    	cycles.
+    	(get_prev_frame_1): Use it instead of get_prev_frame_raw directly,
+    	and checking for stack cycles here.
+
+Index: gdb-7.6.1/gdb/frame.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/frame.c
++++ gdb-7.6.1/gdb/frame.c
+@@ -189,23 +189,31 @@ frame_stash_create (void)
+ 			     NULL);
+ }
+ 
+-/* Internal function to add a frame to the frame_stash hash table.  Do
+-   not store frames below 0 as they may not have any addresses to
+-   calculate a hash.  */
++/* Internal function to add a frame to the frame_stash hash table.
++   Returns false if a frame with the same ID was already stashed, true
++   otherwise.  */
+ 
+-static void
++static int
+ frame_stash_add (struct frame_info *frame)
+ {
+-  /* Do not stash frames below level 0.  */
+-  if (frame->level >= 0)
+-    {
+-      struct frame_info **slot;
++  struct frame_info **slot;
+ 
+-      slot = (struct frame_info **) htab_find_slot (frame_stash,
+-						    frame,
+-						    INSERT);
+-      *slot = frame;
+-    }
++  /* Do not try to stash the sentinel frame.  */
++  gdb_assert (frame->level >= 0);
++
++  slot = (struct frame_info **) htab_find_slot (frame_stash,
++						frame,
++						INSERT);
++
++  /* If we already have a frame in the stack with the same id, we
++     either have a stack cycle (corrupted stack?), or some bug
++     elsewhere in GDB.  In any case, ignore the duplicate and return
++     an indication to the caller.  */
++  if (*slot != NULL)
++    return 0;
++
++  *slot = frame;
++  return 1;
+ }
+ 
+ /* Internal function to search the frame stash for an entry with the
+@@ -397,6 +405,34 @@ skip_artificial_frames (struct frame_inf
+   return frame;
+ }
+ 
++/* Compute the frame's uniq ID that can be used to, later, re-find the
++   frame.  */
++
++static void
++compute_frame_id (struct frame_info *fi)
++{
++  gdb_assert (!fi->this_id.p);
++
++  if (frame_debug)
++    fprintf_unfiltered (gdb_stdlog, "{ compute_frame_id (fi=%d) ",
++			fi->level);
++  /* Find the unwinder.  */
++  if (fi->unwind == NULL)
++    frame_unwind_find_by_frame (fi, &fi->prologue_cache);
++  /* Find THIS frame's ID.  */
++  /* Default to outermost if no ID is found.  */
++  fi->this_id.value = outer_frame_id;
++  fi->unwind->this_id (fi, &fi->prologue_cache, &fi->this_id.value);
++  gdb_assert (frame_id_p (fi->this_id.value));
++  fi->this_id.p = 1;
++  if (frame_debug)
++    {
++      fprintf_unfiltered (gdb_stdlog, "-> ");
++      fprint_frame_id (gdb_stdlog, fi->this_id.value);
++      fprintf_unfiltered (gdb_stdlog, " }\n");
++    }
++}
++
+ /* Return a frame uniq ID that can be used to, later, re-find the
+    frame.  */
+ 
+@@ -406,29 +442,7 @@ get_frame_id (struct frame_info *fi)
+   if (fi == NULL)
+     return null_frame_id;
+ 
+-  if (!fi->this_id.p)
+-    {
+-      if (frame_debug)
+-	fprintf_unfiltered (gdb_stdlog, "{ get_frame_id (fi=%d) ",
+-			    fi->level);
+-      /* Find the unwinder.  */
+-      if (fi->unwind == NULL)
+-	frame_unwind_find_by_frame (fi, &fi->prologue_cache);
+-      /* Find THIS frame's ID.  */
+-      /* Default to outermost if no ID is found.  */
+-      fi->this_id.value = outer_frame_id;
+-      fi->unwind->this_id (fi, &fi->prologue_cache, &fi->this_id.value);
+-      gdb_assert (frame_id_p (fi->this_id.value));
+-      fi->this_id.p = 1;
+-      if (frame_debug)
+-	{
+-	  fprintf_unfiltered (gdb_stdlog, "-> ");
+-	  fprint_frame_id (gdb_stdlog, fi->this_id.value);
+-	  fprintf_unfiltered (gdb_stdlog, " }\n");
+-	}
+-      frame_stash_add (fi);
+-    }
+-
++  gdb_assert (fi->this_id.p);
+   return fi->this_id.value;
+ }
+ 
+@@ -1678,6 +1692,42 @@ frame_register_unwind_location (struct f
+     }
+ }
+ 
++/* Get the previous raw frame, and check that it is not identical to
++   same other frame frame already in the chain.  If it is, there is
++   most likely a stack cycle, so we discard it, and mark THIS_FRAME as
++   outermost, with UNWIND_SAME_ID stop reason.  Unlike the other
++   validity tests, that compare THIS_FRAME and the next frame, we do
++   this right after creating the previous frame, to avoid ever ending
++   up with two frames with the same id in the frame chain.  */
++
++static struct frame_info *
++get_prev_frame_if_no_cycle (struct frame_info *this_frame)
++{
++  struct frame_info *prev_frame;
++
++  prev_frame = get_prev_frame_raw (this_frame);
++  if (prev_frame == NULL)
++    return NULL;
++
++  compute_frame_id (prev_frame);
++  if (frame_stash_add (prev_frame))
++    return prev_frame;
++
++  /* Another frame with the same id was already in the stash.  We just
++     detected a cycle.  */
++  if (frame_debug)
++    {
++      fprintf_unfiltered (gdb_stdlog, "-> ");
++      fprint_frame (gdb_stdlog, NULL);
++      fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n");
++    }
++  this_frame->stop_reason = UNWIND_SAME_ID;
++  /* Unlink.  */
++  prev_frame->next = NULL;
++  this_frame->prev = NULL;
++  return NULL;
++}
++
+ /* Return a "struct frame_info" corresponding to the frame that called
+    THIS_FRAME.  Returns NULL if there is no such frame.
+ 
+@@ -1689,7 +1739,6 @@ get_prev_frame_1 (struct frame_info *thi
+ {
+   struct frame_id this_id;
+   struct gdbarch *gdbarch;
+-  struct frame_info *prev_frame;
+ 
+   gdb_assert (this_frame != NULL);
+   gdbarch = get_frame_arch (this_frame);
+@@ -1732,7 +1781,7 @@ get_prev_frame_1 (struct frame_info *thi
+      until we have unwound all the way down to the previous non-inline
+      frame.  */
+   if (get_frame_type (this_frame) == INLINE_FRAME)
+-    return get_prev_frame_raw (this_frame);
++    return get_prev_frame_if_no_cycle (this_frame);
+ 
+   /* Check that this frame is unwindable.  If it isn't, don't try to
+      unwind to the prev frame.  */
+@@ -1838,31 +1887,7 @@ get_prev_frame_1 (struct frame_info *thi
+ 	}
+     }
+ 
+-  prev_frame = get_prev_frame_raw (this_frame);
+-
+-  /* Check that this and the prev frame are not identical.  If they
+-     are, there is most likely a stack cycle.  Unlike the tests above,
+-     we do this right after creating the prev frame, to avoid ever
+-     ending up with two frames with the same id in the frame
+-     chain.  */
+-  if (prev_frame != NULL
+-      && frame_id_eq (get_frame_id (prev_frame),
+-		      get_frame_id (this_frame)))
+-    {
+-      if (frame_debug)
+-	{
+-	  fprintf_unfiltered (gdb_stdlog, "-> ");
+-	  fprint_frame (gdb_stdlog, NULL);
+-	  fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n");
+-	}
+-      this_frame->stop_reason = UNWIND_SAME_ID;
+-      /* Unlink.  */
+-      prev_frame->next = NULL;
+-      this_frame->prev = NULL;
+-      return NULL;
+-    }
+-
+-  return prev_frame;
++  return get_prev_frame_if_no_cycle (this_frame);
+ }
+ 
+ /* Construct a new "struct frame_info" and link it previous to
diff --git a/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-4of8.patch b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-4of8.patch
new file mode 100644
index 0000000..8073669
--- /dev/null
+++ b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-4of8.patch
@@ -0,0 +1,61 @@
+commit 6eeee81c8e59511962bdd83df5e7785bfdf871d2
+Author: Tom Tromey <tromey@redhat.com>
+Date:   Fri Nov 22 17:38:44 2013 +0000
+
+    Detect infinite loop in value_fetch_lazy's lval_register handling.
+    
+    If value_fetch_lazy loops infinitely while unwrapping lval_register
+    values, it means we either somehow ended up with two frames with the
+    same ID in the frame chain, or some code is trying to unwind behind
+    get_prev_frame's back (e.g., a frame unwind sniffer trying to unwind).
+    In any case, it should always be an internal error to end up in this
+    situation.
+    
+    This patch adds a check and throws an internal error if the same frame
+    is returned.
+    
+    2013-11-22  Tom Tromey  <tromey@redhat.com>
+    	    Pedro Alves  <palves@redhat.com>
+    
+    	PR backtrace/16155
+    	* value.c (value_fetch_lazy): Internal error if
+    	get_frame_register_value returns the same register.
+
+Index: gdb-7.6.1/gdb/valops.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/valops.c
++++ gdb-7.6.1/gdb/valops.c
+@@ -1093,7 +1093,9 @@ value_fetch_lazy (struct value *val)
+ 
+       while (VALUE_LVAL (new_val) == lval_register && value_lazy (new_val))
+ 	{
+-	  frame = frame_find_by_id (VALUE_FRAME_ID (new_val));
++	  struct frame_id frame_id = VALUE_FRAME_ID (new_val);
++
++	  frame = frame_find_by_id (frame_id);
+ 	  regnum = VALUE_REGNUM (new_val);
+ 
+ 	  gdb_assert (frame != NULL);
+@@ -1107,6 +1109,22 @@ value_fetch_lazy (struct value *val)
+ 						   regnum, type));
+ 
+ 	  new_val = get_frame_register_value (frame, regnum);
++
++	  /* If we get another lazy lval_register value, it means the
++	     register is found by reading it from the next frame.
++	     get_frame_register_value should never return a value with
++	     the frame id pointing to FRAME.  If it does, it means we
++	     either have two consecutive frames with the same frame id
++	     in the frame chain, or some code is trying to unwind
++	     behind get_prev_frame's back (e.g., a frame unwind
++	     sniffer trying to unwind), bypassing its validations.  In
++	     any case, it should always be an internal error to end up
++	     in this situation.  */
++	  if (VALUE_LVAL (new_val) == lval_register
++	      && value_lazy (new_val)
++	      && frame_id_eq (VALUE_FRAME_ID (new_val), frame_id))
++	    internal_error (__FILE__, __LINE__,
++			    _("infinite loop while fetching a register"));
+ 	}
+ 
+       /* If it's still lazy (for instance, a saved register on the
diff --git a/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-5of8.patch b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-5of8.patch
new file mode 100644
index 0000000..21c6b7e
--- /dev/null
+++ b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-5of8.patch
@@ -0,0 +1,69 @@
+commit 2d6f0de676f46ebd8bb7d98a0093aa081e17e94b
+Author: Yao Qi <yao@codesourcery.com>
+Date:   Mon Jun 30 11:47:51 2014 +0800
+
+    Tweak gdb.trace/tfile.c for thumb mode
+    
+    We see the fail below happens on thumb related multi-libs
+    (-mthumb -march={armv4t,armv7-a}),
+    
+    target tfile tfile-basic.tf ^M
+    warning: Uploaded tracepoint 1 has no source location, using raw address^M
+    warning: Breakpoint address adjusted from 0x00008959 to 0x00008958.^M
+    Tracepoint 3 at 0x8958: file /scratch/yqi/arm-none-linux-gnueabi/src/gdb-trunk/gdb/testsuite/gdb.trace/tfile.c, line 91.^M
+    Created tracepoint 3 for target's tracepoint 1 at 0x8959.^M
+    warning: Breakpoint address adjusted from 0x00008959 to 0x00008958.^M
+    warning: Breakpoint address adjusted from 0x00008959 to 0x00008958.^M
+    warning: Breakpoint address adjusted from 0x00008959 to 0x00008958.^M
+    (gdb) FAIL: gdb.trace/tfile.exp: complete-command 'target tfile'
+    
+    The address of write_basic_trace_file is two-bytes aligned,
+    
+    (gdb) p write_basic_trace_file
+    $1 = {void (void)} 0x8958 <write_basic_trace_file>
+    
+    but the ld sets the LSB of every reference to the function address
+    (indicating the address is in thumb mode), so "&write_basic_trace_file"
+    in the program becomes 0x8959, which is saved in the trace file.  That
+    is why the warnnings are emitted.
+    
+    This patch is to clear the LSB of the function address written to trace
+    file in thumb and thumb2 mode.  This patch fixes the fail above.
+    
+    gdb/testsuite:
+    
+    2014-07-10  Yao Qi  <yao@codesourcery.com>
+    
+    	* gdb.trace/tfile.c (write_basic_trace_file)
+    	[__thumb__||__thumb2__]: Clear the Thumb bit of the function
+    	address written to trace file.
+
+Index: gdb-7.6.1/gdb/testsuite/gdb.trace/tfile.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/gdb.trace/tfile.c
++++ gdb-7.6.1/gdb/testsuite/gdb.trace/tfile.c
+@@ -68,6 +68,7 @@ write_basic_trace_file (void)
+ {
+   int fd, int_x;
+   short short_x;
++  long func_addr;
+ 
+   fd = start_trace_file ("basic.tf");
+ 
+@@ -86,8 +87,14 @@ write_basic_trace_file (void)
+   /* Dump tracepoint definitions, in syntax similar to that used
+      for reconnection uploads.  */
+   /* FIXME need a portable way to print function address in hex */
+-  snprintf (spbuf, sizeof spbuf, "tp T1:%lx:E:0:0\n",
+-	    (long) &write_basic_trace_file);
++  func_addr = (long) &write_basic_trace_file;
++#if defined(__thumb__) || defined(__thumb2__)
++  /* Although Thumb functions are two-byte aligned, function
++     pointers have the Thumb bit set.  Clear it.  */
++  func_addr &= ~1;
++#endif
++
++  snprintf (spbuf, sizeof spbuf, "tp T1:%lx:E:0:0\n", func_addr);
+   write (fd, spbuf, strlen (spbuf));
+   /* (Note that we would only need actions defined if we wanted to
+      test tdump.) */
diff --git a/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-6of8.patch b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-6of8.patch
new file mode 100644
index 0000000..1cce577
--- /dev/null
+++ b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-6of8.patch
@@ -0,0 +1,88 @@
+commit 62261490a36c6911c5eb61be7cddcfb1bd19ba18
+Author: Pedro Alves <palves@redhat.com>
+Date:   Thu Jan 16 17:43:26 2014 +0000
+
+    Fix gdb.trace/mi-traceframe-changed.exp on s390.
+    
+    The test fails on s390 with:
+    
+      -trace-find frame-number 0^M
+      &"PC not available\n"^M
+      ^done,found="1",tracepoint="1",traceframe="0",frame={level="-1",addr="<unavailable>",func="??",args=[]}^M
+      (gdb) ^M
+      FAIL: gdb.trace/mi-traceframe-changed.exp: tfile: -trace-find frame-number 0
+    
+    tfile knows to infer the PC from the tracepoint's address if the PC
+    wasn't collected (tfile_fetch_registers) but, that only works on
+    targets whose PC register is a raw register, and on s390, the PC
+    register is a pseudo register.
+    
+    But even if GDB doesn't know how to infer the value of PC, saying the
+    current frame is level -1 is a bug:
+    
+      ^done,found="1",tracepoint="1",traceframe="0",frame={level="-1",addr="<unavailable>",func="??",args=[]}^M
+                                                           ^^^^^^^^^
+    
+    '-1' is the level of the sentinel frame, which should never be visible.
+    
+    This is caused by the s390's heuristic unwinder accepting the frame
+    (the fallback heuristic unwinders _always_ accept the frame), but then
+    the unwind->this_id method throws that "PC not available\n" error.
+    
+    IOW, the s390's heuristic unwinder was never adjusted to handle
+    unavailable register values gracefully, which can happen with e.g., a
+    trimmed core file too.
+    
+    This is just the minimal necessary for
+    <unavailable> frames, which at least gets us:
+    
+      (gdb) tfind
+      Found trace frame 0, tracepoint 1
+      #0  <unavailable> in ?? ()
+    
+    That is, frame #0 instead of -1.
+    
+    We could get better info out of "info frame" (this patch makes us show
+    "outermost"), but this change would still be necessary.
+    
+    gdb/
+    2014-01-16  Pedro Alves  <palves@redhat.com>
+    
+    	* s390-linux-tdep.c (s390_frame_unwind_cache): Swallow
+    	NOT_AVAILABLE_ERROR errors while parsing the prologue or reading
+    	the backchain.
+
+Index: gdb-7.6.1/gdb/s390-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/s390-tdep.c
++++ gdb-7.6.1/gdb/s390-tdep.c
+@@ -1995,7 +1995,9 @@ static struct s390_unwind_cache *
+ s390_frame_unwind_cache (struct frame_info *this_frame,
+ 			 void **this_prologue_cache)
+ {
++  volatile struct gdb_exception ex;
+   struct s390_unwind_cache *info;
++
+   if (*this_prologue_cache)
+     return *this_prologue_cache;
+ 
+@@ -2006,10 +2008,15 @@ s390_frame_unwind_cache (struct frame_in
+   info->frame_base = -1;
+   info->local_base = -1;
+ 
+-  /* Try to use prologue analysis to fill the unwind cache.
+-     If this fails, fall back to reading the stack backchain.  */
+-  if (!s390_prologue_frame_unwind_cache (this_frame, info))
+-    s390_backchain_frame_unwind_cache (this_frame, info);
++  TRY_CATCH (ex, RETURN_MASK_ERROR)
++    {
++      /* Try to use prologue analysis to fill the unwind cache.
++	 If this fails, fall back to reading the stack backchain.  */
++      if (!s390_prologue_frame_unwind_cache (this_frame, info))
++	s390_backchain_frame_unwind_cache (this_frame, info);
++    }
++  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
++    throw_exception (ex);
+ 
+   return info;
+ }
diff --git a/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-7of8.patch b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-7of8.patch
new file mode 100644
index 0000000..60e1308
--- /dev/null
+++ b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-7of8.patch
@@ -0,0 +1,288 @@
+commit 1b5d0ab34c53d6e896d2c0958b1176e324bb7878
+Author: Pedro Alves <palves@redhat.com>
+Date:   Wed Jul 16 19:25:41 2014 +0100
+
+    gdb.trace/tfile.c: Remove Thumb bit in one more more, general cleanup
+    
+    I noticed that the existing code casts a function's address to 'long',
+    but that doesn't work correctly on some ABIs, like Win64, where long
+    is 32-bit and while pointers are 64-bit:
+    
+      func_addr = (long) &write_basic_trace_file;
+    
+    Fixing that showed there's actually another place in the file that
+    writes a function address to file, and therefore should clear the
+    Thumb bit.  This commit adds a macro+function pair to centralize the
+    Thumb bit handling, and uses it in both places.
+    
+    The rest is just enough changes to make the file build without
+    warnings with "-Wall -Wextra" with x86_64-w64-mingw32-gcc and
+    i686-w64-mingw32-gcc cross compilers, and with -m32/-m64 on x86_64
+    GNU/Linux.  Currently with x86_64-w64-mingw32-gcc we get:
+    
+      $ x86_64-w64-mingw32-gcc tfile.c  -Wall -DTFILE_DIR=\"\"
+      tfile.c: In function 'start_trace_file':
+      tfile.c:51:23: error: 'S_IRGRP' undeclared (first use in this function)
+    	 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+    			 ^
+      tfile.c:51:23: note: each undeclared identifier is reported only once for each function it appears in
+      tfile.c:51:31: error: 'S_IROTH' undeclared (first use in this function)
+    	 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+    				 ^
+      tfile.c: In function 'add_memory_block':
+      tfile.c:79:10: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
+         ll_x = (unsigned long) addr;
+    	    ^
+      tfile.c: In function 'write_basic_trace_file':
+      tfile.c:113:15: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
+         func_addr = (long) &write_basic_trace_file;
+    		 ^
+      tfile.c:137:3: warning: passing argument 1 of 'add_memory_block' from incompatible pointer type [enabled by default]
+         add_memory_block (&testglob, sizeof (testglob));
+         ^
+      tfile.c:72:1: note: expected 'char *' but argument is of type 'int *'
+       add_memory_block (char *addr, int size)
+       ^
+      tfile.c:139:3: warning: passing argument 1 of 'add_memory_block' from incompatible pointer type [enabled by default]
+         add_memory_block (&testglob2, 1);
+         ^
+      tfile.c:72:1: note: expected 'char *' but argument is of type 'int *'
+       add_memory_block (char *addr, int size)
+       ^
+      tfile.c: In function 'write_error_trace_file':
+      tfile.c:185:3: warning: implicit declaration of function 'alloca' [-Wimplicit-function-declaration]
+         char *hex = alloca (len * 2 + 1);
+         ^
+      tfile.c:185:15: warning: incompatible implicit declaration of built-in function 'alloca' [enabled by default]
+         char *hex = alloca (len * 2 + 1);
+    		 ^
+      tfile.c:211:6: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
+    	(long) &write_basic_trace_file);
+          ^
+    
+    Tested on x86_64 Fedora 20, -m64 and -m32.
+    Tested by Yao on arm targets.
+    
+    gdb/testsuite/
+    2014-07-16  Pedro Alves  <palves@redhat.com>
+    
+    	* gdb.trace/tfile.c: Include unistd.h and stdint.h.
+    	(start_trace_file): Guard S_IRGRP and S_IROTH uses behind #ifdef.
+    	(tfile_write_64, tfile_write_16, tfile_write_8, tfile_write_addr)
+    	(tfile_write_buf): New functions.
+    	(add_memory_block): Rewrite using the above.
+    	(adjust_function_address): New function.
+    	(FUNCTION_ADDRESS): New macro.
+    	(write_basic_trace_file): Remove short_x local, and use
+    	tfile_write_16. Change type of func_addr local to unsigned long
+    	long.  Use FUNCTION_ADDRESS instead of handling the Thumb bit
+    	here.  Cast argument of add_memory_block to char pointer.
+    	(write_error_trace_file): Avoid alloca.  Use FUNCTION_ADDRESS.
+    	(main): Remove parameters.
+    	* gdb.trace/tfile.exp: Remove nowarnings.
+
+Index: gdb-7.6.1/gdb/testsuite/gdb.trace/tfile.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/gdb.trace/tfile.c
++++ gdb-7.6.1/gdb/testsuite/gdb.trace/tfile.c
+@@ -3,9 +3,11 @@
+    GDB.  */
+ 
+ #include <stdio.h>
++#include <unistd.h>
+ #include <string.h>
+ #include <fcntl.h>
+ #include <sys/stat.h>
++#include <stdint.h>
+ 
+ char spbuf[200];
+ 
+@@ -23,9 +25,17 @@ int
+ start_trace_file (char *filename)
+ {
+   int fd;
++  mode_t mode = S_IRUSR | S_IWUSR;
+ 
+-  fd = open (filename, O_WRONLY|O_CREAT|O_APPEND,
+-	     S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
++#ifdef S_IRGRP
++  mode |= S_IRGRP;
++#endif
++
++#ifdef S_IROTH
++  mode |= S_IROTH;
++#endif
++
++  fd = open (filename, O_WRONLY|O_CREAT|O_APPEND, mode);
+ 
+   if (fd < 0)
+     return fd;
+@@ -44,31 +54,73 @@ finish_trace_file (int fd)
+   close (fd);
+ }
+ 
++static void
++tfile_write_64 (uint64_t value)
++{
++  memcpy (trptr, &value, sizeof (uint64_t));
++  trptr += sizeof (uint64_t);
++}
+ 
+-void
+-add_memory_block (char *addr, int size)
++static void
++tfile_write_16 (uint16_t value)
++{
++  memcpy (trptr, &value, sizeof (uint16_t));
++  trptr += sizeof (uint16_t);
++}
++
++static void
++tfile_write_8 (uint8_t value)
+ {
+-  short short_x;
+-  unsigned long long ll_x;
++  memcpy (trptr, &value, sizeof (uint8_t));
++  trptr += sizeof (uint8_t);
++}
+ 
+-  *((char *) trptr) = 'M';
+-  trptr += 1;
+-  ll_x = (unsigned long) addr;
+-  memcpy (trptr, &ll_x, sizeof (unsigned long long));
+-  trptr += sizeof (unsigned long long);
+-  short_x = size;
+-  memcpy (trptr, &short_x, 2);
+-  trptr += 2;
++static void
++tfile_write_addr (char *addr)
++{
++  tfile_write_64 ((uint64_t) (uintptr_t) addr);
++}
++
++static void
++tfile_write_buf (const void *addr, size_t size)
++{
+   memcpy (trptr, addr, size);
+   trptr += size;
+ }
+ 
+ void
++add_memory_block (char *addr, int size)
++{
++  tfile_write_8 ('M');
++  tfile_write_addr (addr);
++  tfile_write_16 (size);
++  tfile_write_buf (addr, size);
++}
++
++/* Adjust a function's address to account for architectural
++   particularities.  */
++
++static uintptr_t
++adjust_function_address (uintptr_t func_addr)
++{
++#if defined(__thumb__) || defined(__thumb2__)
++  /* Although Thumb functions are two-byte aligned, function
++     pointers have the Thumb bit set.  Clear it.  */
++  return func_addr & ~1;
++#else
++  return func_addr;
++#endif
++}
++
++/* Get a function's address as an integer.  */
++
++#define FUNCTION_ADDRESS(FUN) adjust_function_address ((uintptr_t) &FUN)
++
++void
+ write_basic_trace_file (void)
+ {
+   int fd, int_x;
+-  short short_x;
+-  long func_addr;
++  unsigned long long func_addr;
+ 
+   fd = start_trace_file ("basic.tf");
+ 
+@@ -86,15 +138,9 @@ write_basic_trace_file (void)
+ 
+   /* Dump tracepoint definitions, in syntax similar to that used
+      for reconnection uploads.  */
+-  /* FIXME need a portable way to print function address in hex */
+-  func_addr = (long) &write_basic_trace_file;
+-#if defined(__thumb__) || defined(__thumb2__)
+-  /* Although Thumb functions are two-byte aligned, function
+-     pointers have the Thumb bit set.  Clear it.  */
+-  func_addr &= ~1;
+-#endif
++  func_addr = FUNCTION_ADDRESS (write_basic_trace_file);
+ 
+-  snprintf (spbuf, sizeof spbuf, "tp T1:%lx:E:0:0\n", func_addr);
++  snprintf (spbuf, sizeof spbuf, "tp T1:%llx:E:0:0\n", func_addr);
+   write (fd, spbuf, strlen (spbuf));
+   /* (Note that we would only need actions defined if we wanted to
+      test tdump.) */
+@@ -106,14 +152,13 @@ write_basic_trace_file (void)
+   /* (Encapsulate better if we're going to do lots of this; note that
+      buffer endianness is the target program's enddianness.) */
+   trptr = trbuf;
+-  short_x = 1;
+-  memcpy (trptr, &short_x, 2);
+-  trptr += 2;
++  tfile_write_16 (1);
++
+   tfsizeptr = trptr;
+   trptr += 4;
+-  add_memory_block (&testglob, sizeof (testglob));
++  add_memory_block ((char *) &testglob, sizeof (testglob));
+   /* Divide a variable between two separate memory blocks.  */
+-  add_memory_block (&testglob2, 1);
++  add_memory_block ((char *) &testglob2, 1);
+   add_memory_block (((char*) &testglob2) + 1, sizeof (testglob2) - 1);
+   /* Go back and patch in the frame size.  */
+   int_x = trptr - tfsizeptr - sizeof (int);
+@@ -158,8 +203,8 @@ write_error_trace_file (void)
+ {
+   int fd;
+   const char made_up[] = "made-up error";
++  char hex[(sizeof (made_up) - 1) * 2 + 1];
+   int len = sizeof (made_up) - 1;
+-  char *hex = alloca (len * 2 + 1);
+ 
+   fd = start_trace_file ("error.tf");
+ 
+@@ -183,9 +228,8 @@ write_error_trace_file (void)
+ 
+   /* Dump tracepoint definitions, in syntax similar to that used
+      for reconnection uploads.  */
+-  /* FIXME need a portable way to print function address in hex */
+-  snprintf (spbuf, sizeof spbuf, "tp T1:%lx:E:0:0\n",
+-	    (long) &write_basic_trace_file);
++  snprintf (spbuf, sizeof spbuf, "tp T1:%llx:E:0:0\n",
++	    (unsigned long long) FUNCTION_ADDRESS (write_basic_trace_file));
+   write (fd, spbuf, strlen (spbuf));
+   /* (Note that we would only need actions defined if we wanted to
+      test tdump.) */
+@@ -210,7 +254,7 @@ done_making_trace_files (void)
+ }
+ 
+ int
+-main (int argc, char **argv, char **envp)
++main (void)
+ {
+   write_basic_trace_file ();
+ 
+Index: gdb-7.6.1/gdb/testsuite/gdb.trace/tfile.exp
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/gdb.trace/tfile.exp
++++ gdb-7.6.1/gdb/testsuite/gdb.trace/tfile.exp
+@@ -26,7 +26,7 @@ gdb_exit
+ gdb_start
+ standard_testfile
+ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+-	  executable {debug nowarnings}] != "" } {
++	  executable {debug}] != "" } {
+     untested ${testfile}.exp
+     return -1
+ }
diff --git a/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-8of8.patch b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-8of8.patch
new file mode 100644
index 0000000..71f07e2
--- /dev/null
+++ b/SOURCES/gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-8of8.patch
@@ -0,0 +1,59 @@
+commit 763905a3ad8f98d33bd9319790a8d53904554265
+Author: Yao Qi <yao@codesourcery.com>
+Date:   Mon Oct 27 16:37:38 2014 +0800
+
+    Fix trace file fails on powerpc64
+    
+    I see the following fails on powerpc64-linux,
+    
+    (gdb) target tfile tfile-basic.tf^M
+    warning: Uploaded tracepoint 1 has no source location, using raw address^M
+    Tracepoint 1 at 0x10012358^M
+    Created tracepoint 1 for target's tracepoint 1 at 0x10012358.^M
+    (gdb) PASS: gdb.trace/tfile.exp: target tfile tfile-basic.tf
+    info trace^M
+    Num     Type           Disp Enb Address            What^M
+    1       tracepoint     keep y   0x0000000010012358 <write_basic_trace_file>^M
+            installed on target^M
+    (gdb) FAIL: gdb.trace/tfile.exp: info tracepoints on trace file
+    
+    -target-select tfile tfile-basic.tf^M
+    =thread-group-started,id="i1",pid="1"^M
+    =thread-created,id="1",group-id="i1"^M
+    &"warning: Uploaded tracepoint 1 has no source location, using raw address\n"^M
+    =breakpoint-created,bkpt={number="1",type="tracepoint",disp="keep",enabled="y",
+    addr="0x0000000010012358",at="<write_basic_trace_file>",thread-groups=["i1"],
+    times="0",installed="y",original-location="*0x10012358"}^M
+    ~"Created tracepoint 1 for target's tracepoint 1 at 0x10012358.\n"^M
+    ^connected^M
+    (gdb) ^M
+    FAIL: gdb.trace/mi-traceframe-changed.exp: tfile: select trace file
+    
+    These fails are caused by writing function descriptor address into trace
+    file instead of function address.  This patch is to teach tfile.c to
+    write function address on powerpc64 target.  With this patch applied,
+    fails in tfile.exp and mi-traceframe-changed.exp are fixed.  Is it
+    OK?
+    
+    gdb/testsuite:
+    
+    2014-10-27  Yao Qi  <yao@codesourcery.com>
+    
+    	* gdb.trace/tfile.c (adjust_function_address)
+    	[__powerpc64__ && _CALL_ELF != 2]: Get function address from
+    	function descriptor.
+
+Index: gdb-7.6.1/gdb/testsuite/gdb.trace/tfile.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/testsuite/gdb.trace/tfile.c
++++ gdb-7.6.1/gdb/testsuite/gdb.trace/tfile.c
+@@ -107,6 +107,9 @@ adjust_function_address (uintptr_t func_
+   /* Although Thumb functions are two-byte aligned, function
+      pointers have the Thumb bit set.  Clear it.  */
+   return func_addr & ~1;
++#elif defined __powerpc64__ && _CALL_ELF != 2
++  /* Get function address from function descriptor.  */
++  return *(uintptr_t *) func_addr;
+ #else
+   return func_addr;
+ #endif
diff --git a/SOURCES/gdb-rhbz1247107-backport-aarch64-stap-sdt-support-1of2.patch b/SOURCES/gdb-rhbz1247107-backport-aarch64-stap-sdt-support-1of2.patch
new file mode 100644
index 0000000..54bc65f
--- /dev/null
+++ b/SOURCES/gdb-rhbz1247107-backport-aarch64-stap-sdt-support-1of2.patch
@@ -0,0 +1,1120 @@
+commit 05c0465e16a5e2db92f8975aebf2bb5aacb1c542
+Author: Sergio Durigan Junior <sergiodj@redhat.com>
+Date:   Thu Dec 19 18:53:40 2013 -0200
+
+    Extend SystemTap SDT probe argument parser
+    
+    This patch extends the current generic parser for SystemTap SDT probe
+    arguments.  It can be almost considered a cleanup, but the main point of
+    it is actually to allow the generic parser to accept multiple prefixes
+    and suffixes for the its operands (i.e., integers, register names, and
+    register indirection).
+    
+    I have chosen to implement this as a list of const strings, and declare
+    this list as "static" inside each target's method used to initialize
+    gdbarch.
+    
+    This patch is actually a preparation for an upcoming patch for ARM,
+    which implements the support for multiple integer prefixes (as defined
+    by ARM's asm spec).  And AArch64 will also need this, for the same
+    reason.
+    
+    This patch was regtested on all architectures that it touches (i.e.,
+    i386, x86_64, ARM, PPC/PPC64, s390x and IA-64).  No regressions were found.
+    
+    2013-12-19  Sergio Durigan Junior  <sergiodj@redhat.com>
+    
+    	* amd64-tdep.c (amd64_init_abi): Declare SystemTap SDT probe
+    	argument prefixes and suffixes.  Initialize gdbarch with them.
+    	* arm-linux-tdep.c (arm_linux_init_abi): Likewise.
+    	* gdbarch.c: Regenerate.
+    	* gdbarch.h: Regenerate.
+    	* gdbarch.sh (stap_integer_prefix, stap_integer_suffix)
+    	(stap_register_prefix, stap_register_suffix)
+    	(stap_register_indirection_prefix)
+    	(stap_register_indirection_suffix): Declare as "const char *const
+    	*" instead of "const char *".  Adjust printing function.  Rename
+    	all of the variables to the plural.
+    	(pstring_list): New function.
+    	* i386-tdep.c (i386_elf_init_abi): Declare SystemTap SDT probe
+    	argument prefixes and suffixes.  Initialize gdbarch with them.
+    	* ia64-linux-tdep.c (ia64_linux_init_abi): Likewise.
+    	* ppc-linux-tdep.c (ppc_linux_init_abi): Likewise.
+    	* s390-linux-tdep.c (s390_gdbarch_init): Likewise.
+    	* stap-probe.c (stap_is_generic_prefix): New function.
+    	(stap_is_register_prefix): Likewise.
+    	(stap_is_register_indirection_prefix): Likewise.
+    	(stap_is_integer_prefix): Likewise.
+    	(stap_generic_check_suffix): Likewise.
+    	(stap_check_integer_suffix): Likewise.
+    	(stap_check_register_suffix): Likewise.
+    	(stap_check_register_indirection_suffix): Likewise.
+    	(stap_parse_register_operand): Remove unecessary declarations for
+    	variables holding prefix and suffix information.  Use the new
+    	functions listed above for checking for prefixes and suffixes.
+    	(stap_parse_single_operand): Likewise.
+
+Index: gdb-7.6.1/gdb/amd64-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/amd64-tdep.c
++++ gdb-7.6.1/gdb/amd64-tdep.c
+@@ -2867,6 +2867,12 @@ amd64_init_abi (struct gdbarch_info info
+ {
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+   const struct target_desc *tdesc = info.target_desc;
++  static const char *const stap_integer_prefixes[] = { "$", NULL };
++  static const char *const stap_register_prefixes[] = { "%", NULL };
++  static const char *const stap_register_indirection_prefixes[] = { "(",
++								    NULL };
++  static const char *const stap_register_indirection_suffixes[] = { ")",
++								    NULL };
+ 
+   /* AMD64 generally uses `fxsave' instead of `fsave' for saving its
+      floating-point registers.  */
+@@ -2976,10 +2982,12 @@ amd64_init_abi (struct gdbarch_info info
+   set_gdbarch_gen_return_address (gdbarch, amd64_gen_return_address);
+ 
+   /* SystemTap variables and functions.  */
+-  set_gdbarch_stap_integer_prefix (gdbarch, "$");
+-  set_gdbarch_stap_register_prefix (gdbarch, "%");
+-  set_gdbarch_stap_register_indirection_prefix (gdbarch, "(");
+-  set_gdbarch_stap_register_indirection_suffix (gdbarch, ")");
++  set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes);
++  set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes);
++  set_gdbarch_stap_register_indirection_prefixes (gdbarch,
++					  stap_register_indirection_prefixes);
++  set_gdbarch_stap_register_indirection_suffixes (gdbarch,
++					  stap_register_indirection_suffixes);
+   set_gdbarch_stap_is_single_operand (gdbarch,
+ 				      i386_stap_is_single_operand);
+   set_gdbarch_stap_parse_special_token (gdbarch,
+Index: gdb-7.6.1/gdb/arm-linux-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/arm-linux-tdep.c
++++ gdb-7.6.1/gdb/arm-linux-tdep.c
+@@ -1182,6 +1182,12 @@ static void
+ arm_linux_init_abi (struct gdbarch_info info,
+ 		    struct gdbarch *gdbarch)
+ {
++  static const char *const stap_integer_prefixes[] = { "#", NULL };
++  static const char *const stap_register_prefixes[] = { "r", NULL };
++  static const char *const stap_register_indirection_prefixes[] = { "[",
++								    NULL };
++  static const char *const stap_register_indirection_suffixes[] = { "]",
++								    NULL };
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ 
+   linux_init_abi (info, gdbarch);
+@@ -1281,10 +1287,12 @@ arm_linux_init_abi (struct gdbarch_info
+   set_gdbarch_process_record (gdbarch, arm_process_record);
+ 
+   /* SystemTap functions.  */
+-  set_gdbarch_stap_integer_prefix (gdbarch, "#");
+-  set_gdbarch_stap_register_prefix (gdbarch, "r");
+-  set_gdbarch_stap_register_indirection_prefix (gdbarch, "[");
+-  set_gdbarch_stap_register_indirection_suffix (gdbarch, "]");
++  set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes);
++  set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes);
++  set_gdbarch_stap_register_indirection_prefixes (gdbarch,
++					  stap_register_indirection_prefixes);
++  set_gdbarch_stap_register_indirection_suffixes (gdbarch,
++					  stap_register_indirection_suffixes);
+   set_gdbarch_stap_gdb_register_prefix (gdbarch, "r");
+   set_gdbarch_stap_is_single_operand (gdbarch, arm_stap_is_single_operand);
+   set_gdbarch_stap_parse_special_token (gdbarch,
+Index: gdb-7.6.1/gdb/gdbarch.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbarch.c
++++ gdb-7.6.1/gdb/gdbarch.c
+@@ -86,6 +86,35 @@ pstring (const char *string)
+   return string;
+ }
+ 
++/* Helper function to print a list of strings, represented as "const
++   char *const *".  The list is printed comma-separated.  */
++
++static char *
++pstring_list (const char *const *list)
++{
++  static char ret[100];
++  const char *const *p;
++  size_t offset = 0;
++
++  if (list == NULL)
++    return "(null)";
++
++  ret[0] = '\0';
++  for (p = list; *p != NULL && offset < sizeof (ret); ++p)
++    {
++      size_t s = xsnprintf (ret + offset, sizeof (ret) - offset, "%s, ", *p);
++      offset += 2 + s;
++    }
++
++  if (offset > 0)
++    {
++      gdb_assert (offset - 2 < sizeof (ret));
++      ret[offset - 2] = '\0';
++    }
++
++  return ret;
++}
++
+ 
+ /* Maintain the struct gdbarch object.  */
+ 
+@@ -264,12 +293,12 @@ struct gdbarch
+   gdbarch_get_siginfo_type_ftype *get_siginfo_type;
+   gdbarch_record_special_symbol_ftype *record_special_symbol;
+   gdbarch_get_syscall_number_ftype *get_syscall_number;
+-  const char * stap_integer_prefix;
+-  const char * stap_integer_suffix;
+-  const char * stap_register_prefix;
+-  const char * stap_register_suffix;
+-  const char * stap_register_indirection_prefix;
+-  const char * stap_register_indirection_suffix;
++  const char *const * stap_integer_prefixes;
++  const char *const * stap_integer_suffixes;
++  const char *const * stap_register_prefixes;
++  const char *const * stap_register_suffixes;
++  const char *const * stap_register_indirection_prefixes;
++  const char *const * stap_register_indirection_suffixes;
+   const char * stap_gdb_register_prefix;
+   const char * stap_gdb_register_suffix;
+   gdbarch_stap_is_single_operand_ftype *stap_is_single_operand;
+@@ -436,12 +465,12 @@ struct gdbarch startup_gdbarch =
+   0,  /* get_siginfo_type */
+   0,  /* record_special_symbol */
+   0,  /* get_syscall_number */
+-  0,  /* stap_integer_prefix */
+-  0,  /* stap_integer_suffix */
+-  0,  /* stap_register_prefix */
+-  0,  /* stap_register_suffix */
+-  0,  /* stap_register_indirection_prefix */
+-  0,  /* stap_register_indirection_suffix */
++  0,  /* stap_integer_prefixes */
++  0,  /* stap_integer_suffixes */
++  0,  /* stap_register_prefixes */
++  0,  /* stap_register_suffixes */
++  0,  /* stap_register_indirection_prefixes */
++  0,  /* stap_register_indirection_suffixes */
+   0,  /* stap_gdb_register_prefix */
+   0,  /* stap_gdb_register_suffix */
+   0,  /* stap_is_single_operand */
+@@ -741,12 +770,12 @@ verify_gdbarch (struct gdbarch *gdbarch)
+   /* Skip verify of get_siginfo_type, has predicate.  */
+   /* Skip verify of record_special_symbol, has predicate.  */
+   /* Skip verify of get_syscall_number, has predicate.  */
+-  /* Skip verify of stap_integer_prefix, invalid_p == 0 */
+-  /* Skip verify of stap_integer_suffix, invalid_p == 0 */
+-  /* Skip verify of stap_register_prefix, invalid_p == 0 */
+-  /* Skip verify of stap_register_suffix, invalid_p == 0 */
+-  /* Skip verify of stap_register_indirection_prefix, invalid_p == 0 */
+-  /* Skip verify of stap_register_indirection_suffix, invalid_p == 0 */
++  /* Skip verify of stap_integer_prefixes, invalid_p == 0 */
++  /* Skip verify of stap_integer_suffixes, invalid_p == 0 */
++  /* Skip verify of stap_register_prefixes, invalid_p == 0 */
++  /* Skip verify of stap_register_suffixes, invalid_p == 0 */
++  /* Skip verify of stap_register_indirection_prefixes, invalid_p == 0 */
++  /* Skip verify of stap_register_indirection_suffixes, invalid_p == 0 */
+   /* Skip verify of stap_gdb_register_prefix, invalid_p == 0 */
+   /* Skip verify of stap_gdb_register_suffix, invalid_p == 0 */
+   /* Skip verify of stap_is_single_operand, has predicate.  */
+@@ -1342,11 +1371,11 @@ gdbarch_dump (struct gdbarch *gdbarch, s
+                       "gdbarch_dump: stap_gdb_register_suffix = %s\n",
+                       pstring (gdbarch->stap_gdb_register_suffix));
+   fprintf_unfiltered (file,
+-                      "gdbarch_dump: stap_integer_prefix = %s\n",
+-                      pstring (gdbarch->stap_integer_prefix));
++                      "gdbarch_dump: stap_integer_prefixes = %s\n",
++                      pstring_list (gdbarch->stap_integer_prefixes));
+   fprintf_unfiltered (file,
+-                      "gdbarch_dump: stap_integer_suffix = %s\n",
+-                      pstring (gdbarch->stap_integer_suffix));
++                      "gdbarch_dump: stap_integer_suffixes = %s\n",
++                      pstring_list (gdbarch->stap_integer_suffixes));
+   fprintf_unfiltered (file,
+                       "gdbarch_dump: gdbarch_stap_is_single_operand_p() = %d\n",
+                       gdbarch_stap_is_single_operand_p (gdbarch));
+@@ -1360,17 +1389,17 @@ gdbarch_dump (struct gdbarch *gdbarch, s
+                       "gdbarch_dump: stap_parse_special_token = <%s>\n",
+                       host_address_to_string (gdbarch->stap_parse_special_token));
+   fprintf_unfiltered (file,
+-                      "gdbarch_dump: stap_register_indirection_prefix = %s\n",
+-                      pstring (gdbarch->stap_register_indirection_prefix));
++                      "gdbarch_dump: stap_register_indirection_prefixes = %s\n",
++                      pstring_list (gdbarch->stap_register_indirection_prefixes));
+   fprintf_unfiltered (file,
+-                      "gdbarch_dump: stap_register_indirection_suffix = %s\n",
+-                      pstring (gdbarch->stap_register_indirection_suffix));
++                      "gdbarch_dump: stap_register_indirection_suffixes = %s\n",
++                      pstring_list (gdbarch->stap_register_indirection_suffixes));
+   fprintf_unfiltered (file,
+-                      "gdbarch_dump: stap_register_prefix = %s\n",
+-                      pstring (gdbarch->stap_register_prefix));
++                      "gdbarch_dump: stap_register_prefixes = %s\n",
++                      pstring_list (gdbarch->stap_register_prefixes));
+   fprintf_unfiltered (file,
+-                      "gdbarch_dump: stap_register_suffix = %s\n",
+-                      pstring (gdbarch->stap_register_suffix));
++                      "gdbarch_dump: stap_register_suffixes = %s\n",
++                      pstring_list (gdbarch->stap_register_suffixes));
+   fprintf_unfiltered (file,
+                       "gdbarch_dump: gdbarch_static_transform_name_p() = %d\n",
+                       gdbarch_static_transform_name_p (gdbarch));
+@@ -3971,106 +4000,106 @@ set_gdbarch_get_syscall_number (struct g
+   gdbarch->get_syscall_number = get_syscall_number;
+ }
+ 
+-const char *
+-gdbarch_stap_integer_prefix (struct gdbarch *gdbarch)
++const char *const *
++gdbarch_stap_integer_prefixes (struct gdbarch *gdbarch)
+ {
+   gdb_assert (gdbarch != NULL);
+-  /* Skip verify of stap_integer_prefix, invalid_p == 0 */
++  /* Skip verify of stap_integer_prefixes, invalid_p == 0 */
+   if (gdbarch_debug >= 2)
+-    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_integer_prefix called\n");
+-  return gdbarch->stap_integer_prefix;
++    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_integer_prefixes called\n");
++  return gdbarch->stap_integer_prefixes;
+ }
+ 
+ void
+-set_gdbarch_stap_integer_prefix (struct gdbarch *gdbarch,
+-                                 const char * stap_integer_prefix)
++set_gdbarch_stap_integer_prefixes (struct gdbarch *gdbarch,
++                                   const char *const * stap_integer_prefixes)
+ {
+-  gdbarch->stap_integer_prefix = stap_integer_prefix;
++  gdbarch->stap_integer_prefixes = stap_integer_prefixes;
+ }
+ 
+-const char *
+-gdbarch_stap_integer_suffix (struct gdbarch *gdbarch)
++const char *const *
++gdbarch_stap_integer_suffixes (struct gdbarch *gdbarch)
+ {
+   gdb_assert (gdbarch != NULL);
+-  /* Skip verify of stap_integer_suffix, invalid_p == 0 */
++  /* Skip verify of stap_integer_suffixes, invalid_p == 0 */
+   if (gdbarch_debug >= 2)
+-    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_integer_suffix called\n");
+-  return gdbarch->stap_integer_suffix;
++    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_integer_suffixes called\n");
++  return gdbarch->stap_integer_suffixes;
+ }
+ 
+ void
+-set_gdbarch_stap_integer_suffix (struct gdbarch *gdbarch,
+-                                 const char * stap_integer_suffix)
++set_gdbarch_stap_integer_suffixes (struct gdbarch *gdbarch,
++                                   const char *const * stap_integer_suffixes)
+ {
+-  gdbarch->stap_integer_suffix = stap_integer_suffix;
++  gdbarch->stap_integer_suffixes = stap_integer_suffixes;
+ }
+ 
+-const char *
+-gdbarch_stap_register_prefix (struct gdbarch *gdbarch)
++const char *const *
++gdbarch_stap_register_prefixes (struct gdbarch *gdbarch)
+ {
+   gdb_assert (gdbarch != NULL);
+-  /* Skip verify of stap_register_prefix, invalid_p == 0 */
++  /* Skip verify of stap_register_prefixes, invalid_p == 0 */
+   if (gdbarch_debug >= 2)
+-    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_prefix called\n");
+-  return gdbarch->stap_register_prefix;
++    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_prefixes called\n");
++  return gdbarch->stap_register_prefixes;
+ }
+ 
+ void
+-set_gdbarch_stap_register_prefix (struct gdbarch *gdbarch,
+-                                  const char * stap_register_prefix)
++set_gdbarch_stap_register_prefixes (struct gdbarch *gdbarch,
++                                    const char *const * stap_register_prefixes)
+ {
+-  gdbarch->stap_register_prefix = stap_register_prefix;
++  gdbarch->stap_register_prefixes = stap_register_prefixes;
+ }
+ 
+-const char *
+-gdbarch_stap_register_suffix (struct gdbarch *gdbarch)
++const char *const *
++gdbarch_stap_register_suffixes (struct gdbarch *gdbarch)
+ {
+   gdb_assert (gdbarch != NULL);
+-  /* Skip verify of stap_register_suffix, invalid_p == 0 */
++  /* Skip verify of stap_register_suffixes, invalid_p == 0 */
+   if (gdbarch_debug >= 2)
+-    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_suffix called\n");
+-  return gdbarch->stap_register_suffix;
++    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_suffixes called\n");
++  return gdbarch->stap_register_suffixes;
+ }
+ 
+ void
+-set_gdbarch_stap_register_suffix (struct gdbarch *gdbarch,
+-                                  const char * stap_register_suffix)
++set_gdbarch_stap_register_suffixes (struct gdbarch *gdbarch,
++                                    const char *const * stap_register_suffixes)
+ {
+-  gdbarch->stap_register_suffix = stap_register_suffix;
++  gdbarch->stap_register_suffixes = stap_register_suffixes;
+ }
+ 
+-const char *
+-gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch)
++const char *const *
++gdbarch_stap_register_indirection_prefixes (struct gdbarch *gdbarch)
+ {
+   gdb_assert (gdbarch != NULL);
+-  /* Skip verify of stap_register_indirection_prefix, invalid_p == 0 */
++  /* Skip verify of stap_register_indirection_prefixes, invalid_p == 0 */
+   if (gdbarch_debug >= 2)
+-    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_indirection_prefix called\n");
+-  return gdbarch->stap_register_indirection_prefix;
++    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_indirection_prefixes called\n");
++  return gdbarch->stap_register_indirection_prefixes;
+ }
+ 
+ void
+-set_gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch,
+-                                              const char * stap_register_indirection_prefix)
++set_gdbarch_stap_register_indirection_prefixes (struct gdbarch *gdbarch,
++                                                const char *const * stap_register_indirection_prefixes)
+ {
+-  gdbarch->stap_register_indirection_prefix = stap_register_indirection_prefix;
++  gdbarch->stap_register_indirection_prefixes = stap_register_indirection_prefixes;
+ }
+ 
+-const char *
+-gdbarch_stap_register_indirection_suffix (struct gdbarch *gdbarch)
++const char *const *
++gdbarch_stap_register_indirection_suffixes (struct gdbarch *gdbarch)
+ {
+   gdb_assert (gdbarch != NULL);
+-  /* Skip verify of stap_register_indirection_suffix, invalid_p == 0 */
++  /* Skip verify of stap_register_indirection_suffixes, invalid_p == 0 */
+   if (gdbarch_debug >= 2)
+-    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_indirection_suffix called\n");
+-  return gdbarch->stap_register_indirection_suffix;
++    fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_indirection_suffixes called\n");
++  return gdbarch->stap_register_indirection_suffixes;
+ }
+ 
+ void
+-set_gdbarch_stap_register_indirection_suffix (struct gdbarch *gdbarch,
+-                                              const char * stap_register_indirection_suffix)
++set_gdbarch_stap_register_indirection_suffixes (struct gdbarch *gdbarch,
++                                                const char *const * stap_register_indirection_suffixes)
+ {
+-  gdbarch->stap_register_indirection_suffix = stap_register_indirection_suffix;
++  gdbarch->stap_register_indirection_suffixes = stap_register_indirection_suffixes;
+ }
+ 
+ const char *
+Index: gdb-7.6.1/gdb/gdbarch.h
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbarch.h
++++ gdb-7.6.1/gdb/gdbarch.h
+@@ -1030,37 +1030,42 @@ extern LONGEST gdbarch_get_syscall_numbe
+ extern void set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch_get_syscall_number_ftype *get_syscall_number);
+ 
+ /* SystemTap related fields and functions.
+-   Prefix used to mark an integer constant on the architecture's assembly
++   A NULL-terminated array of prefixes used to mark an integer constant
++   on the architecture's assembly.
+    For example, on x86 integer constants are written as:
+   
+     $10 ;; integer constant 10
+   
+    in this case, this prefix would be the character `$'. */
+ 
+-extern const char * gdbarch_stap_integer_prefix (struct gdbarch *gdbarch);
+-extern void set_gdbarch_stap_integer_prefix (struct gdbarch *gdbarch, const char * stap_integer_prefix);
++extern const char *const * gdbarch_stap_integer_prefixes (struct gdbarch *gdbarch);
++extern void set_gdbarch_stap_integer_prefixes (struct gdbarch *gdbarch, const char *const * stap_integer_prefixes);
+ 
+-/* Suffix used to mark an integer constant on the architecture's assembly. */
++/* A NULL-terminated array of suffixes used to mark an integer constant
++   on the architecture's assembly. */
+ 
+-extern const char * gdbarch_stap_integer_suffix (struct gdbarch *gdbarch);
+-extern void set_gdbarch_stap_integer_suffix (struct gdbarch *gdbarch, const char * stap_integer_suffix);
++extern const char *const * gdbarch_stap_integer_suffixes (struct gdbarch *gdbarch);
++extern void set_gdbarch_stap_integer_suffixes (struct gdbarch *gdbarch, const char *const * stap_integer_suffixes);
+ 
+-/* Prefix used to mark a register name on the architecture's assembly.
++/* A NULL-terminated array of prefixes used to mark a register name on
++   the architecture's assembly.
+    For example, on x86 the register name is written as:
+   
+     %eax ;; register eax
+   
+    in this case, this prefix would be the character `%'. */
+ 
+-extern const char * gdbarch_stap_register_prefix (struct gdbarch *gdbarch);
+-extern void set_gdbarch_stap_register_prefix (struct gdbarch *gdbarch, const char * stap_register_prefix);
++extern const char *const * gdbarch_stap_register_prefixes (struct gdbarch *gdbarch);
++extern void set_gdbarch_stap_register_prefixes (struct gdbarch *gdbarch, const char *const * stap_register_prefixes);
+ 
+-/* Suffix used to mark a register name on the architecture's assembly */
++/* A NULL-terminated array of suffixes used to mark a register name on
++   the architecture's assembly. */
+ 
+-extern const char * gdbarch_stap_register_suffix (struct gdbarch *gdbarch);
+-extern void set_gdbarch_stap_register_suffix (struct gdbarch *gdbarch, const char * stap_register_suffix);
++extern const char *const * gdbarch_stap_register_suffixes (struct gdbarch *gdbarch);
++extern void set_gdbarch_stap_register_suffixes (struct gdbarch *gdbarch, const char *const * stap_register_suffixes);
+ 
+-/* Prefix used to mark a register indirection on the architecture's assembly.
++/* A NULL-terminated array of prefixes used to mark a register
++   indirection on the architecture's assembly.
+    For example, on x86 the register indirection is written as:
+   
+     (%eax) ;; indirecting eax
+@@ -1070,10 +1075,11 @@ extern void set_gdbarch_stap_register_su
+    Please note that we use the indirection prefix also for register
+    displacement, e.g., `4(%eax)' on x86. */
+ 
+-extern const char * gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch);
+-extern void set_gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch, const char * stap_register_indirection_prefix);
++extern const char *const * gdbarch_stap_register_indirection_prefixes (struct gdbarch *gdbarch);
++extern void set_gdbarch_stap_register_indirection_prefixes (struct gdbarch *gdbarch, const char *const * stap_register_indirection_prefixes);
+ 
+-/* Suffix used to mark a register indirection on the architecture's assembly.
++/* A NULL-terminated array of suffixes used to mark a register
++   indirection on the architecture's assembly.
+    For example, on x86 the register indirection is written as:
+   
+     (%eax) ;; indirecting eax
+@@ -1083,10 +1089,10 @@ extern void set_gdbarch_stap_register_in
+    Please note that we use the indirection suffix also for register
+    displacement, e.g., `4(%eax)' on x86. */
+ 
+-extern const char * gdbarch_stap_register_indirection_suffix (struct gdbarch *gdbarch);
+-extern void set_gdbarch_stap_register_indirection_suffix (struct gdbarch *gdbarch, const char * stap_register_indirection_suffix);
++extern const char *const * gdbarch_stap_register_indirection_suffixes (struct gdbarch *gdbarch);
++extern void set_gdbarch_stap_register_indirection_suffixes (struct gdbarch *gdbarch, const char *const * stap_register_indirection_suffixes);
+ 
+-/* Prefix used to name a register using GDB's nomenclature.
++/* Prefix(es) used to name a register using GDB's nomenclature.
+   
+    For example, on PPC a register is represented by a number in the assembly
+    language (e.g., `10' is the 10th general-purpose register).  However,
+Index: gdb-7.6.1/gdb/gdbarch.sh
+===================================================================
+--- gdb-7.6.1.orig/gdb/gdbarch.sh
++++ gdb-7.6.1/gdb/gdbarch.sh
+@@ -823,29 +823,34 @@ M:LONGEST:get_syscall_number:ptid_t ptid
+ 
+ # SystemTap related fields and functions.
+ 
+-# Prefix used to mark an integer constant on the architecture's assembly
++# A NULL-terminated array of prefixes used to mark an integer constant
++# on the architecture's assembly.
+ # For example, on x86 integer constants are written as:
+ #
+ #  \$10 ;; integer constant 10
+ #
+ # in this case, this prefix would be the character \`\$\'.
+-v:const char *:stap_integer_prefix:::0:0::0:pstring (gdbarch->stap_integer_prefix)
++v:const char *const *:stap_integer_prefixes:::0:0::0:pstring_list (gdbarch->stap_integer_prefixes)
+ 
+-# Suffix used to mark an integer constant on the architecture's assembly.
+-v:const char *:stap_integer_suffix:::0:0::0:pstring (gdbarch->stap_integer_suffix)
++# A NULL-terminated array of suffixes used to mark an integer constant
++# on the architecture's assembly.
++v:const char *const *:stap_integer_suffixes:::0:0::0:pstring_list (gdbarch->stap_integer_suffixes)
+ 
+-# Prefix used to mark a register name on the architecture's assembly.
++# A NULL-terminated array of prefixes used to mark a register name on
++# the architecture's assembly.
+ # For example, on x86 the register name is written as:
+ #
+ #  \%eax ;; register eax
+ #
+ # in this case, this prefix would be the character \`\%\'.
+-v:const char *:stap_register_prefix:::0:0::0:pstring (gdbarch->stap_register_prefix)
++v:const char *const *:stap_register_prefixes:::0:0::0:pstring_list (gdbarch->stap_register_prefixes)
+ 
+-# Suffix used to mark a register name on the architecture's assembly
+-v:const char *:stap_register_suffix:::0:0::0:pstring (gdbarch->stap_register_suffix)
++# A NULL-terminated array of suffixes used to mark a register name on
++# the architecture's assembly.
++v:const char *const *:stap_register_suffixes:::0:0::0:pstring_list (gdbarch->stap_register_suffixes)
+ 
+-# Prefix used to mark a register indirection on the architecture's assembly.
++# A NULL-terminated array of prefixes used to mark a register
++# indirection on the architecture's assembly.
+ # For example, on x86 the register indirection is written as:
+ #
+ #  \(\%eax\) ;; indirecting eax
+@@ -854,9 +859,10 @@ v:const char *:stap_register_suffix:::0:
+ #
+ # Please note that we use the indirection prefix also for register
+ # displacement, e.g., \`4\(\%eax\)\' on x86.
+-v:const char *:stap_register_indirection_prefix:::0:0::0:pstring (gdbarch->stap_register_indirection_prefix)
++v:const char *const *:stap_register_indirection_prefixes:::0:0::0:pstring_list (gdbarch->stap_register_indirection_prefixes)
+ 
+-# Suffix used to mark a register indirection on the architecture's assembly.
++# A NULL-terminated array of suffixes used to mark a register
++# indirection on the architecture's assembly.
+ # For example, on x86 the register indirection is written as:
+ #
+ #  \(\%eax\) ;; indirecting eax
+@@ -865,9 +871,9 @@ v:const char *:stap_register_indirection
+ #
+ # Please note that we use the indirection suffix also for register
+ # displacement, e.g., \`4\(\%eax\)\' on x86.
+-v:const char *:stap_register_indirection_suffix:::0:0::0:pstring (gdbarch->stap_register_indirection_suffix)
++v:const char *const *:stap_register_indirection_suffixes:::0:0::0:pstring_list (gdbarch->stap_register_indirection_suffixes)
+ 
+-# Prefix used to name a register using GDB's nomenclature.
++# Prefix(es) used to name a register using GDB's nomenclature.
+ #
+ # For example, on PPC a register is represented by a number in the assembly
+ # language (e.g., \`10\' is the 10th general-purpose register).  However,
+@@ -1478,6 +1484,35 @@ pstring (const char *string)
+   return string;
+ }
+ 
++/* Helper function to print a list of strings, represented as "const
++   char *const *".  The list is printed comma-separated.  */
++
++static char *
++pstring_list (const char *const *list)
++{
++  static char ret[100];
++  const char *const *p;
++  size_t offset = 0;
++
++  if (list == NULL)
++    return "(null)";
++
++  ret[0] = '\0';
++  for (p = list; *p != NULL && offset < sizeof (ret); ++p)
++    {
++      size_t s = xsnprintf (ret + offset, sizeof (ret) - offset, "%s, ", *p);
++      offset += 2 + s;
++    }
++
++  if (offset > 0)
++    {
++      gdb_assert (offset - 2 < sizeof (ret));
++      ret[offset - 2] = '\0';
++    }
++
++  return ret;
++}
++
+ EOF
+ 
+ # gdbarch open the gdbarch object
+Index: gdb-7.6.1/gdb/i386-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/i386-tdep.c
++++ gdb-7.6.1/gdb/i386-tdep.c
+@@ -3767,14 +3767,23 @@ i386_stap_parse_special_token (struct gd
+ void
+ i386_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+ {
++  static const char *const stap_integer_prefixes[] = { "$", NULL };
++  static const char *const stap_register_prefixes[] = { "%", NULL };
++  static const char *const stap_register_indirection_prefixes[] = { "(",
++								    NULL };
++  static const char *const stap_register_indirection_suffixes[] = { ")",
++								    NULL };
++
+   /* We typically use stabs-in-ELF with the SVR4 register numbering.  */
+   set_gdbarch_stab_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum);
+ 
+   /* Registering SystemTap handlers.  */
+-  set_gdbarch_stap_integer_prefix (gdbarch, "$");
+-  set_gdbarch_stap_register_prefix (gdbarch, "%");
+-  set_gdbarch_stap_register_indirection_prefix (gdbarch, "(");
+-  set_gdbarch_stap_register_indirection_suffix (gdbarch, ")");
++  set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes);
++  set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes);
++  set_gdbarch_stap_register_indirection_prefixes (gdbarch,
++					  stap_register_indirection_prefixes);
++  set_gdbarch_stap_register_indirection_suffixes (gdbarch,
++					  stap_register_indirection_suffixes);
+   set_gdbarch_stap_is_single_operand (gdbarch,
+ 				      i386_stap_is_single_operand);
+   set_gdbarch_stap_parse_special_token (gdbarch,
+Index: gdb-7.6.1/gdb/ppc-linux-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/ppc-linux-tdep.c
++++ gdb-7.6.1/gdb/ppc-linux-tdep.c
+@@ -1723,6 +1723,11 @@ ppc_linux_init_abi (struct gdbarch_info
+ {
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+   struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info;
++  static const char *const stap_integer_prefixes[] = { "i", NULL };
++  static const char *const stap_register_indirection_prefixes[] = { "(",
++								    NULL };
++  static const char *const stap_register_indirection_suffixes[] = { ")",
++								    NULL };
+ 
+   linux_init_abi (info, gdbarch);
+ 
+@@ -1741,9 +1746,11 @@ ppc_linux_init_abi (struct gdbarch_info
+   set_gdbarch_get_syscall_number (gdbarch, ppc_linux_get_syscall_number);
+ 
+   /* SystemTap functions.  */
+-  set_gdbarch_stap_integer_prefix (gdbarch, "i");
+-  set_gdbarch_stap_register_indirection_prefix (gdbarch, "(");
+-  set_gdbarch_stap_register_indirection_suffix (gdbarch, ")");
++  set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes);
++  set_gdbarch_stap_register_indirection_prefixes (gdbarch,
++					  stap_register_indirection_prefixes);
++  set_gdbarch_stap_register_indirection_suffixes (gdbarch,
++					  stap_register_indirection_suffixes);
+   set_gdbarch_stap_gdb_register_prefix (gdbarch, "r");
+   set_gdbarch_stap_is_single_operand (gdbarch, ppc_stap_is_single_operand);
+   set_gdbarch_stap_parse_special_token (gdbarch,
+Index: gdb-7.6.1/gdb/s390-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/s390-tdep.c
++++ gdb-7.6.1/gdb/s390-tdep.c
+@@ -3032,6 +3032,11 @@ s390_gdbarch_init (struct gdbarch_info i
+   int have_linux_v1 = 0;
+   int have_linux_v2 = 0;
+   int first_pseudo_reg, last_pseudo_reg;
++  static const char *const stap_register_prefixes[] = { "%", NULL };
++  static const char *const stap_register_indirection_prefixes[] = { "(",
++								    NULL };
++  static const char *const stap_register_indirection_suffixes[] = { ")",
++								    NULL };
+ 
+   /* Default ABI and register size.  */
+   switch (info.bfd_arch_info->mach)
+@@ -3364,9 +3369,11 @@ s390_gdbarch_init (struct gdbarch_info i
+   set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
+ 
+   /* SystemTap functions.  */
+-  set_gdbarch_stap_register_prefix (gdbarch, "%");
+-  set_gdbarch_stap_register_indirection_prefix (gdbarch, "(");
+-  set_gdbarch_stap_register_indirection_suffix (gdbarch, ")");
++  set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes);
++  set_gdbarch_stap_register_indirection_prefixes (gdbarch,
++					  stap_register_indirection_prefixes);
++  set_gdbarch_stap_register_indirection_suffixes (gdbarch,
++					  stap_register_indirection_suffixes);
+   set_gdbarch_stap_is_single_operand (gdbarch, s390_stap_is_single_operand);
+ 
+   return gdbarch;
+Index: gdb-7.6.1/gdb/stap-probe.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/stap-probe.c
++++ gdb-7.6.1/gdb/stap-probe.c
+@@ -346,6 +346,191 @@ stap_get_expected_argument_type (struct
+     }
+ }
+ 
++/* Helper function to check for a generic list of prefixes.  GDBARCH
++   is the current gdbarch being used.  S is the expression being
++   analyzed.  If R is not NULL, it will be used to return the found
++   prefix.  PREFIXES is the list of expected prefixes.
++
++   This function does a case-insensitive match.
++
++   Return 1 if any prefix has been found, zero otherwise.  */
++
++static int
++stap_is_generic_prefix (struct gdbarch *gdbarch, const char *s,
++			const char **r, const char *const *prefixes)
++{
++  const char *const *p;
++
++  if (prefixes == NULL)
++    {
++      if (r != NULL)
++	*r = "";
++
++      return 1;
++    }
++
++  for (p = prefixes; *p != NULL; ++p)
++    {
++      if (strncasecmp (s, *p, strlen (*p)) == 0)
++	{
++	  if (r != NULL)
++	    *r = *p;
++
++	  return 1;
++	}
++    }
++
++  return 0;
++}
++
++/* Return 1 if S points to a register prefix, zero otherwise.  For a
++   description of the arguments, look at stap_is_generic_prefix.  */
++
++static int
++stap_is_register_prefix (struct gdbarch *gdbarch, const char *s,
++			 const char **r)
++{
++  const char *const *t = gdbarch_stap_register_prefixes (gdbarch);
++
++  return stap_is_generic_prefix (gdbarch, s, r, t);
++}
++
++/* Return 1 if S points to a register indirection prefix, zero
++   otherwise.  For a description of the arguments, look at
++   stap_is_generic_prefix.  */
++
++static int
++stap_is_register_indirection_prefix (struct gdbarch *gdbarch, const char *s,
++				     const char **r)
++{
++  const char *const *t = gdbarch_stap_register_indirection_prefixes (gdbarch);
++
++  return stap_is_generic_prefix (gdbarch, s, r, t);
++}
++
++/* Return 1 if S points to an integer prefix, zero otherwise.  For a
++   description of the arguments, look at stap_is_generic_prefix.
++
++   This function takes care of analyzing whether we are dealing with
++   an expected integer prefix, or, if there is no integer prefix to be
++   expected, whether we are dealing with a digit.  It does a
++   case-insensitive match.  */
++
++static int
++stap_is_integer_prefix (struct gdbarch *gdbarch, const char *s,
++			const char **r)
++{
++  const char *const *t = gdbarch_stap_integer_prefixes (gdbarch);
++  const char *const *p;
++
++  if (t == NULL)
++    {
++      /* A NULL value here means that integers do not have a prefix.
++	 We just check for a digit then.  */
++      if (r != NULL)
++	*r = "";
++
++      return isdigit (*s);
++    }
++
++  for (p = t; *p != NULL; ++p)
++    {
++      size_t len = strlen (*p);
++
++      if ((len == 0 && isdigit (*s))
++	  || (len > 0 && strncasecmp (s, *p, len) == 0))
++	{
++	  /* Integers may or may not have a prefix.  The "len == 0"
++	     check covers the case when integers do not have a prefix
++	     (therefore, we just check if we have a digit).  The call
++	     to "strncasecmp" covers the case when they have a
++	     prefix.  */
++	  if (r != NULL)
++	    *r = *p;
++
++	  return 1;
++	}
++    }
++
++  return 0;
++}
++
++/* Helper function to check for a generic list of suffixes.  If we are
++   not expecting any suffixes, then it just returns 1.  If we are
++   expecting at least one suffix, then it returns 1 if a suffix has
++   been found, zero otherwise.  GDBARCH is the current gdbarch being
++   used.  S is the expression being analyzed.  If R is not NULL, it
++   will be used to return the found suffix.  SUFFIXES is the list of
++   expected suffixes.  This function does a case-insensitive
++   match.  */
++
++static int
++stap_generic_check_suffix (struct gdbarch *gdbarch, const char *s,
++			   const char **r, const char *const *suffixes)
++{
++  const char *const *p;
++  int found = 0;
++
++  if (suffixes == NULL)
++    {
++      if (r != NULL)
++	*r = "";
++
++      return 1;
++    }
++
++  for (p = suffixes; *p != NULL; ++p)
++    if (strncasecmp (s, *p, strlen (*p)) == 0)
++      {
++	if (r != NULL)
++	  *r = *p;
++
++	found = 1;
++	break;
++      }
++
++  return found;
++}
++
++/* Return 1 if S points to an integer suffix, zero otherwise.  For a
++   description of the arguments, look at
++   stap_generic_check_suffix.  */
++
++static int
++stap_check_integer_suffix (struct gdbarch *gdbarch, const char *s,
++			   const char **r)
++{
++  const char *const *p = gdbarch_stap_integer_suffixes (gdbarch);
++
++  return stap_generic_check_suffix (gdbarch, s, r, p);
++}
++
++/* Return 1 if S points to a register suffix, zero otherwise.  For a
++   description of the arguments, look at
++   stap_generic_check_suffix.  */
++
++static int
++stap_check_register_suffix (struct gdbarch *gdbarch, const char *s,
++			    const char **r)
++{
++  const char *const *p = gdbarch_stap_register_suffixes (gdbarch);
++
++  return stap_generic_check_suffix (gdbarch, s, r, p);
++}
++
++/* Return 1 if S points to a register indirection suffix, zero
++   otherwise.  For a description of the arguments, look at
++   stap_generic_check_suffix.  */
++
++static int
++stap_check_register_indirection_suffix (struct gdbarch *gdbarch, const char *s,
++					const char **r)
++{
++  const char *const *p = gdbarch_stap_register_indirection_suffixes (gdbarch);
++
++  return stap_generic_check_suffix (gdbarch, s, r, p);
++}
++
+ /* Function responsible for parsing a register operand according to
+    SystemTap parlance.  Assuming:
+ 
+@@ -385,24 +570,14 @@ stap_parse_register_operand (struct stap
+   const char *start;
+   char *regname;
+   int len;
+-
+-  /* Prefixes for the parser.  */
+-  const char *reg_prefix = gdbarch_stap_register_prefix (gdbarch);
+-  const char *reg_ind_prefix
+-    = gdbarch_stap_register_indirection_prefix (gdbarch);
+   const char *gdb_reg_prefix = gdbarch_stap_gdb_register_prefix (gdbarch);
+-  int reg_prefix_len = reg_prefix ? strlen (reg_prefix) : 0;
+-  int reg_ind_prefix_len = reg_ind_prefix ? strlen (reg_ind_prefix) : 0;
+   int gdb_reg_prefix_len = gdb_reg_prefix ? strlen (gdb_reg_prefix) : 0;
+-
+-  /* Suffixes for the parser.  */
+-  const char *reg_suffix = gdbarch_stap_register_suffix (gdbarch);
+-  const char *reg_ind_suffix
+-    = gdbarch_stap_register_indirection_suffix (gdbarch);
+   const char *gdb_reg_suffix = gdbarch_stap_gdb_register_suffix (gdbarch);
+-  int reg_suffix_len = reg_suffix ? strlen (reg_suffix) : 0;
+-  int reg_ind_suffix_len = reg_ind_suffix ? strlen (reg_ind_suffix) : 0;
+   int gdb_reg_suffix_len = gdb_reg_suffix ? strlen (gdb_reg_suffix) : 0;
++  const char *reg_prefix;
++  const char *reg_ind_prefix;
++  const char *reg_suffix;
++  const char *reg_ind_suffix;
+ 
+   /* Checking for a displacement argument.  */
+   if (*p->arg == '+')
+@@ -436,11 +611,10 @@ stap_parse_register_operand (struct stap
+     }
+ 
+   /* Getting rid of register indirection prefix.  */
+-  if (reg_ind_prefix
+-      && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0)
++  if (stap_is_register_indirection_prefix (gdbarch, p->arg, &reg_ind_prefix))
+     {
+       indirect_p = 1;
+-      p->arg += reg_ind_prefix_len;
++      p->arg += strlen (reg_ind_prefix);
+     }
+ 
+   if (disp_p && !indirect_p)
+@@ -448,8 +622,8 @@ stap_parse_register_operand (struct stap
+ 	   p->saved_arg);
+ 
+   /* Getting rid of register prefix.  */
+-  if (reg_prefix && strncmp (p->arg, reg_prefix, reg_prefix_len) == 0)
+-    p->arg += reg_prefix_len;
++  if (stap_is_register_prefix (gdbarch, p->arg, &reg_prefix))
++    p->arg += strlen (reg_prefix);
+ 
+   /* Now we should have only the register name.  Let's extract it and get
+      the associated number.  */
+@@ -507,23 +681,21 @@ stap_parse_register_operand (struct stap
+     }
+ 
+   /* Getting rid of the register name suffix.  */
+-  if (reg_suffix)
+-    {
+-      if (strncmp (p->arg, reg_suffix, reg_suffix_len) != 0)
+-	error (_("Missing register name suffix `%s' on expression `%s'."),
+-	       reg_suffix, p->saved_arg);
+-
+-      p->arg += reg_suffix_len;
+-    }
++  if (stap_check_register_suffix (gdbarch, p->arg, &reg_suffix))
++    p->arg += strlen (reg_suffix);
++  else
++    error (_("Missing register name suffix on expression `%s'."),
++	   p->saved_arg);
+ 
+   /* Getting rid of the register indirection suffix.  */
+-  if (indirect_p && reg_ind_suffix)
++  if (indirect_p)
+     {
+-      if (strncmp (p->arg, reg_ind_suffix, reg_ind_suffix_len) != 0)
+-	error (_("Missing indirection suffix `%s' on expression `%s'."),
+-	       reg_ind_suffix, p->saved_arg);
+-
+-      p->arg += reg_ind_suffix_len;
++      if (stap_check_register_indirection_suffix (gdbarch, p->arg,
++						  &reg_ind_suffix))
++	p->arg += strlen (reg_ind_suffix);
++      else
++	error (_("Missing indirection suffix on expression `%s'."),
++	       p->saved_arg);
+     }
+ }
+ 
+@@ -546,19 +718,7 @@ static void
+ stap_parse_single_operand (struct stap_parse_info *p)
+ {
+   struct gdbarch *gdbarch = p->gdbarch;
+-
+-  /* Prefixes for the parser.  */
+-  const char *const_prefix = gdbarch_stap_integer_prefix (gdbarch);
+-  const char *reg_prefix = gdbarch_stap_register_prefix (gdbarch);
+-  const char *reg_ind_prefix
+-    = gdbarch_stap_register_indirection_prefix (gdbarch);
+-  int const_prefix_len = const_prefix ? strlen (const_prefix) : 0;
+-  int reg_prefix_len = reg_prefix ? strlen (reg_prefix) : 0;
+-  int reg_ind_prefix_len = reg_ind_prefix ? strlen (reg_ind_prefix) : 0;
+-
+-  /* Suffixes for the parser.  */
+-  const char *const_suffix = gdbarch_stap_integer_suffix (gdbarch);
+-  int const_suffix_len = const_suffix ? strlen (const_suffix) : 0;
++  const char *int_prefix = NULL;
+ 
+   /* We first try to parse this token as a "special token".  */
+   if (gdbarch_stap_parse_special_token_p (gdbarch))
+@@ -600,8 +760,7 @@ stap_parse_single_operand (struct stap_p
+       if (isdigit (*tmp))
+ 	number = strtol (tmp, (char **) &tmp, 10);
+ 
+-      if (!reg_ind_prefix
+-	  || strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) != 0)
++      if (!stap_is_register_indirection_prefix (gdbarch, tmp, NULL))
+ 	{
+ 	  /* This is not a displacement.  We skip the operator, and deal
+ 	     with it later.  */
+@@ -629,15 +788,22 @@ stap_parse_single_operand (struct stap_p
+       const char *tmp = p->arg;
+       long number;
+ 
+-      /* We can be dealing with a numeric constant (if `const_prefix' is
+-	 NULL), or with a register displacement.  */
++      /* We can be dealing with a numeric constant, or with a register
++	 displacement.  */
+       number = strtol (tmp, (char **) &tmp, 10);
+ 
+       if (p->inside_paren_p)
+ 	tmp = skip_spaces_const (tmp);
+-      if (!const_prefix && reg_ind_prefix
+-	  && strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) != 0)
++
++      /* If "stap_is_integer_prefix" returns true, it means we can
++	 accept integers without a prefix here.  But we also need to
++	 check whether the next token (i.e., "tmp") is not a register
++	 indirection prefix.  */
++      if (stap_is_integer_prefix (gdbarch, p->arg, NULL)
++	  && !stap_is_register_indirection_prefix (gdbarch, tmp, NULL))
+ 	{
++	  const char *int_suffix;
++
+ 	  /* We are dealing with a numeric constant.  */
+ 	  write_exp_elt_opcode (OP_LONG);
+ 	  write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
+@@ -646,29 +812,25 @@ stap_parse_single_operand (struct stap_p
+ 
+ 	  p->arg = tmp;
+ 
+-	  if (const_suffix)
+-	    {
+-	      if (strncmp (p->arg, const_suffix, const_suffix_len) == 0)
+-		p->arg += const_suffix_len;
+-	      else
+-		error (_("Invalid constant suffix on expression `%s'."),
+-		       p->saved_arg);
+-	    }
++	  if (stap_check_integer_suffix (gdbarch, p->arg, &int_suffix))
++	    p->arg += strlen (int_suffix);
++	  else
++	    error (_("Invalid constant suffix on expression `%s'."),
++		   p->saved_arg);
+ 	}
+-      else if (reg_ind_prefix
+-	       && strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) == 0)
++      else if (stap_is_register_indirection_prefix (gdbarch, tmp, NULL))
+ 	stap_parse_register_operand (p);
+       else
+ 	error (_("Unknown numeric token on expression `%s'."),
+ 	       p->saved_arg);
+     }
+-  else if (const_prefix
+-	   && strncmp (p->arg, const_prefix, const_prefix_len) == 0)
++  else if (stap_is_integer_prefix (gdbarch, p->arg, &int_prefix))
+     {
+       /* We are dealing with a numeric constant.  */
+       long number;
++      const char *int_suffix;
+ 
+-      p->arg += const_prefix_len;
++      p->arg += strlen (int_prefix);
+       number = strtol (p->arg, (char **) &p->arg, 10);
+ 
+       write_exp_elt_opcode (OP_LONG);
+@@ -676,19 +838,14 @@ stap_parse_single_operand (struct stap_p
+       write_exp_elt_longcst (number);
+       write_exp_elt_opcode (OP_LONG);
+ 
+-      if (const_suffix)
+-	{
+-	  if (strncmp (p->arg, const_suffix, const_suffix_len) == 0)
+-	    p->arg += const_suffix_len;
+-	  else
+-	    error (_("Invalid constant suffix on expression `%s'."),
+-		   p->saved_arg);
+-	}
++      if (stap_check_integer_suffix (gdbarch, p->arg, &int_suffix))
++	p->arg += strlen (int_suffix);
++      else
++	error (_("Invalid constant suffix on expression `%s'."),
++	       p->saved_arg);
+     }
+-  else if ((reg_prefix
+-	    && strncmp (p->arg, reg_prefix, reg_prefix_len) == 0)
+-	   || (reg_ind_prefix
+-	       && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0))
++  else if (stap_is_register_prefix (gdbarch, p->arg, NULL)
++	   || stap_is_register_indirection_prefix (gdbarch, p->arg, NULL))
+     stap_parse_register_operand (p);
+   else
+     error (_("Operator `%c' not recognized on expression `%s'."),
diff --git a/SOURCES/gdb-rhbz1247107-backport-aarch64-stap-sdt-support-2of2.patch b/SOURCES/gdb-rhbz1247107-backport-aarch64-stap-sdt-support-2of2.patch
new file mode 100644
index 0000000..c85895e
--- /dev/null
+++ b/SOURCES/gdb-rhbz1247107-backport-aarch64-stap-sdt-support-2of2.patch
@@ -0,0 +1,213 @@
+commit 08248ca9fe11040e9a4126cefebc5023d1d67222
+Author: Sergio Durigan Junior <sergiodj@redhat.com>
+Date:   Sat Dec 28 14:14:11 2013 -0200
+
+    Implement SystemTap SDT probe support for AArch64
+    
+    This commit implements the needed bits for SystemTap SDT probe support
+    on AArch64 architectures.
+    
+    First, I started by looking at AArch64 assembly specification and
+    filling the necessary options on gdbarch's stap machinery in order to
+    make the generic asm parser (implemented in stap-probe.c) recognize
+    AArch64's asm.
+    
+    After my last patch for the SystemTap SDT API, which extends it in order
+    to accept multiple prefixes and suffixes, this patch became simpler.  I
+    also followed Marcus suggestion and did not shared code between 32- and
+    64-bit ARM.
+    
+    Tom asked me in a previous message how I did my tests.  I believe I
+    replied that, but just in case: I ran the tests on
+    gdb.base/stap-probe.exp by hand.  I also managed to run the tests on
+    real hardware, and they pass without regressions.
+    
+    2013-12-28  Sergio Durigan Junior  <sergiodj@redhat.com>
+    
+    	PR tdep/15653
+    	* NEWS: Mention SystemTap SDT probe support for AArch64 GNU/Linux.
+    	* aarch64-linux-tdep.c: Include necessary headers for parsing of
+    	SystemTap SDT probes.
+    	(aarch64_stap_is_single_operand): New function.
+    	(aarch64_stap_parse_special_token): Likewise.
+    	(aarch64_linux_init_abi): Declare SystemTap SDT probe argument
+    	prefixes and suffixes.  Initialize gdbarch with them.
+
+Index: gdb-7.6.1/gdb/NEWS
+===================================================================
+--- gdb-7.6.1.orig/gdb/NEWS
++++ gdb-7.6.1/gdb/NEWS
+@@ -30,6 +30,8 @@ qXfer:libraries-svr4:read's annex
+ 
+ *** Changes in GDB 7.6
+ 
++* GDB now supports SystemTap SDT probes on AArch64 GNU/Linux.
++
+ * Target record has been renamed to record-full.
+   Record/replay is now enabled with the "record full" command.
+   This also affects settings that are associated with full record/replay
+Index: gdb-7.6.1/gdb/aarch64-linux-tdep.c
+===================================================================
+--- gdb-7.6.1.orig/gdb/aarch64-linux-tdep.c
++++ gdb-7.6.1/gdb/aarch64-linux-tdep.c
+@@ -35,6 +35,12 @@
+ #include "regcache.h"
+ #include "regset.h"
+ 
++#include "cli/cli-utils.h"
++#include "stap-probe.h"
++#include "parser-defs.h"
++#include "user-regs.h"
++#include <ctype.h>
++
+ /* The general-purpose regset consists of 31 X registers, plus SP, PC,
+    and PSTATE registers, as defined in the AArch64 port of the Linux
+    kernel.  */
+@@ -268,9 +274,129 @@ aarch64_linux_regset_from_core_section (
+   return NULL;
+ }
+ 
++/* Implementation of `gdbarch_stap_is_single_operand', as defined in
++   gdbarch.h.  */
++
++static int
++aarch64_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
++{
++  return (*s == '#' || isdigit (*s) /* Literal number.  */
++	  || *s == '[' /* Register indirection.  */
++	  || isalpha (*s)); /* Register value.  */
++}
++
++/* This routine is used to parse a special token in AArch64's assembly.
++
++   The special tokens parsed by it are:
++
++      - Register displacement (e.g, [fp, #-8])
++
++   It returns one if the special token has been parsed successfully,
++   or zero if the current token is not considered special.  */
++
++static int
++aarch64_stap_parse_special_token (struct gdbarch *gdbarch,
++				  struct stap_parse_info *p)
++{
++  if (*p->arg == '[')
++    {
++      /* Temporary holder for lookahead.  */
++      const char *tmp = p->arg;
++      char *endp;
++      /* Used to save the register name.  */
++      const char *start;
++      char *regname;
++      int len;
++      int got_minus = 0;
++      long displacement;
++      struct stoken str;
++
++      ++tmp;
++      start = tmp;
++
++      /* Register name.  */
++      while (isalnum (*tmp))
++	++tmp;
++
++      if (*tmp != ',')
++	return 0;
++
++      len = tmp - start;
++      regname = alloca (len + 2);
++
++      strncpy (regname, start, len);
++      regname[len] = '\0';
++
++      if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
++	error (_("Invalid register name `%s' on expression `%s'."),
++	       regname, p->saved_arg);
++
++      ++tmp;
++      tmp = skip_spaces_const (tmp);
++      /* Now we expect a number.  It can begin with '#' or simply
++	 a digit.  */
++      if (*tmp == '#')
++	++tmp;
++
++      if (*tmp == '-')
++	{
++	  ++tmp;
++	  got_minus = 1;
++	}
++      else if (*tmp == '+')
++	++tmp;
++
++      if (!isdigit (*tmp))
++	return 0;
++
++      displacement = strtol (tmp, &endp, 10);
++      tmp = endp;
++
++      /* Skipping last `]'.  */
++      if (*tmp++ != ']')
++	return 0;
++
++      /* The displacement.  */
++      write_exp_elt_opcode (OP_LONG);
++      write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
++      write_exp_elt_longcst (displacement);
++      write_exp_elt_opcode (OP_LONG);
++      if (got_minus)
++	write_exp_elt_opcode (UNOP_NEG);
++
++      /* The register name.  */
++      write_exp_elt_opcode (OP_REGISTER);
++      str.ptr = regname;
++      str.length = len;
++      write_exp_string (str);
++      write_exp_elt_opcode (OP_REGISTER);
++
++      write_exp_elt_opcode (BINOP_ADD);
++
++      /* Casting to the expected type.  */
++      write_exp_elt_opcode (UNOP_CAST);
++      write_exp_elt_type (lookup_pointer_type (p->arg_type));
++      write_exp_elt_opcode (UNOP_CAST);
++
++      write_exp_elt_opcode (UNOP_IND);
++
++      p->arg = tmp;
++    }
++  else
++    return 0;
++
++  return 1;
++}
++
+ static void
+ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+ {
++  static const char *const stap_integer_prefixes[] = { "#", "", NULL };
++  static const char *const stap_register_prefixes[] = { "", NULL };
++  static const char *const stap_register_indirection_prefixes[] = { "[",
++								    NULL };
++  static const char *const stap_register_indirection_suffixes[] = { "]",
++								    NULL };
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ 
+   tdep->lowest_pc = 0x8000;
+@@ -295,6 +421,17 @@ aarch64_linux_init_abi (struct gdbarch_i
+ 
+   set_gdbarch_regset_from_core_section (gdbarch,
+ 					aarch64_linux_regset_from_core_section);
++
++  /* SystemTap related.  */
++  set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes);
++  set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes);
++  set_gdbarch_stap_register_indirection_prefixes (gdbarch,
++					    stap_register_indirection_prefixes);
++  set_gdbarch_stap_register_indirection_suffixes (gdbarch,
++					    stap_register_indirection_suffixes);
++  set_gdbarch_stap_is_single_operand (gdbarch, aarch64_stap_is_single_operand);
++  set_gdbarch_stap_parse_special_token (gdbarch,
++					aarch64_stap_parse_special_token);
+ }
+ 
+ /* Provide a prototype to silence -Wmissing-prototypes.  */
diff --git a/SOURCES/gdb-rhbz1260558-ppc64le-skip_trampoline_code.patch b/SOURCES/gdb-rhbz1260558-ppc64le-skip_trampoline_code.patch
new file mode 100644
index 0000000..114cda5
--- /dev/null
+++ b/SOURCES/gdb-rhbz1260558-ppc64le-skip_trampoline_code.patch
@@ -0,0 +1,229 @@
+https://bugzilla.redhat.com/show_bug.cgi?id=1260558
+
+[ppc64le patch v3] Use skip_entrypoint for skip_trampoline_code
+https://sourceware.org/ml/gdb-patches/2015-09/msg00183.html
+
+diff --git a/gdb/linespec.c b/gdb/linespec.c
+index 8f102fa..4c29c12 100644
+--- a/gdb/linespec.c
++++ b/gdb/linespec.c
+@@ -3423,6 +3423,8 @@ minsym_found (struct linespec_state *sel
+ 	  sal.pc = SYMBOL_VALUE_ADDRESS (msymbol);
+ 	  sal.pc = gdbarch_convert_from_func_ptr_addr (gdbarch, sal.pc,
+ 						       &current_target);
++	  if (gdbarch_skip_entrypoint_p (gdbarch))
++	    sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc);
+ 	}
+       else
+ 	skip_prologue_sal (&sal);
+diff --git a/gdb/ppc64-tdep.c b/gdb/ppc64-tdep.c
+index bb23b6a..4a0b93a 100644
+--- a/gdb/ppc64-tdep.c
++++ b/gdb/ppc64-tdep.c
+@@ -454,8 +454,8 @@ ppc64_standard_linkage4_target (struct frame_info *frame,
+    When the execution direction is EXEC_REVERSE, scan backward to
+    check whether we are in the middle of a PLT stub.  */
+ 
+-CORE_ADDR
+-ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
++static CORE_ADDR
++ppc64_skip_trampoline_code_1 (struct frame_info *frame, CORE_ADDR pc)
+ {
+ #define MAX(a,b) ((a) > (b) ? (a) : (b))
+   unsigned int insns[MAX (MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1),
+@@ -530,6 +530,20 @@ ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+   return 0;
+ }
+ 
++/* Wrapper of ppc64_skip_trampoline_code_1 checking also
++   ppc_elfv2_skip_entrypoint.  */
++
++CORE_ADDR
++ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
++{
++  struct gdbarch *gdbarch = get_frame_arch (frame);
++
++  pc = ppc64_skip_trampoline_code_1 (frame, pc);
++  if (pc != 0 && gdbarch_skip_entrypoint_p (gdbarch))
++    pc = gdbarch_skip_entrypoint (gdbarch, pc);
++  return pc;
++}
++
+ /* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC64
+    GNU/Linux.
+ 
+diff --git a/gdb/symtab.c b/gdb/symtab.c
+index 1ba691e..07eb78b 100644
+--- a/gdb/symtab.c
++++ b/gdb/symtab.c
+@@ -2779,7 +2779,11 @@ find_function_start_sal (struct symbol *
+       && (sal.symtab->locations_valid
+ 	  || sal.symtab->language == language_asm))
+     {
++      struct gdbarch *gdbarch = get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile);
++
+       sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
++      if (gdbarch_skip_entrypoint_p (gdbarch))
++	sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc);
+       return sal;
+     }
+ 
+diff --git a/gdb/testsuite/gdb.opt/solib-intra-step-lib.c b/gdb/testsuite/gdb.opt/solib-intra-step-lib.c
+new file mode 100644
+index 0000000..9ab1211
+--- /dev/null
++++ b/gdb/testsuite/gdb.opt/solib-intra-step-lib.c
+@@ -0,0 +1,30 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++   Copyright 2015 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/>.  */
++
++#include <stdlib.h>
++
++void
++shlib_second (int dummy)
++{ /* second-retry */
++  abort (); /* second-hit */
++}
++
++void
++shlib_first (void)
++{ /* first-retry */
++  shlib_second (0); /* first-hit */
++}
+diff --git a/gdb/testsuite/gdb.opt/solib-intra-step-main.c b/gdb/testsuite/gdb.opt/solib-intra-step-main.c
+new file mode 100644
+index 0000000..186bd5f
+--- /dev/null
++++ b/gdb/testsuite/gdb.opt/solib-intra-step-main.c
+@@ -0,0 +1,25 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++   Copyright 2015 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/>.  */
++
++extern void shlib_first (void);
++
++int
++main (void)
++{
++  shlib_first ();
++  return 0;
++}
+diff --git a/gdb/testsuite/gdb.opt/solib-intra-step.exp b/gdb/testsuite/gdb.opt/solib-intra-step.exp
+new file mode 100644
+index 0000000..044c4bd
+--- /dev/null
++++ b/gdb/testsuite/gdb.opt/solib-intra-step.exp
+@@ -0,0 +1,86 @@
++# Copyright 2015 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/>.
++
++standard_testfile
++
++if {[skip_shlib_tests]} {
++    return 0
++}
++
++# Library file.
++set libname "${testfile}-lib"
++set srcfile_lib ${srcdir}/${subdir}/${libname}.c
++set binfile_lib [standard_output_file ${libname}.so]
++set lib_flags [list debug optimize=-O2]
++# Binary file.
++set testfile "${testfile}-main"
++set srcfile ${srcdir}/${subdir}/${testfile}.c
++set binfile [standard_output_file ${testfile}]
++set bin_flags [list debug shlib=${binfile_lib}]
++
++if [get_compiler_info] {
++    return -1
++}
++
++if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != ""
++     || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } {
++  untested "Could not compile $binfile_lib or $binfile."
++  return -1
++}
++
++clean_restart ${binfile}
++gdb_load_shlibs $binfile_lib
++
++if ![runto_main] then {
++  return 0
++}
++
++set test "first-hit"
++gdb_test_multiple "step" $test {
++    -re " first-hit .*\r\n$gdb_prompt $" {
++	pass $test
++    }
++    -re " first-retry .*\r\n$gdb_prompt $" {
++	gdb_test "step" " first-hit .*" "first-hit (optimized)"
++    }
++}
++
++set test "second-hit"
++gdb_test_multiple "step" $test {
++    -re " second-hit .*\r\n$gdb_prompt $" {
++	pass $test
++    }
++    -re " first-retry .*\r\n$gdb_prompt $" {
++	set test "second-hit (optimized 1)"
++	gdb_test_multiple "step" $test {
++	    -re " second-hit .*\r\n$gdb_prompt $" {
++		pass $test
++	    }
++	    -re " first-hit .*\r\n$gdb_prompt $" {
++		gdb_test "step" " second-hit .*" "second-hit (optimized 2)"
++	    }
++	}
++    }
++    -re " second-retry .*\r\n$gdb_prompt $" {
++	gdb_test "step" " second-hit .*" "second-hit (optimized 3)"
++    }
++}
++
++if ![runto_main] then {
++  return 0
++}
++
++gdb_breakpoint "shlib_second"
++gdb_continue_to_breakpoint "second-hit" ".* (second-hit|second-retry) .*"
diff --git a/SPECS/gdb.spec b/SPECS/gdb.spec
index c918ee4..c3c42c2 100644
--- a/SPECS/gdb.spec
+++ b/SPECS/gdb.spec
@@ -37,7 +37,7 @@ Version: 7.6.1
 
 # The release always contains a leading reserved number, start it at 1.
 # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
-Release: 64%{?dist}
+Release: 80%{?dist}
 
 License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain
 Group: Development/Debuggers
@@ -666,6 +666,80 @@ Patch972: gdb-rhbz1103894-slow-gstack-performance.patch
 # BZ 1163339, Jan Kratochvil).
 Patch976: gdb-rhbz1163339-add-auto-load-scripts-directory.patch
 
+# Fix 'gdb/linux-nat.c:1411: internal-error:
+# linux_nat_post_attach_wait: Assertion `pid == new_pid' failed.'
+# (Pedro Alves, RH BZ 1210135).
+Patch994: gdb-rhbz1210135-internal-error-linux_nat_post_attach_wait.patch
+
+# Fix 'gdb internal error' [Threaded program calls clone, which
+# crashes GDB] (Pedro Alves, RH BZ 1210889).
+Patch995: gdb-rhbz1210889-thread-call-clone.patch
+
+# Fix '`catch syscall' doesn't work for parent after `fork' is called'
+# (Philippe Waroquiers, RH BZ 1149207).
+Patch996: gdb-rhbz1149207-catch-syscall-after-fork.patch
+
+# Fix 'ppc64: segv in `gdb -q
+# /lib/modules/3.10.0-215.el7.ppc64/kernel/fs/nfsd/nfsd.ko`' (Jan
+# Kratochvil, RH BZ 1190506).
+Patch997: gdb-rhbz1190506-segv-in-ko-ppc64.patch
+
+# Fix 'apply_frame_filter() wrong backport' (Tom Tromey, RH BZ
+# 1197665).
+Patch998: gdb-rhbz1197665-fix-applyframefilter-backport.patch
+
+# Implement '[7.2 FEAT] Enable reverse debugging support for PowerPC
+# on GDB' (Wei-cheng Wang, RH BZ 1218710, thanks to Edjunior Machado
+# for backporting).
+Patch999: gdb-rhbz1218710-reverse-debugging-ppc-1of7.patch
+Patch1000: gdb-rhbz1218710-reverse-debugging-ppc-2of7.patch
+Patch1001: gdb-rhbz1218710-reverse-debugging-ppc-3of7.patch
+Patch1002: gdb-rhbz1218710-reverse-debugging-ppc-4of7.patch
+Patch1003: gdb-rhbz1218710-reverse-debugging-ppc-5of7.patch
+Patch1004: gdb-rhbz1218710-reverse-debugging-ppc-6of7.patch
+Patch1005: gdb-rhbz1218710-reverse-debugging-ppc-7of7.patch
+
+# Fix 'gdb invoked oom-killer analyzing a vmcore on aarch64' (Pedro
+# Alves, Tom Tromey, RH BZ 1225569).
+Patch1006: gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-1of8.patch
+Patch1007: gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-2of8.patch
+Patch1008: gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-3of8.patch
+Patch1009: gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-4of8.patch
+Patch1010: gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-5of8.patch
+Patch1011: gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-6of8.patch
+Patch1012: gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-7of8.patch
+Patch1013: gdb-rhbz1225569-oom-killer-aarch64-frame-same-id-8of8.patch
+
+# Fix 'gdb output a internal-error: Assertion `num_lwps (GET_PID
+# (inferior_ptid)) == 1' failed' (Pedro Alves, RH BZ 1184724).
+Patch1014: gdb-rhbz1184724-gdb-internal-error-num-lwps.patch
+
+# Fix '[7.2 FEAT] GDB Transactional Diagnostic Block support on System
+# z' (Andreas Arnez, RH BZ 1105165).
+Patch1015: gdb-rhbz1105165-ibm-tdb-support-system-z-1of9.patch
+Patch1016: gdb-rhbz1105165-ibm-tdb-support-system-z-2of9.patch
+Patch1017: gdb-rhbz1105165-ibm-tdb-support-system-z-3of9.patch
+Patch1018: gdb-rhbz1105165-ibm-tdb-support-system-z-4of9.patch
+Patch1019: gdb-rhbz1105165-ibm-tdb-support-system-z-5of9.patch
+Patch1020: gdb-rhbz1105165-ibm-tdb-support-system-z-6of9.patch
+Patch1021: gdb-rhbz1105165-ibm-tdb-support-system-z-7of9.patch
+Patch1022: gdb-rhbz1105165-ibm-tdb-support-system-z-8of9.patch
+Patch1023: gdb-rhbz1105165-ibm-tdb-support-system-z-9of9.patch
+
+# Fix '[ppc64] and [s390x] wrong prologue skip on -O2 -g code' (Jan
+# Kratochvil, RH BZ 1084404).
+Patch1024: gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-1of3.patch
+Patch1025: gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-2of3.patch
+Patch1026: gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch
+
+# Fix 'Backport upstream GDB AArch64 SDT probe support to RHEL GDB'
+# (Sergio Durigan Junior, RH BZ 1247107).
+Patch1027: gdb-rhbz1247107-backport-aarch64-stap-sdt-support-1of2.patch
+Patch1028: gdb-rhbz1247107-backport-aarch64-stap-sdt-support-2of2.patch
+
+# [ppc64le] Use skip_entrypoint for skip_trampoline_code (RH BZ 1260558).
+Patch1030: gdb-rhbz1260558-ppc64le-skip_trampoline_code.patch
+
 %if 0%{!?rhel:1} || 0%{?rhel} > 6
 # RL_STATE_FEDORA_GDB would not be found for:
 # Patch642: gdb-readline62-ask-more-rh.patch
@@ -737,8 +811,11 @@ BuildRequires: gcc gcc-c++ gcc-gfortran gcc-objc
 BuildRequires: gcc-java libgcj%{bits_local} libgcj%{bits_other}
 %endif
 %if 0%{!?rhel:1} || 0%{?rhel} > 6
+# These Fedoras do not yet have gcc-go built.
+%ifnarch ppc64le aarch64
 BuildRequires: gcc-go
 %endif
+%endif
 # archer-sergiodj-stap-patch-split
 BuildRequires: systemtap-sdt-devel
 # Copied from prelink-0.4.2-3.fc13.
@@ -767,8 +844,11 @@ BuildRequires: libgcc%{bits_local} libgcc%{bits_other}
 # libstdc++-devel of matching bits is required only for g++ -static.
 BuildRequires: libstdc++%{bits_local} libstdc++%{bits_other}
 %if 0%{!?rhel:1} || 0%{?rhel} > 6
+# These Fedoras do not yet have gcc-go built.
+%ifnarch ppc64le aarch64
 BuildRequires: libgo-devel%{bits_local} libgo-devel%{bits_other}
 %endif
+%endif
 %if 0%{!?el5:1}
 BuildRequires: glibc-static%{bits_local}
 %endif
@@ -1044,12 +1124,52 @@ find -name "*.info*"|xargs rm -f
 %patch968 -p1
 %patch972 -p1
 %patch976 -p1
+%patch994 -p1
+%patch995 -p1
+%patch996 -p1
+%patch997 -p1
 
 %patch836 -p1
 %patch837 -p1
+%patch998 -p1
+
+%patch999 -p1
+%patch1000 -p1
+%patch1001 -p1
+%patch1002 -p1
+%patch1003 -p1
+%patch1004 -p1
+%patch1005 -p1
+%patch1006 -p1
+%patch1007 -p1
+%patch1008 -p1
+%patch1009 -p1
+%patch1010 -p1
+%patch1011 -p1
+%patch1012 -p1
+%patch1013 -p1
+%patch1014 -p1
+
+%patch1015 -p1
+%patch1016 -p1
+%patch1017 -p1
+%patch1018 -p1
+%patch1019 -p1
+%patch1020 -p1
+%patch1021 -p1
+%patch1022 -p1
+%patch1023 -p1
+%patch1024 -p1
+%patch1025 -p1
+%patch1026 -p1
+%patch1027 -p1
+%patch1028 -p1
+%patch1030 -p1
+
 %if 0%{?scl:1}
 %patch836 -p1 -R
 %patch837 -p1 -R
+%patch998 -p1 -R
 %endif
 %patch393 -p1
 %if 0%{!?el5:1} || 0%{?scl:1}
@@ -1062,14 +1182,9 @@ find -name "*.info*"|xargs rm -f
 %patch642 -p1
 %if 0%{?rhel:1} && 0%{?rhel} <= 6
 %patch642 -p1 -R
-%endif
 %patch337 -p1
 %patch331 -p1
 %patch335 -p1
-%if 0%{!?rhel:1} || 0%{?rhel} > 6
-%patch335 -p1 -R
-%patch331 -p1 -R
-%patch337 -p1 -R
 %endif
 
 find -name "*.orig" | xargs rm -f
@@ -1573,6 +1688,74 @@ fi
 %endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch"
 
 %changelog
+* Fri Sep 11 2015 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.6.1-80.el7
+- [testsuite] Fix gcc-go BuildRequires for --with testsuite.
+
+* Thu Sep 10 2015 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.6.1-79.el7
+- [ppc64le] Use skip_entrypoint for skip_trampoline_code (RH BZ 1260558).
+
+* Wed Aug 19 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-78.el7
+- Fix 'Backport upstream GDB AArch64 SDT probe support to RHEL GDB'
+  (Sergio Durigan Junior, RH BZ 1247107).
+
+* Tue Jul 07 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-77.el7
+- Address issues from Coverity Scan related to '[7.2 FEAT] Enable
+  reverse debugging support for PowerPC on GDB' (RH BZ 1218710).
+
+* Wed Jul 01 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-76.el7
+- Fix '[ppc64] and [s390x] wrong prologue skip on -O2 -g code' (Jan
+  Kratochvil, RH BZ 1084404).
+
+* Wed Jul 01 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-75.el7
+- Fix typo/thinko on
+  'gdb-rhbz1105165-ibm-tdb-support-system-z-3of9.patch', where the
+  type of the 'hwcap' variable in the 's390_core_read_description'
+  function should be 'CORE_ADDR', and not 'unsigned log'.  This caused
+  a build breakage on s390 (31-bit) (RH BZ 1105165).
+
+* Tue Jun 30 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-74.el7
+- Fix '[7.2 FEAT] GDB Transactional Diagnostic Block support on System
+  z' (Andreas Arnez, RH BZ 1105165).
+
+* Mon Jun 29 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-73.el7
+- Remove wrongly backported patches (5of7, 6of7, 7of7) from RH BZ
+  1225569 backport.  Add new patches necessary to fix failures.
+
+* Fri Jun 19 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-72.el7
+- Fix 'gdb output a internal-error: Assertion `num_lwps (GET_PID
+  (inferior_ptid)) == 1' failed' (Pedro Alves, RH BZ 1184724).
+
+* Fri Jun 19 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-71.el7
+- Fix 'gdb invoked oom-killer analyzing a vmcore on aarch64' (Pedro
+  Alves, Tom Tromey, RH BZ 1225569).
+
+* Tue May 26 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-70.el7
+- Implement '[7.2 FEAT] Enable reverse debugging support for PowerPC
+  on GDB' (Wei-cheng Wang, RH BZ 1218710, thanks to Edjunior Machado
+  for backporting).
+
+* Mon May 25 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-69.el7
+- Fix 'apply_frame_filter() wrong backport' (Tom Tromey, RH BZ
+  1197665).
+
+* Fri May 08 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-68.el7
+- Fix 'ppc64: segv in `gdb -q
+  /lib/modules/3.10.0-215.el7.ppc64/kernel/fs/nfsd/nfsd.ko`' (Jan
+  Kratochvil, RH BZ 1190506).
+
+* Thu May 07 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-67.el7
+- Fix '`catch syscall' doesn't work for parent after `fork' is called'
+  (Philippe Waroquiers, RH BZ 1149207).
+
+* Wed May 06 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-66.el7
+- Fix 'gdb internal error' [Threaded program calls clone, which
+  crashes GDB] (Pedro Alves, RH BZ 1210889).
+
+* Wed May 06 2015 Sergio Durigan Junior <sergiodj@redhat.com> - 7.6.1-65.el7
+- Fix 'gdb/linux-nat.c:1411: internal-error:
+  linux_nat_post_attach_wait: Assertion `pid == new_pid' failed.'
+  (Pedro Alves, RH BZ 1210135).
+
 * Sat Nov 22 2014 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.6.1-64.el7
 - Fix '[FJ7.0 Bug]: gdb: fail to refer to errno on a core dump file'
   (RH BZ 1166549, Jan Kratochvil).