diff --git a/SOURCES/_gdb.spec.Patch.include b/SOURCES/_gdb.spec.Patch.include index df21a03..a993ba9 100644 --- a/SOURCES/_gdb.spec.Patch.include +++ b/SOURCES/_gdb.spec.Patch.include @@ -547,3 +547,91 @@ Patch133: gdb-rhbz1491128-batch-mode-exit-status-2of2.patch # needed to unbreak GDB when compiling on 32-bit arches. Patch134: gdb-use-pulongest-aarch64-linux-tdep.patch +# Fix for 'GDB crashes when running from a deleted directory' +# (Tom Tromey, RHBZ#1653410) +Patch135: gdb-rhbz1653410-avoid-crash-when-calling-warning-too-early.patch + +# Fix for 'py-bt is broken, results in exception'. +# RHBZ 1639242 +Patch136: gdb-rhbz1639242-fix-dwarf2_find_containing_comp_unit-binary-search.patch + +# Fix 'Assertion `SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE (dict)->la_language' failed.' +# Keith Seitz, RHBZ#1560010. +Patch137: gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-1of5.patch + +# Fix 'Assertion `SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE (dict)->la_language' failed.' +# Keith Seitz, RHBZ#1560010. +Patch138: gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-2of5.patch + +# Fix 'Assertion `SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE (dict)->la_language' failed.' +# Keith Seitz, RHBZ#1560010. +Patch139: gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-3of5.patch + +# Fix 'Assertion `SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE (dict)->la_language' failed.' +# Keith Seitz, RHBZ#1560010. +Patch140: gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-4of5.patch + +# Fix 'Assertion `SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE (dict)->la_language' failed.' +# Keith Seitz, RHBZ#1560010. +Patch141: gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-5of5.patch + +# Fix remote.c build failure +# Szabolcs Nagy +Patch142: gdb-rhbz1187581-power8-regs-not-in-8.2-01of15.patch + +# Add grok/write functions for new ppc core note sections +# Edjunior Barbosa Machado +Patch143: gdb-rhbz1187581-power8-regs-not-in-8.2-02of15.patch + +# Zero-initialize linux note sections +# Pedro Franco de Carvalho +Patch144: gdb-rhbz1187581-power8-regs-not-in-8.2-03of15.patch + +# [PowerPC] Don't zero-initialize vector register buffers +# Pedro Franco de Carvalho +Patch145: gdb-rhbz1187581-power8-regs-not-in-8.2-04of15.patch + +# Add decfloat registers to float reggroup +# Pedro Franco de Carvalho +Patch146: gdb-rhbz1187581-power8-regs-not-in-8.2-05of15.patch + +# [PowerPC] Remove rs6000_pseudo_register_reggroup_p +# Pedro Franco de Carvalho +Patch147: gdb-rhbz1187581-power8-regs-not-in-8-2-06of15.patch + +# [PowerPC] Fix two if statements in gdb/ppc-linux-nat.c +# Pedro Franco de Carvalho +Patch148: gdb-rhbz1187581-power8-regs-not-in-8-2-07of15.patch + +# [PowerPC] Fix indentation in arch/ppc-linux-common.c +# Pedro Franco de Carvalho +Patch149: gdb-rhbz1187581-power8-regs-not-in-8-2-08of15.patch + +# [PowerPC] Refactor have_ initializers in rs6000-tdep.c +# Pedro Franco de Carvalho +Patch150: gdb-rhbz1187581-power8-regs-not-in-8-2-09of15.patch + +# [PowerPC] Add support for PPR and DSCR +# Edjunior Barbosa Machado and Pedro Franco de Carvalho +Patch151: gdb-rhbz1187581-power8-regs-not-in-8-2-10of15.patch + +# [PowerPC] Add support for TAR +# Edjunior Barbosa Machado and Pedro Franco de Carvalho +Patch152: gdb-rhbz1187581-power8-regs-not-in-8-2-11of15.patch + +# [PowerPC] Add support for EBB and PMU registers +# Edjunior Barbosa Machado and Pedro Franco de Carvalho +Patch153: gdb-rhbz1187581-power8-regs-not-in-8-2-12of15.patch + +# [PowerPC] Reject tdescs with VSX and no FPU or Altivec +# Pedro Franco de Carvalho +Patch154: gdb-rhbz1187581-power8-regs-not-in-8-2-13of15.patch + +# [PowerPC] Add support for HTM registers +# Edjunior Barbosa Machado and Pedro Franco de Carvalho +Patch155: gdb-rhbz1187581-power8-regs-not-in-8-2-14of15.patch + +# [PowerPC] Document requirements for VSX feature +# Pedro Franco de Carvalho +Patch156: gdb-rhbz1187581-power8-regs-doc-not-in-8.2-15of15.patch + diff --git a/SOURCES/_gdb.spec.patch.include b/SOURCES/_gdb.spec.patch.include index b9516bc..ee35969 100644 --- a/SOURCES/_gdb.spec.patch.include +++ b/SOURCES/_gdb.spec.patch.include @@ -132,3 +132,25 @@ %patch132 -p1 %patch133 -p1 %patch134 -p1 +%patch135 -p1 +%patch136 -p1 +%patch137 -p1 +%patch138 -p1 +%patch139 -p1 +%patch140 -p1 +%patch141 -p1 +%patch142 -p1 +%patch143 -p1 +%patch144 -p1 +%patch145 -p1 +%patch146 -p1 +%patch147 -p1 +%patch148 -p1 +%patch149 -p1 +%patch150 -p1 +%patch151 -p1 +%patch152 -p1 +%patch153 -p1 +%patch154 -p1 +%patch155 -p1 +%patch156 -p1 diff --git a/SOURCES/gdb-7.2.50-sparc-add-workaround-to-broken-debug-files.patch b/SOURCES/gdb-7.2.50-sparc-add-workaround-to-broken-debug-files.patch index fc75329..848429d 100644 --- a/SOURCES/gdb-7.2.50-sparc-add-workaround-to-broken-debug-files.patch +++ b/SOURCES/gdb-7.2.50-sparc-add-workaround-to-broken-debug-files.patch @@ -42,14 +42,14 @@ diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c #ifdef HAVE_MMAP if (sect->map_addr != NULL) { -@@ -493,6 +496,7 @@ free_one_bfd_section (bfd *abfd, asection *sectp, void *ignore) - gdb_assert (res == 0); +@@ -494,6 +497,7 @@ free_one_bfd_section (bfd *abfd, asection *sectp, void *ignore) } else -+#endif #endif ++#endif xfree (sect->data); } + } @@ -659,6 +663,7 @@ gdb_bfd_map_section (asection *sectp, bfd_size_type *size) if (descriptor->data != NULL) goto done; diff --git a/SOURCES/gdb-archer-pie-addons-keep-disabled.patch b/SOURCES/gdb-archer-pie-addons-keep-disabled.patch index 8824e54..38371db 100644 --- a/SOURCES/gdb-archer-pie-addons-keep-disabled.patch +++ b/SOURCES/gdb-archer-pie-addons-keep-disabled.patch @@ -8,11 +8,10 @@ Subject: gdb-archer-pie-addons-keep-disabled.patch diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c -@@ -15522,6 +15522,50 @@ initialize_breakpoint_ops (void) - +@@ -15523,6 +15523,50 @@ initialize_breakpoint_ops (void) static struct cmd_list_element *enablebreaklist = NULL; -+void + void +breakpoints_relocate (struct objfile *objfile, struct section_offsets *delta) +{ + struct bp_location *bl, **blp_tmp; @@ -56,9 +55,10 @@ diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c + bp_locations_compare); +} + - void ++void _initialize_breakpoint (void) { + struct cmd_list_element *c; diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-doc-not-in-8.2-15of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-doc-not-in-8.2-15of15.patch new file mode 100644 index 0000000..64affbe --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-doc-not-in-8.2-15of15.patch @@ -0,0 +1,43 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:19 -0500 +Subject: gdb-rhbz1187581-power8-regs-doc-not-in-8.2-15of15.patch + +;; [PowerPC] Document requirements for VSX feature +;; Pedro Franco de Carvalho + + [PowerPC] Document requirements for VSX feature + + As suggested in + https://sourceware.org/ml/gdb-patches/2018-10/msg00510.html, this + patch changes the documentation for the VSX tdesc feature to make it + clear that the altivec and FPU features are requirements. + + gdb/doc/ChangeLog: + 2018-11-09 Pedro Franco de Carvalho + + * gdb.texinfo (PowerPC Features): Document the altivec and fpu + requirements for the org.gnu.gdb.power.vsx feature. + +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -42562,11 +42562,13 @@ contain registers @samp{vr0} through @samp{vr31}, @samp{vscr}, + and @samp{vrsave}. + + The @samp{org.gnu.gdb.power.vsx} feature is optional. It should +-contain registers @samp{vs0h} through @samp{vs31h}. @value{GDBN} +-will combine these registers with the floating point registers +-(@samp{f0} through @samp{f31}) and the altivec registers (@samp{vr0} +-through @samp{vr31}) to present the 128-bit wide registers @samp{vs0} +-through @samp{vs63}, the set of vector registers for POWER7. ++contain registers @samp{vs0h} through @samp{vs31h}. @value{GDBN} will ++combine these registers with the floating point registers (@samp{f0} ++through @samp{f31}) and the altivec registers (@samp{vr0} through ++@samp{vr31}) to present the 128-bit wide registers @samp{vs0} through ++@samp{vs63}, the set of vector-scalar registers for POWER7. ++Therefore, this feature requires both @samp{org.gnu.gdb.power.fpu} and ++@samp{org.gnu.gdb.power.altivec}. + + The @samp{org.gnu.gdb.power.spe} feature is optional. It should + contain registers @samp{ev0h} through @samp{ev31h}, @samp{acc}, and diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-06of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-06of15.patch new file mode 100644 index 0000000..62a4525 --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-06of15.patch @@ -0,0 +1,72 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:14 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8-2-06of15.patch + +;; [PowerPC] Remove rs6000_pseudo_register_reggroup_p +;; Pedro Franco de Carvalho + + [PowerPC] Remove rs6000_pseudo_register_reggroup_p + + This patch removes rs6000_pseudo_register_reggroup_p. + + Group membership for the pseudoregisters can be detected through their + types in default_register_reggroup_p through + tdesc_register_reggroup_p. + + gdb/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * rs6000-tdep.c: Remove reggroups.h include. + (rs6000_pseudo_register_reggroup_p): Remove. + (rs6000_gdbarch_init): Remove call to + set_tdesc_pseudo_register_reggroup_p. + +diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c +--- a/gdb/rs6000-tdep.c ++++ b/gdb/rs6000-tdep.c +@@ -36,7 +36,6 @@ + #include "infcall.h" + #include "sim-regno.h" + #include "gdb/sim-ppc.h" +-#include "reggroups.h" + #include "dwarf2-frame.h" + #include "target-descriptions.h" + #include "user-regs.h" +@@ -2461,27 +2460,6 @@ rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum) + return builtin_type (gdbarch)->builtin_double; + } + +-/* Is REGNUM a member of REGGROUP? */ +-static int +-rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum, +- struct reggroup *group) +-{ +- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- +- /* These are the only pseudo-registers we support. */ +- gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum) +- || IS_DFP_PSEUDOREG (tdep, regnum) +- || IS_VSX_PSEUDOREG (tdep, regnum) +- || IS_EFP_PSEUDOREG (tdep, regnum)); +- +- /* These are the e500 pseudo-registers or the POWER7 VSX registers. */ +- if (IS_SPE_PSEUDOREG (tdep, regnum) || IS_VSX_PSEUDOREG (tdep, regnum)) +- return group == all_reggroup || group == vector_reggroup; +- else +- /* PPC decimal128 or Extended FP pseudo-registers. */ +- return group == all_reggroup || group == float_reggroup; +-} +- + /* The register format for RS/6000 floating point registers is always + double, we need a conversion if the memory format is float. */ + +@@ -6493,8 +6471,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + } + + set_tdesc_pseudo_register_type (gdbarch, rs6000_pseudo_register_type); +- set_tdesc_pseudo_register_reggroup_p (gdbarch, +- rs6000_pseudo_register_reggroup_p); + tdesc_use_registers (gdbarch, tdesc, tdesc_data); + + /* Override the normal target description method to make the SPE upper diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-07of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-07of15.patch new file mode 100644 index 0000000..f804191 --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-07of15.patch @@ -0,0 +1,41 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:15 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8-2-07of15.patch + +;; [PowerPC] Fix two if statements in gdb/ppc-linux-nat.c +;; Pedro Franco de Carvalho + + [PowerPC] Fix two if statements in gdb/ppc-linux-nat.c + + This patch changes two if statements to else if statements in + ppc-linux-nat.c:fetch_register for clarity. + + gdb/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * ppc-linux-nat.c (fetch_register): Change if statement to else + if. + (store_register): Likewise. + +diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c +--- a/gdb/ppc-linux-nat.c ++++ b/gdb/ppc-linux-nat.c +@@ -554,7 +554,7 @@ fetch_register (struct regcache *regcache, int tid, int regno) + AltiVec registers, fall through and return zeroes, because + regaddr will be -1 in this case. */ + } +- if (vsx_register_p (gdbarch, regno)) ++ else if (vsx_register_p (gdbarch, regno)) + { + if (have_ptrace_getsetvsxregs) + { +@@ -933,7 +933,7 @@ store_register (const struct regcache *regcache, int tid, int regno) + store_altivec_registers (regcache, tid, regno); + return; + } +- if (vsx_register_p (gdbarch, regno)) ++ else if (vsx_register_p (gdbarch, regno)) + { + store_vsx_registers (regcache, tid, regno); + return; diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-08of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-08of15.patch new file mode 100644 index 0000000..b76d832 --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-08of15.patch @@ -0,0 +1,64 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:15 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8-2-08of15.patch + +;; [PowerPC] Fix indentation in arch/ppc-linux-common.c +;; Pedro Franco de Carvalho + + [PowerPC] Fix indentation in arch/ppc-linux-common.c + + This patch parenthesizes the tdesc selection expressions in + arch/ppc-linux-common.c so that they can be tab-indented. + + gdb/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * arch/ppc-linux-common.c (ppc_linux_match_description): + Parenthesize tdesc assignements and indent them properly. + +diff --git a/gdb/arch/ppc-linux-common.c b/gdb/arch/ppc-linux-common.c +--- a/gdb/arch/ppc-linux-common.c ++++ b/gdb/arch/ppc-linux-common.c +@@ -53,14 +53,14 @@ ppc_linux_match_description (struct ppc_linux_features features) + if (features.cell) + tdesc = tdesc_powerpc_cell64l; + else if (features.vsx) +- tdesc = features.isa205 +- ? tdesc_powerpc_isa205_vsx64l : tdesc_powerpc_vsx64l; ++ tdesc = (features.isa205? tdesc_powerpc_isa205_vsx64l ++ : tdesc_powerpc_vsx64l); + else if (features.altivec) +- tdesc = features.isa205 +- ? tdesc_powerpc_isa205_altivec64l : tdesc_powerpc_altivec64l; ++ tdesc = (features.isa205? tdesc_powerpc_isa205_altivec64l ++ : tdesc_powerpc_altivec64l); + else +- tdesc = features.isa205? +- tdesc_powerpc_isa205_64l : tdesc_powerpc_64l; ++ tdesc = (features.isa205? tdesc_powerpc_isa205_64l ++ : tdesc_powerpc_64l); + } + else + { +@@ -69,14 +69,14 @@ ppc_linux_match_description (struct ppc_linux_features features) + if (features.cell) + tdesc = tdesc_powerpc_cell32l; + else if (features.vsx) +- tdesc = features.isa205 +- ? tdesc_powerpc_isa205_vsx32l : tdesc_powerpc_vsx32l; ++ tdesc = (features.isa205? tdesc_powerpc_isa205_vsx32l ++ : tdesc_powerpc_vsx32l); + else if (features.altivec) +- tdesc = features.isa205 +- ? tdesc_powerpc_isa205_altivec32l : tdesc_powerpc_altivec32l; ++ tdesc = (features.isa205? tdesc_powerpc_isa205_altivec32l ++ : tdesc_powerpc_altivec32l); + else +- tdesc = features.isa205 +- ? tdesc_powerpc_isa205_32l : tdesc_powerpc_32l; ++ tdesc = (features.isa205? tdesc_powerpc_isa205_32l ++ : tdesc_powerpc_32l); + } + + gdb_assert (tdesc != NULL); diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-09of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-09of15.patch new file mode 100644 index 0000000..67b6a3a --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-09of15.patch @@ -0,0 +1,36 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:16 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8-2-09of15.patch + +;; [PowerPC] Refactor have_ initializers in rs6000-tdep.c +;; Pedro Franco de Carvalho + + [PowerPC] Refactor have_ initializers in rs6000-tdep.c + + This patch refactors a series of initializers in rs6000_gdbarch_init + for clarity. The have_fpu initializer is also changed to set the + variable to 0, like the other similar variables. This doesn't affect + program behavior. + + gdb/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * rs6000-tdep.c (rs6000_gdbarch_init): Replace line wrapping by a + second initializer line for the have_* variables. Initialize + have_fpu to 0 instead of 1. + +diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c +--- a/gdb/rs6000-tdep.c ++++ b/gdb/rs6000-tdep.c +@@ -5845,8 +5845,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + enum powerpc_long_double_abi long_double_abi = POWERPC_LONG_DOUBLE_AUTO; + enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global; + enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO; +- int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0, +- have_vsx = 0; ++ int have_fpu = 0, have_spe = 0, have_mq = 0, have_altivec = 0; ++ int have_dfp = 0, have_vsx = 0; + int tdesc_wordsize = -1; + const struct target_desc *tdesc = info.target_desc; + struct tdesc_arch_data *tdesc_data = NULL; diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-10of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-10of15.patch new file mode 100644 index 0000000..c3e1e6f --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-10of15.patch @@ -0,0 +1,1987 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:16 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8-2-10of15.patch + +;; [PowerPC] Add support for PPR and DSCR +;; Edjunior Barbosa Machado and Pedro Franco de Carvalho + + [PowerPC] Add support for PPR and DSCR + + This patch adds gdb support for the Program Priorty Register and the + Data Stream Control Register, for the powerpc linux native and core + file targets, and for the powerpc linux server stub. + + gdb/ChangeLog: + 2018-10-26 Edjunior Barbosa Machado + Pedro Franco de Carvalho + + * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa205_ppr_dscr_vsx32l) + (tdesc_powerpc_isa205_ppr_dscr_vsx64l): Declare. + * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_PPRREGSET) + (PPC_LINUX_SIZEOF_DSCRREGSET): Define. + (struct ppc_linux_features) : New field. + (ppc_linux_no_features): Add initializer for ppr_dscr field. + * arch/ppc-linux-common.c (ppc_linux_match_description): Return + new tdescs. + * nat/ppc-linux.h (PPC_FEATURE2_DSCR, NT_PPC_PPR, NT_PPC_DSCR): + Define if not already defined. + * features/Makefile (WHICH): Add + rs6000/powerpc-isa205-ppr-dscr-vsx32l and + rs6000/powerpc-isa205-ppr-dscr-vsx64l. + (XMLTOC): Add rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and + rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml. + * features/rs6000/power-dscr.xml: New file. + * features/rs6000/power-ppr.xml: New file. + * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml: New file. + * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml: New file. + * features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c: Generate. + * features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c: Generate. + * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx32l.dat: Generate. + * regformats/rs6000/powerpc-isa205-ppr-dscr-vsx64l.dat: Generate. + * ppc-linux-nat.c: Include . + (fetch_regset, store_regset, check_regset): New functions. + (fetch_register, fetch_ppc_registers): Call fetch_regset with + DSCR and PPR regsets. + (store_register, store_ppc_registers): Call store_regset with + DSCR and PPR regsets. + (ppc_linux_get_hwcap2): New function. + (ppc_linux_nat_target::read_description): Call + ppc_linux_get_hwcap2 and check_regset, set ppr_dscr field in the + features struct if needed. + * ppc-linux-tdep.c: Include + features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c and + features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c. + (ppc32_regmap_ppr, ppc32_regmap_dscr, ppc32_linux_pprregset) + (ppc32_linux_dscrregset): New globals. + (ppc_linux_iterate_over_regset_sections): Call back with the ppr + and dscr regsets. + (ppc_linux_core_read_description): Check if the ppr and dscr + sections are present and set ppr_dscr in the features struct. + (_initialize_ppc_linux_tdep): Call + initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l and + initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l. + * ppc-linux-tdep.h (ppc32_linux_pprregset) + (ppc32_linux_dscrregset): Declare. + * ppc-tdep.h (struct gdbarch_tdep) : New field. + : New field. + (enum) : New enum values. + * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate ppr + and dscr features. + (ppc_process_record_op31): Record changes to PPR and DSCR. + + gdb/gdbserver/ChangeLog: + 2018-10-26 Edjunior Barbosa Machado + Pedro Franco de Carvalho + + * configure.srv (ipa_ppc_linux_regobj): Add + powerpc-isa205-ppr-dscr-vsx32l-ipa.o and + powerpc-isa205-ppr-dscr-vsx64l-ipa.o. + (powerpc*-*-linux*): Add powerpc-isa205-ppr-dscr-vsx32l.o and + powerpc-isa205-ppr-dscr-vsx64l.o to srv_regobj, add + rs6000/power-dscr.xml, rs6000/power-ppr.xml, + rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml and + rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml to srv_xmlfiles. + * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) + : New enum value. + (init_registers_powerpc_isa205_ppr_dscr_vsx32l) + (init_registers_powerpc_isa205_ppr_dscr_vsx64l): Declare. + * linux-ppc-low.c: Include "elf/common.h" and . + (ppc_hwcap): Add comment. + (ppc_hwcap2): New global. + (ppc_check_regset, ppc_fill_pprregset, ppc_store_pprregset) + (ppc_fill_dscrregset, ppc_store_dscrregset): New functions. + (ppc_regsets): Add entries for the DSCR and PPR regsets. + (ppc_arch_setup): Get AT_HWCAP2. Set ppr_dscr in features struct + when needed. Set sizes for the the DSCR and PPR regsets. + (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA205_PPR_DSCR_VSX. + (initialize_low_arch): Call + init_registers_powerpc_isa205_ppr_dscr_vsx32l and + init_registers_powerpc_isa205_ppr_dscr_vsx64l. + * linux-ppc-ipa.c (get_ipa_tdesc): Handle + PPC_TDESC_ISA205_PPR_DSCR_VSX. + (initialize_low_tracepoint): Call + init_registers_powerpc_isa205_ppr_dscr_vsx32l and + init_registers_powerpc_isa205_ppr_dscr_vsx64l. + + gdb/testsuite/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * gdb.arch/powerpc-ppr-dscr.c: New file. + * gdb.arch/powerpc-ppr-dscr.exp: New file. + + gdb/doc/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * gdb.texinfo (PowerPC Features): Describe new features + "org.gnu.gdb.power.ppr" and "org.gnu.gdb.power.dscr". + +diff --git a/gdb/arch/ppc-linux-common.c b/gdb/arch/ppc-linux-common.c +--- a/gdb/arch/ppc-linux-common.c ++++ b/gdb/arch/ppc-linux-common.c +@@ -53,7 +53,8 @@ ppc_linux_match_description (struct ppc_linux_features features) + if (features.cell) + tdesc = tdesc_powerpc_cell64l; + else if (features.vsx) +- tdesc = (features.isa205? tdesc_powerpc_isa205_vsx64l ++ tdesc = (features.ppr_dscr? tdesc_powerpc_isa205_ppr_dscr_vsx64l ++ : features.isa205? tdesc_powerpc_isa205_vsx64l + : tdesc_powerpc_vsx64l); + else if (features.altivec) + tdesc = (features.isa205? tdesc_powerpc_isa205_altivec64l +@@ -69,7 +70,8 @@ ppc_linux_match_description (struct ppc_linux_features features) + if (features.cell) + tdesc = tdesc_powerpc_cell32l; + else if (features.vsx) +- tdesc = (features.isa205? tdesc_powerpc_isa205_vsx32l ++ tdesc = (features.ppr_dscr? tdesc_powerpc_isa205_ppr_dscr_vsx32l ++ : features.isa205? tdesc_powerpc_isa205_vsx32l + : tdesc_powerpc_vsx32l); + else if (features.altivec) + tdesc = (features.isa205? tdesc_powerpc_isa205_altivec32l +diff --git a/gdb/arch/ppc-linux-common.h b/gdb/arch/ppc-linux-common.h +--- a/gdb/arch/ppc-linux-common.h ++++ b/gdb/arch/ppc-linux-common.h +@@ -30,6 +30,8 @@ struct target_desc; + #define PPC_LINUX_SIZEOF_VRREGSET 544 + + #define PPC_LINUX_SIZEOF_VSXREGSET 256 ++#define PPC_LINUX_SIZEOF_PPRREGSET 8 ++#define PPC_LINUX_SIZEOF_DSCRREGSET 8 + + /* Check if the hwcap auxv entry indicates that isa205 is supported. */ + bool ppc_linux_has_isa205 (CORE_ADDR hwcap); +@@ -41,6 +43,7 @@ struct ppc_linux_features + bool altivec; + bool vsx; + bool isa205; ++ bool ppr_dscr; + bool cell; + }; + +@@ -51,6 +54,7 @@ const struct ppc_linux_features ppc_linux_no_features = { + false, + false, + false, ++ false, + }; + + /* Return a target description that matches FEATURES. */ +diff --git a/gdb/arch/ppc-linux-tdesc.h b/gdb/arch/ppc-linux-tdesc.h +--- a/gdb/arch/ppc-linux-tdesc.h ++++ b/gdb/arch/ppc-linux-tdesc.h +@@ -29,6 +29,7 @@ extern struct target_desc *tdesc_powerpc_vsx32l; + extern struct target_desc *tdesc_powerpc_isa205_32l; + extern struct target_desc *tdesc_powerpc_isa205_altivec32l; + extern struct target_desc *tdesc_powerpc_isa205_vsx32l; ++extern struct target_desc *tdesc_powerpc_isa205_ppr_dscr_vsx32l; + extern struct target_desc *tdesc_powerpc_e500l; + + extern struct target_desc *tdesc_powerpc_64l; +@@ -38,5 +39,6 @@ extern struct target_desc *tdesc_powerpc_vsx64l; + extern struct target_desc *tdesc_powerpc_isa205_64l; + extern struct target_desc *tdesc_powerpc_isa205_altivec64l; + extern struct target_desc *tdesc_powerpc_isa205_vsx64l; ++extern struct target_desc *tdesc_powerpc_isa205_ppr_dscr_vsx64l; + + #endif /* ARCH_PPC_LINUX_TDESC_H */ +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -42576,6 +42576,12 @@ contain registers @samp{ev0h} through @samp{ev31h}, @samp{acc}, and + these to present registers @samp{ev0} through @samp{ev31} to the + user. + ++The @samp{org.gnu.gdb.power.ppr} feature is optional. It should ++contain the 64-bit register @samp{ppr}. ++ ++The @samp{org.gnu.gdb.power.dscr} feature is optional. It should ++contain the 64-bit register @samp{dscr}. ++ + @node S/390 and System z Features + @subsection S/390 and System z Features + @cindex target descriptions, S/390 features +diff --git a/gdb/features/Makefile b/gdb/features/Makefile +--- a/gdb/features/Makefile ++++ b/gdb/features/Makefile +@@ -73,6 +73,8 @@ WHICH = aarch64 \ + rs6000/powerpc-isa205-32l rs6000/powerpc-isa205-64l \ + rs6000/powerpc-isa205-altivec32l rs6000/powerpc-isa205-altivec64l \ + rs6000/powerpc-isa205-vsx32l rs6000/powerpc-isa205-vsx64l \ ++ rs6000/powerpc-isa205-ppr-dscr-vsx32l \ ++ rs6000/powerpc-isa205-ppr-dscr-vsx64l \ + s390-linux32 s390-linux64 s390x-linux64 \ + s390-linux32v1 s390-linux64v1 s390x-linux64v1 \ + s390-linux32v2 s390-linux64v2 s390x-linux64v2 \ +@@ -167,6 +169,8 @@ XMLTOC = \ + rs6000/powerpc-isa205-altivec64l.xml \ + rs6000/powerpc-isa205-vsx32l.xml \ + rs6000/powerpc-isa205-vsx64l.xml \ ++ rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml \ ++ rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml \ + rs6000/powerpc-vsx32.xml \ + rs6000/powerpc-vsx32l.xml \ + rs6000/powerpc-vsx64.xml \ +diff --git a/gdb/features/rs6000/power-dscr.xml b/gdb/features/rs6000/power-dscr.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-dscr.xml +@@ -0,0 +1,12 @@ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/power-ppr.xml b/gdb/features/rs6000/power-ppr.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-ppr.xml +@@ -0,0 +1,12 @@ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c b/gdb/features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c +@@ -0,0 +1,200 @@ ++/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: ++ Original: powerpc-isa205-ppr-dscr-vsx32l.xml */ ++ ++#include "defs.h" ++#include "osabi.h" ++#include "target-descriptions.h" ++ ++struct target_desc *tdesc_powerpc_isa205_ppr_dscr_vsx32l; ++static void ++initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l (void) ++{ ++ struct target_desc *result = allocate_target_description (); ++ set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); ++ ++ struct tdesc_feature *feature; ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); ++ tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r24", 24, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r25", 25, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r26", 26, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r27", 27, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r28", 28, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "pc", 64, 1, NULL, 32, "code_ptr"); ++ tdesc_create_reg (feature, "msr", 65, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "lr", 67, 1, NULL, 32, "code_ptr"); ++ tdesc_create_reg (feature, "ctr", 68, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu"); ++ tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "fpscr", 70, 1, "float", 64, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux"); ++ tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 32, "int"); ++ tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); ++ tdesc_type *element_type; ++ element_type = tdesc_named_type (feature, "ieee_single"); ++ tdesc_create_vector (feature, "v4f", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int32"); ++ tdesc_create_vector (feature, "v4i32", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int16"); ++ tdesc_create_vector (feature, "v8i16", element_type, 8); ++ ++ element_type = tdesc_named_type (feature, "int8"); ++ tdesc_create_vector (feature, "v16i8", element_type, 16); ++ ++ tdesc_type_with_fields *type_with_fields; ++ type_with_fields = tdesc_create_union (feature, "vec128"); ++ tdesc_type *field_type; ++ field_type = tdesc_named_type (feature, "uint128"); ++ tdesc_add_field (type_with_fields, "uint128", field_type); ++ field_type = tdesc_named_type (feature, "v4f"); ++ tdesc_add_field (type_with_fields, "v4_float", field_type); ++ field_type = tdesc_named_type (feature, "v4i32"); ++ tdesc_add_field (type_with_fields, "v4_int32", field_type); ++ field_type = tdesc_named_type (feature, "v8i16"); ++ tdesc_add_field (type_with_fields, "v8_int16", field_type); ++ field_type = tdesc_named_type (feature, "v16i8"); ++ tdesc_add_field (type_with_fields, "v16_int8", field_type); ++ ++ tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int"); ++ tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.vsx"); ++ tdesc_create_reg (feature, "vs0h", 107, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs1h", 108, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs2h", 109, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs3h", 110, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs4h", 111, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs5h", 112, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs6h", 113, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs7h", 114, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs8h", 115, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs9h", 116, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs10h", 117, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs11h", 118, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs12h", 119, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs13h", 120, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs14h", 121, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs15h", 122, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs16h", 123, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs17h", 124, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs18h", 125, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs19h", 126, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs20h", 127, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs21h", 128, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs22h", 129, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs23h", 130, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs24h", 131, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs25h", 132, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs26h", 133, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs27h", 134, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs28h", 135, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs29h", 136, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs30h", 137, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs31h", 138, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.ppr"); ++ tdesc_create_reg (feature, "ppr", 139, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.dscr"); ++ tdesc_create_reg (feature, "dscr", 140, 1, NULL, 64, "uint64"); ++ ++ tdesc_powerpc_isa205_ppr_dscr_vsx32l = result; ++} +diff --git a/gdb/features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml b/gdb/features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml +@@ -0,0 +1,18 @@ ++ ++ ++ ++ ++ ++ powerpc:common ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c b/gdb/features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c +@@ -0,0 +1,200 @@ ++/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: ++ Original: powerpc-isa205-ppr-dscr-vsx64l.xml */ ++ ++#include "defs.h" ++#include "osabi.h" ++#include "target-descriptions.h" ++ ++struct target_desc *tdesc_powerpc_isa205_ppr_dscr_vsx64l; ++static void ++initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l (void) ++{ ++ struct target_desc *result = allocate_target_description (); ++ set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); ++ ++ struct tdesc_feature *feature; ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); ++ tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "pc", 64, 1, NULL, 64, "code_ptr"); ++ tdesc_create_reg (feature, "msr", 65, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "lr", 67, 1, NULL, 64, "code_ptr"); ++ tdesc_create_reg (feature, "ctr", 68, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu"); ++ tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "fpscr", 70, 1, "float", 64, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux"); ++ tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 64, "int"); ++ tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); ++ tdesc_type *element_type; ++ element_type = tdesc_named_type (feature, "ieee_single"); ++ tdesc_create_vector (feature, "v4f", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int32"); ++ tdesc_create_vector (feature, "v4i32", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int16"); ++ tdesc_create_vector (feature, "v8i16", element_type, 8); ++ ++ element_type = tdesc_named_type (feature, "int8"); ++ tdesc_create_vector (feature, "v16i8", element_type, 16); ++ ++ tdesc_type_with_fields *type_with_fields; ++ type_with_fields = tdesc_create_union (feature, "vec128"); ++ tdesc_type *field_type; ++ field_type = tdesc_named_type (feature, "uint128"); ++ tdesc_add_field (type_with_fields, "uint128", field_type); ++ field_type = tdesc_named_type (feature, "v4f"); ++ tdesc_add_field (type_with_fields, "v4_float", field_type); ++ field_type = tdesc_named_type (feature, "v4i32"); ++ tdesc_add_field (type_with_fields, "v4_int32", field_type); ++ field_type = tdesc_named_type (feature, "v8i16"); ++ tdesc_add_field (type_with_fields, "v8_int16", field_type); ++ field_type = tdesc_named_type (feature, "v16i8"); ++ tdesc_add_field (type_with_fields, "v16_int8", field_type); ++ ++ tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int"); ++ tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.vsx"); ++ tdesc_create_reg (feature, "vs0h", 107, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs1h", 108, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs2h", 109, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs3h", 110, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs4h", 111, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs5h", 112, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs6h", 113, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs7h", 114, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs8h", 115, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs9h", 116, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs10h", 117, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs11h", 118, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs12h", 119, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs13h", 120, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs14h", 121, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs15h", 122, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs16h", 123, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs17h", 124, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs18h", 125, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs19h", 126, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs20h", 127, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs21h", 128, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs22h", 129, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs23h", 130, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs24h", 131, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs25h", 132, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs26h", 133, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs27h", 134, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs28h", 135, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs29h", 136, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs30h", 137, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs31h", 138, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.ppr"); ++ tdesc_create_reg (feature, "ppr", 139, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.dscr"); ++ tdesc_create_reg (feature, "dscr", 140, 1, NULL, 64, "uint64"); ++ ++ tdesc_powerpc_isa205_ppr_dscr_vsx64l = result; ++} +diff --git a/gdb/features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml b/gdb/features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml +@@ -0,0 +1,18 @@ ++ ++ ++ ++ ++ ++ powerpc:common64 ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv +--- a/gdb/gdbserver/configure.srv ++++ b/gdb/gdbserver/configure.srv +@@ -32,7 +32,7 @@ else + srv_amd64_linux_regobj="" + fi + +-ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o" ++ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-isa205-ppr-dscr-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o powerpc-isa205-ppr-dscr-vsx64l-ipa.o" + + # Linux object files. This is so we don't have to repeat + # these files over and over again. +@@ -217,6 +217,7 @@ case "${target}" in + srv_regobj="${srv_regobj} powerpc-isa205-32l.o" + srv_regobj="${srv_regobj} powerpc-isa205-altivec32l.o" + srv_regobj="${srv_regobj} powerpc-isa205-vsx32l.o" ++ srv_regobj="${srv_regobj} powerpc-isa205-ppr-dscr-vsx32l.o" + srv_regobj="${srv_regobj} powerpc-e500l.o" + srv_regobj="${srv_regobj} powerpc-64l.o" + srv_regobj="${srv_regobj} powerpc-altivec64l.o" +@@ -225,6 +226,7 @@ case "${target}" in + srv_regobj="${srv_regobj} powerpc-isa205-64l.o" + srv_regobj="${srv_regobj} powerpc-isa205-altivec64l.o" + srv_regobj="${srv_regobj} powerpc-isa205-vsx64l.o" ++ srv_regobj="${srv_regobj} powerpc-isa205-ppr-dscr-vsx64l.o" + srv_tgtobj="$srv_linux_obj linux-ppc-low.o ppc-linux.o" + srv_tgtobj="${srv_tgtobj} arch/ppc-linux-common.o" + srv_xmlfiles="rs6000/powerpc-32l.xml" +@@ -234,12 +236,15 @@ case "${target}" in + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-32l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-altivec32l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-vsx32l.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-altivec.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-vsx.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-core.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-linux.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-fpu.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-fpu-isa205.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-dscr.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-ppr.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-e500l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-spe.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-64l.xml" +@@ -249,6 +254,7 @@ case "${target}" in + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-64l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-altivec64l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-vsx64l.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power64-core.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power64-linux.xml" + srv_linux_usrregs=yes +diff --git a/gdb/gdbserver/linux-ppc-ipa.c b/gdb/gdbserver/linux-ppc-ipa.c +--- a/gdb/gdbserver/linux-ppc-ipa.c ++++ b/gdb/gdbserver/linux-ppc-ipa.c +@@ -191,6 +191,8 @@ get_ipa_tdesc (int idx) + return tdesc_powerpc_isa205_altivec64l; + case PPC_TDESC_ISA205_VSX: + return tdesc_powerpc_isa205_vsx64l; ++ case PPC_TDESC_ISA205_PPR_DSCR_VSX: ++ return tdesc_powerpc_isa205_ppr_dscr_vsx64l; + #else + case PPC_TDESC_BASE: + return tdesc_powerpc_32l; +@@ -206,6 +208,8 @@ get_ipa_tdesc (int idx) + return tdesc_powerpc_isa205_altivec32l; + case PPC_TDESC_ISA205_VSX: + return tdesc_powerpc_isa205_vsx32l; ++ case PPC_TDESC_ISA205_PPR_DSCR_VSX: ++ return tdesc_powerpc_isa205_ppr_dscr_vsx32l; + case PPC_TDESC_E500: + return tdesc_powerpc_e500l; + #endif +@@ -234,6 +238,7 @@ initialize_low_tracepoint (void) + init_registers_powerpc_isa205_64l (); + init_registers_powerpc_isa205_altivec64l (); + init_registers_powerpc_isa205_vsx64l (); ++ init_registers_powerpc_isa205_ppr_dscr_vsx64l (); + #else + init_registers_powerpc_32l (); + init_registers_powerpc_altivec32l (); +@@ -242,6 +247,7 @@ initialize_low_tracepoint (void) + init_registers_powerpc_isa205_32l (); + init_registers_powerpc_isa205_altivec32l (); + init_registers_powerpc_isa205_vsx32l (); ++ init_registers_powerpc_isa205_ppr_dscr_vsx32l (); + init_registers_powerpc_e500l (); + #endif + } +diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c +--- a/gdb/gdbserver/linux-ppc-low.c ++++ b/gdb/gdbserver/linux-ppc-low.c +@@ -20,6 +20,8 @@ + #include "server.h" + #include "linux-low.h" + ++#include "elf/common.h" ++#include + #include + #include + +@@ -41,8 +43,14 @@ + #define PPC_LI(insn) (PPC_SEXT (PPC_FIELD (insn, 6, 24), 24) << 2) + #define PPC_BD(insn) (PPC_SEXT (PPC_FIELD (insn, 16, 14), 14) << 2) + ++/* Holds the AT_HWCAP auxv entry. */ ++ + static unsigned long ppc_hwcap; + ++/* Holds the AT_HWCAP2 auxv entry. */ ++ ++static unsigned long ppc_hwcap2; ++ + + #define ppc_num_regs 73 + +@@ -116,6 +124,24 @@ static int ppc_regmap_e500[] = + }; + #endif + ++/* Check whether the kernel provides a register set with number ++ REGSET_ID of size REGSETSIZE for process/thread TID. */ ++ ++static int ++ppc_check_regset (int tid, int regset_id, int regsetsize) ++{ ++ void *buf = alloca (regsetsize); ++ struct iovec iov; ++ ++ iov.iov_base = buf; ++ iov.iov_len = regsetsize; ++ ++ if (ptrace (PTRACE_GETREGSET, tid, regset_id, &iov) >= 0 ++ || errno == ENODATA) ++ return 1; ++ return 0; ++} ++ + static int + ppc_cannot_store_register (int regno) + { +@@ -459,6 +485,46 @@ static void ppc_fill_gregset (struct regcache *regcache, void *buf) + ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]); + } + ++/* Program Priority Register regset fill function. */ ++ ++static void ++ppc_fill_pprregset (struct regcache *regcache, void *buf) ++{ ++ char *ppr = (char *) buf; ++ ++ collect_register_by_name (regcache, "ppr", ppr); ++} ++ ++/* Program Priority Register regset store function. */ ++ ++static void ++ppc_store_pprregset (struct regcache *regcache, const void *buf) ++{ ++ const char *ppr = (const char *) buf; ++ ++ supply_register_by_name (regcache, "ppr", ppr); ++} ++ ++/* Data Stream Control Register regset fill function. */ ++ ++static void ++ppc_fill_dscrregset (struct regcache *regcache, void *buf) ++{ ++ char *dscr = (char *) buf; ++ ++ collect_register_by_name (regcache, "dscr", dscr); ++} ++ ++/* Data Stream Control Register regset store function. */ ++ ++static void ++ppc_store_dscrregset (struct regcache *regcache, const void *buf) ++{ ++ const char *dscr = (const char *) buf; ++ ++ supply_register_by_name (regcache, "dscr", dscr); ++} ++ + static void + ppc_fill_vsxregset (struct regcache *regcache, void *buf) + { +@@ -568,6 +634,10 @@ static struct regset_info ppc_regsets[] = { + fetch them every time, but still fall back to PTRACE_PEEKUSER for the + general registers. Some kernels support these, but not the newer + PPC_PTRACE_GETREGS. */ ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PPR, 0, EXTENDED_REGS, ++ ppc_fill_pprregset, ppc_store_pprregset }, ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_DSCR, 0, EXTENDED_REGS, ++ ppc_fill_dscrregset, ppc_store_dscrregset }, + { PTRACE_GETVSXREGS, PTRACE_SETVSXREGS, 0, 0, EXTENDED_REGS, + ppc_fill_vsxregset, ppc_store_vsxregset }, + { PTRACE_GETVRREGS, PTRACE_SETVRREGS, 0, 0, EXTENDED_REGS, +@@ -625,6 +695,7 @@ ppc_arch_setup (void) + /* The value of current_process ()->tdesc needs to be set for this + call. */ + ppc_get_auxv (AT_HWCAP, &ppc_hwcap); ++ ppc_get_auxv (AT_HWCAP2, &ppc_hwcap2); + + features.isa205 = ppc_linux_has_isa205 (ppc_hwcap); + +@@ -634,6 +705,11 @@ ppc_arch_setup (void) + if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC) + features.altivec = true; + ++ if ((ppc_hwcap2 & PPC_FEATURE2_DSCR) ++ && ppc_check_regset (tid, NT_PPC_DSCR, PPC_LINUX_SIZEOF_DSCRREGSET) ++ && ppc_check_regset (tid, NT_PPC_PPR, PPC_LINUX_SIZEOF_PPRREGSET)) ++ features.ppr_dscr = true; ++ + if (ppc_hwcap & PPC_FEATURE_CELL) + features.cell = true; + +@@ -678,6 +754,21 @@ ppc_arch_setup (void) + else + regset->size = 0; + break; ++ case PTRACE_GETREGSET: ++ switch (regset->nt_type) ++ { ++ case NT_PPC_PPR: ++ regset->size = (features.ppr_dscr ? ++ PPC_LINUX_SIZEOF_PPRREGSET : 0); ++ break; ++ case NT_PPC_DSCR: ++ regset->size = (features.ppr_dscr ? ++ PPC_LINUX_SIZEOF_DSCRREGSET : 0); ++ break; ++ default: ++ break; ++ } ++ break; + default: + break; + } +@@ -3053,6 +3144,8 @@ ppc_get_ipa_tdesc_idx (void) + return PPC_TDESC_ISA205_ALTIVEC; + if (tdesc == tdesc_powerpc_isa205_vsx64l) + return PPC_TDESC_ISA205_VSX; ++ if (tdesc == tdesc_powerpc_isa205_ppr_dscr_vsx64l) ++ return PPC_TDESC_ISA205_PPR_DSCR_VSX; + #endif + + if (tdesc == tdesc_powerpc_32l) +@@ -3069,6 +3162,8 @@ ppc_get_ipa_tdesc_idx (void) + return PPC_TDESC_ISA205_ALTIVEC; + if (tdesc == tdesc_powerpc_isa205_vsx32l) + return PPC_TDESC_ISA205_VSX; ++ if (tdesc == tdesc_powerpc_isa205_ppr_dscr_vsx32l) ++ return PPC_TDESC_ISA205_PPR_DSCR_VSX; + if (tdesc == tdesc_powerpc_e500l) + return PPC_TDESC_E500; + +@@ -3127,6 +3222,7 @@ initialize_low_arch (void) + init_registers_powerpc_isa205_32l (); + init_registers_powerpc_isa205_altivec32l (); + init_registers_powerpc_isa205_vsx32l (); ++ init_registers_powerpc_isa205_ppr_dscr_vsx32l (); + init_registers_powerpc_e500l (); + #if __powerpc64__ + init_registers_powerpc_64l (); +@@ -3136,6 +3232,7 @@ initialize_low_arch (void) + init_registers_powerpc_isa205_64l (); + init_registers_powerpc_isa205_altivec64l (); + init_registers_powerpc_isa205_vsx64l (); ++ init_registers_powerpc_isa205_ppr_dscr_vsx64l (); + #endif + + initialize_regsets_info (&ppc_regsets_info); +diff --git a/gdb/gdbserver/linux-ppc-tdesc-init.h b/gdb/gdbserver/linux-ppc-tdesc-init.h +--- a/gdb/gdbserver/linux-ppc-tdesc-init.h ++++ b/gdb/gdbserver/linux-ppc-tdesc-init.h +@@ -29,6 +29,7 @@ enum ppc_linux_tdesc { + PPC_TDESC_ISA205, + PPC_TDESC_ISA205_ALTIVEC, + PPC_TDESC_ISA205_VSX, ++ PPC_TDESC_ISA205_PPR_DSCR_VSX, + PPC_TDESC_E500, + }; + +@@ -55,6 +56,9 @@ void init_registers_powerpc_isa205_altivec32l (void); + /* Defined in auto-generated file powerpc-isa205-vsx32l.c. */ + void init_registers_powerpc_isa205_vsx32l (void); + ++/* Defined in auto-generated file powerpc-isa205-ppr-dscr-vsx32l.c. */ ++void init_registers_powerpc_isa205_ppr_dscr_vsx32l (void); ++ + /* Defined in auto-generated file powerpc-e500l.c. */ + void init_registers_powerpc_e500l (void); + +@@ -83,4 +87,7 @@ void init_registers_powerpc_isa205_altivec64l (void); + /* Defined in auto-generated file powerpc-isa205-vsx64l.c. */ + void init_registers_powerpc_isa205_vsx64l (void); + ++/* Defined in auto-generated file powerpc-isa205-ppr-dscr-vsx64l.c. */ ++void init_registers_powerpc_isa205_ppr_dscr_vsx64l (void); ++ + #endif +diff --git a/gdb/nat/ppc-linux.h b/gdb/nat/ppc-linux.h +--- a/gdb/nat/ppc-linux.h ++++ b/gdb/nat/ppc-linux.h +@@ -51,6 +51,9 @@ + #ifndef PPC_FEATURE_HAS_SPE + #define PPC_FEATURE_HAS_SPE 0x00800000 + #endif ++#ifndef PPC_FEATURE2_DSCR ++#define PPC_FEATURE2_DSCR 0x20000000 ++#endif + + /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a + configure time check. Some older glibc's (for instance 2.2.1) +@@ -82,6 +85,16 @@ + #define PTRACE_SETEVRREGS 21 + #endif + ++/* Program Priority Register. */ ++#ifndef NT_PPC_PPR ++#define NT_PPC_PPR 0x104 ++#endif ++ ++/* Data Stream Control Register. */ ++#ifndef NT_PPC_DSCR ++#define NT_PPC_DSCR 0x105 ++#endif ++ + /* Return the wordsize of the target, either 4 or 8 bytes. */ + int ppc_linux_target_wordsize (int tid); + +diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c +--- a/gdb/ppc-linux-nat.c ++++ b/gdb/ppc-linux-nat.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include "gdb_wait.h" + #include + #include +@@ -528,6 +529,78 @@ fetch_spe_register (struct regcache *regcache, int tid, int regno) + regcache->raw_supply (tdep->ppc_spefscr_regnum, &evrregs.spefscr); + } + ++/* Use ptrace to fetch all registers from the register set with note ++ type REGSET_ID, size REGSIZE, and layout described by REGSET, from ++ process/thread TID and supply their values to REGCACHE. If ptrace ++ returns ENODATA to indicate the regset is unavailable, mark the ++ registers as unavailable in REGCACHE. */ ++ ++static void ++fetch_regset (struct regcache *regcache, int tid, ++ int regset_id, int regsetsize, const struct regset *regset) ++{ ++ void *buf = alloca (regsetsize); ++ struct iovec iov; ++ ++ iov.iov_base = buf; ++ iov.iov_len = regsetsize; ++ ++ if (ptrace (PTRACE_GETREGSET, tid, regset_id, &iov) < 0) ++ { ++ if (errno == ENODATA) ++ regset->supply_regset (regset, regcache, -1, NULL, regsetsize); ++ else ++ perror_with_name (_("Couldn't get register set")); ++ } ++ else ++ regset->supply_regset (regset, regcache, -1, buf, regsetsize); ++} ++ ++/* Use ptrace to store register REGNUM of the regset with note type ++ REGSET_ID, size REGSETSIZE, and layout described by REGSET, from ++ REGCACHE back to process/thread TID. If REGNUM is -1 all registers ++ in the set are collected and stored. */ ++ ++static void ++store_regset (const struct regcache *regcache, int tid, int regnum, ++ int regset_id, int regsetsize, const struct regset *regset) ++{ ++ void *buf = alloca (regsetsize); ++ struct iovec iov; ++ ++ iov.iov_base = buf; ++ iov.iov_len = regsetsize; ++ ++ /* Make sure that the buffer that will be stored has up to date values ++ for the registers that won't be collected. */ ++ if (ptrace (PTRACE_GETREGSET, tid, regset_id, &iov) < 0) ++ perror_with_name (_("Couldn't get register set")); ++ ++ regset->collect_regset (regset, regcache, regnum, buf, regsetsize); ++ ++ if (ptrace (PTRACE_SETREGSET, tid, regset_id, &iov) < 0) ++ perror_with_name (_("Couldn't set register set")); ++} ++ ++/* Check whether the kernel provides a register set with number ++ REGSET_ID of size REGSETSIZE for process/thread TID. */ ++ ++static bool ++check_regset (int tid, int regset_id, int regsetsize) ++{ ++ void *buf = alloca (regsetsize); ++ struct iovec iov; ++ ++ iov.iov_base = buf; ++ iov.iov_len = regsetsize; ++ ++ if (ptrace (PTRACE_GETREGSET, tid, regset_id, &iov) >= 0 ++ || errno == ENODATA) ++ return true; ++ else ++ return false; ++} ++ + static void + fetch_register (struct regcache *regcache, int tid, int regno) + { +@@ -567,6 +640,24 @@ fetch_register (struct regcache *regcache, int tid, int regno) + fetch_spe_register (regcache, tid, regno); + return; + } ++ else if (regno == PPC_DSCR_REGNUM) ++ { ++ gdb_assert (tdep->ppc_dscr_regnum != -1); ++ ++ fetch_regset (regcache, tid, NT_PPC_DSCR, ++ PPC_LINUX_SIZEOF_DSCRREGSET, ++ &ppc32_linux_dscrregset); ++ return; ++ } ++ else if (regno == PPC_PPR_REGNUM) ++ { ++ gdb_assert (tdep->ppc_ppr_regnum != -1); ++ ++ fetch_regset (regcache, tid, NT_PPC_PPR, ++ PPC_LINUX_SIZEOF_PPRREGSET, ++ &ppc32_linux_pprregset); ++ return; ++ } + + if (regaddr == -1) + { +@@ -763,6 +854,14 @@ fetch_ppc_registers (struct regcache *regcache, int tid) + fetch_vsx_registers (regcache, tid, -1); + if (tdep->ppc_ev0_upper_regnum >= 0) + fetch_spe_register (regcache, tid, -1); ++ if (tdep->ppc_ppr_regnum != -1) ++ fetch_regset (regcache, tid, NT_PPC_PPR, ++ PPC_LINUX_SIZEOF_PPRREGSET, ++ &ppc32_linux_pprregset); ++ if (tdep->ppc_dscr_regnum != -1) ++ fetch_regset (regcache, tid, NT_PPC_DSCR, ++ PPC_LINUX_SIZEOF_DSCRREGSET, ++ &ppc32_linux_dscrregset); + } + + /* Fetch registers from the child process. Fetch all registers if +@@ -943,6 +1042,24 @@ store_register (const struct regcache *regcache, int tid, int regno) + store_spe_register (regcache, tid, regno); + return; + } ++ else if (regno == PPC_DSCR_REGNUM) ++ { ++ gdb_assert (tdep->ppc_dscr_regnum != -1); ++ ++ store_regset (regcache, tid, regno, NT_PPC_DSCR, ++ PPC_LINUX_SIZEOF_DSCRREGSET, ++ &ppc32_linux_dscrregset); ++ return; ++ } ++ else if (regno == PPC_PPR_REGNUM) ++ { ++ gdb_assert (tdep->ppc_ppr_regnum != -1); ++ ++ store_regset (regcache, tid, regno, NT_PPC_PPR, ++ PPC_LINUX_SIZEOF_PPRREGSET, ++ &ppc32_linux_pprregset); ++ return; ++ } + + if (regaddr == -1) + return; +@@ -1157,6 +1274,14 @@ store_ppc_registers (const struct regcache *regcache, int tid) + store_vsx_registers (regcache, tid, -1); + if (tdep->ppc_ev0_upper_regnum >= 0) + store_spe_register (regcache, tid, -1); ++ if (tdep->ppc_ppr_regnum != -1) ++ store_regset (regcache, tid, -1, NT_PPC_PPR, ++ PPC_LINUX_SIZEOF_PPRREGSET, ++ &ppc32_linux_pprregset); ++ if (tdep->ppc_dscr_regnum != -1) ++ store_regset (regcache, tid, -1, NT_PPC_DSCR, ++ PPC_LINUX_SIZEOF_DSCRREGSET, ++ &ppc32_linux_dscrregset); + } + + /* Fetch the AT_HWCAP entry from the aux vector. */ +@@ -1171,6 +1296,19 @@ ppc_linux_get_hwcap (void) + return field; + } + ++/* Fetch the AT_HWCAP2 entry from the aux vector. */ ++ ++static CORE_ADDR ++ppc_linux_get_hwcap2 (void) ++{ ++ CORE_ADDR field; ++ ++ if (target_auxv_search (current_top_target (), AT_HWCAP2, &field) != 1) ++ return 0; ++ ++ return field; ++} ++ + /* The cached DABR value, to install in new threads. + This variable is used when the PowerPC HWDEBUG ptrace + interface is not available. */ +@@ -2233,6 +2371,7 @@ ppc_linux_nat_target::read_description () + features.wordsize = ppc_linux_target_wordsize (tid); + + CORE_ADDR hwcap = ppc_linux_get_hwcap (); ++ CORE_ADDR hwcap2 = ppc_linux_get_hwcap2 (); + + if (have_ptrace_getsetvsxregs + && (hwcap & PPC_FEATURE_HAS_VSX)) +@@ -2267,6 +2406,11 @@ ppc_linux_nat_target::read_description () + + features.isa205 = ppc_linux_has_isa205 (hwcap); + ++ if ((hwcap2 & PPC_FEATURE2_DSCR) ++ && check_regset (tid, NT_PPC_PPR, PPC_LINUX_SIZEOF_PPRREGSET) ++ && check_regset (tid, NT_PPC_DSCR, PPC_LINUX_SIZEOF_DSCRREGSET)) ++ features.ppr_dscr = true; ++ + return ppc_linux_match_description (features); + } + +diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c +--- a/gdb/ppc-linux-tdep.c ++++ b/gdb/ppc-linux-tdep.c +@@ -71,6 +71,7 @@ + #include "features/rs6000/powerpc-isa205-32l.c" + #include "features/rs6000/powerpc-isa205-altivec32l.c" + #include "features/rs6000/powerpc-isa205-vsx32l.c" ++#include "features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c" + #include "features/rs6000/powerpc-64l.c" + #include "features/rs6000/powerpc-altivec64l.c" + #include "features/rs6000/powerpc-cell64l.c" +@@ -78,6 +79,7 @@ + #include "features/rs6000/powerpc-isa205-64l.c" + #include "features/rs6000/powerpc-isa205-altivec64l.c" + #include "features/rs6000/powerpc-isa205-vsx64l.c" ++#include "features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c" + #include "features/rs6000/powerpc-e500l.c" + + /* Shared library operations for PowerPC-Linux. */ +@@ -547,6 +549,38 @@ static const struct regset ppc32_linux_vsxregset = { + regcache_collect_regset + }; + ++/* Program Priorty Register regmap. */ ++ ++static const struct regcache_map_entry ppc32_regmap_ppr[] = ++ { ++ { 1, PPC_PPR_REGNUM, 8 }, ++ { 0 } ++ }; ++ ++/* Program Priorty Register regset. */ ++ ++const struct regset ppc32_linux_pprregset = { ++ ppc32_regmap_ppr, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ ++/* Data Stream Control Register regmap. */ ++ ++static const struct regcache_map_entry ppc32_regmap_dscr[] = ++ { ++ { 1, PPC_DSCR_REGNUM, 8 }, ++ { 0 } ++ }; ++ ++/* Data Stream Control Register regset. */ ++ ++const struct regset ppc32_linux_dscrregset = { ++ ppc32_regmap_dscr, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ + const struct regset * + ppc_linux_gregset (int wordsize) + { +@@ -585,6 +619,8 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int have_altivec = tdep->ppc_vr0_regnum != -1; + int have_vsx = tdep->ppc_vsr0_upper_regnum != -1; ++ int have_ppr = tdep->ppc_ppr_regnum != -1; ++ int have_dscr = tdep->ppc_dscr_regnum != -1; + + if (tdep->wordsize == 4) + cb (".reg", 48 * 4, 48 * 4, &ppc32_linux_gregset, NULL, cb_data); +@@ -603,6 +639,17 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, + if (have_vsx) + cb (".reg-ppc-vsx", PPC_LINUX_SIZEOF_VSXREGSET, PPC_LINUX_SIZEOF_VSXREGSET, + &ppc32_linux_vsxregset, "POWER7 VSX", cb_data); ++ ++ if (have_ppr) ++ cb (".reg-ppc-ppr", PPC_LINUX_SIZEOF_PPRREGSET, ++ PPC_LINUX_SIZEOF_PPRREGSET, ++ &ppc32_linux_pprregset, "Priority Program Register", cb_data); ++ ++ if (have_dscr) ++ cb (".reg-ppc-dscr", PPC_LINUX_SIZEOF_DSCRREGSET, ++ PPC_LINUX_SIZEOF_DSCRREGSET, ++ &ppc32_linux_dscrregset, "Data Stream Control Register", ++ cb_data); + } + + static void +@@ -1015,6 +1062,8 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, + asection *altivec = bfd_get_section_by_name (abfd, ".reg-ppc-vmx"); + asection *vsx = bfd_get_section_by_name (abfd, ".reg-ppc-vsx"); + asection *section = bfd_get_section_by_name (abfd, ".reg"); ++ asection *ppr = bfd_get_section_by_name (abfd, ".reg-ppc-ppr"); ++ asection *dscr = bfd_get_section_by_name (abfd, ".reg-ppc-dscr"); + + if (! section) + return NULL; +@@ -1047,6 +1096,9 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, + + features.isa205 = ppc_linux_has_isa205 (hwcap); + ++ if (ppr && dscr) ++ features.ppr_dscr = true; ++ + return ppc_linux_match_description (features); + } + +@@ -1920,6 +1972,7 @@ _initialize_ppc_linux_tdep (void) + initialize_tdesc_powerpc_isa205_32l (); + initialize_tdesc_powerpc_isa205_altivec32l (); + initialize_tdesc_powerpc_isa205_vsx32l (); ++ initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l (); + initialize_tdesc_powerpc_64l (); + initialize_tdesc_powerpc_altivec64l (); + initialize_tdesc_powerpc_cell64l (); +@@ -1927,5 +1980,6 @@ _initialize_ppc_linux_tdep (void) + initialize_tdesc_powerpc_isa205_64l (); + initialize_tdesc_powerpc_isa205_altivec64l (); + initialize_tdesc_powerpc_isa205_vsx64l (); ++ initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l (); + initialize_tdesc_powerpc_e500l (); + } +diff --git a/gdb/ppc-linux-tdep.h b/gdb/ppc-linux-tdep.h +--- a/gdb/ppc-linux-tdep.h ++++ b/gdb/ppc-linux-tdep.h +@@ -44,4 +44,8 @@ enum { + /* Return 1 if PPC_ORIG_R3_REGNUM and PPC_TRAP_REGNUM are usable. */ + int ppc_linux_trap_reg_p (struct gdbarch *gdbarch); + ++/* Additional register sets, defined in ppc-linux-tdep.c. */ ++extern const struct regset ppc32_linux_pprregset; ++extern const struct regset ppc32_linux_dscrregset; ++ + #endif /* PPC_LINUX_TDEP_H */ +diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h +--- a/gdb/ppc-tdep.h ++++ b/gdb/ppc-tdep.h +@@ -253,6 +253,12 @@ struct gdbarch_tdep + int ppc_acc_regnum; /* SPE 'acc' register. */ + int ppc_spefscr_regnum; /* SPE 'spefscr' register. */ + ++ /* Program Priority Register. */ ++ int ppc_ppr_regnum; ++ ++ /* Data Stream Control Register. */ ++ int ppc_dscr_regnum; ++ + /* Decimal 128 registers. */ + int ppc_dl0_regnum; /* First Decimal128 argument register pair. */ + +@@ -309,6 +315,8 @@ enum { + PPC_VRSAVE_REGNUM = 139, + PPC_VSR0_UPPER_REGNUM = 140, + PPC_VSR31_UPPER_REGNUM = 171, ++ PPC_PPR_REGNUM = 172, ++ PPC_DSCR_REGNUM = 173, + PPC_NUM_REGS + }; + +diff --git a/gdb/regformats/rs6000/powerpc-isa205-ppr-dscr-vsx32l.dat b/gdb/regformats/rs6000/powerpc-isa205-ppr-dscr-vsx32l.dat +new file mode 100644 +--- /dev/null ++++ b/gdb/regformats/rs6000/powerpc-isa205-ppr-dscr-vsx32l.dat +@@ -0,0 +1,146 @@ ++# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: ++# Generated from: rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml ++name:powerpc_isa205_ppr_dscr_vsx32l ++xmltarget:powerpc-isa205-ppr-dscr-vsx32l.xml ++expedite:r1,pc ++32:r0 ++32:r1 ++32:r2 ++32:r3 ++32:r4 ++32:r5 ++32:r6 ++32:r7 ++32:r8 ++32:r9 ++32:r10 ++32:r11 ++32:r12 ++32:r13 ++32:r14 ++32:r15 ++32:r16 ++32:r17 ++32:r18 ++32:r19 ++32:r20 ++32:r21 ++32:r22 ++32:r23 ++32:r24 ++32:r25 ++32:r26 ++32:r27 ++32:r28 ++32:r29 ++32:r30 ++32:r31 ++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:f16 ++64:f17 ++64:f18 ++64:f19 ++64:f20 ++64:f21 ++64:f22 ++64:f23 ++64:f24 ++64:f25 ++64:f26 ++64:f27 ++64:f28 ++64:f29 ++64:f30 ++64:f31 ++32:pc ++32:msr ++32:cr ++32:lr ++32:ctr ++32:xer ++64:fpscr ++32:orig_r3 ++32:trap ++128:vr0 ++128:vr1 ++128:vr2 ++128:vr3 ++128:vr4 ++128:vr5 ++128:vr6 ++128:vr7 ++128:vr8 ++128:vr9 ++128:vr10 ++128:vr11 ++128:vr12 ++128:vr13 ++128:vr14 ++128:vr15 ++128:vr16 ++128:vr17 ++128:vr18 ++128:vr19 ++128:vr20 ++128:vr21 ++128:vr22 ++128:vr23 ++128:vr24 ++128:vr25 ++128:vr26 ++128:vr27 ++128:vr28 ++128:vr29 ++128:vr30 ++128:vr31 ++32:vscr ++32:vrsave ++64:vs0h ++64:vs1h ++64:vs2h ++64:vs3h ++64:vs4h ++64:vs5h ++64:vs6h ++64:vs7h ++64:vs8h ++64:vs9h ++64:vs10h ++64:vs11h ++64:vs12h ++64:vs13h ++64:vs14h ++64:vs15h ++64:vs16h ++64:vs17h ++64:vs18h ++64:vs19h ++64:vs20h ++64:vs21h ++64:vs22h ++64:vs23h ++64:vs24h ++64:vs25h ++64:vs26h ++64:vs27h ++64:vs28h ++64:vs29h ++64:vs30h ++64:vs31h ++64:ppr ++64:dscr +diff --git a/gdb/regformats/rs6000/powerpc-isa205-ppr-dscr-vsx64l.dat b/gdb/regformats/rs6000/powerpc-isa205-ppr-dscr-vsx64l.dat +new file mode 100644 +--- /dev/null ++++ b/gdb/regformats/rs6000/powerpc-isa205-ppr-dscr-vsx64l.dat +@@ -0,0 +1,146 @@ ++# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: ++# Generated from: rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml ++name:powerpc_isa205_ppr_dscr_vsx64l ++xmltarget:powerpc-isa205-ppr-dscr-vsx64l.xml ++expedite:r1,pc ++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 ++64:r16 ++64:r17 ++64:r18 ++64:r19 ++64:r20 ++64:r21 ++64:r22 ++64:r23 ++64:r24 ++64:r25 ++64:r26 ++64:r27 ++64:r28 ++64:r29 ++64:r30 ++64:r31 ++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:f16 ++64:f17 ++64:f18 ++64:f19 ++64:f20 ++64:f21 ++64:f22 ++64:f23 ++64:f24 ++64:f25 ++64:f26 ++64:f27 ++64:f28 ++64:f29 ++64:f30 ++64:f31 ++64:pc ++64:msr ++32:cr ++64:lr ++64:ctr ++32:xer ++64:fpscr ++64:orig_r3 ++64:trap ++128:vr0 ++128:vr1 ++128:vr2 ++128:vr3 ++128:vr4 ++128:vr5 ++128:vr6 ++128:vr7 ++128:vr8 ++128:vr9 ++128:vr10 ++128:vr11 ++128:vr12 ++128:vr13 ++128:vr14 ++128:vr15 ++128:vr16 ++128:vr17 ++128:vr18 ++128:vr19 ++128:vr20 ++128:vr21 ++128:vr22 ++128:vr23 ++128:vr24 ++128:vr25 ++128:vr26 ++128:vr27 ++128:vr28 ++128:vr29 ++128:vr30 ++128:vr31 ++32:vscr ++32:vrsave ++64:vs0h ++64:vs1h ++64:vs2h ++64:vs3h ++64:vs4h ++64:vs5h ++64:vs6h ++64:vs7h ++64:vs8h ++64:vs9h ++64:vs10h ++64:vs11h ++64:vs12h ++64:vs13h ++64:vs14h ++64:vs15h ++64:vs16h ++64:vs17h ++64:vs18h ++64:vs19h ++64:vs20h ++64:vs21h ++64:vs22h ++64:vs23h ++64:vs24h ++64:vs25h ++64:vs26h ++64:vs27h ++64:vs28h ++64:vs29h ++64:vs30h ++64:vs31h ++64:ppr ++64:dscr +diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c +--- a/gdb/rs6000-tdep.c ++++ b/gdb/rs6000-tdep.c +@@ -4466,6 +4466,17 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, + case 570: /* Count Trailing Zeros Doubleword */ + case 890: /* Extend-Sign Word and Shift Left Immediate (445) */ + case 890 | 1: /* Extend-Sign Word and Shift Left Immediate (445) */ ++ ++ if (ext == 444 && tdep->ppc_ppr_regnum >= 0 ++ && (PPC_RS (insn) == PPC_RA (insn)) ++ && (PPC_RA (insn) == PPC_RB (insn)) ++ && !PPC_RC (insn)) ++ { ++ /* or Rx,Rx,Rx alters PRI in PPR. */ ++ record_full_arch_list_add_reg (regcache, tdep->ppc_ppr_regnum); ++ return 0; ++ } ++ + if (PPC_RC (insn)) + record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum); + record_full_arch_list_add_reg (regcache, +@@ -4675,6 +4686,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, + case 1: /* XER */ + record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum); + return 0; ++ case 3: /* DSCR */ ++ if (tdep->ppc_dscr_regnum >= 0) ++ record_full_arch_list_add_reg (regcache, tdep->ppc_dscr_regnum); ++ return 0; + case 8: /* LR */ + record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum); + return 0; +@@ -4684,6 +4699,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, + case 256: /* VRSAVE */ + record_full_arch_list_add_reg (regcache, tdep->ppc_vrsave_regnum); + return 0; ++ case 896: ++ case 898: /* PPR */ ++ if (tdep->ppc_ppr_regnum >= 0) ++ record_full_arch_list_add_reg (regcache, tdep->ppc_ppr_regnum); ++ return 0; + } + + goto UNKNOWN_OP; +@@ -5846,7 +5866,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global; + enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO; + int have_fpu = 0, have_spe = 0, have_mq = 0, have_altivec = 0; +- int have_dfp = 0, have_vsx = 0; ++ int have_dfp = 0, have_vsx = 0, have_ppr = 0, have_dscr = 0; + int tdesc_wordsize = -1; + const struct target_desc *tdesc = info.target_desc; + struct tdesc_arch_data *tdesc_data = NULL; +@@ -6129,6 +6149,44 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + } + else + have_spe = 0; ++ ++ /* Program Priority Register. */ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.ppr"); ++ if (feature != NULL) ++ { ++ valid_p = 1; ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_PPR_REGNUM, "ppr"); ++ ++ if (!valid_p) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ have_ppr = 1; ++ } ++ else ++ have_ppr = 0; ++ ++ /* Data Stream Control Register. */ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.dscr"); ++ if (feature != NULL) ++ { ++ valid_p = 1; ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_DSCR_REGNUM, "dscr"); ++ ++ if (!valid_p) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ have_dscr = 1; ++ } ++ else ++ have_dscr = 0; + } + + /* If we have a 64-bit binary on a 32-bit target, complain. Also +@@ -6323,6 +6381,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + tdep->ppc_ev0_upper_regnum = have_spe ? PPC_SPE_UPPER_GP0_REGNUM : -1; + tdep->ppc_acc_regnum = have_spe ? PPC_SPE_ACC_REGNUM : -1; + tdep->ppc_spefscr_regnum = have_spe ? PPC_SPE_FSCR_REGNUM : -1; ++ tdep->ppc_ppr_regnum = have_ppr ? PPC_PPR_REGNUM : -1; ++ tdep->ppc_dscr_regnum = have_dscr ? PPC_DSCR_REGNUM : -1; + + set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM); + set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1); +diff --git a/gdb/testsuite/gdb.arch/powerpc-ppr-dscr.c b/gdb/testsuite/gdb.arch/powerpc-ppr-dscr.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/powerpc-ppr-dscr.c +@@ -0,0 +1,34 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright (C) 2018 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 . */ ++ ++int main (void) ++{ ++ /* Set Load Stream Disable bit in DSCR. */ ++ unsigned long dscr = 0x20; ++ ++ /* This is the non-privileged SPR number to access DSCR, ++ available since isa 207. */ ++ asm volatile ("mtspr 3,%0" : : "r" (dscr)); ++ ++ /* Set PPR to low priority (010 in bits 11:13, or ++ 0x0008000000000000). */ ++ asm volatile ("or 1,1,1"); ++ asm volatile ("nop"); // marker ++ asm volatile ("nop"); ++ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.arch/powerpc-ppr-dscr.exp b/gdb/testsuite/gdb.arch/powerpc-ppr-dscr.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/powerpc-ppr-dscr.exp +@@ -0,0 +1,120 @@ ++# Copyright (C) 2018 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 . ++ ++# This file is part of the gdb testsuite. ++ ++# Test access to special purpose registers PPR and DSCR. The test ++# inferior writes to these registers, we check that GDB reads the same ++# values, then write to the registers trough GDB, step once, and check ++# again if we read back the same values. ++ ++if {![istarget "powerpc*-*-linux*"]} then { ++ verbose "Skipping PowerPC test for PPR and DSCR registers." ++ return ++} ++ ++standard_testfile .c ++ ++if {[build_executable "compile" $binfile $srcfile {debug}] == -1} { ++ return ++} ++ ++proc check_register_access { regname } { ++ global gdb_prompt ++ ++ set test "$regname register access" ++ gdb_test_multiple "info reg $regname" "$test" { ++ -re "Invalid register.*\r\n$gdb_prompt $" { ++ unsupported "$test" ++ return 0 ++ } ++ -re "\r\n$regname.*\r\n$gdb_prompt $" { ++ pass "$test" ++ return 1 ++ } ++ } ++ return 0 ++} ++ ++# Do one pass to check if the instructions in our test programs are ++# available to this processor (e.g. mtspr 3, RS for accessing DSCR). ++proc ppr_dscr_available {} { ++ global gdb_prompt ++ global inferior_exited_re ++ ++ set test "PPR/DSCR available to inferior" ++ gdb_test_multiple "continue" "" { ++ -re "Illegal instruction.*\r\n$gdb_prompt $" { ++ unsupported "$test" ++ return 0 ++ } ++ -re "$inferior_exited_re normally.*$gdb_prompt $" { ++ pass "$test" ++ return 1 ++ } ++ } ++ return 0 ++} ++ ++with_test_prefix "check PPR/DSCR access" { ++ clean_restart $binfile ++ ++ if ![runto_main] { ++ return ++ } ++ ++ if {![check_register_access "ppr"]} { ++ return ++ } ++ ++ if {![check_register_access "dscr"]} { ++ return ++ } ++ ++ if {![ppr_dscr_available]} { ++ return ++ } ++} ++ ++# Now do the actual test ++clean_restart $binfile ++ ++if ![runto_main] { ++ return ++} ++ ++gdb_breakpoint [gdb_get_line_number "marker"] ++ ++gdb_continue_to_breakpoint "continue to marker" ++ ++# At the breakpoint the inferior should have set the ++# registers to these expected values. ++ ++with_test_prefix "before write" { ++ gdb_test "info reg dscr" "dscr.*0x0*20\[ \t\]+.*" ++ gdb_test "info reg ppr" "ppr.*0x0*8000000000000\[ \t\]+.*" ++} ++ ++# Set Store Stream Enable in DSCR and set PPR to the medium-low ++# priority. ++gdb_test_no_output "set \$dscr = 0x8" ++gdb_test_no_output "set \$ppr = 0xC000000000000" ++ ++gdb_test "stepi" "asm.*" ++ ++with_test_prefix "after write" { ++ gdb_test "info reg dscr" "dscr.*0x0*8+\[ \t\]+.*" ++ gdb_test "info reg ppr" "ppr.*0x0*\[cC\]000000000000\[ \t\]+.*" ++} diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-11of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-11of15.patch new file mode 100644 index 0000000..4fc4c38 --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-11of15.patch @@ -0,0 +1,1654 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:17 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8-2-11of15.patch + +;; [PowerPC] Add support for TAR +;; Edjunior Barbosa Machado and Pedro Franco de Carvalho + + [PowerPC] Add support for TAR + + This patch adds support for the Target Address Register for powerpc + linux native and core file targets, and in the powerpc linux server + stub. + + gdb/ChangeLog: + 2018-10-26 Edjunior Barbosa Machado + Pedro Franco de Carvalho + + * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa207_vsx32l) + (tdesc_powerpc_isa207_vsx64l): Declare. + * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_TARREGSET): Define. + (struct ppc_linux_features) : New field. + (ppc_linux_no_features): Add initializer for isa207 field. + * arch/ppc-linux-common.c (ppc_linux_match_description): Return + new tdescs. + * nat/ppc-linux.h (PPC_FEATURE2_ARCH_2_07, PPC_FEATURE2_TAR) + (NT_PPC_TAR): Define if not already defined. + * features/Makefile (WHICH): Add rs6000/powerpc-isa207-vsx32l and + rs6000/powerpc-isa207-vsx64l. + (XMLTOC): Add rs6000/powerpc-isa207-vsx32l.xml and + rs6000/powerpc-isa207-vsx64l.xml. + * features/rs6000/power-tar.xml: New file. + * features/rs6000/powerpc-isa207-vsx32l.xml: New file. + * features/rs6000/powerpc-isa207-vsx64l.xml: New file. + * features/rs6000/powerpc-isa207-vsx32l.c: Generate. + * features/rs6000/powerpc-isa207-vsx64l.c: Generate. + * regformats/rs6000/powerpc-isa207-vsx32l.dat: Generate. + * regformats/rs6000/powerpc-isa207-vsx64l.dat: Generate. + * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call + fetch_regset with the TAR regset. + (store_register, store_ppc_registers): Call store_regset with the + TAR regset. + (ppc_linux_nat_target::read_description): Set isa207 field in the + features struct if needed. + * ppc-linux-tdep.c: Include + features/rs6000/powerpc-isa207-vsx32l.c and + features/rs6000/powerpc-isa207-vsx64l.c. + (ppc32_regmap_tar, ppc32_linux_tarregset): New globals. + (ppc_linux_iterate_over_regset_sections): Call back with the tar + regset. + (ppc_linux_core_read_description): Check if the tar section is + present and set isa207 in the features struct. + (_initialize_ppc_linux_tdep): Call + initialize_tdesc_powerpc_isa207_vsx32l and + initialize_tdesc_powerpc_isa207_vsx64l. + * ppc-linux-tdep.h (ppc32_linux_tarregset): Declare. + * ppc-tdep.h (gdbarch_tdep) : New field. + (enum) : New enum value. + * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate tar + feature. + (ppc_process_record_op31): Record changes to TAR. + + gdb/gdbserver/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * configure.srv (ipa_ppc_linux_regobj): Add + powerpc-isa207-vsx64l-ipa.o and powerpc-isa207-vsx32l-ipa.o. + (powerpc*-*-linux*): Add powerpc-isa207-vsx32l.o and + powerpc-isa207-vsx64l.o to srv_regobj, add rs6000/power-tar.xml, + rs6000/powerpc-isa207-vsx32l.xml, and + rs6000/powerpc-isa207-vsx64l.xml to srv_xmlfiles. + * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) + : New enum value. + (init_registers_powerpc_isa207_vsx32l): Declare. + (init_registers_powerpc_isa207_vsx64l): Declare. + * linux-ppc-low.c (ppc_fill_tarregset): New function. + (ppc_store_tarregset): New function. + (ppc_regsets): Add entry for the TAR regset. + (ppc_arch_setup): Set isa207 in features struct when needed. Set + size for the TAR regsets. + (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_VSX. + (initialize_low_arch): Call init_registers_powerpc_isa207_vsx32l + and init_registers_powerpc_isa207_vsx64l. + * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA207_VSX. + (initialize_low_tracepoint): Call + init_registers_powerpc_isa207_vsx32l and + init_registers_powerpc_isa207_vsx64l. + + gdb/testsuite/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * gdb.arch/powerpc-tar.c: New file. + * gdb.arch/powerpc-tar.exp: New file. + + gdb/doc/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * gdb.texinfo (PowerPC Features): Describe new feature + "org.gnu.gdb.power.tar". + +diff --git a/gdb/arch/ppc-linux-common.c b/gdb/arch/ppc-linux-common.c +--- a/gdb/arch/ppc-linux-common.c ++++ b/gdb/arch/ppc-linux-common.c +@@ -53,7 +53,8 @@ ppc_linux_match_description (struct ppc_linux_features features) + if (features.cell) + tdesc = tdesc_powerpc_cell64l; + else if (features.vsx) +- tdesc = (features.ppr_dscr? tdesc_powerpc_isa205_ppr_dscr_vsx64l ++ tdesc = (features.isa207? tdesc_powerpc_isa207_vsx64l ++ : features.ppr_dscr? tdesc_powerpc_isa205_ppr_dscr_vsx64l + : features.isa205? tdesc_powerpc_isa205_vsx64l + : tdesc_powerpc_vsx64l); + else if (features.altivec) +@@ -70,7 +71,8 @@ ppc_linux_match_description (struct ppc_linux_features features) + if (features.cell) + tdesc = tdesc_powerpc_cell32l; + else if (features.vsx) +- tdesc = (features.ppr_dscr? tdesc_powerpc_isa205_ppr_dscr_vsx32l ++ tdesc = (features.isa207? tdesc_powerpc_isa207_vsx32l ++ : features.ppr_dscr? tdesc_powerpc_isa205_ppr_dscr_vsx32l + : features.isa205? tdesc_powerpc_isa205_vsx32l + : tdesc_powerpc_vsx32l); + else if (features.altivec) +diff --git a/gdb/arch/ppc-linux-common.h b/gdb/arch/ppc-linux-common.h +--- a/gdb/arch/ppc-linux-common.h ++++ b/gdb/arch/ppc-linux-common.h +@@ -32,6 +32,7 @@ struct target_desc; + #define PPC_LINUX_SIZEOF_VSXREGSET 256 + #define PPC_LINUX_SIZEOF_PPRREGSET 8 + #define PPC_LINUX_SIZEOF_DSCRREGSET 8 ++#define PPC_LINUX_SIZEOF_TARREGSET 8 + + /* Check if the hwcap auxv entry indicates that isa205 is supported. */ + bool ppc_linux_has_isa205 (CORE_ADDR hwcap); +@@ -44,6 +45,7 @@ struct ppc_linux_features + bool vsx; + bool isa205; + bool ppr_dscr; ++ bool isa207; + bool cell; + }; + +@@ -55,6 +57,7 @@ const struct ppc_linux_features ppc_linux_no_features = { + false, + false, + false, ++ false, + }; + + /* Return a target description that matches FEATURES. */ +diff --git a/gdb/arch/ppc-linux-tdesc.h b/gdb/arch/ppc-linux-tdesc.h +--- a/gdb/arch/ppc-linux-tdesc.h ++++ b/gdb/arch/ppc-linux-tdesc.h +@@ -30,6 +30,7 @@ extern struct target_desc *tdesc_powerpc_isa205_32l; + extern struct target_desc *tdesc_powerpc_isa205_altivec32l; + extern struct target_desc *tdesc_powerpc_isa205_vsx32l; + extern struct target_desc *tdesc_powerpc_isa205_ppr_dscr_vsx32l; ++extern struct target_desc *tdesc_powerpc_isa207_vsx32l; + extern struct target_desc *tdesc_powerpc_e500l; + + extern struct target_desc *tdesc_powerpc_64l; +@@ -40,5 +41,6 @@ extern struct target_desc *tdesc_powerpc_isa205_64l; + extern struct target_desc *tdesc_powerpc_isa205_altivec64l; + extern struct target_desc *tdesc_powerpc_isa205_vsx64l; + extern struct target_desc *tdesc_powerpc_isa205_ppr_dscr_vsx64l; ++extern struct target_desc *tdesc_powerpc_isa207_vsx64l; + + #endif /* ARCH_PPC_LINUX_TDESC_H */ +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -42582,6 +42582,9 @@ contain the 64-bit register @samp{ppr}. + The @samp{org.gnu.gdb.power.dscr} feature is optional. It should + contain the 64-bit register @samp{dscr}. + ++The @samp{org.gnu.gdb.power.tar} feature is optional. It should ++contain the 64-bit register @samp{tar}. ++ + @node S/390 and System z Features + @subsection S/390 and System z Features + @cindex target descriptions, S/390 features +diff --git a/gdb/features/Makefile b/gdb/features/Makefile +--- a/gdb/features/Makefile ++++ b/gdb/features/Makefile +@@ -75,6 +75,7 @@ WHICH = aarch64 \ + rs6000/powerpc-isa205-vsx32l rs6000/powerpc-isa205-vsx64l \ + rs6000/powerpc-isa205-ppr-dscr-vsx32l \ + rs6000/powerpc-isa205-ppr-dscr-vsx64l \ ++ rs6000/powerpc-isa207-vsx32l rs6000/powerpc-isa207-vsx64l \ + s390-linux32 s390-linux64 s390x-linux64 \ + s390-linux32v1 s390-linux64v1 s390x-linux64v1 \ + s390-linux32v2 s390-linux64v2 s390x-linux64v2 \ +@@ -171,6 +172,8 @@ XMLTOC = \ + rs6000/powerpc-isa205-vsx64l.xml \ + rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml \ + rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml \ ++ rs6000/powerpc-isa207-vsx32l.xml \ ++ rs6000/powerpc-isa207-vsx64l.xml \ + rs6000/powerpc-vsx32.xml \ + rs6000/powerpc-vsx32l.xml \ + rs6000/powerpc-vsx64.xml \ +diff --git a/gdb/features/rs6000/power-tar.xml b/gdb/features/rs6000/power-tar.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-tar.xml +@@ -0,0 +1,12 @@ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/powerpc-isa207-vsx32l.c b/gdb/features/rs6000/powerpc-isa207-vsx32l.c +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/powerpc-isa207-vsx32l.c +@@ -0,0 +1,203 @@ ++/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: ++ Original: powerpc-isa207-vsx32l.xml */ ++ ++#include "defs.h" ++#include "osabi.h" ++#include "target-descriptions.h" ++ ++struct target_desc *tdesc_powerpc_isa207_vsx32l; ++static void ++initialize_tdesc_powerpc_isa207_vsx32l (void) ++{ ++ struct target_desc *result = allocate_target_description (); ++ set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); ++ ++ struct tdesc_feature *feature; ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); ++ tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r24", 24, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r25", 25, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r26", 26, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r27", 27, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r28", 28, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "pc", 64, 1, NULL, 32, "code_ptr"); ++ tdesc_create_reg (feature, "msr", 65, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "lr", 67, 1, NULL, 32, "code_ptr"); ++ tdesc_create_reg (feature, "ctr", 68, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu"); ++ tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "fpscr", 70, 1, "float", 64, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux"); ++ tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 32, "int"); ++ tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); ++ tdesc_type *element_type; ++ element_type = tdesc_named_type (feature, "ieee_single"); ++ tdesc_create_vector (feature, "v4f", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int32"); ++ tdesc_create_vector (feature, "v4i32", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int16"); ++ tdesc_create_vector (feature, "v8i16", element_type, 8); ++ ++ element_type = tdesc_named_type (feature, "int8"); ++ tdesc_create_vector (feature, "v16i8", element_type, 16); ++ ++ tdesc_type_with_fields *type_with_fields; ++ type_with_fields = tdesc_create_union (feature, "vec128"); ++ tdesc_type *field_type; ++ field_type = tdesc_named_type (feature, "uint128"); ++ tdesc_add_field (type_with_fields, "uint128", field_type); ++ field_type = tdesc_named_type (feature, "v4f"); ++ tdesc_add_field (type_with_fields, "v4_float", field_type); ++ field_type = tdesc_named_type (feature, "v4i32"); ++ tdesc_add_field (type_with_fields, "v4_int32", field_type); ++ field_type = tdesc_named_type (feature, "v8i16"); ++ tdesc_add_field (type_with_fields, "v8_int16", field_type); ++ field_type = tdesc_named_type (feature, "v16i8"); ++ tdesc_add_field (type_with_fields, "v16_int8", field_type); ++ ++ tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int"); ++ tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.vsx"); ++ tdesc_create_reg (feature, "vs0h", 107, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs1h", 108, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs2h", 109, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs3h", 110, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs4h", 111, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs5h", 112, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs6h", 113, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs7h", 114, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs8h", 115, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs9h", 116, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs10h", 117, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs11h", 118, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs12h", 119, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs13h", 120, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs14h", 121, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs15h", 122, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs16h", 123, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs17h", 124, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs18h", 125, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs19h", 126, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs20h", 127, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs21h", 128, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs22h", 129, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs23h", 130, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs24h", 131, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs25h", 132, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs26h", 133, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs27h", 134, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs28h", 135, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs29h", 136, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs30h", 137, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs31h", 138, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.ppr"); ++ tdesc_create_reg (feature, "ppr", 139, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.dscr"); ++ tdesc_create_reg (feature, "dscr", 140, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar"); ++ tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64"); ++ ++ tdesc_powerpc_isa207_vsx32l = result; ++} +diff --git a/gdb/features/rs6000/powerpc-isa207-vsx32l.xml b/gdb/features/rs6000/powerpc-isa207-vsx32l.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/powerpc-isa207-vsx32l.xml +@@ -0,0 +1,19 @@ ++ ++ ++ ++ ++ ++ powerpc:common ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/powerpc-isa207-vsx64l.c b/gdb/features/rs6000/powerpc-isa207-vsx64l.c +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/powerpc-isa207-vsx64l.c +@@ -0,0 +1,203 @@ ++/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: ++ Original: powerpc-isa207-vsx64l.xml */ ++ ++#include "defs.h" ++#include "osabi.h" ++#include "target-descriptions.h" ++ ++struct target_desc *tdesc_powerpc_isa207_vsx64l; ++static void ++initialize_tdesc_powerpc_isa207_vsx64l (void) ++{ ++ struct target_desc *result = allocate_target_description (); ++ set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); ++ ++ struct tdesc_feature *feature; ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); ++ tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "pc", 64, 1, NULL, 64, "code_ptr"); ++ tdesc_create_reg (feature, "msr", 65, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "lr", 67, 1, NULL, 64, "code_ptr"); ++ tdesc_create_reg (feature, "ctr", 68, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu"); ++ tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "fpscr", 70, 1, "float", 64, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux"); ++ tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 64, "int"); ++ tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); ++ tdesc_type *element_type; ++ element_type = tdesc_named_type (feature, "ieee_single"); ++ tdesc_create_vector (feature, "v4f", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int32"); ++ tdesc_create_vector (feature, "v4i32", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int16"); ++ tdesc_create_vector (feature, "v8i16", element_type, 8); ++ ++ element_type = tdesc_named_type (feature, "int8"); ++ tdesc_create_vector (feature, "v16i8", element_type, 16); ++ ++ tdesc_type_with_fields *type_with_fields; ++ type_with_fields = tdesc_create_union (feature, "vec128"); ++ tdesc_type *field_type; ++ field_type = tdesc_named_type (feature, "uint128"); ++ tdesc_add_field (type_with_fields, "uint128", field_type); ++ field_type = tdesc_named_type (feature, "v4f"); ++ tdesc_add_field (type_with_fields, "v4_float", field_type); ++ field_type = tdesc_named_type (feature, "v4i32"); ++ tdesc_add_field (type_with_fields, "v4_int32", field_type); ++ field_type = tdesc_named_type (feature, "v8i16"); ++ tdesc_add_field (type_with_fields, "v8_int16", field_type); ++ field_type = tdesc_named_type (feature, "v16i8"); ++ tdesc_add_field (type_with_fields, "v16_int8", field_type); ++ ++ tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int"); ++ tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.vsx"); ++ tdesc_create_reg (feature, "vs0h", 107, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs1h", 108, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs2h", 109, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs3h", 110, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs4h", 111, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs5h", 112, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs6h", 113, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs7h", 114, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs8h", 115, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs9h", 116, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs10h", 117, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs11h", 118, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs12h", 119, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs13h", 120, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs14h", 121, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs15h", 122, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs16h", 123, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs17h", 124, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs18h", 125, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs19h", 126, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs20h", 127, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs21h", 128, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs22h", 129, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs23h", 130, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs24h", 131, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs25h", 132, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs26h", 133, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs27h", 134, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs28h", 135, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs29h", 136, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs30h", 137, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs31h", 138, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.ppr"); ++ tdesc_create_reg (feature, "ppr", 139, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.dscr"); ++ tdesc_create_reg (feature, "dscr", 140, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar"); ++ tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64"); ++ ++ tdesc_powerpc_isa207_vsx64l = result; ++} +diff --git a/gdb/features/rs6000/powerpc-isa207-vsx64l.xml b/gdb/features/rs6000/powerpc-isa207-vsx64l.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/powerpc-isa207-vsx64l.xml +@@ -0,0 +1,19 @@ ++ ++ ++ ++ ++ ++ powerpc:common64 ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv +--- a/gdb/gdbserver/configure.srv ++++ b/gdb/gdbserver/configure.srv +@@ -32,7 +32,7 @@ else + srv_amd64_linux_regobj="" + fi + +-ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-isa205-ppr-dscr-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o powerpc-isa205-ppr-dscr-vsx64l-ipa.o" ++ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-isa205-ppr-dscr-vsx32l-ipa.o powerpc-isa207-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o powerpc-isa205-ppr-dscr-vsx64l-ipa.o powerpc-isa207-vsx64l-ipa.o" + + # Linux object files. This is so we don't have to repeat + # these files over and over again. +@@ -218,6 +218,7 @@ case "${target}" in + srv_regobj="${srv_regobj} powerpc-isa205-altivec32l.o" + srv_regobj="${srv_regobj} powerpc-isa205-vsx32l.o" + srv_regobj="${srv_regobj} powerpc-isa205-ppr-dscr-vsx32l.o" ++ srv_regobj="${srv_regobj} powerpc-isa207-vsx32l.o" + srv_regobj="${srv_regobj} powerpc-e500l.o" + srv_regobj="${srv_regobj} powerpc-64l.o" + srv_regobj="${srv_regobj} powerpc-altivec64l.o" +@@ -227,6 +228,7 @@ case "${target}" in + srv_regobj="${srv_regobj} powerpc-isa205-altivec64l.o" + srv_regobj="${srv_regobj} powerpc-isa205-vsx64l.o" + srv_regobj="${srv_regobj} powerpc-isa205-ppr-dscr-vsx64l.o" ++ srv_regobj="${srv_regobj} powerpc-isa207-vsx64l.o" + srv_tgtobj="$srv_linux_obj linux-ppc-low.o ppc-linux.o" + srv_tgtobj="${srv_tgtobj} arch/ppc-linux-common.o" + srv_xmlfiles="rs6000/powerpc-32l.xml" +@@ -237,6 +239,7 @@ case "${target}" in + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-altivec32l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-vsx32l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-vsx32l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-altivec.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-vsx.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-core.xml" +@@ -245,6 +248,7 @@ case "${target}" in + srv_xmlfiles="${srv_xmlfiles} rs6000/power-fpu-isa205.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-dscr.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-ppr.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-tar.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-e500l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-spe.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-64l.xml" +@@ -255,6 +259,7 @@ case "${target}" in + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-altivec64l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-vsx64l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-vsx64l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power64-core.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power64-linux.xml" + srv_linux_usrregs=yes +diff --git a/gdb/gdbserver/linux-ppc-ipa.c b/gdb/gdbserver/linux-ppc-ipa.c +--- a/gdb/gdbserver/linux-ppc-ipa.c ++++ b/gdb/gdbserver/linux-ppc-ipa.c +@@ -193,6 +193,8 @@ get_ipa_tdesc (int idx) + return tdesc_powerpc_isa205_vsx64l; + case PPC_TDESC_ISA205_PPR_DSCR_VSX: + return tdesc_powerpc_isa205_ppr_dscr_vsx64l; ++ case PPC_TDESC_ISA207_VSX: ++ return tdesc_powerpc_isa207_vsx64l; + #else + case PPC_TDESC_BASE: + return tdesc_powerpc_32l; +@@ -210,6 +212,8 @@ get_ipa_tdesc (int idx) + return tdesc_powerpc_isa205_vsx32l; + case PPC_TDESC_ISA205_PPR_DSCR_VSX: + return tdesc_powerpc_isa205_ppr_dscr_vsx32l; ++ case PPC_TDESC_ISA207_VSX: ++ return tdesc_powerpc_isa207_vsx32l; + case PPC_TDESC_E500: + return tdesc_powerpc_e500l; + #endif +@@ -239,6 +243,7 @@ initialize_low_tracepoint (void) + init_registers_powerpc_isa205_altivec64l (); + init_registers_powerpc_isa205_vsx64l (); + init_registers_powerpc_isa205_ppr_dscr_vsx64l (); ++ init_registers_powerpc_isa207_vsx64l (); + #else + init_registers_powerpc_32l (); + init_registers_powerpc_altivec32l (); +@@ -248,6 +253,7 @@ initialize_low_tracepoint (void) + init_registers_powerpc_isa205_altivec32l (); + init_registers_powerpc_isa205_vsx32l (); + init_registers_powerpc_isa205_ppr_dscr_vsx32l (); ++ init_registers_powerpc_isa207_vsx32l (); + init_registers_powerpc_e500l (); + #endif + } +diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c +--- a/gdb/gdbserver/linux-ppc-low.c ++++ b/gdb/gdbserver/linux-ppc-low.c +@@ -525,6 +525,26 @@ ppc_store_dscrregset (struct regcache *regcache, const void *buf) + supply_register_by_name (regcache, "dscr", dscr); + } + ++/* Target Address Register regset fill function. */ ++ ++static void ++ppc_fill_tarregset (struct regcache *regcache, void *buf) ++{ ++ char *tar = (char *) buf; ++ ++ collect_register_by_name (regcache, "tar", tar); ++} ++ ++/* Target Address Register regset store function. */ ++ ++static void ++ppc_store_tarregset (struct regcache *regcache, const void *buf) ++{ ++ const char *tar = (const char *) buf; ++ ++ supply_register_by_name (regcache, "tar", tar); ++} ++ + static void + ppc_fill_vsxregset (struct regcache *regcache, void *buf) + { +@@ -634,6 +654,8 @@ static struct regset_info ppc_regsets[] = { + fetch them every time, but still fall back to PTRACE_PEEKUSER for the + general registers. Some kernels support these, but not the newer + PPC_PTRACE_GETREGS. */ ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TAR, 0, EXTENDED_REGS, ++ ppc_fill_tarregset, ppc_store_tarregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PPR, 0, EXTENDED_REGS, + ppc_fill_pprregset, ppc_store_pprregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_DSCR, 0, EXTENDED_REGS, +@@ -708,7 +730,14 @@ ppc_arch_setup (void) + if ((ppc_hwcap2 & PPC_FEATURE2_DSCR) + && ppc_check_regset (tid, NT_PPC_DSCR, PPC_LINUX_SIZEOF_DSCRREGSET) + && ppc_check_regset (tid, NT_PPC_PPR, PPC_LINUX_SIZEOF_PPRREGSET)) +- features.ppr_dscr = true; ++ { ++ features.ppr_dscr = true; ++ if ((ppc_hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ && (ppc_hwcap2 & PPC_FEATURE2_TAR) ++ && ppc_check_regset (tid, NT_PPC_TAR, ++ PPC_LINUX_SIZEOF_TARREGSET)) ++ features.isa207 = true; ++ } + + if (ppc_hwcap & PPC_FEATURE_CELL) + features.cell = true; +@@ -765,6 +794,10 @@ ppc_arch_setup (void) + regset->size = (features.ppr_dscr ? + PPC_LINUX_SIZEOF_DSCRREGSET : 0); + break; ++ case NT_PPC_TAR: ++ regset->size = (features.isa207 ? ++ PPC_LINUX_SIZEOF_TARREGSET : 0); ++ break; + default: + break; + } +@@ -3146,6 +3179,8 @@ ppc_get_ipa_tdesc_idx (void) + return PPC_TDESC_ISA205_VSX; + if (tdesc == tdesc_powerpc_isa205_ppr_dscr_vsx64l) + return PPC_TDESC_ISA205_PPR_DSCR_VSX; ++ if (tdesc == tdesc_powerpc_isa207_vsx64l) ++ return PPC_TDESC_ISA207_VSX; + #endif + + if (tdesc == tdesc_powerpc_32l) +@@ -3164,6 +3199,8 @@ ppc_get_ipa_tdesc_idx (void) + return PPC_TDESC_ISA205_VSX; + if (tdesc == tdesc_powerpc_isa205_ppr_dscr_vsx32l) + return PPC_TDESC_ISA205_PPR_DSCR_VSX; ++ if (tdesc == tdesc_powerpc_isa207_vsx32l) ++ return PPC_TDESC_ISA207_VSX; + if (tdesc == tdesc_powerpc_e500l) + return PPC_TDESC_E500; + +@@ -3223,6 +3260,7 @@ initialize_low_arch (void) + init_registers_powerpc_isa205_altivec32l (); + init_registers_powerpc_isa205_vsx32l (); + init_registers_powerpc_isa205_ppr_dscr_vsx32l (); ++ init_registers_powerpc_isa207_vsx32l (); + init_registers_powerpc_e500l (); + #if __powerpc64__ + init_registers_powerpc_64l (); +@@ -3233,6 +3271,7 @@ initialize_low_arch (void) + init_registers_powerpc_isa205_altivec64l (); + init_registers_powerpc_isa205_vsx64l (); + init_registers_powerpc_isa205_ppr_dscr_vsx64l (); ++ init_registers_powerpc_isa207_vsx64l (); + #endif + + initialize_regsets_info (&ppc_regsets_info); +diff --git a/gdb/gdbserver/linux-ppc-tdesc-init.h b/gdb/gdbserver/linux-ppc-tdesc-init.h +--- a/gdb/gdbserver/linux-ppc-tdesc-init.h ++++ b/gdb/gdbserver/linux-ppc-tdesc-init.h +@@ -30,6 +30,7 @@ enum ppc_linux_tdesc { + PPC_TDESC_ISA205_ALTIVEC, + PPC_TDESC_ISA205_VSX, + PPC_TDESC_ISA205_PPR_DSCR_VSX, ++ PPC_TDESC_ISA207_VSX, + PPC_TDESC_E500, + }; + +@@ -59,6 +60,9 @@ void init_registers_powerpc_isa205_vsx32l (void); + /* Defined in auto-generated file powerpc-isa205-ppr-dscr-vsx32l.c. */ + void init_registers_powerpc_isa205_ppr_dscr_vsx32l (void); + ++/* Defined in auto-generated file powerpc-isa207-vsx32l.c. */ ++void init_registers_powerpc_isa207_vsx32l (void); ++ + /* Defined in auto-generated file powerpc-e500l.c. */ + void init_registers_powerpc_e500l (void); + +@@ -90,4 +94,7 @@ void init_registers_powerpc_isa205_vsx64l (void); + /* Defined in auto-generated file powerpc-isa205-ppr-dscr-vsx64l.c. */ + void init_registers_powerpc_isa205_ppr_dscr_vsx64l (void); + ++/* Defined in auto-generated file powerpc-isa207-vsx64l.c. */ ++void init_registers_powerpc_isa207_vsx64l (void); ++ + #endif +diff --git a/gdb/nat/ppc-linux.h b/gdb/nat/ppc-linux.h +--- a/gdb/nat/ppc-linux.h ++++ b/gdb/nat/ppc-linux.h +@@ -54,6 +54,12 @@ + #ifndef PPC_FEATURE2_DSCR + #define PPC_FEATURE2_DSCR 0x20000000 + #endif ++#ifndef PPC_FEATURE2_ARCH_2_07 ++#define PPC_FEATURE2_ARCH_2_07 0x80000000 ++#endif ++#ifndef PPC_FEATURE2_TAR ++#define PPC_FEATURE2_TAR 0x04000000 ++#endif + + /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a + configure time check. Some older glibc's (for instance 2.2.1) +@@ -85,6 +91,11 @@ + #define PTRACE_SETEVRREGS 21 + #endif + ++/* Target Address Register. */ ++#ifndef NT_PPC_TAR ++#define NT_PPC_TAR 0x103 ++#endif ++ + /* Program Priority Register. */ + #ifndef NT_PPC_PPR + #define NT_PPC_PPR 0x104 +diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c +--- a/gdb/ppc-linux-nat.c ++++ b/gdb/ppc-linux-nat.c +@@ -658,6 +658,15 @@ fetch_register (struct regcache *regcache, int tid, int regno) + &ppc32_linux_pprregset); + return; + } ++ else if (regno == PPC_TAR_REGNUM) ++ { ++ gdb_assert (tdep->ppc_tar_regnum != -1); ++ ++ fetch_regset (regcache, tid, NT_PPC_TAR, ++ PPC_LINUX_SIZEOF_TARREGSET, ++ &ppc32_linux_tarregset); ++ return; ++ } + + if (regaddr == -1) + { +@@ -862,6 +871,10 @@ fetch_ppc_registers (struct regcache *regcache, int tid) + fetch_regset (regcache, tid, NT_PPC_DSCR, + PPC_LINUX_SIZEOF_DSCRREGSET, + &ppc32_linux_dscrregset); ++ if (tdep->ppc_tar_regnum != -1) ++ fetch_regset (regcache, tid, NT_PPC_TAR, ++ PPC_LINUX_SIZEOF_TARREGSET, ++ &ppc32_linux_tarregset); + } + + /* Fetch registers from the child process. Fetch all registers if +@@ -1060,6 +1073,15 @@ store_register (const struct regcache *regcache, int tid, int regno) + &ppc32_linux_pprregset); + return; + } ++ else if (regno == PPC_TAR_REGNUM) ++ { ++ gdb_assert (tdep->ppc_tar_regnum != -1); ++ ++ store_regset (regcache, tid, regno, NT_PPC_TAR, ++ PPC_LINUX_SIZEOF_TARREGSET, ++ &ppc32_linux_tarregset); ++ return; ++ } + + if (regaddr == -1) + return; +@@ -1282,6 +1304,10 @@ store_ppc_registers (const struct regcache *regcache, int tid) + store_regset (regcache, tid, -1, NT_PPC_DSCR, + PPC_LINUX_SIZEOF_DSCRREGSET, + &ppc32_linux_dscrregset); ++ if (tdep->ppc_tar_regnum != -1) ++ store_regset (regcache, tid, -1, NT_PPC_TAR, ++ PPC_LINUX_SIZEOF_TARREGSET, ++ &ppc32_linux_tarregset); + } + + /* Fetch the AT_HWCAP entry from the aux vector. */ +@@ -2409,7 +2435,13 @@ ppc_linux_nat_target::read_description () + if ((hwcap2 & PPC_FEATURE2_DSCR) + && check_regset (tid, NT_PPC_PPR, PPC_LINUX_SIZEOF_PPRREGSET) + && check_regset (tid, NT_PPC_DSCR, PPC_LINUX_SIZEOF_DSCRREGSET)) +- features.ppr_dscr = true; ++ { ++ features.ppr_dscr = true; ++ if ((hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ && (hwcap2 & PPC_FEATURE2_TAR) ++ && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET)) ++ features.isa207 = true; ++ } + + return ppc_linux_match_description (features); + } +diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c +--- a/gdb/ppc-linux-tdep.c ++++ b/gdb/ppc-linux-tdep.c +@@ -72,6 +72,7 @@ + #include "features/rs6000/powerpc-isa205-altivec32l.c" + #include "features/rs6000/powerpc-isa205-vsx32l.c" + #include "features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c" ++#include "features/rs6000/powerpc-isa207-vsx32l.c" + #include "features/rs6000/powerpc-64l.c" + #include "features/rs6000/powerpc-altivec64l.c" + #include "features/rs6000/powerpc-cell64l.c" +@@ -80,6 +81,7 @@ + #include "features/rs6000/powerpc-isa205-altivec64l.c" + #include "features/rs6000/powerpc-isa205-vsx64l.c" + #include "features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c" ++#include "features/rs6000/powerpc-isa207-vsx64l.c" + #include "features/rs6000/powerpc-e500l.c" + + /* Shared library operations for PowerPC-Linux. */ +@@ -581,6 +583,22 @@ const struct regset ppc32_linux_dscrregset = { + regcache_collect_regset + }; + ++/* Target Address Register regmap. */ ++ ++static const struct regcache_map_entry ppc32_regmap_tar[] = ++ { ++ { 1, PPC_TAR_REGNUM, 8 }, ++ { 0 } ++ }; ++ ++/* Target Address Register regset. */ ++ ++const struct regset ppc32_linux_tarregset = { ++ ppc32_regmap_tar, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ + const struct regset * + ppc_linux_gregset (int wordsize) + { +@@ -621,6 +639,7 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, + int have_vsx = tdep->ppc_vsr0_upper_regnum != -1; + int have_ppr = tdep->ppc_ppr_regnum != -1; + int have_dscr = tdep->ppc_dscr_regnum != -1; ++ int have_tar = tdep->ppc_tar_regnum != -1; + + if (tdep->wordsize == 4) + cb (".reg", 48 * 4, 48 * 4, &ppc32_linux_gregset, NULL, cb_data); +@@ -650,6 +669,11 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, + PPC_LINUX_SIZEOF_DSCRREGSET, + &ppc32_linux_dscrregset, "Data Stream Control Register", + cb_data); ++ ++ if (have_tar) ++ cb (".reg-ppc-tar", PPC_LINUX_SIZEOF_TARREGSET, ++ PPC_LINUX_SIZEOF_TARREGSET, ++ &ppc32_linux_tarregset, "Target Address Register", cb_data); + } + + static void +@@ -1064,6 +1088,7 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, + asection *section = bfd_get_section_by_name (abfd, ".reg"); + asection *ppr = bfd_get_section_by_name (abfd, ".reg-ppc-ppr"); + asection *dscr = bfd_get_section_by_name (abfd, ".reg-ppc-dscr"); ++ asection *tar = bfd_get_section_by_name (abfd, ".reg-ppc-tar"); + + if (! section) + return NULL; +@@ -1097,7 +1122,11 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, + features.isa205 = ppc_linux_has_isa205 (hwcap); + + if (ppr && dscr) +- features.ppr_dscr = true; ++ { ++ features.ppr_dscr = true; ++ if (tar) ++ features.isa207 = true; ++ } + + return ppc_linux_match_description (features); + } +@@ -1973,6 +2002,7 @@ _initialize_ppc_linux_tdep (void) + initialize_tdesc_powerpc_isa205_altivec32l (); + initialize_tdesc_powerpc_isa205_vsx32l (); + initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l (); ++ initialize_tdesc_powerpc_isa207_vsx32l (); + initialize_tdesc_powerpc_64l (); + initialize_tdesc_powerpc_altivec64l (); + initialize_tdesc_powerpc_cell64l (); +@@ -1981,5 +2011,6 @@ _initialize_ppc_linux_tdep (void) + initialize_tdesc_powerpc_isa205_altivec64l (); + initialize_tdesc_powerpc_isa205_vsx64l (); + initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l (); ++ initialize_tdesc_powerpc_isa207_vsx64l (); + initialize_tdesc_powerpc_e500l (); + } +diff --git a/gdb/ppc-linux-tdep.h b/gdb/ppc-linux-tdep.h +--- a/gdb/ppc-linux-tdep.h ++++ b/gdb/ppc-linux-tdep.h +@@ -47,5 +47,6 @@ int ppc_linux_trap_reg_p (struct gdbarch *gdbarch); + /* Additional register sets, defined in ppc-linux-tdep.c. */ + extern const struct regset ppc32_linux_pprregset; + extern const struct regset ppc32_linux_dscrregset; ++extern const struct regset ppc32_linux_tarregset; + + #endif /* PPC_LINUX_TDEP_H */ +diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h +--- a/gdb/ppc-tdep.h ++++ b/gdb/ppc-tdep.h +@@ -259,6 +259,9 @@ struct gdbarch_tdep + /* Data Stream Control Register. */ + int ppc_dscr_regnum; + ++ /* Target Address Register. */ ++ int ppc_tar_regnum; ++ + /* Decimal 128 registers. */ + int ppc_dl0_regnum; /* First Decimal128 argument register pair. */ + +@@ -317,6 +320,7 @@ enum { + PPC_VSR31_UPPER_REGNUM = 171, + PPC_PPR_REGNUM = 172, + PPC_DSCR_REGNUM = 173, ++ PPC_TAR_REGNUM = 174, + PPC_NUM_REGS + }; + +diff --git a/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat b/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat +new file mode 100644 +--- /dev/null ++++ b/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat +@@ -0,0 +1,147 @@ ++# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: ++# Generated from: rs6000/powerpc-isa207-vsx32l.xml ++name:powerpc_isa207_vsx32l ++xmltarget:powerpc-isa207-vsx32l.xml ++expedite:r1,pc ++32:r0 ++32:r1 ++32:r2 ++32:r3 ++32:r4 ++32:r5 ++32:r6 ++32:r7 ++32:r8 ++32:r9 ++32:r10 ++32:r11 ++32:r12 ++32:r13 ++32:r14 ++32:r15 ++32:r16 ++32:r17 ++32:r18 ++32:r19 ++32:r20 ++32:r21 ++32:r22 ++32:r23 ++32:r24 ++32:r25 ++32:r26 ++32:r27 ++32:r28 ++32:r29 ++32:r30 ++32:r31 ++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:f16 ++64:f17 ++64:f18 ++64:f19 ++64:f20 ++64:f21 ++64:f22 ++64:f23 ++64:f24 ++64:f25 ++64:f26 ++64:f27 ++64:f28 ++64:f29 ++64:f30 ++64:f31 ++32:pc ++32:msr ++32:cr ++32:lr ++32:ctr ++32:xer ++64:fpscr ++32:orig_r3 ++32:trap ++128:vr0 ++128:vr1 ++128:vr2 ++128:vr3 ++128:vr4 ++128:vr5 ++128:vr6 ++128:vr7 ++128:vr8 ++128:vr9 ++128:vr10 ++128:vr11 ++128:vr12 ++128:vr13 ++128:vr14 ++128:vr15 ++128:vr16 ++128:vr17 ++128:vr18 ++128:vr19 ++128:vr20 ++128:vr21 ++128:vr22 ++128:vr23 ++128:vr24 ++128:vr25 ++128:vr26 ++128:vr27 ++128:vr28 ++128:vr29 ++128:vr30 ++128:vr31 ++32:vscr ++32:vrsave ++64:vs0h ++64:vs1h ++64:vs2h ++64:vs3h ++64:vs4h ++64:vs5h ++64:vs6h ++64:vs7h ++64:vs8h ++64:vs9h ++64:vs10h ++64:vs11h ++64:vs12h ++64:vs13h ++64:vs14h ++64:vs15h ++64:vs16h ++64:vs17h ++64:vs18h ++64:vs19h ++64:vs20h ++64:vs21h ++64:vs22h ++64:vs23h ++64:vs24h ++64:vs25h ++64:vs26h ++64:vs27h ++64:vs28h ++64:vs29h ++64:vs30h ++64:vs31h ++64:ppr ++64:dscr ++64:tar +diff --git a/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat b/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat +new file mode 100644 +--- /dev/null ++++ b/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat +@@ -0,0 +1,147 @@ ++# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: ++# Generated from: rs6000/powerpc-isa207-vsx64l.xml ++name:powerpc_isa207_vsx64l ++xmltarget:powerpc-isa207-vsx64l.xml ++expedite:r1,pc ++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 ++64:r16 ++64:r17 ++64:r18 ++64:r19 ++64:r20 ++64:r21 ++64:r22 ++64:r23 ++64:r24 ++64:r25 ++64:r26 ++64:r27 ++64:r28 ++64:r29 ++64:r30 ++64:r31 ++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:f16 ++64:f17 ++64:f18 ++64:f19 ++64:f20 ++64:f21 ++64:f22 ++64:f23 ++64:f24 ++64:f25 ++64:f26 ++64:f27 ++64:f28 ++64:f29 ++64:f30 ++64:f31 ++64:pc ++64:msr ++32:cr ++64:lr ++64:ctr ++32:xer ++64:fpscr ++64:orig_r3 ++64:trap ++128:vr0 ++128:vr1 ++128:vr2 ++128:vr3 ++128:vr4 ++128:vr5 ++128:vr6 ++128:vr7 ++128:vr8 ++128:vr9 ++128:vr10 ++128:vr11 ++128:vr12 ++128:vr13 ++128:vr14 ++128:vr15 ++128:vr16 ++128:vr17 ++128:vr18 ++128:vr19 ++128:vr20 ++128:vr21 ++128:vr22 ++128:vr23 ++128:vr24 ++128:vr25 ++128:vr26 ++128:vr27 ++128:vr28 ++128:vr29 ++128:vr30 ++128:vr31 ++32:vscr ++32:vrsave ++64:vs0h ++64:vs1h ++64:vs2h ++64:vs3h ++64:vs4h ++64:vs5h ++64:vs6h ++64:vs7h ++64:vs8h ++64:vs9h ++64:vs10h ++64:vs11h ++64:vs12h ++64:vs13h ++64:vs14h ++64:vs15h ++64:vs16h ++64:vs17h ++64:vs18h ++64:vs19h ++64:vs20h ++64:vs21h ++64:vs22h ++64:vs23h ++64:vs24h ++64:vs25h ++64:vs26h ++64:vs27h ++64:vs28h ++64:vs29h ++64:vs30h ++64:vs31h ++64:ppr ++64:dscr ++64:tar +diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c +--- a/gdb/rs6000-tdep.c ++++ b/gdb/rs6000-tdep.c +@@ -4699,6 +4699,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache, + case 256: /* VRSAVE */ + record_full_arch_list_add_reg (regcache, tdep->ppc_vrsave_regnum); + return 0; ++ case 815: /* TAR */ ++ if (tdep->ppc_tar_regnum >= 0) ++ record_full_arch_list_add_reg (regcache, tdep->ppc_tar_regnum); ++ return 0; + case 896: + case 898: /* PPR */ + if (tdep->ppc_ppr_regnum >= 0) +@@ -5867,6 +5871,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO; + int have_fpu = 0, have_spe = 0, have_mq = 0, have_altivec = 0; + int have_dfp = 0, have_vsx = 0, have_ppr = 0, have_dscr = 0; ++ int have_tar = 0; + int tdesc_wordsize = -1; + const struct target_desc *tdesc = info.target_desc; + struct tdesc_arch_data *tdesc_data = NULL; +@@ -6187,6 +6192,25 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + } + else + have_dscr = 0; ++ ++ /* Target Address Register. */ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.tar"); ++ if (feature != NULL) ++ { ++ valid_p = 1; ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_TAR_REGNUM, "tar"); ++ ++ if (!valid_p) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ have_tar = 1; ++ } ++ else ++ have_tar = 0; + } + + /* If we have a 64-bit binary on a 32-bit target, complain. Also +@@ -6383,6 +6407,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + tdep->ppc_spefscr_regnum = have_spe ? PPC_SPE_FSCR_REGNUM : -1; + tdep->ppc_ppr_regnum = have_ppr ? PPC_PPR_REGNUM : -1; + tdep->ppc_dscr_regnum = have_dscr ? PPC_DSCR_REGNUM : -1; ++ tdep->ppc_tar_regnum = have_tar ? PPC_TAR_REGNUM : -1; + + set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM); + set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1); +diff --git a/gdb/testsuite/gdb.arch/powerpc-tar.c b/gdb/testsuite/gdb.arch/powerpc-tar.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/powerpc-tar.c +@@ -0,0 +1,33 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright (C) 2018 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 . */ ++ ++int main (void) ++{ ++ void * target1 = &&target1_l; ++ void * target2 = &&target2_l; ++ asm volatile ("mtspr 815,%0" : : "r" (target1) : ); ++ ++ /* Branch always to TAR. */ ++ asm volatile ("bctar 20,0,0"); // marker ++ ++ target2_l: ++ asm volatile ("nop"); // marker 2 ++ target1_l: ++ asm volatile ("nop"); ++ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.arch/powerpc-tar.exp b/gdb/testsuite/gdb.arch/powerpc-tar.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/powerpc-tar.exp +@@ -0,0 +1,122 @@ ++# Copyright (C) 2018 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 . ++ ++# This file is part of the gdb testsuite. ++ ++# Test access to special purpose register TAR (the Target Address ++# Register). The test inferior writes to this register, we check that ++# GDB reads the same value, then write to the register the address of ++# another label. We then let the inferior continue and execute a ++# branch to TAR and check that we stop at the address that we wrote to ++# register. ++ ++if {![istarget "powerpc*-*-linux*"]} then { ++ verbose "Skipping PowerPC test for the TAR register." ++ return ++} ++ ++standard_testfile .c ++ ++if {[build_executable "compile" $binfile $srcfile {debug}] == -1} { ++ return -1 ++} ++ ++proc check_register_access { regname } { ++ global gdb_prompt ++ ++ set test "$regname register access" ++ gdb_test_multiple "info reg $regname" "$test" { ++ -re "Invalid register.*\r\n$gdb_prompt $" { ++ unsupported "$test" ++ return 0 ++ } ++ -re "\r\n$regname.*\r\n$gdb_prompt $" { ++ pass "$test" ++ return 1 ++ } ++ } ++ return 0 ++} ++ ++proc tar_available {} { ++ global gdb_prompt ++ global inferior_exited_re ++ ++ set test "TAR available to inferior" ++ gdb_test_multiple "continue" "" { ++ -re "Illegal instruction.*\r\n$gdb_prompt $" { ++ unsupported "$test" ++ return 0 ++ } ++ -re "$inferior_exited_re normally.*$gdb_prompt $" { ++ pass "$test" ++ return 1 ++ } ++ } ++ return 0 ++} ++ ++# Do one pass to check if TAR is usable, system ++# software can prevent it from being used. ++with_test_prefix "check TAR access" { ++ clean_restart $binfile ++ ++ if ![runto_main] { ++ return ++ } ++ ++ if {![check_register_access "tar"]} { ++ return ++ } ++ ++ if {![tar_available]} { ++ return ++ } ++} ++ ++# Now do the actual test ++clean_restart $binfile ++ ++if ![runto_main] { ++ return ++} ++ ++gdb_breakpoint [gdb_get_line_number "marker"] ++ ++gdb_continue_to_breakpoint "continue to marker" ++ ++set target1 [get_hexadecimal_valueof "target1" -1] ++set tar [get_hexadecimal_valueof "\$tar" -2] ++ ++set test "TAR value from mtspr" ++ ++if {${target1} == ${tar}} { ++ pass $test ++} else { ++ fail $test ++} ++ ++set target2 [get_hexadecimal_valueof "target2" -1] ++ ++if {$target2 == -1} { ++ fail "Could not get value of target2" ++ return ++} ++ ++gdb_test_no_output "set \$tar = $target2" "set tar" ++ ++gdb_breakpoint [gdb_get_line_number "marker 2"] ++ ++gdb_continue_to_breakpoint "continue to new target address" ".*marker 2.*" diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-12of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-12of15.patch new file mode 100644 index 0000000..efe455b --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-12of15.patch @@ -0,0 +1,779 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:17 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8-2-12of15.patch + +;; [PowerPC] Add support for EBB and PMU registers +;; Edjunior Barbosa Machado and Pedro Franco de Carvalho + + [PowerPC] Add support for EBB and PMU registers + + This patch adds support for registers of the Event Based Branching and + Performance Monitoring Units for the powerpc linux native and core + file targets, and for the powerpc linux server stub. + + All three EBB registers are accessible. Only a subset of the PMU + registers can be accessed through ptrace. Because of this, the PMU + registers are enumerated individually in gdbarch_tdep, as opposed to + having a single "have_pmu" flag. This is intended to make it easier + to add additional PMU registers in the future, since checking a + "have_pmu" flag elsewhere in the code would no longer be correct. The + tdesc feature is named org.gnu.gdb.power.linux.pmu because of this. + + It's unclear if it makes sense to save and restore these registers + across function calls, since some of them can be modified + asynchronously. They are also not tracked in record-replay mode. + + The kernel can return ENODATA when ptrace is used to get the EBB + registers, unless a linux performance event that uses EBB is open in + the inferior. For this reason, the "fill" functions in the server + stub for the ebb register sets is not implemented. + + Since gdbserver writes all registers in one go before resuming the + inferior, this error would not be detected at the time the user tries + to write to one of the registers on the client side, and gdbserver + would print out warnings every time it resumes the inferior when no + ebb performance event is opened, so there is currently no + straightforward way to handle this case. This means the ebb registers + in the client-side regcache can become dirty when the user tries to + write to them, until the inferior is resumed and stopped again. + + A related issue is that 'G' packets used to write to unrelated + registers will include bad data for the EBB registers if they are + unavailable, since no register status information is included in the + 'G' packet. This data won't be written to the inferior by the + gdbserver stub because the "fill" functions are not implemented, and + currently the gdbserver stub doesn't change the status of the + registers in its own regcache in response to 'G' packets. + + Another limitation for the ebb registers is that traceframes don't + record if registers are available or not, so if these registers are + collected when a tracepoint is hit and the inferior has no ebb event + opened, the user will see zero values for all of them, instead of the + usual . + + Because these registers are often unavailable, trying to store them + with target_store_registers with -1 for the regno argument (all + registers) would almost always fail, so they are ignored in this case. + + gdb/ChangeLog: + 2018-10-26 Edjunior Barbosa Machado + Pedro Franco de Carvalho + + * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_EBBREGSET) + (PPC_LINUX_SIZEOF_PMUREGSET): Declare. + * nat/ppc-linux.h (PPC_FEATURE2_EBB, NT_PPC_EBB, NT_PPC_PMU): + Define if not already defined. + * features/rs6000/power-ebb.xml: New file. + * features/rs6000/power-linux-pmu.xml: New file. + * features/rs6000/powerpc-isa207-vsx32l.xml: Include ebb and pmu + features. + * features/rs6000/powerpc-isa207-vsx64l.xml: Likewise. + * features/rs6000/powerpc-isa207-vsx32l.c: Re-generate. + * features/rs6000/powerpc-isa207-vsx64l.c: Re-generate. + * regformats/rs6000/powerpc-isa207-vsx32l.dat: Re-generate. + * regformats/rs6000/powerpc-isa207-vsx64l.dat: Re-generate. + * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call + fetch_regset with ebb and pmu regsets. + (store_register, store_ppc_registers): Call store_regset with ebb + and pmu regsets. + (ppc_linux_nat_target::read_description): Set isa207 field in the + features struct if ebb and pmu are avaiable. + * ppc-linux-tdep.c (ppc32_regmap_ebb, ppc32_regmap_pmu) + (ppc32_linux_ebbregset, ppc32_linux_pmuregset): New globals. + (ppc_linux_iterate_over_regset_sections): Call back with the ebb + and pmu regsets. + (ppc_linux_core_read_description): Check if the pmu section is + present and set isa207 in the features struct. + * ppc-linux-tdep.h (ppc32_linux_ebbregset) + (ppc32_linux_pmuregset): Declare. + * ppc-tdep.h (struct gdbarch_tdep) : New field. + : New fields. + : New field. + (enum): : + New enum values. + : New enum + values. + : New enum values. + (PPC_IS_EBB_REGNUM, PPC_IS_PMU_REGNUM): Define. + * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate the + ebb and pmu features. + + gdb/gdbserver/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * configure.srv (powerpc*-*-linux*): Add rs6000/power-ebb.xml and + rs6000/power-linux-pmu.xml to srv_xmlfiles. + * linux-ppc-low.c (ppc_store_ebbregset, ppc_fill_pmuregset) + (ppc_store_pmuregset): New functions. + (ppc_regsets): Add entries for ebb and pmu regsets. + (ppc_arch_setup): Set isa207 in features struct if the ebb and + pmu regsets are available. Set sizes for these regsets. + + gdb/doc/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * gdb.texinfo (PowerPC Features): Describe new features + "org.gnu.gdb.power.ebb" and "org.gnu.gdb.power.linux.pmu". + +diff --git a/gdb/arch/ppc-linux-common.h b/gdb/arch/ppc-linux-common.h +--- a/gdb/arch/ppc-linux-common.h ++++ b/gdb/arch/ppc-linux-common.h +@@ -33,6 +33,8 @@ struct target_desc; + #define PPC_LINUX_SIZEOF_PPRREGSET 8 + #define PPC_LINUX_SIZEOF_DSCRREGSET 8 + #define PPC_LINUX_SIZEOF_TARREGSET 8 ++#define PPC_LINUX_SIZEOF_EBBREGSET (3*8) ++#define PPC_LINUX_SIZEOF_PMUREGSET (5*8) + + /* Check if the hwcap auxv entry indicates that isa205 is supported. */ + bool ppc_linux_has_isa205 (CORE_ADDR hwcap); +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -42585,6 +42585,15 @@ contain the 64-bit register @samp{dscr}. + The @samp{org.gnu.gdb.power.tar} feature is optional. It should + contain the 64-bit register @samp{tar}. + ++The @samp{org.gnu.gdb.power.ebb} feature is optional. It should ++contain registers @samp{bescr}, @samp{ebbhr} and @samp{ebbrr}, all ++64-bit wide. ++ ++The @samp{org.gnu.gdb.power.linux.pmu} feature is optional. It should ++contain registers @samp{mmcr0}, @samp{mmcr2}, @samp{siar}, @samp{sdar} ++and @samp{sier}, all 64-bit wide. This is the subset of the isa 2.07 ++server PMU registers provided by @sc{gnu}/Linux. ++ + @node S/390 and System z Features + @subsection S/390 and System z Features + @cindex target descriptions, S/390 features +diff --git a/gdb/features/rs6000/power-ebb.xml b/gdb/features/rs6000/power-ebb.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-ebb.xml +@@ -0,0 +1,14 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/power-linux-pmu.xml b/gdb/features/rs6000/power-linux-pmu.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-linux-pmu.xml +@@ -0,0 +1,17 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/powerpc-isa207-vsx32l.c b/gdb/features/rs6000/powerpc-isa207-vsx32l.c +--- a/gdb/features/rs6000/powerpc-isa207-vsx32l.c ++++ b/gdb/features/rs6000/powerpc-isa207-vsx32l.c +@@ -199,5 +199,17 @@ initialize_tdesc_powerpc_isa207_vsx32l (void) + feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar"); + tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64"); + ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb"); ++ tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu"); ++ tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64"); ++ + tdesc_powerpc_isa207_vsx32l = result; + } +diff --git a/gdb/features/rs6000/powerpc-isa207-vsx32l.xml b/gdb/features/rs6000/powerpc-isa207-vsx32l.xml +--- a/gdb/features/rs6000/powerpc-isa207-vsx32l.xml ++++ b/gdb/features/rs6000/powerpc-isa207-vsx32l.xml +@@ -16,4 +16,6 @@ + + + ++ ++ + +diff --git a/gdb/features/rs6000/powerpc-isa207-vsx64l.c b/gdb/features/rs6000/powerpc-isa207-vsx64l.c +--- a/gdb/features/rs6000/powerpc-isa207-vsx64l.c ++++ b/gdb/features/rs6000/powerpc-isa207-vsx64l.c +@@ -199,5 +199,17 @@ initialize_tdesc_powerpc_isa207_vsx64l (void) + feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar"); + tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64"); + ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb"); ++ tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu"); ++ tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64"); ++ + tdesc_powerpc_isa207_vsx64l = result; + } +diff --git a/gdb/features/rs6000/powerpc-isa207-vsx64l.xml b/gdb/features/rs6000/powerpc-isa207-vsx64l.xml +--- a/gdb/features/rs6000/powerpc-isa207-vsx64l.xml ++++ b/gdb/features/rs6000/powerpc-isa207-vsx64l.xml +@@ -16,4 +16,6 @@ + + + ++ ++ + +diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv +--- a/gdb/gdbserver/configure.srv ++++ b/gdb/gdbserver/configure.srv +@@ -249,6 +249,8 @@ case "${target}" in + srv_xmlfiles="${srv_xmlfiles} rs6000/power-dscr.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-ppr.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-tar.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-ebb.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-linux-pmu.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-e500l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-spe.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-64l.xml" +diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c +--- a/gdb/gdbserver/linux-ppc-low.c ++++ b/gdb/gdbserver/linux-ppc-low.c +@@ -545,6 +545,61 @@ ppc_store_tarregset (struct regcache *regcache, const void *buf) + supply_register_by_name (regcache, "tar", tar); + } + ++/* Event-Based Branching regset store function. Unless the inferior ++ has a perf event open, ptrace can return in error when reading and ++ writing to the regset, with ENODATA. For reading, the registers ++ will correctly show as unavailable. For writing, gdbserver ++ currently only caches any register writes from P and G packets and ++ the stub always tries to write all the regsets when resuming the ++ inferior, which would result in frequent warnings. For this ++ reason, we don't define a fill function. This also means that the ++ client-side regcache will be dirty if the user tries to write to ++ the EBB registers. G packets that the client sends to write to ++ unrelated registers will also include data for EBB registers, even ++ if they are unavailable. */ ++ ++static void ++ppc_store_ebbregset (struct regcache *regcache, const void *buf) ++{ ++ const char *regset = (const char *) buf; ++ ++ /* The order in the kernel regset is: EBBRR, EBBHR, BESCR. In the ++ .dat file is BESCR, EBBHR, EBBRR. */ ++ supply_register_by_name (regcache, "ebbrr", ®set[0]); ++ supply_register_by_name (regcache, "ebbhr", ®set[8]); ++ supply_register_by_name (regcache, "bescr", ®set[16]); ++} ++ ++/* Performance Monitoring Unit regset fill function. */ ++ ++static void ++ppc_fill_pmuregset (struct regcache *regcache, void *buf) ++{ ++ char *regset = (char *) buf; ++ ++ /* The order in the kernel regset is SIAR, SDAR, SIER, MMCR2, MMCR0. ++ In the .dat file is MMCR0, MMCR2, SIAR, SDAR, SIER. */ ++ collect_register_by_name (regcache, "siar", ®set[0]); ++ collect_register_by_name (regcache, "sdar", ®set[8]); ++ collect_register_by_name (regcache, "sier", ®set[16]); ++ collect_register_by_name (regcache, "mmcr2", ®set[24]); ++ collect_register_by_name (regcache, "mmcr0", ®set[32]); ++} ++ ++/* Performance Monitoring Unit regset store function. */ ++ ++static void ++ppc_store_pmuregset (struct regcache *regcache, const void *buf) ++{ ++ const char *regset = (const char *) buf; ++ ++ supply_register_by_name (regcache, "siar", ®set[0]); ++ supply_register_by_name (regcache, "sdar", ®set[8]); ++ supply_register_by_name (regcache, "sier", ®set[16]); ++ supply_register_by_name (regcache, "mmcr2", ®set[24]); ++ supply_register_by_name (regcache, "mmcr0", ®set[32]); ++} ++ + static void + ppc_fill_vsxregset (struct regcache *regcache, void *buf) + { +@@ -654,6 +709,10 @@ static struct regset_info ppc_regsets[] = { + fetch them every time, but still fall back to PTRACE_PEEKUSER for the + general registers. Some kernels support these, but not the newer + PPC_PTRACE_GETREGS. */ ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_EBB, 0, EXTENDED_REGS, ++ NULL, ppc_store_ebbregset }, ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PMU, 0, EXTENDED_REGS, ++ ppc_fill_pmuregset, ppc_store_pmuregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TAR, 0, EXTENDED_REGS, + ppc_fill_tarregset, ppc_store_tarregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PPR, 0, EXTENDED_REGS, +@@ -734,8 +793,13 @@ ppc_arch_setup (void) + features.ppr_dscr = true; + if ((ppc_hwcap2 & PPC_FEATURE2_ARCH_2_07) + && (ppc_hwcap2 & PPC_FEATURE2_TAR) ++ && (ppc_hwcap2 & PPC_FEATURE2_EBB) + && ppc_check_regset (tid, NT_PPC_TAR, +- PPC_LINUX_SIZEOF_TARREGSET)) ++ PPC_LINUX_SIZEOF_TARREGSET) ++ && ppc_check_regset (tid, NT_PPC_EBB, ++ PPC_LINUX_SIZEOF_EBBREGSET) ++ && ppc_check_regset (tid, NT_PPC_PMU, ++ PPC_LINUX_SIZEOF_PMUREGSET)) + features.isa207 = true; + } + +@@ -798,6 +862,14 @@ ppc_arch_setup (void) + regset->size = (features.isa207 ? + PPC_LINUX_SIZEOF_TARREGSET : 0); + break; ++ case NT_PPC_EBB: ++ regset->size = (features.isa207 ? ++ PPC_LINUX_SIZEOF_EBBREGSET : 0); ++ break; ++ case NT_PPC_PMU: ++ regset->size = (features.isa207 ? ++ PPC_LINUX_SIZEOF_PMUREGSET : 0); ++ break; + default: + break; + } +diff --git a/gdb/nat/ppc-linux.h b/gdb/nat/ppc-linux.h +--- a/gdb/nat/ppc-linux.h ++++ b/gdb/nat/ppc-linux.h +@@ -60,6 +60,9 @@ + #ifndef PPC_FEATURE2_TAR + #define PPC_FEATURE2_TAR 0x04000000 + #endif ++#ifndef PPC_FEATURE2_EBB ++#define PPC_FEATURE2_EBB 0x10000000 ++#endif + + /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a + configure time check. Some older glibc's (for instance 2.2.1) +@@ -106,6 +109,16 @@ + #define NT_PPC_DSCR 0x105 + #endif + ++/* Event Based Branch Registers. */ ++#ifndef NT_PPC_EBB ++#define NT_PPC_EBB 0x106 ++#endif ++ ++/* Performance Monitor Registers. */ ++#ifndef NT_PPC_PMU ++#define NT_PPC_PMU 0x107 ++#endif ++ + /* Return the wordsize of the target, either 4 or 8 bytes. */ + int ppc_linux_target_wordsize (int tid); + +diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c +--- a/gdb/ppc-linux-nat.c ++++ b/gdb/ppc-linux-nat.c +@@ -667,6 +667,24 @@ fetch_register (struct regcache *regcache, int tid, int regno) + &ppc32_linux_tarregset); + return; + } ++ else if (PPC_IS_EBB_REGNUM (regno)) ++ { ++ gdb_assert (tdep->have_ebb); ++ ++ fetch_regset (regcache, tid, NT_PPC_EBB, ++ PPC_LINUX_SIZEOF_EBBREGSET, ++ &ppc32_linux_ebbregset); ++ return; ++ } ++ else if (PPC_IS_PMU_REGNUM (regno)) ++ { ++ gdb_assert (tdep->ppc_mmcr0_regnum != -1); ++ ++ fetch_regset (regcache, tid, NT_PPC_PMU, ++ PPC_LINUX_SIZEOF_PMUREGSET, ++ &ppc32_linux_pmuregset); ++ return; ++ } + + if (regaddr == -1) + { +@@ -875,6 +893,14 @@ fetch_ppc_registers (struct regcache *regcache, int tid) + fetch_regset (regcache, tid, NT_PPC_TAR, + PPC_LINUX_SIZEOF_TARREGSET, + &ppc32_linux_tarregset); ++ if (tdep->have_ebb) ++ fetch_regset (regcache, tid, NT_PPC_EBB, ++ PPC_LINUX_SIZEOF_EBBREGSET, ++ &ppc32_linux_ebbregset); ++ if (tdep->ppc_mmcr0_regnum != -1) ++ fetch_regset (regcache, tid, NT_PPC_PMU, ++ PPC_LINUX_SIZEOF_PMUREGSET, ++ &ppc32_linux_pmuregset); + } + + /* Fetch registers from the child process. Fetch all registers if +@@ -1082,6 +1108,24 @@ store_register (const struct regcache *regcache, int tid, int regno) + &ppc32_linux_tarregset); + return; + } ++ else if (PPC_IS_EBB_REGNUM (regno)) ++ { ++ gdb_assert (tdep->have_ebb); ++ ++ store_regset (regcache, tid, regno, NT_PPC_EBB, ++ PPC_LINUX_SIZEOF_EBBREGSET, ++ &ppc32_linux_ebbregset); ++ return; ++ } ++ else if (PPC_IS_PMU_REGNUM (regno)) ++ { ++ gdb_assert (tdep->ppc_mmcr0_regnum != -1); ++ ++ store_regset (regcache, tid, regno, NT_PPC_PMU, ++ PPC_LINUX_SIZEOF_PMUREGSET, ++ &ppc32_linux_pmuregset); ++ return; ++ } + + if (regaddr == -1) + return; +@@ -1308,6 +1352,15 @@ store_ppc_registers (const struct regcache *regcache, int tid) + store_regset (regcache, tid, -1, NT_PPC_TAR, + PPC_LINUX_SIZEOF_TARREGSET, + &ppc32_linux_tarregset); ++ ++ if (tdep->ppc_mmcr0_regnum != -1) ++ store_regset (regcache, tid, -1, NT_PPC_PMU, ++ PPC_LINUX_SIZEOF_PMUREGSET, ++ &ppc32_linux_pmuregset); ++ ++ /* Because the EBB registers can be unavailable, attempts to store ++ them here would cause this function to fail most of the time, so ++ we ignore them. */ + } + + /* Fetch the AT_HWCAP entry from the aux vector. */ +@@ -2439,7 +2492,10 @@ ppc_linux_nat_target::read_description () + features.ppr_dscr = true; + if ((hwcap2 & PPC_FEATURE2_ARCH_2_07) + && (hwcap2 & PPC_FEATURE2_TAR) +- && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET)) ++ && (hwcap2 & PPC_FEATURE2_EBB) ++ && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET) ++ && check_regset (tid, NT_PPC_EBB, PPC_LINUX_SIZEOF_EBBREGSET) ++ && check_regset (tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET)) + features.isa207 = true; + } + +diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c +--- a/gdb/ppc-linux-tdep.c ++++ b/gdb/ppc-linux-tdep.c +@@ -599,6 +599,44 @@ const struct regset ppc32_linux_tarregset = { + regcache_collect_regset + }; + ++/* Event-Based Branching regmap. */ ++ ++static const struct regcache_map_entry ppc32_regmap_ebb[] = ++ { ++ { 1, PPC_EBBRR_REGNUM, 8 }, ++ { 1, PPC_EBBHR_REGNUM, 8 }, ++ { 1, PPC_BESCR_REGNUM, 8 }, ++ { 0 } ++ }; ++ ++/* Event-Based Branching regset. */ ++ ++const struct regset ppc32_linux_ebbregset = { ++ ppc32_regmap_ebb, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ ++/* Performance Monitoring Unit regmap. */ ++ ++static const struct regcache_map_entry ppc32_regmap_pmu[] = ++ { ++ { 1, PPC_SIAR_REGNUM, 8 }, ++ { 1, PPC_SDAR_REGNUM, 8 }, ++ { 1, PPC_SIER_REGNUM, 8 }, ++ { 1, PPC_MMCR2_REGNUM, 8 }, ++ { 1, PPC_MMCR0_REGNUM, 8 }, ++ { 0 } ++ }; ++ ++/* Performance Monitoring Unit regset. */ ++ ++const struct regset ppc32_linux_pmuregset = { ++ ppc32_regmap_pmu, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ + const struct regset * + ppc_linux_gregset (int wordsize) + { +@@ -674,6 +712,22 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, + cb (".reg-ppc-tar", PPC_LINUX_SIZEOF_TARREGSET, + PPC_LINUX_SIZEOF_TARREGSET, + &ppc32_linux_tarregset, "Target Address Register", cb_data); ++ ++ /* EBB registers are unavailable when ptrace returns ENODATA. Check ++ availability when generating a core file (regcache != NULL). */ ++ if (tdep->have_ebb) ++ if (regcache == NULL ++ || REG_VALID == regcache->get_register_status (PPC_BESCR_REGNUM)) ++ cb (".reg-ppc-ebb", PPC_LINUX_SIZEOF_EBBREGSET, ++ PPC_LINUX_SIZEOF_EBBREGSET, ++ &ppc32_linux_ebbregset, "Event-based Branching Registers", ++ cb_data); ++ ++ if (tdep->ppc_mmcr0_regnum != -1) ++ cb (".reg-ppc-pmu", PPC_LINUX_SIZEOF_PMUREGSET, ++ PPC_LINUX_SIZEOF_PMUREGSET, ++ &ppc32_linux_pmuregset, "Performance Monitor Registers", ++ cb_data); + } + + static void +@@ -1089,6 +1143,7 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, + asection *ppr = bfd_get_section_by_name (abfd, ".reg-ppc-ppr"); + asection *dscr = bfd_get_section_by_name (abfd, ".reg-ppc-dscr"); + asection *tar = bfd_get_section_by_name (abfd, ".reg-ppc-tar"); ++ asection *pmu = bfd_get_section_by_name (abfd, ".reg-ppc-pmu"); + + if (! section) + return NULL; +@@ -1124,7 +1179,12 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, + if (ppr && dscr) + { + features.ppr_dscr = true; +- if (tar) ++ ++ /* We don't require the EBB note section to be present in the ++ core file to select isa207 because these registers could have ++ been unavailable when the core file was created. They will ++ be in the tdep but will show as unavailable. */ ++ if (tar && pmu) + features.isa207 = true; + } + +diff --git a/gdb/ppc-linux-tdep.h b/gdb/ppc-linux-tdep.h +--- a/gdb/ppc-linux-tdep.h ++++ b/gdb/ppc-linux-tdep.h +@@ -48,5 +48,7 @@ int ppc_linux_trap_reg_p (struct gdbarch *gdbarch); + extern const struct regset ppc32_linux_pprregset; + extern const struct regset ppc32_linux_dscrregset; + extern const struct regset ppc32_linux_tarregset; ++extern const struct regset ppc32_linux_ebbregset; ++extern const struct regset ppc32_linux_pmuregset; + + #endif /* PPC_LINUX_TDEP_H */ +diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h +--- a/gdb/ppc-tdep.h ++++ b/gdb/ppc-tdep.h +@@ -265,6 +265,15 @@ struct gdbarch_tdep + /* Decimal 128 registers. */ + int ppc_dl0_regnum; /* First Decimal128 argument register pair. */ + ++ int have_ebb; ++ ++ /* PMU registers. */ ++ int ppc_mmcr0_regnum; ++ int ppc_mmcr2_regnum; ++ int ppc_siar_regnum; ++ int ppc_sdar_regnum; ++ int ppc_sier_regnum; ++ + /* Offset to ABI specific location where link register is saved. */ + int lr_frame_offset; + +@@ -321,12 +330,31 @@ enum { + PPC_PPR_REGNUM = 172, + PPC_DSCR_REGNUM = 173, + PPC_TAR_REGNUM = 174, ++ ++ /* EBB registers. */ ++ PPC_BESCR_REGNUM = 175, ++ PPC_EBBHR_REGNUM = 176, ++ PPC_EBBRR_REGNUM = 177, ++ ++ /* PMU registers. */ ++ PPC_MMCR0_REGNUM = 178, ++ PPC_MMCR2_REGNUM = 179, ++ PPC_SIAR_REGNUM = 180, ++ PPC_SDAR_REGNUM = 181, ++ PPC_SIER_REGNUM = 182, ++ + PPC_NUM_REGS + }; + + /* Big enough to hold the size of the largest register in bytes. */ + #define PPC_MAX_REGISTER_SIZE 64 + ++#define PPC_IS_EBB_REGNUM(i) \ ++ ((i) >= PPC_BESCR_REGNUM && (i) <= PPC_EBBRR_REGNUM) ++ ++#define PPC_IS_PMU_REGNUM(i) \ ++ ((i) >= PPC_MMCR0_REGNUM && (i) <= PPC_SIER_REGNUM) ++ + /* An instruction to match. */ + + struct ppc_insn_pattern +diff --git a/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat b/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat +--- a/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat ++++ b/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat +@@ -145,3 +145,11 @@ expedite:r1,pc + 64:ppr + 64:dscr + 64:tar ++64:bescr ++64:ebbhr ++64:ebbrr ++64:mmcr0 ++64:mmcr2 ++64:siar ++64:sdar ++64:sier +diff --git a/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat b/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat +--- a/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat ++++ b/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat +@@ -145,3 +145,11 @@ expedite:r1,pc + 64:ppr + 64:dscr + 64:tar ++64:bescr ++64:ebbhr ++64:ebbrr ++64:mmcr0 ++64:mmcr2 ++64:siar ++64:sdar ++64:sier +diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c +--- a/gdb/rs6000-tdep.c ++++ b/gdb/rs6000-tdep.c +@@ -5871,7 +5871,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO; + int have_fpu = 0, have_spe = 0, have_mq = 0, have_altivec = 0; + int have_dfp = 0, have_vsx = 0, have_ppr = 0, have_dscr = 0; +- int have_tar = 0; ++ int have_tar = 0, have_ebb = 0, have_pmu = 0; + int tdesc_wordsize = -1; + const struct target_desc *tdesc = info.target_desc; + struct tdesc_arch_data *tdesc_data = NULL; +@@ -6211,6 +6211,64 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + } + else + have_tar = 0; ++ ++ /* Event-based Branching Registers. */ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.ebb"); ++ if (feature != NULL) ++ { ++ static const char *const ebb_regs[] = { ++ "bescr", "ebbhr", "ebbrr" ++ }; ++ ++ valid_p = 1; ++ for (i = 0; i < ARRAY_SIZE (ebb_regs); i++) ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_BESCR_REGNUM + i, ++ ebb_regs[i]); ++ if (!valid_p) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ have_ebb = 1; ++ } ++ else ++ have_ebb = 0; ++ ++ /* Subset of the ISA 2.07 Performance Monitor Registers provided ++ by Linux. */ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.linux.pmu"); ++ if (feature != NULL) ++ { ++ valid_p = 1; ++ ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_MMCR0_REGNUM, ++ "mmcr0"); ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_MMCR2_REGNUM, ++ "mmcr2"); ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_SIAR_REGNUM, ++ "siar"); ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_SDAR_REGNUM, ++ "sdar"); ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_SIER_REGNUM, ++ "sier"); ++ ++ if (!valid_p) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ have_pmu = 1; ++ } ++ else ++ have_pmu = 0; + } + + /* If we have a 64-bit binary on a 32-bit target, complain. Also +@@ -6408,6 +6466,20 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + tdep->ppc_ppr_regnum = have_ppr ? PPC_PPR_REGNUM : -1; + tdep->ppc_dscr_regnum = have_dscr ? PPC_DSCR_REGNUM : -1; + tdep->ppc_tar_regnum = have_tar ? PPC_TAR_REGNUM : -1; ++ tdep->have_ebb = have_ebb; ++ ++ /* If additional pmu registers are added, care must be taken when ++ setting new fields in the tdep below, to maintain compatibility ++ with features that only provide some of the registers. Currently ++ gdb access to the pmu registers is only supported in linux, and ++ linux only provides a subset of the pmu registers defined in the ++ architecture. */ ++ ++ tdep->ppc_mmcr0_regnum = have_pmu ? PPC_MMCR0_REGNUM : -1; ++ tdep->ppc_mmcr2_regnum = have_pmu ? PPC_MMCR2_REGNUM : -1; ++ tdep->ppc_siar_regnum = have_pmu ? PPC_SIAR_REGNUM : -1; ++ tdep->ppc_sdar_regnum = have_pmu ? PPC_SDAR_REGNUM : -1; ++ tdep->ppc_sier_regnum = have_pmu ? PPC_SIER_REGNUM : -1; + + set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM); + set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1); diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-13of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-13of15.patch new file mode 100644 index 0000000..aa7899f --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-13of15.patch @@ -0,0 +1,38 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:18 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8-2-13of15.patch + +;; [PowerPC] Reject tdescs with VSX and no FPU or Altivec +;; Pedro Franco de Carvalho + + [PowerPC] Reject tdescs with VSX and no FPU or Altivec + + Currently rs6000_gdbarch_init will accept a tdesc with the + "org.gnu.gdb.power.vsx" feature but without the + "org.gnu.gdb.power.altivec" or "org.gnu.gdb.power.fpu". + + It isn't clear from the standard features documentation that these are + requirements. However, these tdescs would cause trouble in the VSX + pseudo-register functions, so this patch will cause them to be + rejected. + + gdb/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * rs6000-tdep.c (rs6000_gdbarch_init): Reject tdescs with vsx but + without altivec or fpu. + +diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c +--- a/gdb/rs6000-tdep.c ++++ b/gdb/rs6000-tdep.c +@@ -6096,7 +6096,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_VSR0_UPPER_REGNUM + i, + vsx_regs[i]); +- if (!valid_p) ++ ++ if (!valid_p || !have_fpu || !have_altivec) + { + tdesc_data_cleanup (tdesc_data); + return NULL; diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-14of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-14of15.patch new file mode 100644 index 0000000..ff9ce09 --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8-2-14of15.patch @@ -0,0 +1,4787 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:18 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8-2-14of15.patch + +;; [PowerPC] Add support for HTM registers +;; Edjunior Barbosa Machado and Pedro Franco de Carvalho + + [PowerPC] Add support for HTM registers + + This patch adds support for Hardware Transactional Memory registers + for the powerpc linux native and core file targets, and for the + pwoerpc linux server stub. + + These registers include both the HTM special-purpose registers (TFHAR, + TEXASR and TFIAR) as well as the set of registers that are + checkpointed (saved) when a transaction is initiated, which the + processor restores in the event of a transaction failure. + + The set of checkpointed general-purpose registers is returned by the + linux kernel in the same format as the regular general-purpose + registers, defined in struct pt_regs. However, the architecture + specifies that only some of the registers present in pt_regs are + checkpointed (GPRs 0-31, CR, XER, LR and CTR). The kernel fills the + slots for MSR and NIP with other info. The other fields usually don't + have meaningful values. GDB doesn't define registers that are not + checkpointed in the architecture, but when generating a core file, GDB + fills the slot for the checkpointed MSR with the regular MSR. These + are usually similar, although some bits might be different, and in + some cases the checkpointed MSR will have a value of 0 in a + kernel-generated core-file. The checkpointed NIP is filled with TFHAR + by GDB in the core-file, which is what the kernel does. The other + fields are set to 0 by GDB. + + Core files generated by the kernel have a note section for + checkpointed GPRs with the same size for both 32-bit and 64-bit + threads, and the values for the registers of a 32-bit thread are + squeezed in the first half, with no useful data in the second half. + GDB generates a smaller note section for 32-bit threads, but can read + both sizes. + + The checkpointed XER is required to be 32-bit in the target + description documentation, even though the more recent ISAs define it + as 64-bit wide, since the high-order 32-bits are reserved, and because + in Linux there is no way to get a 64-bit checkpointed XER for 32-bit + threads. If this changes in the future, the target description + feature requirement can be relaxed to allow for a 64-bit checkpointed + XER. + + Access to the checkpointed CR (condition register) can be confusing. + The architecture only specifies that CR fields 1 to 7 (the 24 least + significant bits) are checkpointed, but the kernel provides all 8 + fields (32 bits). The value of field 0 is not masked by ptrace, so it + will sometimes show the result of some kernel operation, probably + treclaim., which sets this field. + + The checkpointed registers are marked not to be saved and restored. + Inferior function calls during an active transaction don't work well, + and it's unclear what should be done in this case. TEXASR and TFIAR + can be altered asynchronously, during transaction failure recording, + so they are also not saved and restored. For consistency neither is + TFHAR. + + Record and replay also doesn't work well when transactions are + involved. This patch doesn't address this, so the values of the HTM + SPRs will sometimes be innacurate when the record/relay target is + enabled. For instance, executing a "tbegin." alters TFHAR and TEXASR, + but these changes are not currently recorded. + + Because the checkpointed registers are only available when a + transaction is active (or suspended), ptrace can return ENODATA when + gdb tries to read these registers and the inferior is not in a + transactional state. The registers are set to the unavailable state + when this happens. When gbd tries to write to one of these registers, + and it is unavailable, an error is raised. + + The "fill" functions for checkpointed register sets in the server stub + are not implemented for the same reason as for the EBB register set, + since ptrace can also return ENODATA for checkpointed regsets. The + same issues with 'G' packets apply here. + + Just like for the EBB registers, tracepoints will not mark the + checkpointed registers as unavailable if the inferior was not in a + transaction, so their content will also show 0 instead of + when inspecting trace data. + + The new tests record the values of the regular registers before + stepping the inferior through a "tbegin." instruction to start a + transaction, then the checkpointed registers are checked against the + recorded pre-transactional values. New values are written to the + checkpointed registers and recorded, the inferior continues until the + transaction aborts (which is usually immediately when it is resumed), + and the regular registers are checked against the recorded values, + because the abort should have reverted the registers to these values. + + Like for the EBB registers, target_store_registers will ignore the + checkpointed registers when called with -1 as the regno + argument (store all registers in one go). + + gdb/ChangeLog: + 2018-10-26 Edjunior Barbosa Machado + Pedro Franco de Carvalho + + * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa207_htm_vsx32l) + (tdesc_powerpc_isa207_htm_vsx64l): Declare. + * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_TM_SPRREGSET) + (PPC32_LINUX_SIZEOF_CGPRREGSET, PPC64_LINUX_SIZEOF_CGPRREGSET) + (PPC_LINUX_SIZEOF_CFPRREGSET, PPC_LINUX_SIZEOF_CVMXREGSET) + (PPC_LINUX_SIZEOF_CVSXREGSET, PPC_LINUX_SIZEOF_CPPRREGSET) + (PPC_LINUX_SIZEOF_CDSCRREGSET, PPC_LINUX_SIZEOF_CTARREGSET): + Define. + (struct ppc_linux_features) : New field. + (ppc_linux_no_features): Add initializer for htm field. + * arch/ppc-linux-common.c (ppc_linux_match_description): Return + new tdescs. + * nat/ppc-linux.h (PPC_FEATURE2_HTM, NT_PPC_TM_CGPR) + (NT_PPC_TM_CFPR, NT_PPC_TM_CVMX, NT_PPC_TM_CVSX) + (NT_PPC_TM_SPR, NT_PPC_TM_CTAR, NT_PPC_TM_CPPR, NT_PPC_TM_CDSCR): + Define if not already defined. + * features/Makefile (WHICH): Add rs6000/powerpc-isa207-htm-vsx32l + and rs6000/powerpc-isa207-htm-vsx64l. + (XMLTOC): Add rs6000/powerpc-isa207-htm-vsx32l.xml and + rs6000/powerpc-isa207-htm-vsx64l.xml. + * features/rs6000/power-htm-spr.xml: New file. + * features/rs6000/power-htm-core.xml: New file. + * features/rs6000/power64-htm-core.xml: New file. + * features/rs6000/power-htm-fpu.xml: New file. + * features/rs6000/power-htm-altivec.xml: New file. + * features/rs6000/power-htm-vsx.xml: New file. + * features/rs6000/power-htm-ppr.xml: New file. + * features/rs6000/power-htm-dscr.xml: New file. + * features/rs6000/power-htm-tar.xml: New file. + * features/rs6000/powerpc-isa207-htm-vsx32l.xml: New file. + * features/rs6000/powerpc-isa207-htm-vsx64l.xml: New file. + * features/rs6000/powerpc-isa207-htm-vsx32l.c: Generate. + * features/rs6000/powerpc-isa207-htm-vsx64l.c: Generate. + * regformats/rs6000/powerpc-isa207-htm-vsx32l.dat: Generate. + * regformats/rs6000/powerpc-isa207-htm-vsx64l.dat: Generate. + * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call + fetch_regset with HTM regsets. + (store_register, store_ppc_registers): Call store_regset with HTM + regsets. + (ppc_linux_nat_target::read_description): Set htm field in the + features struct if needed. + * ppc-linux-tdep.c: Include + features/rs6000/powerpc-isa207-htm-vsx32l.c and + features/rs6000/powerpc-isa207-htm-vsx64l.c. + (ppc32_regmap_tm_spr, ppc32_regmap_cgpr, ppc64_le_regmap_cgpr) + (ppc64_be_regmap_cgpr, ppc32_regmap_cfpr, ppc32_le_regmap_cvmx) + (ppc32_be_regmap_cvmx, ppc32_regmap_cvsx, ppc32_regmap_cppr) + (ppc32_regmap_cdscr, ppc32_regmap_ctar): New globals. + (ppc32_linux_tm_sprregset, ppc32_linux_cgprregset) + (ppc64_be_linux_cgprregset, ppc64_le_linux_cgprregset) + (ppc32_linux_cfprregset, ppc32_le_linux_cvmxregset) + (ppc32_be_linux_cvmxregset, ppc32_linux_cvsxregset) + (ppc32_linux_cpprregset, ppc32_linux_cdscrregset) + (ppc32_linux_ctarregset): New globals. + (ppc_linux_cgprregset, ppc_linux_cvmxregset): New functions. + (ppc_linux_collect_core_cpgrregset): New function. + (ppc_linux_iterate_over_regset_sections): Call back with the htm + regsets. + (ppc_linux_core_read_description): Check if the tm spr section is + present and set htm in the features struct. + (_initialize_ppc_linux_tdep): Call + initialize_tdesc_powerpc_isa207_htm_vsx32l and + initialize_tdesc_powerpc_isa207_htm_vsx64l. + * ppc-linux-tdep.h (ppc_linux_cgprregset, ppc_linux_cvmxregset): + Declare. + (ppc32_linux_tm_sprregset, ppc32_linux_cfprregset) + (ppc32_linux_cvsxregset, ppc32_linux_cpprregset) + (ppc32_linux_cdscrregset, ppc32_linux_ctarregset): Declare. + * ppc-tdep.h (struct gdbarch_tdep) : + New fields. + : + Likewise. + : Likewise. + : Likewise. + (enum) : + New enum fields. + : Likewise. + : Likewise. + : Likewise. + : Likewise. + : Likewise. + : Likewise. + (PPC_IS_TMSPR_REGNUM, PPC_IS_CKPTGP_REGNUM, PPC_IS_CKPTFP_REGNUM) + (PPC_IS_CKPTVMX_REGNUM, PPC_IS_CKPTVSX_REGNUM): Define. + * rs6000-tdep.c (IS_CDFP_PSEUDOREG, IS_CVSX_PSEUDOREG) + (IS_CEFP_PSEUDOREG): Define. + (rs6000_register_name): Hide the upper halves of checkpointed VSX + registers. Return names for the checkpointed DFP, VSX, and EFP + pseudo registers. + (rs6000_pseudo_register_type): Remove initial assert and raise an + internal error in the else clause instead. Return types for the + checkpointed DFP, VSX, and EFP pseudo registers. + (dfp_pseudo_register_read, dfp_pseudo_register_write): Handle + checkpointed DFP pseudo registers. + (vsx_pseudo_register_read, vsx_pseudo_register_write): Handle + checkpointed VSX pseudo registers. + (efp_pseudo_register_read, efp_pseudo_register_write): Rename + from efpr_pseudo_register_read and + efpr_pseudo_register_write. Handle checkpointed EFP pseudo + registers. + (rs6000_pseudo_register_read, rs6000_pseudo_register_write): + Handle checkpointed DFP, VSX, and EFP registers. + (dfp_ax_pseudo_register_collect, vsx_ax_pseudo_register_collect) + (efp_ax_pseudo_register_collect): New functions. + (rs6000_ax_pseudo_register_collect): Move DFP, VSX and EFP pseudo + register logic to new functions. Handle checkpointed DFP, VSX, + and EFP pseudo registers. + (rs6000_gdbarch_init): Look for and validate the htm features. + Include checkpointed DFP, VSX and EFP pseudo-registers. + * NEWS: Mention access to PPR, DSCR, TAR, EBB/PMU registers and + HTM registers. + + gdb/gdbserver/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * configure.srv (ipa_ppc_linux_regobj): Add + powerpc-isa207-htm-vsx32l-ipa.o and + powerpc-isa207-htm-vsx64l-ipa.o. + (powerpc*-*-linux*): Add powerpc-isa207-htm-vsx32l.o and + powerpc-isa207-htm-vsx64l.o to srv_regobj. Add + rs6000/power-htm-spr.xml, rs6000/power-htm-core.xml, + rs6000/power64-htm-core.xml, rs6000/power-htm-fpu.xml, + rs6000/power-htm-altivec.xml, rs6000/power-htm-vsx.xml, + rs6000/power-htm-ppr.xml, rs6000/power-htm-dscr.xml, + rs6000/power-htm-tar.xml, rs6000/powerpc-isa207-htm-vsx32l.xml, + and rs6000/powerpc-isa207-htm-vsx64l.xml to srv_xmlfiles. + * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) + : New enum value. + (init_registers_powerpc_isa207_htm_vsx32l) + (init_registers_powerpc_isa207_htm_vsx64l): Declare. + * linux-ppc-low.c (ppc_fill_tm_sprregset, ppc_store_tm_sprregset) + (ppc_store_tm_cgprregset, ppc_store_tm_cfprregset) + (ppc_store_tm_cvrregset, ppc_store_tm_cvsxregset) + (ppc_store_tm_cpprregset, ppc_store_tm_cdscrregset) + (ppc_store_tm_ctarregset): New functions. + (ppc_regsets): Add entries for HTM regsets. + (ppc_arch_setup): Set htm in features struct when needed. Set + sizes for the HTM regsets. + (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_HTM_VSX. + (initialize_low_arch): Call + init_registers_powerpc_isa207_htm_vsx32l and + init_registers_powerpc_isa207_htm_vsx64l. + * linux-ppc-ipa.c (get_ipa_tdesc): Handle + PPC_TDESC_ISA207_HTM_VSX. + (initialize_low_tracepoint): Call + init_registers_powerpc_isa207_htm_vsx32l and + init_registers_powerpc_isa207_htm_vsx64l. + + gdb/testsuite/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * gdb.arch/powerpc-htm-regs.c: New file. + * gdb.arch/powerpc-htm-regs.exp: New file. + + gdb/doc/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * gdb.texinfo (PowerPC Features): Describe new features + "org.gnu.gdb.power.htm.spr", "org.gnu.gdb.power.htm.core", + "org.gnu.gdb.power.htm.fpu", "org.gnu.gdb.power.htm.altivec", + "org.gnu.gdb.power.htm.vsx", "org.gnu.gdb.power.htm.ppr", + "org.gnu.gdb.power.htm.dscr", "org.gnu.gdb.power.htm.tar". + +diff --git a/gdb/NEWS b/gdb/NEWS +--- a/gdb/NEWS ++++ b/gdb/NEWS +@@ -12,6 +12,10 @@ + + *** Changes in GDB 8.2 + ++* GDB and GDBserver now support access to additional registers on ++ PowerPC GNU/Linux targets: PPR, DSCR, TAR, EBB/PMU registers, and ++ HTM registers. ++ + * The 'set disassembler-options' command now supports specifying options + for the MIPS target. + +diff --git a/gdb/arch/ppc-linux-common.c b/gdb/arch/ppc-linux-common.c +--- a/gdb/arch/ppc-linux-common.c ++++ b/gdb/arch/ppc-linux-common.c +@@ -53,7 +53,8 @@ ppc_linux_match_description (struct ppc_linux_features features) + if (features.cell) + tdesc = tdesc_powerpc_cell64l; + else if (features.vsx) +- tdesc = (features.isa207? tdesc_powerpc_isa207_vsx64l ++ tdesc = (features.htm? tdesc_powerpc_isa207_htm_vsx64l ++ : features.isa207? tdesc_powerpc_isa207_vsx64l + : features.ppr_dscr? tdesc_powerpc_isa205_ppr_dscr_vsx64l + : features.isa205? tdesc_powerpc_isa205_vsx64l + : tdesc_powerpc_vsx64l); +@@ -71,7 +72,8 @@ ppc_linux_match_description (struct ppc_linux_features features) + if (features.cell) + tdesc = tdesc_powerpc_cell32l; + else if (features.vsx) +- tdesc = (features.isa207? tdesc_powerpc_isa207_vsx32l ++ tdesc = (features.htm? tdesc_powerpc_isa207_htm_vsx32l ++ : features.isa207? tdesc_powerpc_isa207_vsx32l + : features.ppr_dscr? tdesc_powerpc_isa205_ppr_dscr_vsx32l + : features.isa205? tdesc_powerpc_isa205_vsx32l + : tdesc_powerpc_vsx32l); +diff --git a/gdb/arch/ppc-linux-common.h b/gdb/arch/ppc-linux-common.h +--- a/gdb/arch/ppc-linux-common.h ++++ b/gdb/arch/ppc-linux-common.h +@@ -35,6 +35,15 @@ struct target_desc; + #define PPC_LINUX_SIZEOF_TARREGSET 8 + #define PPC_LINUX_SIZEOF_EBBREGSET (3*8) + #define PPC_LINUX_SIZEOF_PMUREGSET (5*8) ++#define PPC_LINUX_SIZEOF_TM_SPRREGSET (3*8) ++#define PPC32_LINUX_SIZEOF_CGPRREGSET (48*4) ++#define PPC64_LINUX_SIZEOF_CGPRREGSET (48*8) ++#define PPC_LINUX_SIZEOF_CFPRREGSET (32*8+8) ++#define PPC_LINUX_SIZEOF_CVMXREGSET (34*16) ++#define PPC_LINUX_SIZEOF_CVSXREGSET (32*8) ++#define PPC_LINUX_SIZEOF_CPPRREGSET 8 ++#define PPC_LINUX_SIZEOF_CDSCRREGSET 8 ++#define PPC_LINUX_SIZEOF_CTARREGSET 8 + + /* Check if the hwcap auxv entry indicates that isa205 is supported. */ + bool ppc_linux_has_isa205 (CORE_ADDR hwcap); +@@ -48,6 +57,7 @@ struct ppc_linux_features + bool isa205; + bool ppr_dscr; + bool isa207; ++ bool htm; + bool cell; + }; + +@@ -60,6 +70,7 @@ const struct ppc_linux_features ppc_linux_no_features = { + false, + false, + false, ++ false, + }; + + /* Return a target description that matches FEATURES. */ +diff --git a/gdb/arch/ppc-linux-tdesc.h b/gdb/arch/ppc-linux-tdesc.h +--- a/gdb/arch/ppc-linux-tdesc.h ++++ b/gdb/arch/ppc-linux-tdesc.h +@@ -31,6 +31,7 @@ extern struct target_desc *tdesc_powerpc_isa205_altivec32l; + extern struct target_desc *tdesc_powerpc_isa205_vsx32l; + extern struct target_desc *tdesc_powerpc_isa205_ppr_dscr_vsx32l; + extern struct target_desc *tdesc_powerpc_isa207_vsx32l; ++extern struct target_desc *tdesc_powerpc_isa207_htm_vsx32l; + extern struct target_desc *tdesc_powerpc_e500l; + + extern struct target_desc *tdesc_powerpc_64l; +@@ -42,5 +43,6 @@ extern struct target_desc *tdesc_powerpc_isa205_altivec64l; + extern struct target_desc *tdesc_powerpc_isa205_vsx64l; + extern struct target_desc *tdesc_powerpc_isa205_ppr_dscr_vsx64l; + extern struct target_desc *tdesc_powerpc_isa207_vsx64l; ++extern struct target_desc *tdesc_powerpc_isa207_htm_vsx64l; + + #endif /* ARCH_PPC_LINUX_TDESC_H */ +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -42594,6 +42594,48 @@ contain registers @samp{mmcr0}, @samp{mmcr2}, @samp{siar}, @samp{sdar} + and @samp{sier}, all 64-bit wide. This is the subset of the isa 2.07 + server PMU registers provided by @sc{gnu}/Linux. + ++The @samp{org.gnu.gdb.power.htm.spr} feature is optional. It should ++contain registers @samp{tfhar}, @samp{texasr} and @samp{tfiar}, all ++64-bit wide. ++ ++The @samp{org.gnu.gdb.power.htm.core} feature is optional. It should ++contain the checkpointed general-purpose registers @samp{cr0} through ++@samp{cr31}, as well as the checkpointed registers @samp{clr} and ++@samp{cctr}. These registers may all be either 32-bit or 64-bit ++depending on the target. It should also contain the checkpointed ++registers @samp{ccr} and @samp{cxer}, which should both be 32-bit ++wide. ++ ++The @samp{org.gnu.gdb.power.htm.fpu} feature is optional. It should ++contain the checkpointed 64-bit floating-point registers @samp{cf0} ++through @samp{cf31}, as well as the checkpointed 64-bit register ++@samp{cfpscr}. ++ ++The @samp{org.gnu.gdb.power.htm.altivec} feature is optional. It ++should contain the checkpointed altivec registers @samp{cvr0} through ++@samp{cvr31}, all 128-bit wide. It should also contain the ++checkpointed registers @samp{cvscr} and @samp{cvrsave}, both 32-bit ++wide. ++ ++The @samp{org.gnu.gdb.power.htm.vsx} feature is optional. It should ++contain registers @samp{cvs0h} through @samp{cvs31h}. @value{GDBN} ++will combine these registers with the checkpointed floating point ++registers (@samp{cf0} through @samp{cf31}) and the checkpointed ++altivec registers (@samp{cvr0} through @samp{cvr31}) to present the ++128-bit wide checkpointed vector-scalar registers @samp{cvs0} through ++@samp{cvs63}. Therefore, this feature requires both ++@samp{org.gnu.gdb.power.htm.altivec} and ++@samp{org.gnu.gdb.power.htm.fpu}. ++ ++The @samp{org.gnu.gdb.power.htm.ppr} feature is optional. It should ++contain the 64-bit checkpointed register @samp{cppr}. ++ ++The @samp{org.gnu.gdb.power.htm.dscr} feature is optional. It should ++contain the 64-bit checkpointed register @samp{cdscr}. ++ ++The @samp{org.gnu.gdb.power.htm.tar} feature is optional. It should ++contain the 64-bit checkpointed register @samp{ctar}. ++ + @node S/390 and System z Features + @subsection S/390 and System z Features + @cindex target descriptions, S/390 features +diff --git a/gdb/features/Makefile b/gdb/features/Makefile +--- a/gdb/features/Makefile ++++ b/gdb/features/Makefile +@@ -76,6 +76,8 @@ WHICH = aarch64 \ + rs6000/powerpc-isa205-ppr-dscr-vsx32l \ + rs6000/powerpc-isa205-ppr-dscr-vsx64l \ + rs6000/powerpc-isa207-vsx32l rs6000/powerpc-isa207-vsx64l \ ++ rs6000/powerpc-isa207-htm-vsx32l \ ++ rs6000/powerpc-isa207-htm-vsx64l \ + s390-linux32 s390-linux64 s390x-linux64 \ + s390-linux32v1 s390-linux64v1 s390x-linux64v1 \ + s390-linux32v2 s390-linux64v2 s390x-linux64v2 \ +@@ -174,6 +176,8 @@ XMLTOC = \ + rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml \ + rs6000/powerpc-isa207-vsx32l.xml \ + rs6000/powerpc-isa207-vsx64l.xml \ ++ rs6000/powerpc-isa207-htm-vsx32l.xml \ ++ rs6000/powerpc-isa207-htm-vsx64l.xml \ + rs6000/powerpc-vsx32.xml \ + rs6000/powerpc-vsx32l.xml \ + rs6000/powerpc-vsx64.xml \ +diff --git a/gdb/features/rs6000/power-htm-altivec.xml b/gdb/features/rs6000/power-htm-altivec.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-htm-altivec.xml +@@ -0,0 +1,58 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/power-htm-core.xml b/gdb/features/rs6000/power-htm-core.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-htm-core.xml +@@ -0,0 +1,48 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/power-htm-dscr.xml b/gdb/features/rs6000/power-htm-dscr.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-htm-dscr.xml +@@ -0,0 +1,12 @@ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/power-htm-fpu.xml b/gdb/features/rs6000/power-htm-fpu.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-htm-fpu.xml +@@ -0,0 +1,45 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/power-htm-ppr.xml b/gdb/features/rs6000/power-htm-ppr.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-htm-ppr.xml +@@ -0,0 +1,12 @@ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/power-htm-spr.xml b/gdb/features/rs6000/power-htm-spr.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-htm-spr.xml +@@ -0,0 +1,14 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/power-htm-tar.xml b/gdb/features/rs6000/power-htm-tar.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-htm-tar.xml +@@ -0,0 +1,12 @@ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/power-htm-vsx.xml b/gdb/features/rs6000/power-htm-vsx.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power-htm-vsx.xml +@@ -0,0 +1,43 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/power64-htm-core.xml b/gdb/features/rs6000/power64-htm-core.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/power64-htm-core.xml +@@ -0,0 +1,48 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.c b/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.c +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.c +@@ -0,0 +1,396 @@ ++/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: ++ Original: powerpc-isa207-htm-vsx32l.xml */ ++ ++#include "defs.h" ++#include "osabi.h" ++#include "target-descriptions.h" ++ ++struct target_desc *tdesc_powerpc_isa207_htm_vsx32l; ++static void ++initialize_tdesc_powerpc_isa207_htm_vsx32l (void) ++{ ++ struct target_desc *result = allocate_target_description (); ++ set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); ++ ++ struct tdesc_feature *feature; ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); ++ tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r24", 24, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r25", 25, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r26", 26, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r27", 27, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r28", 28, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "pc", 64, 1, NULL, 32, "code_ptr"); ++ tdesc_create_reg (feature, "msr", 65, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "lr", 67, 1, NULL, 32, "code_ptr"); ++ tdesc_create_reg (feature, "ctr", 68, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu"); ++ tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "fpscr", 70, 1, "float", 64, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux"); ++ tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 32, "int"); ++ tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); ++ tdesc_type *element_type; ++ element_type = tdesc_named_type (feature, "ieee_single"); ++ tdesc_create_vector (feature, "v4f", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int32"); ++ tdesc_create_vector (feature, "v4i32", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int16"); ++ tdesc_create_vector (feature, "v8i16", element_type, 8); ++ ++ element_type = tdesc_named_type (feature, "int8"); ++ tdesc_create_vector (feature, "v16i8", element_type, 16); ++ ++ tdesc_type_with_fields *type_with_fields; ++ type_with_fields = tdesc_create_union (feature, "vec128"); ++ tdesc_type *field_type; ++ field_type = tdesc_named_type (feature, "uint128"); ++ tdesc_add_field (type_with_fields, "uint128", field_type); ++ field_type = tdesc_named_type (feature, "v4f"); ++ tdesc_add_field (type_with_fields, "v4_float", field_type); ++ field_type = tdesc_named_type (feature, "v4i32"); ++ tdesc_add_field (type_with_fields, "v4_int32", field_type); ++ field_type = tdesc_named_type (feature, "v8i16"); ++ tdesc_add_field (type_with_fields, "v8_int16", field_type); ++ field_type = tdesc_named_type (feature, "v16i8"); ++ tdesc_add_field (type_with_fields, "v16_int8", field_type); ++ ++ tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int"); ++ tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.vsx"); ++ tdesc_create_reg (feature, "vs0h", 107, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs1h", 108, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs2h", 109, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs3h", 110, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs4h", 111, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs5h", 112, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs6h", 113, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs7h", 114, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs8h", 115, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs9h", 116, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs10h", 117, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs11h", 118, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs12h", 119, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs13h", 120, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs14h", 121, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs15h", 122, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs16h", 123, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs17h", 124, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs18h", 125, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs19h", 126, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs20h", 127, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs21h", 128, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs22h", 129, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs23h", 130, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs24h", 131, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs25h", 132, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs26h", 133, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs27h", 134, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs28h", 135, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs29h", 136, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs30h", 137, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs31h", 138, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.ppr"); ++ tdesc_create_reg (feature, "ppr", 139, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.dscr"); ++ tdesc_create_reg (feature, "dscr", 140, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar"); ++ tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb"); ++ tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu"); ++ tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.spr"); ++ tdesc_create_reg (feature, "tfhar", 150, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "texasr", 151, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "tfiar", 152, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.core"); ++ tdesc_create_reg (feature, "cr0", 153, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr1", 154, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr2", 155, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr3", 156, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr4", 157, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr5", 158, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr6", 159, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr7", 160, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr8", 161, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr9", 162, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr10", 163, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr11", 164, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr12", 165, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr13", 166, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr14", 167, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr15", 168, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr16", 169, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr17", 170, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr18", 171, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr19", 172, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr20", 173, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr21", 174, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr22", 175, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr23", 176, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr24", 177, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr25", 178, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr26", 179, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr27", 180, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr28", 181, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr29", 182, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr30", 183, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cr31", 184, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "ccr", 185, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cxer", 186, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "clr", 187, 0, NULL, 32, "code_ptr"); ++ tdesc_create_reg (feature, "cctr", 188, 0, NULL, 32, "uint32"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.fpu"); ++ tdesc_create_reg (feature, "cf0", 189, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf1", 190, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf2", 191, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf3", 192, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf4", 193, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf5", 194, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf6", 195, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf7", 196, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf8", 197, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf9", 198, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf10", 199, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf11", 200, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf12", 201, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf13", 202, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf14", 203, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf15", 204, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf16", 205, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf17", 206, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf18", 207, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf19", 208, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf20", 209, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf21", 210, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf22", 211, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf23", 212, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf24", 213, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf25", 214, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf26", 215, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf27", 216, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf28", 217, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf29", 218, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf30", 219, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf31", 220, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cfpscr", 221, 0, "float", 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.altivec"); ++ element_type = tdesc_named_type (feature, "ieee_single"); ++ tdesc_create_vector (feature, "v4f", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int32"); ++ tdesc_create_vector (feature, "v4i32", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int16"); ++ tdesc_create_vector (feature, "v8i16", element_type, 8); ++ ++ element_type = tdesc_named_type (feature, "int8"); ++ tdesc_create_vector (feature, "v16i8", element_type, 16); ++ ++ type_with_fields = tdesc_create_union (feature, "vec128"); ++ field_type = tdesc_named_type (feature, "uint128"); ++ tdesc_add_field (type_with_fields, "uint128", field_type); ++ field_type = tdesc_named_type (feature, "v4f"); ++ tdesc_add_field (type_with_fields, "v4_float", field_type); ++ field_type = tdesc_named_type (feature, "v4i32"); ++ tdesc_add_field (type_with_fields, "v4_int32", field_type); ++ field_type = tdesc_named_type (feature, "v8i16"); ++ tdesc_add_field (type_with_fields, "v8_int16", field_type); ++ field_type = tdesc_named_type (feature, "v16i8"); ++ tdesc_add_field (type_with_fields, "v16_int8", field_type); ++ ++ tdesc_create_reg (feature, "cvr0", 222, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr1", 223, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr2", 224, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr3", 225, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr4", 226, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr5", 227, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr6", 228, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr7", 229, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr8", 230, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr9", 231, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr10", 232, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr11", 233, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr12", 234, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr13", 235, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr14", 236, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr15", 237, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr16", 238, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr17", 239, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr18", 240, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr19", 241, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr20", 242, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr21", 243, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr22", 244, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr23", 245, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr24", 246, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr25", 247, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr26", 248, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr27", 249, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr28", 250, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr29", 251, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr30", 252, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr31", 253, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvscr", 254, 0, "vector", 32, "int"); ++ tdesc_create_reg (feature, "cvrsave", 255, 0, "vector", 32, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.vsx"); ++ tdesc_create_reg (feature, "cvs0h", 256, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs1h", 257, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs2h", 258, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs3h", 259, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs4h", 260, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs5h", 261, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs6h", 262, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs7h", 263, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs8h", 264, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs9h", 265, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs10h", 266, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs11h", 267, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs12h", 268, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs13h", 269, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs14h", 270, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs15h", 271, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs16h", 272, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs17h", 273, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs18h", 274, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs19h", 275, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs20h", 276, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs21h", 277, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs22h", 278, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs23h", 279, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs24h", 280, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs25h", 281, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs26h", 282, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs27h", 283, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs28h", 284, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs29h", 285, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs30h", 286, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs31h", 287, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.ppr"); ++ tdesc_create_reg (feature, "cppr", 288, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.dscr"); ++ tdesc_create_reg (feature, "cdscr", 289, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.tar"); ++ tdesc_create_reg (feature, "ctar", 290, 0, NULL, 64, "uint64"); ++ ++ tdesc_powerpc_isa207_htm_vsx32l = result; ++} +diff --git a/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml b/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml +@@ -0,0 +1,29 @@ ++ ++ ++ ++ ++ ++ powerpc:common ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.c b/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.c +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.c +@@ -0,0 +1,396 @@ ++/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: ++ Original: powerpc-isa207-htm-vsx64l.xml */ ++ ++#include "defs.h" ++#include "osabi.h" ++#include "target-descriptions.h" ++ ++struct target_desc *tdesc_powerpc_isa207_htm_vsx64l; ++static void ++initialize_tdesc_powerpc_isa207_htm_vsx64l (void) ++{ ++ struct target_desc *result = allocate_target_description (); ++ set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); ++ ++ struct tdesc_feature *feature; ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); ++ tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "pc", 64, 1, NULL, 64, "code_ptr"); ++ tdesc_create_reg (feature, "msr", 65, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "lr", 67, 1, NULL, 64, "code_ptr"); ++ tdesc_create_reg (feature, "ctr", 68, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu"); ++ tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "fpscr", 70, 1, "float", 64, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux"); ++ tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 64, "int"); ++ tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); ++ tdesc_type *element_type; ++ element_type = tdesc_named_type (feature, "ieee_single"); ++ tdesc_create_vector (feature, "v4f", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int32"); ++ tdesc_create_vector (feature, "v4i32", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int16"); ++ tdesc_create_vector (feature, "v8i16", element_type, 8); ++ ++ element_type = tdesc_named_type (feature, "int8"); ++ tdesc_create_vector (feature, "v16i8", element_type, 16); ++ ++ tdesc_type_with_fields *type_with_fields; ++ type_with_fields = tdesc_create_union (feature, "vec128"); ++ tdesc_type *field_type; ++ field_type = tdesc_named_type (feature, "uint128"); ++ tdesc_add_field (type_with_fields, "uint128", field_type); ++ field_type = tdesc_named_type (feature, "v4f"); ++ tdesc_add_field (type_with_fields, "v4_float", field_type); ++ field_type = tdesc_named_type (feature, "v4i32"); ++ tdesc_add_field (type_with_fields, "v4_int32", field_type); ++ field_type = tdesc_named_type (feature, "v8i16"); ++ tdesc_add_field (type_with_fields, "v8_int16", field_type); ++ field_type = tdesc_named_type (feature, "v16i8"); ++ tdesc_add_field (type_with_fields, "v16_int8", field_type); ++ ++ tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int"); ++ tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.vsx"); ++ tdesc_create_reg (feature, "vs0h", 107, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs1h", 108, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs2h", 109, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs3h", 110, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs4h", 111, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs5h", 112, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs6h", 113, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs7h", 114, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs8h", 115, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs9h", 116, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs10h", 117, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs11h", 118, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs12h", 119, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs13h", 120, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs14h", 121, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs15h", 122, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs16h", 123, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs17h", 124, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs18h", 125, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs19h", 126, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs20h", 127, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs21h", 128, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs22h", 129, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs23h", 130, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs24h", 131, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs25h", 132, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs26h", 133, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs27h", 134, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs28h", 135, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs29h", 136, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs30h", 137, 1, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "vs31h", 138, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.ppr"); ++ tdesc_create_reg (feature, "ppr", 139, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.dscr"); ++ tdesc_create_reg (feature, "dscr", 140, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar"); ++ tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb"); ++ tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu"); ++ tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.spr"); ++ tdesc_create_reg (feature, "tfhar", 150, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "texasr", 151, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "tfiar", 152, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.core"); ++ tdesc_create_reg (feature, "cr0", 153, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr1", 154, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr2", 155, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr3", 156, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr4", 157, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr5", 158, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr6", 159, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr7", 160, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr8", 161, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr9", 162, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr10", 163, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr11", 164, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr12", 165, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr13", 166, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr14", 167, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr15", 168, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr16", 169, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr17", 170, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr18", 171, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr19", 172, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr20", 173, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr21", 174, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr22", 175, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr23", 176, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr24", 177, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr25", 178, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr26", 179, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr27", 180, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr28", 181, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr29", 182, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr30", 183, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cr31", 184, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "ccr", 185, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "cxer", 186, 0, NULL, 32, "uint32"); ++ tdesc_create_reg (feature, "clr", 187, 0, NULL, 64, "code_ptr"); ++ tdesc_create_reg (feature, "cctr", 188, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.fpu"); ++ tdesc_create_reg (feature, "cf0", 189, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf1", 190, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf2", 191, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf3", 192, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf4", 193, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf5", 194, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf6", 195, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf7", 196, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf8", 197, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf9", 198, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf10", 199, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf11", 200, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf12", 201, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf13", 202, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf14", 203, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf15", 204, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf16", 205, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf17", 206, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf18", 207, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf19", 208, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf20", 209, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf21", 210, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf22", 211, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf23", 212, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf24", 213, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf25", 214, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf26", 215, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf27", 216, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf28", 217, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf29", 218, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf30", 219, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cf31", 220, 0, NULL, 64, "ieee_double"); ++ tdesc_create_reg (feature, "cfpscr", 221, 0, "float", 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.altivec"); ++ element_type = tdesc_named_type (feature, "ieee_single"); ++ tdesc_create_vector (feature, "v4f", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int32"); ++ tdesc_create_vector (feature, "v4i32", element_type, 4); ++ ++ element_type = tdesc_named_type (feature, "int16"); ++ tdesc_create_vector (feature, "v8i16", element_type, 8); ++ ++ element_type = tdesc_named_type (feature, "int8"); ++ tdesc_create_vector (feature, "v16i8", element_type, 16); ++ ++ type_with_fields = tdesc_create_union (feature, "vec128"); ++ field_type = tdesc_named_type (feature, "uint128"); ++ tdesc_add_field (type_with_fields, "uint128", field_type); ++ field_type = tdesc_named_type (feature, "v4f"); ++ tdesc_add_field (type_with_fields, "v4_float", field_type); ++ field_type = tdesc_named_type (feature, "v4i32"); ++ tdesc_add_field (type_with_fields, "v4_int32", field_type); ++ field_type = tdesc_named_type (feature, "v8i16"); ++ tdesc_add_field (type_with_fields, "v8_int16", field_type); ++ field_type = tdesc_named_type (feature, "v16i8"); ++ tdesc_add_field (type_with_fields, "v16_int8", field_type); ++ ++ tdesc_create_reg (feature, "cvr0", 222, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr1", 223, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr2", 224, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr3", 225, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr4", 226, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr5", 227, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr6", 228, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr7", 229, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr8", 230, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr9", 231, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr10", 232, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr11", 233, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr12", 234, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr13", 235, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr14", 236, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr15", 237, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr16", 238, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr17", 239, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr18", 240, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr19", 241, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr20", 242, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr21", 243, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr22", 244, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr23", 245, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr24", 246, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr25", 247, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr26", 248, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr27", 249, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr28", 250, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr29", 251, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr30", 252, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvr31", 253, 0, NULL, 128, "vec128"); ++ tdesc_create_reg (feature, "cvscr", 254, 0, "vector", 32, "int"); ++ tdesc_create_reg (feature, "cvrsave", 255, 0, "vector", 32, "int"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.vsx"); ++ tdesc_create_reg (feature, "cvs0h", 256, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs1h", 257, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs2h", 258, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs3h", 259, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs4h", 260, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs5h", 261, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs6h", 262, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs7h", 263, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs8h", 264, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs9h", 265, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs10h", 266, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs11h", 267, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs12h", 268, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs13h", 269, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs14h", 270, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs15h", 271, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs16h", 272, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs17h", 273, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs18h", 274, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs19h", 275, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs20h", 276, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs21h", 277, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs22h", 278, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs23h", 279, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs24h", 280, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs25h", 281, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs26h", 282, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs27h", 283, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs28h", 284, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs29h", 285, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs30h", 286, 0, NULL, 64, "uint64"); ++ tdesc_create_reg (feature, "cvs31h", 287, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.ppr"); ++ tdesc_create_reg (feature, "cppr", 288, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.dscr"); ++ tdesc_create_reg (feature, "cdscr", 289, 0, NULL, 64, "uint64"); ++ ++ feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.tar"); ++ tdesc_create_reg (feature, "ctar", 290, 0, NULL, 64, "uint64"); ++ ++ tdesc_powerpc_isa207_htm_vsx64l = result; ++} +diff --git a/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml b/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml +new file mode 100644 +--- /dev/null ++++ b/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml +@@ -0,0 +1,29 @@ ++ ++ ++ ++ ++ ++ powerpc:common64 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv +--- a/gdb/gdbserver/configure.srv ++++ b/gdb/gdbserver/configure.srv +@@ -32,7 +32,7 @@ else + srv_amd64_linux_regobj="" + fi + +-ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-isa205-ppr-dscr-vsx32l-ipa.o powerpc-isa207-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o powerpc-isa205-ppr-dscr-vsx64l-ipa.o powerpc-isa207-vsx64l-ipa.o" ++ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-isa205-ppr-dscr-vsx32l-ipa.o powerpc-isa207-vsx32l-ipa.o powerpc-isa207-htm-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o powerpc-isa205-ppr-dscr-vsx64l-ipa.o powerpc-isa207-vsx64l-ipa.o powerpc-isa207-htm-vsx64l-ipa.o" + + # Linux object files. This is so we don't have to repeat + # these files over and over again. +@@ -219,6 +219,7 @@ case "${target}" in + srv_regobj="${srv_regobj} powerpc-isa205-vsx32l.o" + srv_regobj="${srv_regobj} powerpc-isa205-ppr-dscr-vsx32l.o" + srv_regobj="${srv_regobj} powerpc-isa207-vsx32l.o" ++ srv_regobj="${srv_regobj} powerpc-isa207-htm-vsx32l.o" + srv_regobj="${srv_regobj} powerpc-e500l.o" + srv_regobj="${srv_regobj} powerpc-64l.o" + srv_regobj="${srv_regobj} powerpc-altivec64l.o" +@@ -229,6 +230,7 @@ case "${target}" in + srv_regobj="${srv_regobj} powerpc-isa205-vsx64l.o" + srv_regobj="${srv_regobj} powerpc-isa205-ppr-dscr-vsx64l.o" + srv_regobj="${srv_regobj} powerpc-isa207-vsx64l.o" ++ srv_regobj="${srv_regobj} powerpc-isa207-htm-vsx64l.o" + srv_tgtobj="$srv_linux_obj linux-ppc-low.o ppc-linux.o" + srv_tgtobj="${srv_tgtobj} arch/ppc-linux-common.o" + srv_xmlfiles="rs6000/powerpc-32l.xml" +@@ -240,6 +242,7 @@ case "${target}" in + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-vsx32l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-vsx32l.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-htm-vsx32l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-altivec.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-vsx.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-core.xml" +@@ -251,6 +254,14 @@ case "${target}" in + srv_xmlfiles="${srv_xmlfiles} rs6000/power-tar.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-ebb.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-linux-pmu.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-spr.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-core.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-fpu.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-altivec.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-vsx.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-ppr.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-dscr.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-tar.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-e500l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-spe.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-64l.xml" +@@ -262,8 +273,10 @@ case "${target}" in + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-vsx64l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-vsx64l.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-htm-vsx64l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power64-core.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power64-linux.xml" ++ srv_xmlfiles="${srv_xmlfiles} rs6000/power64-htm-core.xml" + srv_linux_usrregs=yes + srv_linux_regsets=yes + srv_linux_thread_db=yes +diff --git a/gdb/gdbserver/linux-ppc-ipa.c b/gdb/gdbserver/linux-ppc-ipa.c +--- a/gdb/gdbserver/linux-ppc-ipa.c ++++ b/gdb/gdbserver/linux-ppc-ipa.c +@@ -195,6 +195,8 @@ get_ipa_tdesc (int idx) + return tdesc_powerpc_isa205_ppr_dscr_vsx64l; + case PPC_TDESC_ISA207_VSX: + return tdesc_powerpc_isa207_vsx64l; ++ case PPC_TDESC_ISA207_HTM_VSX: ++ return tdesc_powerpc_isa207_htm_vsx64l; + #else + case PPC_TDESC_BASE: + return tdesc_powerpc_32l; +@@ -214,6 +216,8 @@ get_ipa_tdesc (int idx) + return tdesc_powerpc_isa205_ppr_dscr_vsx32l; + case PPC_TDESC_ISA207_VSX: + return tdesc_powerpc_isa207_vsx32l; ++ case PPC_TDESC_ISA207_HTM_VSX: ++ return tdesc_powerpc_isa207_htm_vsx32l; + case PPC_TDESC_E500: + return tdesc_powerpc_e500l; + #endif +@@ -244,6 +248,7 @@ initialize_low_tracepoint (void) + init_registers_powerpc_isa205_vsx64l (); + init_registers_powerpc_isa205_ppr_dscr_vsx64l (); + init_registers_powerpc_isa207_vsx64l (); ++ init_registers_powerpc_isa207_htm_vsx64l (); + #else + init_registers_powerpc_32l (); + init_registers_powerpc_altivec32l (); +@@ -254,6 +259,7 @@ initialize_low_tracepoint (void) + init_registers_powerpc_isa205_vsx32l (); + init_registers_powerpc_isa205_ppr_dscr_vsx32l (); + init_registers_powerpc_isa207_vsx32l (); ++ init_registers_powerpc_isa207_htm_vsx32l (); + init_registers_powerpc_e500l (); + #endif + } +diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c +--- a/gdb/gdbserver/linux-ppc-low.c ++++ b/gdb/gdbserver/linux-ppc-low.c +@@ -600,6 +600,158 @@ ppc_store_pmuregset (struct regcache *regcache, const void *buf) + supply_register_by_name (regcache, "mmcr0", ®set[32]); + } + ++/* Hardware Transactional Memory special-purpose register regset fill ++ function. */ ++ ++static void ++ppc_fill_tm_sprregset (struct regcache *regcache, void *buf) ++{ ++ int i, base; ++ char *regset = (char *) buf; ++ ++ base = find_regno (regcache->tdesc, "tfhar"); ++ for (i = 0; i < 3; i++) ++ collect_register (regcache, base + i, ®set[i * 8]); ++} ++ ++/* Hardware Transactional Memory special-purpose register regset store ++ function. */ ++ ++static void ++ppc_store_tm_sprregset (struct regcache *regcache, const void *buf) ++{ ++ int i, base; ++ const char *regset = (const char *) buf; ++ ++ base = find_regno (regcache->tdesc, "tfhar"); ++ for (i = 0; i < 3; i++) ++ supply_register (regcache, base + i, ®set[i * 8]); ++} ++ ++/* For the same reasons as the EBB regset, none of the HTM ++ checkpointed regsets have a fill function. These registers are ++ only available if the inferior is in a transaction. */ ++ ++/* Hardware Transactional Memory checkpointed general-purpose regset ++ store function. */ ++ ++static void ++ppc_store_tm_cgprregset (struct regcache *regcache, const void *buf) ++{ ++ int i, base, size, endian_offset; ++ const char *regset = (const char *) buf; ++ ++ base = find_regno (regcache->tdesc, "cr0"); ++ size = register_size (regcache->tdesc, base); ++ ++ gdb_assert (size == 4 || size == 8); ++ ++ for (i = 0; i < 32; i++) ++ supply_register (regcache, base + i, ®set[i * size]); ++ ++ endian_offset = 0; ++ ++ if ((size == 8) && (__BYTE_ORDER == __BIG_ENDIAN)) ++ endian_offset = 4; ++ ++ supply_register_by_name (regcache, "ccr", ++ ®set[PT_CCR * size + endian_offset]); ++ ++ supply_register_by_name (regcache, "cxer", ++ ®set[PT_XER * size + endian_offset]); ++ ++ supply_register_by_name (regcache, "clr", ®set[PT_LNK * size]); ++ supply_register_by_name (regcache, "cctr", ®set[PT_CTR * size]); ++} ++ ++/* Hardware Transactional Memory checkpointed floating-point regset ++ store function. */ ++ ++static void ++ppc_store_tm_cfprregset (struct regcache *regcache, const void *buf) ++{ ++ int i, base; ++ const char *regset = (const char *) buf; ++ ++ base = find_regno (regcache->tdesc, "cf0"); ++ ++ for (i = 0; i < 32; i++) ++ supply_register (regcache, base + i, ®set[i * 8]); ++ ++ supply_register_by_name (regcache, "cfpscr", ®set[32 * 8]); ++} ++ ++/* Hardware Transactional Memory checkpointed vector regset store ++ function. */ ++ ++static void ++ppc_store_tm_cvrregset (struct regcache *regcache, const void *buf) ++{ ++ int i, base; ++ const char *regset = (const char *) buf; ++ int vscr_offset = 0; ++ ++ base = find_regno (regcache->tdesc, "cvr0"); ++ ++ for (i = 0; i < 32; i++) ++ supply_register (regcache, base + i, ®set[i * 16]); ++ ++ if (__BYTE_ORDER == __BIG_ENDIAN) ++ vscr_offset = 12; ++ ++ supply_register_by_name (regcache, "cvscr", ++ ®set[32 * 16 + vscr_offset]); ++ ++ supply_register_by_name (regcache, "cvrsave", ®set[33 * 16]); ++} ++ ++/* Hardware Transactional Memory checkpointed vector-scalar regset ++ store function. */ ++ ++static void ++ppc_store_tm_cvsxregset (struct regcache *regcache, const void *buf) ++{ ++ int i, base; ++ const char *regset = (const char *) buf; ++ ++ base = find_regno (regcache->tdesc, "cvs0h"); ++ for (i = 0; i < 32; i++) ++ supply_register (regcache, base + i, ®set[i * 8]); ++} ++ ++/* Hardware Transactional Memory checkpointed Program Priority ++ Register regset store function. */ ++ ++static void ++ppc_store_tm_cpprregset (struct regcache *regcache, const void *buf) ++{ ++ const char *cppr = (const char *) buf; ++ ++ supply_register_by_name (regcache, "cppr", cppr); ++} ++ ++/* Hardware Transactional Memory checkpointed Data Stream Control ++ Register regset store function. */ ++ ++static void ++ppc_store_tm_cdscrregset (struct regcache *regcache, const void *buf) ++{ ++ const char *cdscr = (const char *) buf; ++ ++ supply_register_by_name (regcache, "cdscr", cdscr); ++} ++ ++/* Hardware Transactional Memory checkpointed Target Address Register ++ regset store function. */ ++ ++static void ++ppc_store_tm_ctarregset (struct regcache *regcache, const void *buf) ++{ ++ const char *ctar = (const char *) buf; ++ ++ supply_register_by_name (regcache, "ctar", ctar); ++} ++ + static void + ppc_fill_vsxregset (struct regcache *regcache, void *buf) + { +@@ -709,6 +861,22 @@ static struct regset_info ppc_regsets[] = { + fetch them every time, but still fall back to PTRACE_PEEKUSER for the + general registers. Some kernels support these, but not the newer + PPC_PTRACE_GETREGS. */ ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CTAR, 0, EXTENDED_REGS, ++ NULL, ppc_store_tm_ctarregset }, ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CDSCR, 0, EXTENDED_REGS, ++ NULL, ppc_store_tm_cdscrregset }, ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CPPR, 0, EXTENDED_REGS, ++ NULL, ppc_store_tm_cpprregset }, ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CVSX, 0, EXTENDED_REGS, ++ NULL, ppc_store_tm_cvsxregset }, ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CVMX, 0, EXTENDED_REGS, ++ NULL, ppc_store_tm_cvrregset }, ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CFPR, 0, EXTENDED_REGS, ++ NULL, ppc_store_tm_cfprregset }, ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CGPR, 0, EXTENDED_REGS, ++ NULL, ppc_store_tm_cgprregset }, ++ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_SPR, 0, EXTENDED_REGS, ++ ppc_fill_tm_sprregset, ppc_store_tm_sprregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_EBB, 0, EXTENDED_REGS, + NULL, ppc_store_ebbregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PMU, 0, EXTENDED_REGS, +@@ -800,7 +968,13 @@ ppc_arch_setup (void) + PPC_LINUX_SIZEOF_EBBREGSET) + && ppc_check_regset (tid, NT_PPC_PMU, + PPC_LINUX_SIZEOF_PMUREGSET)) +- features.isa207 = true; ++ { ++ features.isa207 = true; ++ if ((ppc_hwcap2 & PPC_FEATURE2_HTM) ++ && ppc_check_regset (tid, NT_PPC_TM_SPR, ++ PPC_LINUX_SIZEOF_TM_SPRREGSET)) ++ features.htm = true; ++ } + } + + if (ppc_hwcap & PPC_FEATURE_CELL) +@@ -870,6 +1044,42 @@ ppc_arch_setup (void) + regset->size = (features.isa207 ? + PPC_LINUX_SIZEOF_PMUREGSET : 0); + break; ++ case NT_PPC_TM_SPR: ++ regset->size = (features.htm ? ++ PPC_LINUX_SIZEOF_TM_SPRREGSET : 0); ++ break; ++ case NT_PPC_TM_CGPR: ++ if (features.wordsize == 4) ++ regset->size = (features.htm ? ++ PPC32_LINUX_SIZEOF_CGPRREGSET : 0); ++ else ++ regset->size = (features.htm ? ++ PPC64_LINUX_SIZEOF_CGPRREGSET : 0); ++ break; ++ case NT_PPC_TM_CFPR: ++ regset->size = (features.htm ? ++ PPC_LINUX_SIZEOF_CFPRREGSET : 0); ++ break; ++ case NT_PPC_TM_CVMX: ++ regset->size = (features.htm ? ++ PPC_LINUX_SIZEOF_CVMXREGSET : 0); ++ break; ++ case NT_PPC_TM_CVSX: ++ regset->size = (features.htm ? ++ PPC_LINUX_SIZEOF_CVSXREGSET : 0); ++ break; ++ case NT_PPC_TM_CPPR: ++ regset->size = (features.htm ? ++ PPC_LINUX_SIZEOF_CPPRREGSET : 0); ++ break; ++ case NT_PPC_TM_CDSCR: ++ regset->size = (features.htm ? ++ PPC_LINUX_SIZEOF_CDSCRREGSET : 0); ++ break; ++ case NT_PPC_TM_CTAR: ++ regset->size = (features.htm ? ++ PPC_LINUX_SIZEOF_CTARREGSET : 0); ++ break; + default: + break; + } +@@ -3253,6 +3463,8 @@ ppc_get_ipa_tdesc_idx (void) + return PPC_TDESC_ISA205_PPR_DSCR_VSX; + if (tdesc == tdesc_powerpc_isa207_vsx64l) + return PPC_TDESC_ISA207_VSX; ++ if (tdesc == tdesc_powerpc_isa207_htm_vsx64l) ++ return PPC_TDESC_ISA207_HTM_VSX; + #endif + + if (tdesc == tdesc_powerpc_32l) +@@ -3273,6 +3485,8 @@ ppc_get_ipa_tdesc_idx (void) + return PPC_TDESC_ISA205_PPR_DSCR_VSX; + if (tdesc == tdesc_powerpc_isa207_vsx32l) + return PPC_TDESC_ISA207_VSX; ++ if (tdesc == tdesc_powerpc_isa207_htm_vsx32l) ++ return PPC_TDESC_ISA207_HTM_VSX; + if (tdesc == tdesc_powerpc_e500l) + return PPC_TDESC_E500; + +@@ -3333,6 +3547,7 @@ initialize_low_arch (void) + init_registers_powerpc_isa205_vsx32l (); + init_registers_powerpc_isa205_ppr_dscr_vsx32l (); + init_registers_powerpc_isa207_vsx32l (); ++ init_registers_powerpc_isa207_htm_vsx32l (); + init_registers_powerpc_e500l (); + #if __powerpc64__ + init_registers_powerpc_64l (); +@@ -3344,6 +3559,7 @@ initialize_low_arch (void) + init_registers_powerpc_isa205_vsx64l (); + init_registers_powerpc_isa205_ppr_dscr_vsx64l (); + init_registers_powerpc_isa207_vsx64l (); ++ init_registers_powerpc_isa207_htm_vsx64l (); + #endif + + initialize_regsets_info (&ppc_regsets_info); +diff --git a/gdb/gdbserver/linux-ppc-tdesc-init.h b/gdb/gdbserver/linux-ppc-tdesc-init.h +--- a/gdb/gdbserver/linux-ppc-tdesc-init.h ++++ b/gdb/gdbserver/linux-ppc-tdesc-init.h +@@ -31,6 +31,7 @@ enum ppc_linux_tdesc { + PPC_TDESC_ISA205_VSX, + PPC_TDESC_ISA205_PPR_DSCR_VSX, + PPC_TDESC_ISA207_VSX, ++ PPC_TDESC_ISA207_HTM_VSX, + PPC_TDESC_E500, + }; + +@@ -63,6 +64,9 @@ void init_registers_powerpc_isa205_ppr_dscr_vsx32l (void); + /* Defined in auto-generated file powerpc-isa207-vsx32l.c. */ + void init_registers_powerpc_isa207_vsx32l (void); + ++/* Defined in auto-generated file powerpc-isa207-htm-vsx32l.c. */ ++void init_registers_powerpc_isa207_htm_vsx32l (void); ++ + /* Defined in auto-generated file powerpc-e500l.c. */ + void init_registers_powerpc_e500l (void); + +@@ -97,4 +101,7 @@ void init_registers_powerpc_isa205_ppr_dscr_vsx64l (void); + /* Defined in auto-generated file powerpc-isa207-vsx64l.c. */ + void init_registers_powerpc_isa207_vsx64l (void); + ++/* Defined in auto-generated file powerpc-isa207-htm-vsx64l.c. */ ++void init_registers_powerpc_isa207_htm_vsx64l (void); ++ + #endif +diff --git a/gdb/nat/ppc-linux.h b/gdb/nat/ppc-linux.h +--- a/gdb/nat/ppc-linux.h ++++ b/gdb/nat/ppc-linux.h +@@ -63,6 +63,9 @@ + #ifndef PPC_FEATURE2_EBB + #define PPC_FEATURE2_EBB 0x10000000 + #endif ++#ifndef PPC_FEATURE2_HTM ++#define PPC_FEATURE2_HTM 0x40000000 ++#endif + + /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a + configure time check. Some older glibc's (for instance 2.2.1) +@@ -119,6 +122,46 @@ + #define NT_PPC_PMU 0x107 + #endif + ++/* TM checkpointed GPR Registers. */ ++#ifndef NT_PPC_TM_CGPR ++#define NT_PPC_TM_CGPR 0x108 ++#endif ++ ++/* TM checkpointed FPR Registers. */ ++#ifndef NT_PPC_TM_CFPR ++#define NT_PPC_TM_CFPR 0x109 ++#endif ++ ++/* TM checkpointed VMX Registers. */ ++#ifndef NT_PPC_TM_CVMX ++#define NT_PPC_TM_CVMX 0x10a ++#endif ++ ++/* TM checkpointed VSX Registers. */ ++#ifndef NT_PPC_TM_CVSX ++#define NT_PPC_TM_CVSX 0x10b ++#endif ++ ++/* TM Special Purpose Registers. */ ++#ifndef NT_PPC_TM_SPR ++#define NT_PPC_TM_SPR 0x10c ++#endif ++ ++/* TM checkpointed Target Address Register. */ ++#ifndef NT_PPC_TM_CTAR ++#define NT_PPC_TM_CTAR 0x10d ++#endif ++ ++/* TM checkpointed Program Priority Register. */ ++#ifndef NT_PPC_TM_CPPR ++#define NT_PPC_TM_CPPR 0x10e ++#endif ++ ++/* TM checkpointed Data Stream Control Register. */ ++#ifndef NT_PPC_TM_CDSCR ++#define NT_PPC_TM_CDSCR 0x10f ++#endif ++ + /* Return the wordsize of the target, either 4 or 8 bytes. */ + int ppc_linux_target_wordsize (int tid); + +diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c +--- a/gdb/ppc-linux-nat.c ++++ b/gdb/ppc-linux-nat.c +@@ -685,6 +685,82 @@ fetch_register (struct regcache *regcache, int tid, int regno) + &ppc32_linux_pmuregset); + return; + } ++ else if (PPC_IS_TMSPR_REGNUM (regno)) ++ { ++ gdb_assert (tdep->have_htm_spr); ++ ++ fetch_regset (regcache, tid, NT_PPC_TM_SPR, ++ PPC_LINUX_SIZEOF_TM_SPRREGSET, ++ &ppc32_linux_tm_sprregset); ++ return; ++ } ++ else if (PPC_IS_CKPTGP_REGNUM (regno)) ++ { ++ gdb_assert (tdep->have_htm_core); ++ ++ const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch); ++ fetch_regset (regcache, tid, NT_PPC_TM_CGPR, ++ (tdep->wordsize == 4? ++ PPC32_LINUX_SIZEOF_CGPRREGSET ++ : PPC64_LINUX_SIZEOF_CGPRREGSET), ++ cgprregset); ++ return; ++ } ++ else if (PPC_IS_CKPTFP_REGNUM (regno)) ++ { ++ gdb_assert (tdep->have_htm_fpu); ++ ++ fetch_regset (regcache, tid, NT_PPC_TM_CFPR, ++ PPC_LINUX_SIZEOF_CFPRREGSET, ++ &ppc32_linux_cfprregset); ++ return; ++ } ++ else if (PPC_IS_CKPTVMX_REGNUM (regno)) ++ { ++ gdb_assert (tdep->have_htm_altivec); ++ ++ const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch); ++ fetch_regset (regcache, tid, NT_PPC_TM_CVMX, ++ PPC_LINUX_SIZEOF_CVMXREGSET, ++ cvmxregset); ++ return; ++ } ++ else if (PPC_IS_CKPTVSX_REGNUM (regno)) ++ { ++ gdb_assert (tdep->have_htm_vsx); ++ ++ fetch_regset (regcache, tid, NT_PPC_TM_CVSX, ++ PPC_LINUX_SIZEOF_CVSXREGSET, ++ &ppc32_linux_cvsxregset); ++ return; ++ } ++ else if (regno == PPC_CPPR_REGNUM) ++ { ++ gdb_assert (tdep->ppc_cppr_regnum != -1); ++ ++ fetch_regset (regcache, tid, NT_PPC_TM_CPPR, ++ PPC_LINUX_SIZEOF_CPPRREGSET, ++ &ppc32_linux_cpprregset); ++ return; ++ } ++ else if (regno == PPC_CDSCR_REGNUM) ++ { ++ gdb_assert (tdep->ppc_cdscr_regnum != -1); ++ ++ fetch_regset (regcache, tid, NT_PPC_TM_CDSCR, ++ PPC_LINUX_SIZEOF_CDSCRREGSET, ++ &ppc32_linux_cdscrregset); ++ return; ++ } ++ else if (regno == PPC_CTAR_REGNUM) ++ { ++ gdb_assert (tdep->ppc_ctar_regnum != -1); ++ ++ fetch_regset (regcache, tid, NT_PPC_TM_CTAR, ++ PPC_LINUX_SIZEOF_CTARREGSET, ++ &ppc32_linux_ctarregset); ++ return; ++ } + + if (regaddr == -1) + { +@@ -901,6 +977,46 @@ fetch_ppc_registers (struct regcache *regcache, int tid) + fetch_regset (regcache, tid, NT_PPC_PMU, + PPC_LINUX_SIZEOF_PMUREGSET, + &ppc32_linux_pmuregset); ++ if (tdep->have_htm_spr) ++ fetch_regset (regcache, tid, NT_PPC_TM_SPR, ++ PPC_LINUX_SIZEOF_TM_SPRREGSET, ++ &ppc32_linux_tm_sprregset); ++ if (tdep->have_htm_core) ++ { ++ const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch); ++ fetch_regset (regcache, tid, NT_PPC_TM_CGPR, ++ (tdep->wordsize == 4? ++ PPC32_LINUX_SIZEOF_CGPRREGSET ++ : PPC64_LINUX_SIZEOF_CGPRREGSET), ++ cgprregset); ++ } ++ if (tdep->have_htm_fpu) ++ fetch_regset (regcache, tid, NT_PPC_TM_CFPR, ++ PPC_LINUX_SIZEOF_CFPRREGSET, ++ &ppc32_linux_cfprregset); ++ if (tdep->have_htm_altivec) ++ { ++ const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch); ++ fetch_regset (regcache, tid, NT_PPC_TM_CVMX, ++ PPC_LINUX_SIZEOF_CVMXREGSET, ++ cvmxregset); ++ } ++ if (tdep->have_htm_vsx) ++ fetch_regset (regcache, tid, NT_PPC_TM_CVSX, ++ PPC_LINUX_SIZEOF_CVSXREGSET, ++ &ppc32_linux_cvsxregset); ++ if (tdep->ppc_cppr_regnum != -1) ++ fetch_regset (regcache, tid, NT_PPC_TM_CPPR, ++ PPC_LINUX_SIZEOF_CPPRREGSET, ++ &ppc32_linux_cpprregset); ++ if (tdep->ppc_cdscr_regnum != -1) ++ fetch_regset (regcache, tid, NT_PPC_TM_CDSCR, ++ PPC_LINUX_SIZEOF_CDSCRREGSET, ++ &ppc32_linux_cdscrregset); ++ if (tdep->ppc_ctar_regnum != -1) ++ fetch_regset (regcache, tid, NT_PPC_TM_CTAR, ++ PPC_LINUX_SIZEOF_CTARREGSET, ++ &ppc32_linux_ctarregset); + } + + /* Fetch registers from the child process. Fetch all registers if +@@ -1126,6 +1242,82 @@ store_register (const struct regcache *regcache, int tid, int regno) + &ppc32_linux_pmuregset); + return; + } ++ else if (PPC_IS_TMSPR_REGNUM (regno)) ++ { ++ gdb_assert (tdep->have_htm_spr); ++ ++ store_regset (regcache, tid, regno, NT_PPC_TM_SPR, ++ PPC_LINUX_SIZEOF_TM_SPRREGSET, ++ &ppc32_linux_tm_sprregset); ++ return; ++ } ++ else if (PPC_IS_CKPTGP_REGNUM (regno)) ++ { ++ gdb_assert (tdep->have_htm_core); ++ ++ const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch); ++ store_regset (regcache, tid, regno, NT_PPC_TM_CGPR, ++ (tdep->wordsize == 4? ++ PPC32_LINUX_SIZEOF_CGPRREGSET ++ : PPC64_LINUX_SIZEOF_CGPRREGSET), ++ cgprregset); ++ return; ++ } ++ else if (PPC_IS_CKPTFP_REGNUM (regno)) ++ { ++ gdb_assert (tdep->have_htm_fpu); ++ ++ store_regset (regcache, tid, regno, NT_PPC_TM_CFPR, ++ PPC_LINUX_SIZEOF_CFPRREGSET, ++ &ppc32_linux_cfprregset); ++ return; ++ } ++ else if (PPC_IS_CKPTVMX_REGNUM (regno)) ++ { ++ gdb_assert (tdep->have_htm_altivec); ++ ++ const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch); ++ store_regset (regcache, tid, regno, NT_PPC_TM_CVMX, ++ PPC_LINUX_SIZEOF_CVMXREGSET, ++ cvmxregset); ++ return; ++ } ++ else if (PPC_IS_CKPTVSX_REGNUM (regno)) ++ { ++ gdb_assert (tdep->have_htm_vsx); ++ ++ store_regset (regcache, tid, regno, NT_PPC_TM_CVSX, ++ PPC_LINUX_SIZEOF_CVSXREGSET, ++ &ppc32_linux_cvsxregset); ++ return; ++ } ++ else if (regno == PPC_CPPR_REGNUM) ++ { ++ gdb_assert (tdep->ppc_cppr_regnum != -1); ++ ++ store_regset (regcache, tid, regno, NT_PPC_TM_CPPR, ++ PPC_LINUX_SIZEOF_CPPRREGSET, ++ &ppc32_linux_cpprregset); ++ return; ++ } ++ else if (regno == PPC_CDSCR_REGNUM) ++ { ++ gdb_assert (tdep->ppc_cdscr_regnum != -1); ++ ++ store_regset (regcache, tid, regno, NT_PPC_TM_CDSCR, ++ PPC_LINUX_SIZEOF_CDSCRREGSET, ++ &ppc32_linux_cdscrregset); ++ return; ++ } ++ else if (regno == PPC_CTAR_REGNUM) ++ { ++ gdb_assert (tdep->ppc_ctar_regnum != -1); ++ ++ store_regset (regcache, tid, regno, NT_PPC_TM_CTAR, ++ PPC_LINUX_SIZEOF_CTARREGSET, ++ &ppc32_linux_ctarregset); ++ return; ++ } + + if (regaddr == -1) + return; +@@ -1358,9 +1550,14 @@ store_ppc_registers (const struct regcache *regcache, int tid) + PPC_LINUX_SIZEOF_PMUREGSET, + &ppc32_linux_pmuregset); + +- /* Because the EBB registers can be unavailable, attempts to store +- them here would cause this function to fail most of the time, so +- we ignore them. */ ++ if (tdep->have_htm_spr) ++ store_regset (regcache, tid, -1, NT_PPC_TM_SPR, ++ PPC_LINUX_SIZEOF_TM_SPRREGSET, ++ &ppc32_linux_tm_sprregset); ++ ++ /* Because the EBB and checkpointed HTM registers can be ++ unavailable, attempts to store them here would cause this ++ function to fail most of the time, so we ignore them. */ + } + + /* Fetch the AT_HWCAP entry from the aux vector. */ +@@ -2496,7 +2693,13 @@ ppc_linux_nat_target::read_description () + && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET) + && check_regset (tid, NT_PPC_EBB, PPC_LINUX_SIZEOF_EBBREGSET) + && check_regset (tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET)) +- features.isa207 = true; ++ { ++ features.isa207 = true; ++ if ((hwcap2 & PPC_FEATURE2_HTM) ++ && check_regset (tid, NT_PPC_TM_SPR, ++ PPC_LINUX_SIZEOF_TM_SPRREGSET)) ++ features.htm = true; ++ } + } + + return ppc_linux_match_description (features); +diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c +--- a/gdb/ppc-linux-tdep.c ++++ b/gdb/ppc-linux-tdep.c +@@ -73,6 +73,7 @@ + #include "features/rs6000/powerpc-isa205-vsx32l.c" + #include "features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c" + #include "features/rs6000/powerpc-isa207-vsx32l.c" ++#include "features/rs6000/powerpc-isa207-htm-vsx32l.c" + #include "features/rs6000/powerpc-64l.c" + #include "features/rs6000/powerpc-altivec64l.c" + #include "features/rs6000/powerpc-cell64l.c" +@@ -82,6 +83,7 @@ + #include "features/rs6000/powerpc-isa205-vsx64l.c" + #include "features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c" + #include "features/rs6000/powerpc-isa207-vsx64l.c" ++#include "features/rs6000/powerpc-isa207-htm-vsx64l.c" + #include "features/rs6000/powerpc-e500l.c" + + /* Shared library operations for PowerPC-Linux. */ +@@ -637,6 +639,239 @@ const struct regset ppc32_linux_pmuregset = { + regcache_collect_regset + }; + ++/* Hardware Transactional Memory special-purpose register regmap. */ ++ ++static const struct regcache_map_entry ppc32_regmap_tm_spr[] = ++ { ++ { 1, PPC_TFHAR_REGNUM, 8 }, ++ { 1, PPC_TEXASR_REGNUM, 8 }, ++ { 1, PPC_TFIAR_REGNUM, 8 }, ++ { 0 } ++ }; ++ ++/* Hardware Transactional Memory special-purpose register regset. */ ++ ++const struct regset ppc32_linux_tm_sprregset = { ++ ppc32_regmap_tm_spr, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ ++/* Regmaps for the Hardware Transactional Memory checkpointed ++ general-purpose regsets for 32-bit, 64-bit big-endian, and 64-bit ++ little endian targets. The ptrace and core file buffers for 64-bit ++ targets use 8-byte fields for the 4-byte registers, and the ++ position of the register in the fields depends on the endianess. ++ The 32-bit regmap is the same for both endian types because the ++ fields are all 4-byte long. ++ ++ The layout of checkpointed GPR regset is the same as a regular ++ struct pt_regs, but we skip all registers that are not actually ++ checkpointed by the processor (e.g. msr, nip), except when ++ generating a core file. The 64-bit regset is 48 * 8 bytes long. ++ In some 64-bit kernels, the regset for a 32-bit inferior has the ++ same length, but all the registers are squeezed in the first half ++ (48 * 4 bytes). The pt_regs struct calls the regular cr ccr, but ++ we use ccr for "checkpointed condition register". Note that CR ++ (condition register) field 0 is not checkpointed, but the kernel ++ returns all 4 bytes. The skipped registers should not be touched ++ when writing the regset to the inferior (with ++ PTRACE_SETREGSET). */ ++ ++static const struct regcache_map_entry ppc32_regmap_cgpr[] = ++ { ++ { 32, PPC_CR0_REGNUM, 4 }, ++ { 3, REGCACHE_MAP_SKIP, 4 }, /* nip, msr, orig_gpr3. */ ++ { 1, PPC_CCTR_REGNUM, 4 }, ++ { 1, PPC_CLR_REGNUM, 4 }, ++ { 1, PPC_CXER_REGNUM, 4 }, ++ { 1, PPC_CCR_REGNUM, 4 }, ++ { 9, REGCACHE_MAP_SKIP, 4 }, /* All the rest. */ ++ { 0 } ++ }; ++ ++static const struct regcache_map_entry ppc64_le_regmap_cgpr[] = ++ { ++ { 32, PPC_CR0_REGNUM, 8 }, ++ { 3, REGCACHE_MAP_SKIP, 8 }, ++ { 1, PPC_CCTR_REGNUM, 8 }, ++ { 1, PPC_CLR_REGNUM, 8 }, ++ { 1, PPC_CXER_REGNUM, 4 }, ++ { 1, REGCACHE_MAP_SKIP, 4 }, /* CXER padding. */ ++ { 1, PPC_CCR_REGNUM, 4 }, ++ { 1, REGCACHE_MAP_SKIP, 4}, /* CCR padding. */ ++ { 9, REGCACHE_MAP_SKIP, 8}, ++ { 0 } ++ }; ++ ++static const struct regcache_map_entry ppc64_be_regmap_cgpr[] = ++ { ++ { 32, PPC_CR0_REGNUM, 8 }, ++ { 3, REGCACHE_MAP_SKIP, 8 }, ++ { 1, PPC_CCTR_REGNUM, 8 }, ++ { 1, PPC_CLR_REGNUM, 8 }, ++ { 1, REGCACHE_MAP_SKIP, 4}, /* CXER padding. */ ++ { 1, PPC_CXER_REGNUM, 4 }, ++ { 1, REGCACHE_MAP_SKIP, 4}, /* CCR padding. */ ++ { 1, PPC_CCR_REGNUM, 4 }, ++ { 9, REGCACHE_MAP_SKIP, 8}, ++ { 0 } ++ }; ++ ++/* Regsets for the Hardware Transactional Memory checkpointed ++ general-purpose registers for 32-bit, 64-bit big-endian, and 64-bit ++ little endian targets. ++ ++ Some 64-bit kernels generate a checkpointed gpr note section with ++ 48*8 bytes for a 32-bit thread, of which only 48*4 are actually ++ used, so we set the variable size flag in the corresponding regset ++ to accept this case. */ ++ ++static const struct regset ppc32_linux_cgprregset = { ++ ppc32_regmap_cgpr, ++ regcache_supply_regset, ++ regcache_collect_regset, ++ REGSET_VARIABLE_SIZE ++}; ++ ++static const struct regset ppc64_be_linux_cgprregset = { ++ ppc64_be_regmap_cgpr, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ ++static const struct regset ppc64_le_linux_cgprregset = { ++ ppc64_le_regmap_cgpr, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ ++/* Hardware Transactional Memory checkpointed floating-point regmap. */ ++ ++static const struct regcache_map_entry ppc32_regmap_cfpr[] = ++ { ++ { 32, PPC_CF0_REGNUM, 8 }, ++ { 1, PPC_CFPSCR_REGNUM, 8 }, ++ { 0 } ++ }; ++ ++/* Hardware Transactional Memory checkpointed floating-point regset. */ ++ ++const struct regset ppc32_linux_cfprregset = { ++ ppc32_regmap_cfpr, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ ++/* Regmaps for the Hardware Transactional Memory checkpointed vector ++ regsets, for big and little endian targets. The position of the ++ 4-byte VSCR in its 16-byte field depends on the endianess. */ ++ ++static const struct regcache_map_entry ppc32_le_regmap_cvmx[] = ++ { ++ { 32, PPC_CVR0_REGNUM, 16 }, ++ { 1, PPC_CVSCR_REGNUM, 4 }, ++ { 1, REGCACHE_MAP_SKIP, 12 }, ++ { 1, PPC_CVRSAVE_REGNUM, 4 }, ++ { 1, REGCACHE_MAP_SKIP, 12 }, ++ { 0 } ++ }; ++ ++static const struct regcache_map_entry ppc32_be_regmap_cvmx[] = ++ { ++ { 32, PPC_CVR0_REGNUM, 16 }, ++ { 1, REGCACHE_MAP_SKIP, 12 }, ++ { 1, PPC_CVSCR_REGNUM, 4 }, ++ { 1, PPC_CVRSAVE_REGNUM, 4 }, ++ { 1, REGCACHE_MAP_SKIP, 12}, ++ { 0 } ++ }; ++ ++/* Hardware Transactional Memory checkpointed vector regsets, for little ++ and big endian targets. */ ++ ++static const struct regset ppc32_le_linux_cvmxregset = { ++ ppc32_le_regmap_cvmx, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ ++static const struct regset ppc32_be_linux_cvmxregset = { ++ ppc32_be_regmap_cvmx, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ ++/* Hardware Transactional Memory checkpointed vector-scalar regmap. */ ++ ++static const struct regcache_map_entry ppc32_regmap_cvsx[] = ++ { ++ { 32, PPC_CVSR0_UPPER_REGNUM, 8 }, ++ { 0 } ++ }; ++ ++/* Hardware Transactional Memory checkpointed vector-scalar regset. */ ++ ++const struct regset ppc32_linux_cvsxregset = { ++ ppc32_regmap_cvsx, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ ++/* Hardware Transactional Memory checkpointed Program Priority Register ++ regmap. */ ++ ++static const struct regcache_map_entry ppc32_regmap_cppr[] = ++ { ++ { 1, PPC_CPPR_REGNUM, 8 }, ++ { 0 } ++ }; ++ ++/* Hardware Transactional Memory checkpointed Program Priority Register ++ regset. */ ++ ++const struct regset ppc32_linux_cpprregset = { ++ ppc32_regmap_cppr, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ ++/* Hardware Transactional Memory checkpointed Data Stream Control ++ Register regmap. */ ++ ++static const struct regcache_map_entry ppc32_regmap_cdscr[] = ++ { ++ { 1, PPC_CDSCR_REGNUM, 8 }, ++ { 0 } ++ }; ++ ++/* Hardware Transactional Memory checkpointed Data Stream Control ++ Register regset. */ ++ ++const struct regset ppc32_linux_cdscrregset = { ++ ppc32_regmap_cdscr, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ ++/* Hardware Transactional Memory checkpointed Target Address Register ++ regmap. */ ++ ++static const struct regcache_map_entry ppc32_regmap_ctar[] = ++ { ++ { 1, PPC_CTAR_REGNUM, 8 }, ++ { 0 } ++ }; ++ ++/* Hardware Transactional Memory checkpointed Target Address Register ++ regset. */ ++ ++const struct regset ppc32_linux_ctarregset = { ++ ppc32_regmap_ctar, ++ regcache_supply_regset, ++ regcache_collect_regset ++}; ++ + const struct regset * + ppc_linux_gregset (int wordsize) + { +@@ -664,6 +899,88 @@ ppc_linux_vsxregset (void) + return &ppc32_linux_vsxregset; + } + ++const struct regset * ++ppc_linux_cgprregset (struct gdbarch *gdbarch) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ ++ if (tdep->wordsize == 4) ++ { ++ return &ppc32_linux_cgprregset; ++ } ++ else ++ { ++ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) ++ return &ppc64_be_linux_cgprregset; ++ else ++ return &ppc64_le_linux_cgprregset; ++ } ++} ++ ++const struct regset * ++ppc_linux_cvmxregset (struct gdbarch *gdbarch) ++{ ++ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) ++ return &ppc32_be_linux_cvmxregset; ++ else ++ return &ppc32_le_linux_cvmxregset; ++} ++ ++/* Collect function used to generate the core note for the ++ checkpointed GPR regset. Here, we don't want to skip the ++ "checkpointed" NIP and MSR, so that the note section we generate is ++ similar to the one generated by the kernel. To avoid having to ++ define additional registers in GDB which are not actually ++ checkpointed in the architecture, we copy TFHAR to the checkpointed ++ NIP slot, which is what the kernel does, and copy the regular MSR ++ to the checkpointed MSR slot, which will have a similar value in ++ most cases. */ ++ ++static void ++ppc_linux_collect_core_cpgrregset (const struct regset *regset, ++ const struct regcache *regcache, ++ int regnum, void *buf, size_t len) ++{ ++ struct gdbarch *gdbarch = regcache->arch (); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ ++ const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch); ++ ++ /* We collect the checkpointed GPRs already defined in the regular ++ regmap, then overlay TFHAR/MSR on the checkpointed NIP/MSR ++ slots. */ ++ cgprregset->collect_regset (cgprregset, regcache, regnum, buf, len); ++ ++ /* Check that we are collecting all the registers, which should be ++ the case when generating a core file. */ ++ if (regnum != -1) ++ return; ++ ++ /* PT_NIP and PT_MSR are 32 and 33 for powerpc. Don't redefine ++ these symbols since this file can run on clients in other ++ architectures where they can already be defined to other ++ values. */ ++ int pt_offset = 32; ++ ++ /* Check that our buffer is long enough to hold two slots at ++ pt_offset * wordsize, one for NIP and one for MSR. */ ++ gdb_assert ((pt_offset + 2) * tdep->wordsize <= len); ++ ++ /* TFHAR is 8 bytes wide, but the NIP slot for a 32-bit thread is ++ 4-bytes long. We use raw_collect_integer which handles ++ differences in the sizes for the source and destination buffers ++ for both endian modes. */ ++ (regcache->raw_collect_integer ++ (PPC_TFHAR_REGNUM, ((gdb_byte *) buf) + pt_offset * tdep->wordsize, ++ tdep->wordsize, false)); ++ ++ pt_offset = 33; ++ ++ (regcache->raw_collect_integer ++ (PPC_MSR_REGNUM, ((gdb_byte *) buf) + pt_offset * tdep->wordsize, ++ tdep->wordsize, false)); ++} ++ + /* Iterate over supported core file register note sections. */ + + static void +@@ -728,6 +1045,121 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, + PPC_LINUX_SIZEOF_PMUREGSET, + &ppc32_linux_pmuregset, "Performance Monitor Registers", + cb_data); ++ ++ if (tdep->have_htm_spr) ++ cb (".reg-ppc-tm-spr", PPC_LINUX_SIZEOF_TM_SPRREGSET, ++ PPC_LINUX_SIZEOF_TM_SPRREGSET, ++ &ppc32_linux_tm_sprregset, ++ "Hardware Transactional Memory Special Purpose Registers", ++ cb_data); ++ ++ /* Checkpointed registers can be unavailable, don't call back if ++ we are generating a core file. */ ++ ++ if (tdep->have_htm_core) ++ { ++ /* Only generate the checkpointed GPR core note if we also have ++ access to the HTM SPRs, because we need TFHAR to fill the ++ "checkpointed" NIP slot. We can read a core file without it ++ since GDB is not aware of this NIP as a visible register. */ ++ if (regcache == NULL || ++ (REG_VALID == regcache->get_register_status (PPC_CR0_REGNUM) ++ && tdep->have_htm_spr)) ++ { ++ int cgpr_size = (tdep->wordsize == 4? ++ PPC32_LINUX_SIZEOF_CGPRREGSET ++ : PPC64_LINUX_SIZEOF_CGPRREGSET); ++ ++ const struct regset *cgprregset = ++ ppc_linux_cgprregset (gdbarch); ++ ++ if (regcache != NULL) ++ { ++ struct regset core_cgprregset = *cgprregset; ++ ++ core_cgprregset.collect_regset ++ = ppc_linux_collect_core_cpgrregset; ++ ++ cb (".reg-ppc-tm-cgpr", ++ cgpr_size, cgpr_size, ++ &core_cgprregset, ++ "Checkpointed General Purpose Registers", cb_data); ++ } ++ else ++ { ++ cb (".reg-ppc-tm-cgpr", ++ cgpr_size, cgpr_size, ++ cgprregset, ++ "Checkpointed General Purpose Registers", cb_data); ++ } ++ } ++ } ++ ++ if (tdep->have_htm_fpu) ++ { ++ if (regcache == NULL || ++ REG_VALID == regcache->get_register_status (PPC_CF0_REGNUM)) ++ cb (".reg-ppc-tm-cfpr", PPC_LINUX_SIZEOF_CFPRREGSET, ++ PPC_LINUX_SIZEOF_CFPRREGSET, ++ &ppc32_linux_cfprregset, ++ "Checkpointed Floating Point Registers", cb_data); ++ } ++ ++ if (tdep->have_htm_altivec) ++ { ++ if (regcache == NULL || ++ REG_VALID == regcache->get_register_status (PPC_CVR0_REGNUM)) ++ { ++ const struct regset *cvmxregset = ++ ppc_linux_cvmxregset (gdbarch); ++ ++ cb (".reg-ppc-tm-cvmx", PPC_LINUX_SIZEOF_CVMXREGSET, ++ PPC_LINUX_SIZEOF_CVMXREGSET, ++ cvmxregset, ++ "Checkpointed Altivec (VMX) Registers", cb_data); ++ } ++ } ++ ++ if (tdep->have_htm_vsx) ++ { ++ if (regcache == NULL || ++ (REG_VALID ++ == regcache->get_register_status (PPC_CVSR0_UPPER_REGNUM))) ++ cb (".reg-ppc-tm-cvsx", PPC_LINUX_SIZEOF_CVSXREGSET, ++ PPC_LINUX_SIZEOF_CVSXREGSET, ++ &ppc32_linux_cvsxregset, ++ "Checkpointed VSX Registers", cb_data); ++ } ++ ++ if (tdep->ppc_cppr_regnum != -1) ++ { ++ if (regcache == NULL || ++ REG_VALID == regcache->get_register_status (PPC_CPPR_REGNUM)) ++ cb (".reg-ppc-tm-cppr", PPC_LINUX_SIZEOF_CPPRREGSET, ++ PPC_LINUX_SIZEOF_CPPRREGSET, ++ &ppc32_linux_cpprregset, ++ "Checkpointed Priority Program Register", cb_data); ++ } ++ ++ if (tdep->ppc_cdscr_regnum != -1) ++ { ++ if (regcache == NULL || ++ REG_VALID == regcache->get_register_status (PPC_CDSCR_REGNUM)) ++ cb (".reg-ppc-tm-cdscr", PPC_LINUX_SIZEOF_CDSCRREGSET, ++ PPC_LINUX_SIZEOF_CDSCRREGSET, ++ &ppc32_linux_cdscrregset, ++ "Checkpointed Data Stream Control Register", cb_data); ++ } ++ ++ if (tdep->ppc_ctar_regnum) ++ { ++ if ( regcache == NULL || ++ REG_VALID == regcache->get_register_status (PPC_CTAR_REGNUM)) ++ cb (".reg-ppc-tm-ctar", PPC_LINUX_SIZEOF_CTARREGSET, ++ PPC_LINUX_SIZEOF_CTARREGSET, ++ &ppc32_linux_ctarregset, ++ "Checkpointed Target Address Register", cb_data); ++ } + } + + static void +@@ -1144,6 +1576,7 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, + asection *dscr = bfd_get_section_by_name (abfd, ".reg-ppc-dscr"); + asection *tar = bfd_get_section_by_name (abfd, ".reg-ppc-tar"); + asection *pmu = bfd_get_section_by_name (abfd, ".reg-ppc-pmu"); ++ asection *htmspr = bfd_get_section_by_name (abfd, ".reg-ppc-tm-spr"); + + if (! section) + return NULL; +@@ -1185,7 +1618,11 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, + been unavailable when the core file was created. They will + be in the tdep but will show as unavailable. */ + if (tar && pmu) +- features.isa207 = true; ++ { ++ features.isa207 = true; ++ if (htmspr) ++ features.htm = true; ++ } + } + + return ppc_linux_match_description (features); +@@ -2063,6 +2500,7 @@ _initialize_ppc_linux_tdep (void) + initialize_tdesc_powerpc_isa205_vsx32l (); + initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l (); + initialize_tdesc_powerpc_isa207_vsx32l (); ++ initialize_tdesc_powerpc_isa207_htm_vsx32l (); + initialize_tdesc_powerpc_64l (); + initialize_tdesc_powerpc_altivec64l (); + initialize_tdesc_powerpc_cell64l (); +@@ -2072,5 +2510,6 @@ _initialize_ppc_linux_tdep (void) + initialize_tdesc_powerpc_isa205_vsx64l (); + initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l (); + initialize_tdesc_powerpc_isa207_vsx64l (); ++ initialize_tdesc_powerpc_isa207_htm_vsx64l (); + initialize_tdesc_powerpc_e500l (); + } +diff --git a/gdb/ppc-linux-tdep.h b/gdb/ppc-linux-tdep.h +--- a/gdb/ppc-linux-tdep.h ++++ b/gdb/ppc-linux-tdep.h +@@ -32,6 +32,14 @@ const struct regset *ppc_linux_fpregset (void); + const struct regset *ppc_linux_vrregset (struct gdbarch *gdbarch); + const struct regset *ppc_linux_vsxregset (void); + ++/* Get the checkpointed GPR regset that matches the target wordsize ++ and byteorder of GDBARCH. */ ++const struct regset *ppc_linux_cgprregset (struct gdbarch *gdbarch); ++ ++/* Get the checkpointed vector regset that matches the target byte ++ order. */ ++const struct regset* ppc_linux_cvmxregset (struct gdbarch *gdbarch); ++ + /* Extra register number constants. The Linux kernel stores a + "trap" code and the original value of r3 into special "registers"; + these need to be saved and restored when performing an inferior +@@ -50,5 +58,11 @@ extern const struct regset ppc32_linux_dscrregset; + extern const struct regset ppc32_linux_tarregset; + extern const struct regset ppc32_linux_ebbregset; + extern const struct regset ppc32_linux_pmuregset; ++extern const struct regset ppc32_linux_tm_sprregset; ++extern const struct regset ppc32_linux_cfprregset; ++extern const struct regset ppc32_linux_cvsxregset; ++extern const struct regset ppc32_linux_cpprregset; ++extern const struct regset ppc32_linux_cdscrregset; ++extern const struct regset ppc32_linux_ctarregset; + + #endif /* PPC_LINUX_TDEP_H */ +diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h +--- a/gdb/ppc-tdep.h ++++ b/gdb/ppc-tdep.h +@@ -274,6 +274,21 @@ struct gdbarch_tdep + int ppc_sdar_regnum; + int ppc_sier_regnum; + ++ /* Hardware Transactional Memory registers. */ ++ int have_htm_spr; ++ int have_htm_core; ++ int have_htm_fpu; ++ int have_htm_altivec; ++ int have_htm_vsx; ++ int ppc_cppr_regnum; ++ int ppc_cdscr_regnum; ++ int ppc_ctar_regnum; ++ ++ /* HTM pseudo registers. */ ++ int ppc_cdl0_regnum; ++ int ppc_cvsr0_regnum; ++ int ppc_cefpr0_regnum; ++ + /* Offset to ABI specific location where link register is saved. */ + int lr_frame_offset; + +@@ -343,6 +358,29 @@ enum { + PPC_SDAR_REGNUM = 181, + PPC_SIER_REGNUM = 182, + ++ /* Hardware transactional memory registers. */ ++ PPC_TFHAR_REGNUM = 183, ++ PPC_TEXASR_REGNUM = 184, ++ PPC_TFIAR_REGNUM = 185, ++ ++ PPC_CR0_REGNUM = 186, ++ PPC_CCR_REGNUM = 218, ++ PPC_CXER_REGNUM = 219, ++ PPC_CLR_REGNUM = 220, ++ PPC_CCTR_REGNUM = 221, ++ ++ PPC_CF0_REGNUM = 222, ++ PPC_CFPSCR_REGNUM = 254, ++ ++ PPC_CVR0_REGNUM = 255, ++ PPC_CVSCR_REGNUM = 287, ++ PPC_CVRSAVE_REGNUM = 288, ++ ++ PPC_CVSR0_UPPER_REGNUM = 289, ++ ++ PPC_CPPR_REGNUM = 321, ++ PPC_CDSCR_REGNUM = 322, ++ PPC_CTAR_REGNUM = 323, + PPC_NUM_REGS + }; + +@@ -355,6 +393,21 @@ enum { + #define PPC_IS_PMU_REGNUM(i) \ + ((i) >= PPC_MMCR0_REGNUM && (i) <= PPC_SIER_REGNUM) + ++#define PPC_IS_TMSPR_REGNUM(i) \ ++ ((i) >= PPC_TFHAR_REGNUM && (i) <= PPC_TFIAR_REGNUM) ++ ++#define PPC_IS_CKPTGP_REGNUM(i) \ ++ ((i) >= PPC_CR0_REGNUM && (i) <= PPC_CCTR_REGNUM) ++ ++#define PPC_IS_CKPTFP_REGNUM(i) \ ++ ((i) >= PPC_CF0_REGNUM && (i) <= PPC_CFPSCR_REGNUM) ++ ++#define PPC_IS_CKPTVMX_REGNUM(i) \ ++ ((i) >= PPC_CVR0_REGNUM && (i) <= PPC_CVRSAVE_REGNUM) ++ ++#define PPC_IS_CKPTVSX_REGNUM(i) \ ++ ((i) >= PPC_CVSR0_UPPER_REGNUM && (i) < (PPC_CVSR0_UPPER_REGNUM + 32)) ++ + /* An instruction to match. */ + + struct ppc_insn_pattern +diff --git a/gdb/regformats/rs6000/powerpc-isa207-htm-vsx32l.dat b/gdb/regformats/rs6000/powerpc-isa207-htm-vsx32l.dat +new file mode 100644 +--- /dev/null ++++ b/gdb/regformats/rs6000/powerpc-isa207-htm-vsx32l.dat +@@ -0,0 +1,296 @@ ++# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: ++# Generated from: rs6000/powerpc-isa207-htm-vsx32l.xml ++name:powerpc_isa207_htm_vsx32l ++xmltarget:powerpc-isa207-htm-vsx32l.xml ++expedite:r1,pc ++32:r0 ++32:r1 ++32:r2 ++32:r3 ++32:r4 ++32:r5 ++32:r6 ++32:r7 ++32:r8 ++32:r9 ++32:r10 ++32:r11 ++32:r12 ++32:r13 ++32:r14 ++32:r15 ++32:r16 ++32:r17 ++32:r18 ++32:r19 ++32:r20 ++32:r21 ++32:r22 ++32:r23 ++32:r24 ++32:r25 ++32:r26 ++32:r27 ++32:r28 ++32:r29 ++32:r30 ++32:r31 ++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:f16 ++64:f17 ++64:f18 ++64:f19 ++64:f20 ++64:f21 ++64:f22 ++64:f23 ++64:f24 ++64:f25 ++64:f26 ++64:f27 ++64:f28 ++64:f29 ++64:f30 ++64:f31 ++32:pc ++32:msr ++32:cr ++32:lr ++32:ctr ++32:xer ++64:fpscr ++32:orig_r3 ++32:trap ++128:vr0 ++128:vr1 ++128:vr2 ++128:vr3 ++128:vr4 ++128:vr5 ++128:vr6 ++128:vr7 ++128:vr8 ++128:vr9 ++128:vr10 ++128:vr11 ++128:vr12 ++128:vr13 ++128:vr14 ++128:vr15 ++128:vr16 ++128:vr17 ++128:vr18 ++128:vr19 ++128:vr20 ++128:vr21 ++128:vr22 ++128:vr23 ++128:vr24 ++128:vr25 ++128:vr26 ++128:vr27 ++128:vr28 ++128:vr29 ++128:vr30 ++128:vr31 ++32:vscr ++32:vrsave ++64:vs0h ++64:vs1h ++64:vs2h ++64:vs3h ++64:vs4h ++64:vs5h ++64:vs6h ++64:vs7h ++64:vs8h ++64:vs9h ++64:vs10h ++64:vs11h ++64:vs12h ++64:vs13h ++64:vs14h ++64:vs15h ++64:vs16h ++64:vs17h ++64:vs18h ++64:vs19h ++64:vs20h ++64:vs21h ++64:vs22h ++64:vs23h ++64:vs24h ++64:vs25h ++64:vs26h ++64:vs27h ++64:vs28h ++64:vs29h ++64:vs30h ++64:vs31h ++64:ppr ++64:dscr ++64:tar ++64:bescr ++64:ebbhr ++64:ebbrr ++64:mmcr0 ++64:mmcr2 ++64:siar ++64:sdar ++64:sier ++64:tfhar ++64:texasr ++64:tfiar ++32:cr0 ++32:cr1 ++32:cr2 ++32:cr3 ++32:cr4 ++32:cr5 ++32:cr6 ++32:cr7 ++32:cr8 ++32:cr9 ++32:cr10 ++32:cr11 ++32:cr12 ++32:cr13 ++32:cr14 ++32:cr15 ++32:cr16 ++32:cr17 ++32:cr18 ++32:cr19 ++32:cr20 ++32:cr21 ++32:cr22 ++32:cr23 ++32:cr24 ++32:cr25 ++32:cr26 ++32:cr27 ++32:cr28 ++32:cr29 ++32:cr30 ++32:cr31 ++32:ccr ++32:cxer ++32:clr ++32:cctr ++64:cf0 ++64:cf1 ++64:cf2 ++64:cf3 ++64:cf4 ++64:cf5 ++64:cf6 ++64:cf7 ++64:cf8 ++64:cf9 ++64:cf10 ++64:cf11 ++64:cf12 ++64:cf13 ++64:cf14 ++64:cf15 ++64:cf16 ++64:cf17 ++64:cf18 ++64:cf19 ++64:cf20 ++64:cf21 ++64:cf22 ++64:cf23 ++64:cf24 ++64:cf25 ++64:cf26 ++64:cf27 ++64:cf28 ++64:cf29 ++64:cf30 ++64:cf31 ++64:cfpscr ++128:cvr0 ++128:cvr1 ++128:cvr2 ++128:cvr3 ++128:cvr4 ++128:cvr5 ++128:cvr6 ++128:cvr7 ++128:cvr8 ++128:cvr9 ++128:cvr10 ++128:cvr11 ++128:cvr12 ++128:cvr13 ++128:cvr14 ++128:cvr15 ++128:cvr16 ++128:cvr17 ++128:cvr18 ++128:cvr19 ++128:cvr20 ++128:cvr21 ++128:cvr22 ++128:cvr23 ++128:cvr24 ++128:cvr25 ++128:cvr26 ++128:cvr27 ++128:cvr28 ++128:cvr29 ++128:cvr30 ++128:cvr31 ++32:cvscr ++32:cvrsave ++64:cvs0h ++64:cvs1h ++64:cvs2h ++64:cvs3h ++64:cvs4h ++64:cvs5h ++64:cvs6h ++64:cvs7h ++64:cvs8h ++64:cvs9h ++64:cvs10h ++64:cvs11h ++64:cvs12h ++64:cvs13h ++64:cvs14h ++64:cvs15h ++64:cvs16h ++64:cvs17h ++64:cvs18h ++64:cvs19h ++64:cvs20h ++64:cvs21h ++64:cvs22h ++64:cvs23h ++64:cvs24h ++64:cvs25h ++64:cvs26h ++64:cvs27h ++64:cvs28h ++64:cvs29h ++64:cvs30h ++64:cvs31h ++64:cppr ++64:cdscr ++64:ctar +diff --git a/gdb/regformats/rs6000/powerpc-isa207-htm-vsx64l.dat b/gdb/regformats/rs6000/powerpc-isa207-htm-vsx64l.dat +new file mode 100644 +--- /dev/null ++++ b/gdb/regformats/rs6000/powerpc-isa207-htm-vsx64l.dat +@@ -0,0 +1,296 @@ ++# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: ++# Generated from: rs6000/powerpc-isa207-htm-vsx64l.xml ++name:powerpc_isa207_htm_vsx64l ++xmltarget:powerpc-isa207-htm-vsx64l.xml ++expedite:r1,pc ++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 ++64:r16 ++64:r17 ++64:r18 ++64:r19 ++64:r20 ++64:r21 ++64:r22 ++64:r23 ++64:r24 ++64:r25 ++64:r26 ++64:r27 ++64:r28 ++64:r29 ++64:r30 ++64:r31 ++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:f16 ++64:f17 ++64:f18 ++64:f19 ++64:f20 ++64:f21 ++64:f22 ++64:f23 ++64:f24 ++64:f25 ++64:f26 ++64:f27 ++64:f28 ++64:f29 ++64:f30 ++64:f31 ++64:pc ++64:msr ++32:cr ++64:lr ++64:ctr ++32:xer ++64:fpscr ++64:orig_r3 ++64:trap ++128:vr0 ++128:vr1 ++128:vr2 ++128:vr3 ++128:vr4 ++128:vr5 ++128:vr6 ++128:vr7 ++128:vr8 ++128:vr9 ++128:vr10 ++128:vr11 ++128:vr12 ++128:vr13 ++128:vr14 ++128:vr15 ++128:vr16 ++128:vr17 ++128:vr18 ++128:vr19 ++128:vr20 ++128:vr21 ++128:vr22 ++128:vr23 ++128:vr24 ++128:vr25 ++128:vr26 ++128:vr27 ++128:vr28 ++128:vr29 ++128:vr30 ++128:vr31 ++32:vscr ++32:vrsave ++64:vs0h ++64:vs1h ++64:vs2h ++64:vs3h ++64:vs4h ++64:vs5h ++64:vs6h ++64:vs7h ++64:vs8h ++64:vs9h ++64:vs10h ++64:vs11h ++64:vs12h ++64:vs13h ++64:vs14h ++64:vs15h ++64:vs16h ++64:vs17h ++64:vs18h ++64:vs19h ++64:vs20h ++64:vs21h ++64:vs22h ++64:vs23h ++64:vs24h ++64:vs25h ++64:vs26h ++64:vs27h ++64:vs28h ++64:vs29h ++64:vs30h ++64:vs31h ++64:ppr ++64:dscr ++64:tar ++64:bescr ++64:ebbhr ++64:ebbrr ++64:mmcr0 ++64:mmcr2 ++64:siar ++64:sdar ++64:sier ++64:tfhar ++64:texasr ++64:tfiar ++64:cr0 ++64:cr1 ++64:cr2 ++64:cr3 ++64:cr4 ++64:cr5 ++64:cr6 ++64:cr7 ++64:cr8 ++64:cr9 ++64:cr10 ++64:cr11 ++64:cr12 ++64:cr13 ++64:cr14 ++64:cr15 ++64:cr16 ++64:cr17 ++64:cr18 ++64:cr19 ++64:cr20 ++64:cr21 ++64:cr22 ++64:cr23 ++64:cr24 ++64:cr25 ++64:cr26 ++64:cr27 ++64:cr28 ++64:cr29 ++64:cr30 ++64:cr31 ++32:ccr ++32:cxer ++64:clr ++64:cctr ++64:cf0 ++64:cf1 ++64:cf2 ++64:cf3 ++64:cf4 ++64:cf5 ++64:cf6 ++64:cf7 ++64:cf8 ++64:cf9 ++64:cf10 ++64:cf11 ++64:cf12 ++64:cf13 ++64:cf14 ++64:cf15 ++64:cf16 ++64:cf17 ++64:cf18 ++64:cf19 ++64:cf20 ++64:cf21 ++64:cf22 ++64:cf23 ++64:cf24 ++64:cf25 ++64:cf26 ++64:cf27 ++64:cf28 ++64:cf29 ++64:cf30 ++64:cf31 ++64:cfpscr ++128:cvr0 ++128:cvr1 ++128:cvr2 ++128:cvr3 ++128:cvr4 ++128:cvr5 ++128:cvr6 ++128:cvr7 ++128:cvr8 ++128:cvr9 ++128:cvr10 ++128:cvr11 ++128:cvr12 ++128:cvr13 ++128:cvr14 ++128:cvr15 ++128:cvr16 ++128:cvr17 ++128:cvr18 ++128:cvr19 ++128:cvr20 ++128:cvr21 ++128:cvr22 ++128:cvr23 ++128:cvr24 ++128:cvr25 ++128:cvr26 ++128:cvr27 ++128:cvr28 ++128:cvr29 ++128:cvr30 ++128:cvr31 ++32:cvscr ++32:cvrsave ++64:cvs0h ++64:cvs1h ++64:cvs2h ++64:cvs3h ++64:cvs4h ++64:cvs5h ++64:cvs6h ++64:cvs7h ++64:cvs8h ++64:cvs9h ++64:cvs10h ++64:cvs11h ++64:cvs12h ++64:cvs13h ++64:cvs14h ++64:cvs15h ++64:cvs16h ++64:cvs17h ++64:cvs18h ++64:cvs19h ++64:cvs20h ++64:cvs21h ++64:cvs22h ++64:cvs23h ++64:cvs24h ++64:cvs25h ++64:cvs26h ++64:cvs27h ++64:cvs28h ++64:cvs29h ++64:cvs30h ++64:cvs31h ++64:cppr ++64:cdscr ++64:ctar +diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c +--- a/gdb/rs6000-tdep.c ++++ b/gdb/rs6000-tdep.c +@@ -105,6 +105,22 @@ + && (regnum) >= (tdep)->ppc_efpr0_regnum \ + && (regnum) < (tdep)->ppc_efpr0_regnum + ppc_num_efprs) + ++/* Determine if regnum is a checkpointed decimal float ++ pseudo-register. */ ++#define IS_CDFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_cdl0_regnum >= 0 \ ++ && (regnum) >= (tdep)->ppc_cdl0_regnum \ ++ && (regnum) < (tdep)->ppc_cdl0_regnum + 16) ++ ++/* Determine if regnum is a Checkpointed POWER7 VSX register. */ ++#define IS_CVSX_PSEUDOREG(tdep, regnum) ((tdep)->ppc_cvsr0_regnum >= 0 \ ++ && (regnum) >= (tdep)->ppc_cvsr0_regnum \ ++ && (regnum) < (tdep)->ppc_cvsr0_regnum + ppc_num_vsrs) ++ ++/* Determine if regnum is a Checkpointed POWER7 Extended FP register. */ ++#define IS_CEFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_cefpr0_regnum >= 0 \ ++ && (regnum) >= (tdep)->ppc_cefpr0_regnum \ ++ && (regnum) < (tdep)->ppc_cefpr0_regnum + ppc_num_efprs) ++ + /* Holds the current set of options to be passed to the disassembler. */ + static char *powerpc_disassembler_options; + +@@ -2375,6 +2391,11 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno) + && regno < tdep->ppc_vsr0_upper_regnum + ppc_num_gprs) + return ""; + ++ /* Hide the upper halves of the cvs0~cvs31 registers. */ ++ if (PPC_CVSR0_UPPER_REGNUM <= regno ++ && regno < PPC_CVSR0_UPPER_REGNUM + ppc_num_gprs) ++ return ""; ++ + /* Check if the SPE pseudo registers are available. */ + if (IS_SPE_PSEUDOREG (tdep, regno)) + { +@@ -2429,6 +2450,48 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno) + return efpr_regnames[regno - tdep->ppc_efpr0_regnum]; + } + ++ /* Check if this is a Checkpointed DFP pseudo-register. */ ++ if (IS_CDFP_PSEUDOREG (tdep, regno)) ++ { ++ static const char *const cdfp128_regnames[] = { ++ "cdl0", "cdl1", "cdl2", "cdl3", ++ "cdl4", "cdl5", "cdl6", "cdl7", ++ "cdl8", "cdl9", "cdl10", "cdl11", ++ "cdl12", "cdl13", "cdl14", "cdl15" ++ }; ++ return cdfp128_regnames[regno - tdep->ppc_cdl0_regnum]; ++ } ++ ++ /* Check if this is a Checkpointed VSX pseudo-register. */ ++ if (IS_CVSX_PSEUDOREG (tdep, regno)) ++ { ++ static const char *const cvsx_regnames[] = { ++ "cvs0", "cvs1", "cvs2", "cvs3", "cvs4", "cvs5", "cvs6", "cvs7", ++ "cvs8", "cvs9", "cvs10", "cvs11", "cvs12", "cvs13", "cvs14", ++ "cvs15", "cvs16", "cvs17", "cvs18", "cvs19", "cvs20", "cvs21", ++ "cvs22", "cvs23", "cvs24", "cvs25", "cvs26", "cvs27", "cvs28", ++ "cvs29", "cvs30", "cvs31", "cvs32", "cvs33", "cvs34", "cvs35", ++ "cvs36", "cvs37", "cvs38", "cvs39", "cvs40", "cvs41", "cvs42", ++ "cvs43", "cvs44", "cvs45", "cvs46", "cvs47", "cvs48", "cvs49", ++ "cvs50", "cvs51", "cvs52", "cvs53", "cvs54", "cvs55", "cvs56", ++ "cvs57", "cvs58", "cvs59", "cvs60", "cvs61", "cvs62", "cvs63" ++ }; ++ return cvsx_regnames[regno - tdep->ppc_cvsr0_regnum]; ++ } ++ ++ /* Check if the this is a Checkpointed Extended FP pseudo-register. */ ++ if (IS_CEFP_PSEUDOREG (tdep, regno)) ++ { ++ static const char *const cefpr_regnames[] = { ++ "cf32", "cf33", "cf34", "cf35", "cf36", "cf37", "cf38", ++ "cf39", "cf40", "cf41", "cf42", "cf43", "cf44", "cf45", ++ "cf46", "cf47", "cf48", "cf49", "cf50", "cf51", ++ "cf52", "cf53", "cf54", "cf55", "cf56", "cf57", ++ "cf58", "cf59", "cf60", "cf61", "cf62", "cf63" ++ }; ++ return cefpr_regnames[regno - tdep->ppc_cefpr0_regnum]; ++ } ++ + return tdesc_register_name (gdbarch, regno); + } + +@@ -2440,24 +2503,26 @@ rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + +- /* These are the only pseudo-registers we support. */ +- gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum) +- || IS_DFP_PSEUDOREG (tdep, regnum) +- || IS_VSX_PSEUDOREG (tdep, regnum) +- || IS_EFP_PSEUDOREG (tdep, regnum)); +- + /* These are the e500 pseudo-registers. */ + if (IS_SPE_PSEUDOREG (tdep, regnum)) + return rs6000_builtin_type_vec64 (gdbarch); +- else if (IS_DFP_PSEUDOREG (tdep, regnum)) ++ else if (IS_DFP_PSEUDOREG (tdep, regnum) ++ || IS_CDFP_PSEUDOREG (tdep, regnum)) + /* PPC decimal128 pseudo-registers. */ + return builtin_type (gdbarch)->builtin_declong; +- else if (IS_VSX_PSEUDOREG (tdep, regnum)) ++ else if (IS_VSX_PSEUDOREG (tdep, regnum) ++ || IS_CVSX_PSEUDOREG (tdep, regnum)) + /* POWER7 VSX pseudo-registers. */ + return rs6000_builtin_type_vec128 (gdbarch); +- else ++ else if (IS_EFP_PSEUDOREG (tdep, regnum) ++ || IS_CEFP_PSEUDOREG (tdep, regnum)) + /* POWER7 Extended FP pseudo-registers. */ + return builtin_type (gdbarch)->builtin_double; ++ else ++ internal_error (__FILE__, __LINE__, ++ _("rs6000_pseudo_register_type: " ++ "called on unexpected register '%s' (%d)"), ++ gdbarch_register_name (gdbarch, regnum), regnum); + } + + /* The register format for RS/6000 floating point registers is always +@@ -2633,25 +2698,35 @@ dfp_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, + int reg_nr, gdb_byte *buffer) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- int reg_index = reg_nr - tdep->ppc_dl0_regnum; ++ int reg_index, fp0; + enum register_status status; + ++ if (IS_DFP_PSEUDOREG (tdep, reg_nr)) ++ { ++ reg_index = reg_nr - tdep->ppc_dl0_regnum; ++ fp0 = PPC_F0_REGNUM; ++ } ++ else ++ { ++ gdb_assert (IS_CDFP_PSEUDOREG (tdep, reg_nr)); ++ ++ reg_index = reg_nr - tdep->ppc_cdl0_regnum; ++ fp0 = PPC_CF0_REGNUM; ++ } ++ + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { + /* Read two FP registers to form a whole dl register. */ +- status = regcache->raw_read (tdep->ppc_fp0_regnum + +- 2 * reg_index, buffer); ++ status = regcache->raw_read (fp0 + 2 * reg_index, buffer); + if (status == REG_VALID) +- status = regcache->raw_read (tdep->ppc_fp0_regnum + +- 2 * reg_index + 1, buffer + 8); ++ status = regcache->raw_read (fp0 + 2 * reg_index + 1, ++ buffer + 8); + } + else + { +- status = regcache->raw_read (tdep->ppc_fp0_regnum + +- 2 * reg_index + 1, buffer); ++ status = regcache->raw_read (fp0 + 2 * reg_index + 1, buffer); + if (status == REG_VALID) +- status = regcache->raw_read (tdep->ppc_fp0_regnum + +- 2 * reg_index, buffer + 8); ++ status = regcache->raw_read (fp0 + 2 * reg_index, buffer + 8); + } + + return status; +@@ -2663,23 +2738,32 @@ dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + int reg_nr, const gdb_byte *buffer) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- int reg_index = reg_nr - tdep->ppc_dl0_regnum; ++ int reg_index, fp0; ++ ++ if (IS_DFP_PSEUDOREG (tdep, reg_nr)) ++ { ++ reg_index = reg_nr - tdep->ppc_dl0_regnum; ++ fp0 = PPC_F0_REGNUM; ++ } ++ else ++ { ++ gdb_assert (IS_CDFP_PSEUDOREG (tdep, reg_nr)); ++ ++ reg_index = reg_nr - tdep->ppc_cdl0_regnum; ++ fp0 = PPC_CF0_REGNUM; ++ } + + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { + /* Write each half of the dl register into a separate +- FP register. */ +- regcache->raw_write (tdep->ppc_fp0_regnum + +- 2 * reg_index, buffer); +- regcache->raw_write (tdep->ppc_fp0_regnum + +- 2 * reg_index + 1, buffer + 8); ++ FP register. */ ++ regcache->raw_write (fp0 + 2 * reg_index, buffer); ++ regcache->raw_write (fp0 + 2 * reg_index + 1, buffer + 8); + } + else + { +- regcache->raw_write (tdep->ppc_fp0_regnum + +- 2 * reg_index + 1, buffer); +- regcache->raw_write (tdep->ppc_fp0_regnum + +- 2 * reg_index, buffer + 8); ++ regcache->raw_write (fp0 + 2 * reg_index + 1, buffer); ++ regcache->raw_write (fp0 + 2 * reg_index, buffer + 8); + } + } + +@@ -2689,30 +2773,43 @@ vsx_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, + int reg_nr, gdb_byte *buffer) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- int reg_index = reg_nr - tdep->ppc_vsr0_regnum; ++ int reg_index, vr0, fp0, vsr0_upper; + enum register_status status; + ++ if (IS_VSX_PSEUDOREG (tdep, reg_nr)) ++ { ++ reg_index = reg_nr - tdep->ppc_vsr0_regnum; ++ vr0 = PPC_VR0_REGNUM; ++ fp0 = PPC_F0_REGNUM; ++ vsr0_upper = PPC_VSR0_UPPER_REGNUM; ++ } ++ else ++ { ++ gdb_assert (IS_CVSX_PSEUDOREG (tdep, reg_nr)); ++ ++ reg_index = reg_nr - tdep->ppc_cvsr0_regnum; ++ vr0 = PPC_CVR0_REGNUM; ++ fp0 = PPC_CF0_REGNUM; ++ vsr0_upper = PPC_CVSR0_UPPER_REGNUM; ++ } ++ + /* Read the portion that overlaps the VMX registers. */ + if (reg_index > 31) +- status = regcache->raw_read (tdep->ppc_vr0_regnum + +- reg_index - 32, buffer); ++ status = regcache->raw_read (vr0 + reg_index - 32, buffer); + else + /* Read the portion that overlaps the FPR registers. */ + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { +- status = regcache->raw_read (tdep->ppc_fp0_regnum + +- reg_index, buffer); ++ status = regcache->raw_read (fp0 + reg_index, buffer); + if (status == REG_VALID) +- status = regcache->raw_read (tdep->ppc_vsr0_upper_regnum + +- reg_index, buffer + 8); ++ status = regcache->raw_read (vsr0_upper + reg_index, ++ buffer + 8); + } + else + { +- status = regcache->raw_read (tdep->ppc_fp0_regnum + +- reg_index, buffer + 8); ++ status = regcache->raw_read (fp0 + reg_index, buffer + 8); + if (status == REG_VALID) +- status = regcache->raw_read (tdep->ppc_vsr0_upper_regnum + +- reg_index, buffer); ++ status = regcache->raw_read (vsr0_upper + reg_index, buffer); + } + + return status; +@@ -2724,56 +2821,103 @@ vsx_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + int reg_nr, const gdb_byte *buffer) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- int reg_index = reg_nr - tdep->ppc_vsr0_regnum; ++ int reg_index, vr0, fp0, vsr0_upper; ++ ++ if (IS_VSX_PSEUDOREG (tdep, reg_nr)) ++ { ++ reg_index = reg_nr - tdep->ppc_vsr0_regnum; ++ vr0 = PPC_VR0_REGNUM; ++ fp0 = PPC_F0_REGNUM; ++ vsr0_upper = PPC_VSR0_UPPER_REGNUM; ++ } ++ else ++ { ++ gdb_assert (IS_CVSX_PSEUDOREG (tdep, reg_nr)); ++ ++ reg_index = reg_nr - tdep->ppc_cvsr0_regnum; ++ vr0 = PPC_CVR0_REGNUM; ++ fp0 = PPC_CF0_REGNUM; ++ vsr0_upper = PPC_CVSR0_UPPER_REGNUM; ++ } + + /* Write the portion that overlaps the VMX registers. */ + if (reg_index > 31) +- regcache->raw_write (tdep->ppc_vr0_regnum + +- reg_index - 32, buffer); ++ regcache->raw_write (vr0 + reg_index - 32, buffer); + else + /* Write the portion that overlaps the FPR registers. */ + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { +- regcache->raw_write (tdep->ppc_fp0_regnum + +- reg_index, buffer); +- regcache->raw_write (tdep->ppc_vsr0_upper_regnum + +- reg_index, buffer + 8); ++ regcache->raw_write (fp0 + reg_index, buffer); ++ regcache->raw_write (vsr0_upper + reg_index, buffer + 8); + } + else + { +- regcache->raw_write (tdep->ppc_fp0_regnum + +- reg_index, buffer + 8); +- regcache->raw_write (tdep->ppc_vsr0_upper_regnum + +- reg_index, buffer); ++ regcache->raw_write (fp0 + reg_index, buffer + 8); ++ regcache->raw_write (vsr0_upper + reg_index, buffer); + } + } + + /* Read method for POWER7 Extended FP pseudo-registers. */ + static enum register_status +-efpr_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, ++efp_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, + int reg_nr, gdb_byte *buffer) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- int reg_index = reg_nr - tdep->ppc_efpr0_regnum; ++ int reg_index, vr0; ++ ++ if (IS_EFP_PSEUDOREG (tdep, reg_nr)) ++ { ++ reg_index = reg_nr - tdep->ppc_efpr0_regnum; ++ vr0 = PPC_VR0_REGNUM; ++ } ++ else ++ { ++ gdb_assert (IS_CEFP_PSEUDOREG (tdep, reg_nr)); ++ ++ reg_index = reg_nr - tdep->ppc_cefpr0_regnum; ++ vr0 = PPC_CVR0_REGNUM; ++ } ++ + int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8; + + /* Read the portion that overlaps the VMX register. */ +- return regcache->raw_read_part (tdep->ppc_vr0_regnum + reg_index, +- offset, register_size (gdbarch, reg_nr), ++ return regcache->raw_read_part (vr0 + reg_index, offset, ++ register_size (gdbarch, reg_nr), + buffer); + } + + /* Write method for POWER7 Extended FP pseudo-registers. */ + static void +-efpr_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, ++efp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + int reg_nr, const gdb_byte *buffer) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- int reg_index = reg_nr - tdep->ppc_efpr0_regnum; ++ int reg_index, vr0; + int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8; + ++ if (IS_EFP_PSEUDOREG (tdep, reg_nr)) ++ { ++ reg_index = reg_nr - tdep->ppc_efpr0_regnum; ++ vr0 = PPC_VR0_REGNUM; ++ } ++ else ++ { ++ gdb_assert (IS_CEFP_PSEUDOREG (tdep, reg_nr)); ++ ++ reg_index = reg_nr - tdep->ppc_cefpr0_regnum; ++ vr0 = PPC_CVR0_REGNUM; ++ ++ /* The call to raw_write_part fails silently if the initial read ++ of the read-update-write sequence returns an invalid status, ++ so we check this manually and throw an error if needed. */ ++ regcache->raw_update (vr0 + reg_index); ++ if (regcache->get_register_status (vr0 + reg_index) != REG_VALID) ++ error (_("Cannot write to the checkpointed EFP register, " ++ "the corresponding vector register is unavailable.")); ++ } ++ + /* Write the portion that overlaps the VMX register. */ +- regcache->raw_write_part (tdep->ppc_vr0_regnum + reg_index, offset, ++ regcache->raw_write_part (vr0 + reg_index, offset, + register_size (gdbarch, reg_nr), buffer); + } + +@@ -2789,12 +2933,15 @@ rs6000_pseudo_register_read (struct gdbarch *gdbarch, + + if (IS_SPE_PSEUDOREG (tdep, reg_nr)) + return e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); +- else if (IS_DFP_PSEUDOREG (tdep, reg_nr)) ++ else if (IS_DFP_PSEUDOREG (tdep, reg_nr) ++ || IS_CDFP_PSEUDOREG (tdep, reg_nr)) + return dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); +- else if (IS_VSX_PSEUDOREG (tdep, reg_nr)) ++ else if (IS_VSX_PSEUDOREG (tdep, reg_nr) ++ || IS_CVSX_PSEUDOREG (tdep, reg_nr)) + return vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); +- else if (IS_EFP_PSEUDOREG (tdep, reg_nr)) +- return efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); ++ else if (IS_EFP_PSEUDOREG (tdep, reg_nr) ++ || IS_CEFP_PSEUDOREG (tdep, reg_nr)) ++ return efp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); + else + internal_error (__FILE__, __LINE__, + _("rs6000_pseudo_register_read: " +@@ -2814,12 +2961,15 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch, + + if (IS_SPE_PSEUDOREG (tdep, reg_nr)) + e500_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); +- else if (IS_DFP_PSEUDOREG (tdep, reg_nr)) ++ else if (IS_DFP_PSEUDOREG (tdep, reg_nr) ++ || IS_CDFP_PSEUDOREG (tdep, reg_nr)) + dfp_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); +- else if (IS_VSX_PSEUDOREG (tdep, reg_nr)) ++ else if (IS_VSX_PSEUDOREG (tdep, reg_nr) ++ || IS_CVSX_PSEUDOREG (tdep, reg_nr)) + vsx_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); +- else if (IS_EFP_PSEUDOREG (tdep, reg_nr)) +- efpr_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); ++ else if (IS_EFP_PSEUDOREG (tdep, reg_nr) ++ || IS_CEFP_PSEUDOREG (tdep, reg_nr)) ++ efp_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); + else + internal_error (__FILE__, __LINE__, + _("rs6000_pseudo_register_write: " +@@ -2827,6 +2977,97 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch, + gdbarch_register_name (gdbarch, reg_nr), reg_nr); + } + ++/* Set the register mask in AX with the registers that form the DFP or ++ checkpointed DFP pseudo-register REG_NR. */ ++ ++static void ++dfp_ax_pseudo_register_collect (struct gdbarch *gdbarch, ++ struct agent_expr *ax, int reg_nr) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ int reg_index, fp0; ++ ++ if (IS_DFP_PSEUDOREG (tdep, reg_nr)) ++ { ++ reg_index = reg_nr - tdep->ppc_dl0_regnum; ++ fp0 = PPC_F0_REGNUM; ++ } ++ else ++ { ++ gdb_assert (IS_CDFP_PSEUDOREG (tdep, reg_nr)); ++ ++ reg_index = reg_nr - tdep->ppc_cdl0_regnum; ++ fp0 = PPC_CF0_REGNUM; ++ } ++ ++ ax_reg_mask (ax, fp0 + 2 * reg_index); ++ ax_reg_mask (ax, fp0 + 2 * reg_index + 1); ++} ++ ++/* Set the register mask in AX with the registers that form the VSX or ++ checkpointed VSX pseudo-register REG_NR. */ ++ ++static void ++vsx_ax_pseudo_register_collect (struct gdbarch *gdbarch, ++ struct agent_expr *ax, int reg_nr) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ int reg_index, vr0, fp0, vsr0_upper; ++ ++ if (IS_VSX_PSEUDOREG (tdep, reg_nr)) ++ { ++ reg_index = reg_nr - tdep->ppc_vsr0_regnum; ++ vr0 = PPC_VR0_REGNUM; ++ fp0 = PPC_F0_REGNUM; ++ vsr0_upper = PPC_VSR0_UPPER_REGNUM; ++ } ++ else ++ { ++ gdb_assert (IS_CVSX_PSEUDOREG (tdep, reg_nr)); ++ ++ reg_index = reg_nr - tdep->ppc_cvsr0_regnum; ++ vr0 = PPC_CVR0_REGNUM; ++ fp0 = PPC_CF0_REGNUM; ++ vsr0_upper = PPC_CVSR0_UPPER_REGNUM; ++ } ++ ++ if (reg_index > 31) ++ { ++ ax_reg_mask (ax, vr0 + reg_index - 32); ++ } ++ else ++ { ++ ax_reg_mask (ax, fp0 + reg_index); ++ ax_reg_mask (ax, vsr0_upper + reg_index); ++ } ++} ++ ++/* Set the register mask in AX with the register that corresponds to ++ the EFP or checkpointed EFP pseudo-register REG_NR. */ ++ ++static void ++efp_ax_pseudo_register_collect (struct gdbarch *gdbarch, ++ struct agent_expr *ax, int reg_nr) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ int reg_index, vr0; ++ ++ if (IS_EFP_PSEUDOREG (tdep, reg_nr)) ++ { ++ reg_index = reg_nr - tdep->ppc_efpr0_regnum; ++ vr0 = PPC_VR0_REGNUM; ++ } ++ else ++ { ++ gdb_assert (IS_CEFP_PSEUDOREG (tdep, reg_nr)); ++ ++ reg_index = reg_nr - tdep->ppc_cefpr0_regnum; ++ vr0 = PPC_CVR0_REGNUM; ++ } ++ ++ ax_reg_mask (ax, vr0 + reg_index); ++} ++ + static int + rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch, + struct agent_expr *ax, int reg_nr) +@@ -2838,29 +3079,20 @@ rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch, + ax_reg_mask (ax, tdep->ppc_gp0_regnum + reg_index); + ax_reg_mask (ax, tdep->ppc_ev0_upper_regnum + reg_index); + } +- else if (IS_DFP_PSEUDOREG (tdep, reg_nr)) ++ else if (IS_DFP_PSEUDOREG (tdep, reg_nr) ++ || IS_CDFP_PSEUDOREG (tdep, reg_nr)) + { +- int reg_index = reg_nr - tdep->ppc_dl0_regnum; +- ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index); +- ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index + 1); ++ dfp_ax_pseudo_register_collect (gdbarch, ax, reg_nr); + } +- else if (IS_VSX_PSEUDOREG (tdep, reg_nr)) ++ else if (IS_VSX_PSEUDOREG (tdep, reg_nr) ++ || IS_CVSX_PSEUDOREG (tdep, reg_nr)) + { +- int reg_index = reg_nr - tdep->ppc_vsr0_regnum; +- if (reg_index > 31) +- { +- ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index - 32); +- } +- else +- { +- ax_reg_mask (ax, tdep->ppc_fp0_regnum + reg_index); +- ax_reg_mask (ax, tdep->ppc_vsr0_upper_regnum + reg_index); +- } ++ vsx_ax_pseudo_register_collect (gdbarch, ax, reg_nr); + } +- else if (IS_EFP_PSEUDOREG (tdep, reg_nr)) ++ else if (IS_EFP_PSEUDOREG (tdep, reg_nr) ++ || IS_CEFP_PSEUDOREG (tdep, reg_nr)) + { +- int reg_index = reg_nr - tdep->ppc_efpr0_regnum; +- ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index); ++ efp_ax_pseudo_register_collect (gdbarch, ax, reg_nr); + } + else + internal_error (__FILE__, __LINE__, +@@ -5871,7 +6103,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO; + int have_fpu = 0, have_spe = 0, have_mq = 0, have_altivec = 0; + int have_dfp = 0, have_vsx = 0, have_ppr = 0, have_dscr = 0; +- int have_tar = 0, have_ebb = 0, have_pmu = 0; ++ int have_tar = 0, have_ebb = 0, have_pmu = 0, have_htm_spr = 0; ++ int have_htm_core = 0, have_htm_fpu = 0, have_htm_altivec = 0; ++ int have_htm_vsx = 0, have_htm_ppr = 0, have_htm_dscr = 0; ++ int have_htm_tar = 0; + int tdesc_wordsize = -1; + const struct target_desc *tdesc = info.target_desc; + struct tdesc_arch_data *tdesc_data = NULL; +@@ -6270,6 +6505,201 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + } + else + have_pmu = 0; ++ ++ /* Hardware Transactional Memory Registers. */ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.htm.spr"); ++ if (feature != NULL) ++ { ++ static const char *const tm_spr_regs[] = { ++ "tfhar", "texasr", "tfiar" ++ }; ++ ++ valid_p = 1; ++ for (i = 0; i < ARRAY_SIZE (tm_spr_regs); i++) ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_TFHAR_REGNUM + i, ++ tm_spr_regs[i]); ++ if (!valid_p) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ ++ have_htm_spr = 1; ++ } ++ else ++ have_htm_spr = 0; ++ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.htm.core"); ++ if (feature != NULL) ++ { ++ static const char *const cgprs[] = { ++ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", ++ "cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14", ++ "cr15", "cr16", "cr17", "cr18", "cr19", "cr20", "cr21", ++ "cr22", "cr23", "cr24", "cr25", "cr26", "cr27", "cr28", ++ "cr29", "cr30", "cr31", "ccr", "cxer", "clr", "cctr" ++ }; ++ ++ valid_p = 1; ++ ++ for (i = 0; i < ARRAY_SIZE (cgprs); i++) ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_CR0_REGNUM + i, ++ cgprs[i]); ++ if (!valid_p) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ ++ have_htm_core = 1; ++ } ++ else ++ have_htm_core = 0; ++ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.htm.fpu"); ++ if (feature != NULL) ++ { ++ valid_p = 1; ++ ++ static const char *const cfprs[] = { ++ "cf0", "cf1", "cf2", "cf3", "cf4", "cf5", "cf6", "cf7", ++ "cf8", "cf9", "cf10", "cf11", "cf12", "cf13", "cf14", "cf15", ++ "cf16", "cf17", "cf18", "cf19", "cf20", "cf21", "cf22", ++ "cf23", "cf24", "cf25", "cf26", "cf27", "cf28", "cf29", ++ "cf30", "cf31", "cfpscr" ++ }; ++ ++ for (i = 0; i < ARRAY_SIZE (cfprs); i++) ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_CF0_REGNUM + i, ++ cfprs[i]); ++ ++ if (!valid_p) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ have_htm_fpu = 1; ++ } ++ else ++ have_htm_fpu = 0; ++ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.htm.altivec"); ++ if (feature != NULL) ++ { ++ valid_p = 1; ++ ++ static const char *const cvmx[] = { ++ "cvr0", "cvr1", "cvr2", "cvr3", "cvr4", "cvr5", "cvr6", ++ "cvr7", "cvr8", "cvr9", "cvr10", "cvr11", "cvr12", "cvr13", ++ "cvr14", "cvr15","cvr16", "cvr17", "cvr18", "cvr19", "cvr20", ++ "cvr21", "cvr22", "cvr23", "cvr24", "cvr25", "cvr26", ++ "cvr27", "cvr28", "cvr29", "cvr30", "cvr31", "cvscr", ++ "cvrsave" ++ }; ++ ++ for (i = 0; i < ARRAY_SIZE (cvmx); i++) ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ PPC_CVR0_REGNUM + i, ++ cvmx[i]); ++ ++ if (!valid_p) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ have_htm_altivec = 1; ++ } ++ else ++ have_htm_altivec = 0; ++ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.htm.vsx"); ++ if (feature != NULL) ++ { ++ valid_p = 1; ++ ++ static const char *const cvsx[] = { ++ "cvs0h", "cvs1h", "cvs2h", "cvs3h", "cvs4h", "cvs5h", ++ "cvs6h", "cvs7h", "cvs8h", "cvs9h", "cvs10h", "cvs11h", ++ "cvs12h", "cvs13h", "cvs14h", "cvs15h", "cvs16h", "cvs17h", ++ "cvs18h", "cvs19h", "cvs20h", "cvs21h", "cvs22h", "cvs23h", ++ "cvs24h", "cvs25h", "cvs26h", "cvs27h", "cvs28h", "cvs29h", ++ "cvs30h", "cvs31h" ++ }; ++ ++ for (i = 0; i < ARRAY_SIZE (cvsx); i++) ++ valid_p &= tdesc_numbered_register (feature, tdesc_data, ++ (PPC_CVSR0_UPPER_REGNUM ++ + i), ++ cvsx[i]); ++ ++ if (!valid_p || !have_htm_fpu || !have_htm_altivec) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ have_htm_vsx = 1; ++ } ++ else ++ have_htm_vsx = 0; ++ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.htm.ppr"); ++ if (feature != NULL) ++ { ++ valid_p = tdesc_numbered_register (feature, tdesc_data, ++ PPC_CPPR_REGNUM, "cppr"); ++ ++ if (!valid_p) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ have_htm_ppr = 1; ++ } ++ else ++ have_htm_ppr = 0; ++ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.htm.dscr"); ++ if (feature != NULL) ++ { ++ valid_p = tdesc_numbered_register (feature, tdesc_data, ++ PPC_CDSCR_REGNUM, "cdscr"); ++ ++ if (!valid_p) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ have_htm_dscr = 1; ++ } ++ else ++ have_htm_dscr = 0; ++ ++ feature = tdesc_find_feature (tdesc, ++ "org.gnu.gdb.power.htm.tar"); ++ if (feature != NULL) ++ { ++ valid_p = tdesc_numbered_register (feature, tdesc_data, ++ PPC_CTAR_REGNUM, "ctar"); ++ ++ if (!valid_p) ++ { ++ tdesc_data_cleanup (tdesc_data); ++ return NULL; ++ } ++ have_htm_tar = 1; ++ } ++ else ++ have_htm_tar = 0; + } + + /* If we have a 64-bit binary on a 32-bit target, complain. Also +@@ -6482,6 +6912,15 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + tdep->ppc_sdar_regnum = have_pmu ? PPC_SDAR_REGNUM : -1; + tdep->ppc_sier_regnum = have_pmu ? PPC_SIER_REGNUM : -1; + ++ tdep->have_htm_spr = have_htm_spr; ++ tdep->have_htm_core = have_htm_core; ++ tdep->have_htm_fpu = have_htm_fpu; ++ tdep->have_htm_altivec = have_htm_altivec; ++ tdep->have_htm_vsx = have_htm_vsx; ++ tdep->ppc_cppr_regnum = have_htm_ppr ? PPC_CPPR_REGNUM : -1; ++ tdep->ppc_cdscr_regnum = have_htm_dscr ? PPC_CDSCR_REGNUM : -1; ++ tdep->ppc_ctar_regnum = have_htm_tar ? PPC_CTAR_REGNUM : -1; ++ + set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM); + set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1); + set_gdbarch_fp0_regnum (gdbarch, tdep->ppc_fp0_regnum); +@@ -6503,7 +6942,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + else + tdep->lr_frame_offset = 4; + +- if (have_spe || have_dfp || have_vsx) ++ if (have_spe || have_dfp || have_vsx || have_htm_fpu || have_htm_vsx) + { + set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, +@@ -6525,6 +6964,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + if (have_vsx) + /* Include both VSX and Extended FP registers. */ + num_pseudoregs += 96; ++ if (have_htm_fpu) ++ num_pseudoregs += 16; ++ /* Include both checkpointed VSX and EFP registers. */ ++ if (have_htm_vsx) ++ num_pseudoregs += 64 + 32; + + set_gdbarch_num_pseudo_regs (gdbarch, num_pseudoregs); + +@@ -6640,6 +7084,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + tdep->ppc_dl0_regnum = -1; + tdep->ppc_vsr0_regnum = -1; + tdep->ppc_efpr0_regnum = -1; ++ tdep->ppc_cdl0_regnum = -1; ++ tdep->ppc_cvsr0_regnum = -1; ++ tdep->ppc_cefpr0_regnum = -1; + + cur_reg = gdbarch_num_regs (gdbarch); + +@@ -6660,6 +7107,18 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + tdep->ppc_efpr0_regnum = cur_reg; + cur_reg += 32; + } ++ if (have_htm_fpu) ++ { ++ tdep->ppc_cdl0_regnum = cur_reg; ++ cur_reg += 16; ++ } ++ if (have_htm_vsx) ++ { ++ tdep->ppc_cvsr0_regnum = cur_reg; ++ cur_reg += 64; ++ tdep->ppc_cefpr0_regnum = cur_reg; ++ cur_reg += 32; ++ } + + gdb_assert (gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch) == cur_reg); +diff --git a/gdb/testsuite/gdb.arch/powerpc-htm-regs.c b/gdb/testsuite/gdb.arch/powerpc-htm-regs.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/powerpc-htm-regs.c +@@ -0,0 +1,39 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright (C) 2018 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 . */ ++ ++int main (void) ++{ ++ /* Touch DSCR. Some kernels won't schedule the thread with a DSCR ++ altered by ptrace unless the register was used at some point. */ ++ unsigned long dscr = 0x0; ++ ++ /* This is the non-privileged SPR number to access DSCR, ++ available since isa 207. */ ++ asm volatile ("mtspr 3,%0" : : "r" (dscr)); ++ ++ asm volatile ("tbegin."); // first marker ++ asm volatile goto ("bc 12,2,%l[end]" ++ : ++ : ++ : ++ : end); ++ asm volatile ("tabort. 0"); ++end: ++ asm volatile ("nop"); // second marker ++ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp b/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp +@@ -0,0 +1,328 @@ ++# Copyright (C) 2018 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 . ++ ++# This file is part of the gdb testsuite. ++ ++# Test access to HTM (Hardware Transactional Memory) registers. The ++# tests read the values of various registers before stepping the ++# inferior through a "tbegin." instruction to start a transaction, ++# then the checkpointed versions of the registers are checked against ++# the pre-transactional values. Then, new values are written to some ++# of the checkpointed registers, these values are read back and saved, ++# the inferior continues until the transaction aborts, and the regular ++# registers are then checked against the saved values, because the ++# abort should have reverted the registers to these values. ++ ++if {![istarget "powerpc*-*-linux*"]} then { ++ verbose "Skipping PowerPC test for HTM registers." ++ return ++} ++ ++standard_testfile .c .gen.c ++ ++# First check if our processor and kernel support access to ++# the registers we need and to the HTM facility. ++ ++proc check_register_access { regname } { ++ global gdb_prompt ++ ++ set test "$regname register access" ++ gdb_test_multiple "info reg $regname" "$test" { ++ -re "Invalid register.*\r\n$gdb_prompt $" { ++ unsupported "$test" ++ return 0 ++ } ++ -re "\r\n$regname.*\r\n$gdb_prompt $" { ++ pass "$test" ++ return 1 ++ } ++ } ++ return 0 ++} ++ ++proc check_htm_support {} { ++ global gdb_prompt ++ set test "htm support" ++ ++ gdb_test_multiple "stepi" "$test" { ++ -re "Illegal instruction.*\r\n$gdb_prompt $" { ++ unsupported $test ++ return 0 ++ } ++ -re "nop.*\r\n$gdb_prompt $" ++ { ++ pass $test ++ return 1 ++ } ++ } ++ return 0; ++} ++ ++with_test_prefix "check htm support" { ++ set gen_src [standard_output_file $srcfile2] ++ ++ gdb_produce_source $gen_src { ++ int main () { ++ asm volatile ("tbegin."); // marker ++ asm volatile ("nop"); ++ return 0; ++ } ++ } ++ ++ if {[build_executable "compile" $binfile $gen_src {debug}] == -1} { ++ return ++ } ++ ++ clean_restart $binfile ++ ++ # Displaced-stepping a tbegin. causes problems, ++ # so we make the breakpoint temporary. ++ gdb_breakpoint [gdb_get_line_number "marker" "$gen_src"] temporary ++ ++ gdb_run_cmd ++ ++ # Wait for the prompt. ++ if {[gdb_test "" "Temporary breakpoint.*"] != 0 } { ++ return ++ } ++ ++ # Make sure that we stopped at the right place (just before tbegin. is ++ # executed). ++ if { [gdb_test "x/i \$pc" "=> $hex.*:.*tbegin\\..*" "disassemble tbegin"] != 0} { ++ return ++ } ++ ++ if {![check_register_access "vs0"]} { ++ return ++ } ++ ++ if {![check_register_access "texasr"]} { ++ return ++ } ++ ++ if {![check_register_access "dscr"]} { ++ return ++ } ++ ++ if {![check_register_access "ppr"]} { ++ return ++ } ++ ++ if {![check_register_access "tar"]} { ++ return ++ } ++ ++ if {![check_htm_support]} { ++ return ++ } ++} ++ ++# Now do the actual test. ++if {[build_executable "compile" $binfile $srcfile {debug}] == -1} { ++ return ++} ++ ++clean_restart $binfile ++ ++gdb_breakpoint [gdb_get_line_number "first marker"] temporary ++ ++gdb_run_cmd ++ ++# Wait for the prompt. ++gdb_test "" "Temporary breakpoint.*" ++ ++if {[gdb_test "x/i \$pc" "=> $hex.*:.*tbegin\\..*" "disassemble tbegin"] != 0} { ++ return ++} ++ ++# Now we write non-zero values to some registers, then read the values ++# of various registers, then stepi to start the transaction. The ++# checkpointed register state should correspond to the values we read. ++ ++# Write to the GPRs ++for {set i 0} {$i < 32} {incr i 1} { ++ gdb_test_no_output "set \$r$i = $i" ++} ++ ++gdb_test_no_output "set \$xer = 0xc0000000" ++ ++# FPRs ++gdb_test_no_output "set \$f0 = 0.5" ++for {set i 1} {$i < 32} {incr i 1} { ++ gdb_test_no_output "set \$f$i = \$f[expr $i - 1] + 1.0" ++} ++ ++gdb_test_no_output "set \$fpscr = 0x84005000" ++ ++# VRs ++for {set i 0} {$i < 32} {incr i 1} { ++ for {set j 0} {$j < 4} {incr j 1} { ++ gdb_test_no_output "set \$vr$i.v4_int32\[$j\] = $i" ++ } ++} ++ ++gdb_test_no_output "set \$dscr = 0x2" ++gdb_test_no_output "set \$tar = &main" "set tar" ++ ++# Get the pre-transactional value of the registers. ++for {set i 0} {$i < 32} {incr i 1} { ++ set "r$i" [get_hexadecimal_valueof "\$r$i" "default0"] ++} ++ ++set cr [get_hexadecimal_valueof "\$cr" "default0"] ++set xer [get_hexadecimal_valueof "\$xer" "default0"] ++set lr [get_hexadecimal_valueof "\$lr" "default0"] ++set ctr [get_hexadecimal_valueof "\$ctr" "default0"] ++ ++for {set i 0} {$i < 32} {incr i 1} { ++ set "f$i" [get_valueof "" "\$f$i" "default0"] ++} ++ ++set fpscr [get_hexadecimal_valueof "\$fpscr" "default0"] ++ ++for {set i 0} {$i < 32} {incr i 1} { ++ set "vr$i" [get_hexadecimal_valueof "\$vr$i.uint128" "default0"] ++} ++ ++set vscr [get_hexadecimal_valueof "\$vscr" "default0"] ++set vrsave [get_hexadecimal_valueof "\$vrsave" "default0"] ++ ++for {set i 0} {$i < 64} {incr i 1} { ++ set "vs$i" [get_hexadecimal_valueof "\$vs$i.uint128" "default0"] ++} ++ ++set dscr [get_hexadecimal_valueof "\$dscr" "default0"] ++set ppr [get_hexadecimal_valueof "\$ppr" "default0"] ++set tar [get_hexadecimal_valueof "\$tar" "default0"] ++ ++gdb_test "stepi" "asm.*bc.*" ++ ++proc test_register_match {reg_name reg_var_name hex} { ++ set test "$reg_name matches $reg_var_name" ++ ++ # In some infrequent cases CXER doesn't match the ++ # pre-transactional XER, possibly due to a linux kernel bug. ++ set should_xfail 0 ++ if [istarget "powerpc*-*-linux*" && reg_name == "cxer"] { ++ set should_xfail 1 ++ } ++ ++ upvar $reg_var_name expected_val ++ ++ if {$hex} { ++ set actual_val [get_hexadecimal_valueof "\$$reg_name" "default1"] ++ } else { ++ set actual_val [get_valueof "" "\$$reg_name" "default1"] ++ } ++ ++ if { "$expected_val" == "$actual_val" } { ++ pass $test ++ } else { ++ if {$should_xfail} { ++ xfail $test ++ } else { ++ fail $test ++ } ++ } ++} ++ ++for {set i 0} {$i < 32} {incr i 1} { ++ test_register_match "cr$i" "r$i" 1 ++} ++ ++test_register_match "ccr" "cr" 1 ++test_register_match "cxer" "xer" 1 ++test_register_match "clr" "lr" 1 ++test_register_match "cctr" "ctr" 1 ++ ++for {set i 0} {$i < 32} {incr i 1} { ++ test_register_match "cf$i" "f$i" 0 ++} ++ ++test_register_match "cfpscr" "fpscr" 1 ++ ++for {set i 0} {$i < 32} {incr i 1} { ++ test_register_match "cvr$i.uint128" "vr$i" 1 ++} ++ ++test_register_match "cvscr" "vscr" 1 ++test_register_match "cvrsave" "vrsave" 1 ++ ++for {set i 0} {$i < 64} {incr i 1} { ++ test_register_match "cvs$i.uint128" "vs$i" 1 ++} ++ ++test_register_match "cdscr" "dscr" 1 ++test_register_match "cppr" "ppr" 1 ++test_register_match "ctar" "tar" 1 ++ ++# Support for writing to the checkpointed registers is not ++# currently available in the gdbserver stub. ++if [target_is_gdbserver] { ++ unsupported "write to checkpointed registers" ++ return ++} ++ ++# Now write different values to some of the checkpointed registers and ++# check that the transaction abort reverts the register to these ++# values. ++for {set i 0} {$i < 32} {incr i 1} { ++ gdb_test_no_output "set \$cr$i = $i + 0xC00" ++} ++ ++gdb_test_no_output "set \$cf0 = 0.25" ++for {set i 1} {$i < 32} {incr i 1} { ++ gdb_test_no_output "set \$cf$i = \$cf[expr $i - 1] + 1.0" ++} ++ ++for {set i 0} {$i < 32} {incr i 1} { ++ for {set j 0} {$j < 4} {incr j 1} { ++ gdb_test_no_output "set \$cvr$i.v4_int32\[$j\] = $i + 0xF00" ++ } ++} ++ ++# Read back the values. ++with_test_prefix "after write" { ++ for {set i 0} {$i < 32} {incr i 1} { ++ set "cr$i" [get_hexadecimal_valueof "\$cr$i" "default0"] ++ } ++ ++ for {set i 0} {$i < 32} {incr i 1} { ++ set "cf$i" [get_valueof "" "\$cf$i" "default0"] ++ } ++ ++ for {set i 0} {$i < 64} {incr i 1} { ++ set "cvs$i" [get_hexadecimal_valueof "\$cvs$i.uint128" "default0"] ++ } ++} ++ ++gdb_breakpoint [gdb_get_line_number "second marker"] ++ ++gdb_test "continue" ++ ++with_test_prefix "after transaction failure" { ++ for {set i 0} {$i < 32} {incr i 1} { ++ test_register_match "r$i" "cr$i" 1 ++ } ++ ++ for {set i 0} {$i < 32} {incr i 1} { ++ test_register_match "f$i" "cf$i" 0 ++ } ++ ++ for {set i 0} {$i < 64} {incr i 1} { ++ test_register_match "vs$i.uint128" "cvs$i" 1 ++ } ++} ++ diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-01of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-01of15.patch new file mode 100644 index 0000000..57edda1 --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-01of15.patch @@ -0,0 +1,35 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:12 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8.2-01of15.patch + +;; Fix remote.c build failure +;; Szabolcs Nagy + + Fix gdb/remote.c build failure + + Add const qualifier to fix + + /S/gdb/common/gdb_locale.h:35:27: error: deprecated conversion from string c + # define _(String) (String) + ^ + /S/gdb/remote.c:12844:19: note: in expansion of macro '_' + char *err_msg = _("Tracepoint packet too large for target."); + ^ + gdb/ChangeLog: + + * remote.c (remote_target::download_tracepoint): Change char* to + const char*. + +diff --git a/gdb/remote.c b/gdb/remote.c +--- a/gdb/remote.c ++++ b/gdb/remote.c +@@ -12808,7 +12808,7 @@ remote_target::download_tracepoint (struct bp_location *loc) + struct tracepoint *t = (struct tracepoint *) b; + struct remote_state *rs = get_remote_state (); + int ret; +- char *err_msg = _("Tracepoint packet too large for target."); ++ const char *err_msg = _("Tracepoint packet too large for target."); + size_t size_left; + + /* We use a buffer other than rs->buf because we'll build strings diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-02of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-02of15.patch new file mode 100644 index 0000000..9d57b28 --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-02of15.patch @@ -0,0 +1,479 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:12 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8.2-02of15.patch + +;; Add grok/write functions for new ppc core note sections +;; Edjunior Barbosa Machado + + Add grok/write functions for new ppc core note sections + + This patch adds functions for grokking and writing more register core + note sections (NT_PPC_TAR, NT_PPC_PPR, NT_PPC_DSCR, NT_PPC_EBB, + NT_PPC_PMU, NT_PPC_TM_CGPR, NT_PPC_TM_CFPR, NT_PPC_TM_CVMX, + NT_PPC_TM_CVSX, NT_PPC_TM_SPR, NT_PPC_TM_CTAR, NT_PPC_TM_CPPR, + NT_PPC_TM_CDSCR). + + 2018-07-16 Edjunior Barbosa Machado + + bfd/ + * elf-bfd.h (elfcore_write_ppc_tar): Add prototype. + (elfcore_write_ppc_ppr): Likewise. + (elfcore_write_ppc_dscr): Likewise. + (elfcore_write_ppc_ebb): Likewise. + (elfcore_write_ppc_pmu): Likewise. + (elfcore_write_ppc_tm_cgpr): Likewise. + (elfcore_write_ppc_tm_cfpr): Likewise. + (elfcore_write_ppc_tm_cvmx): Likewise. + (elfcore_write_ppc_tm_cvsx): Likewise. + (elfcore_write_ppc_tm_spr): Likewise. + (elfcore_write_ppc_tm_ctar): Likewise. + (elfcore_write_ppc_tm_cppr): Likewise. + (elfcore_write_ppc_tm_cdscr): Likewise. + * elf.c (elfcore_write_ppc_tar): New function. + (elfcore_write_ppc_ppr): Likewise. + (elfcore_write_ppc_dscr): Likewise. + (elfcore_write_ppc_ebb): Likewise. + (elfcore_write_ppc_pmu): Likewise. + (elfcore_write_ppc_tm_cgpr): Likewise. + (elfcore_write_ppc_tm_cfpr): Likewise. + (elfcore_write_ppc_tm_cvmx): Likewise. + (elfcore_write_ppc_tm_cvsx): Likewise. + (elfcore_write_ppc_tm_spr): Likewise. + (elfcore_write_ppc_tm_ctar): Likewise. + (elfcore_write_ppc_tm_cppr): Likewise. + (elfcore_write_ppc_tm_cdscr): Likewise. + (elfcore_write_register_note): Call them. + (elfcore_grok_ppc_tar): New function. + (elfcore_grok_ppc_ppr): Likewise. + (elfcore_grok_ppc_dscr): Likewise. + (elfcore_grok_ppc_ebb): Likewise. + (elfcore_grok_ppc_pmu): Likewise. + (elfcore_grok_ppc_tm_cgpr): Likewise. + (elfcore_grok_ppc_tm_cfpr): Likewise. + (elfcore_grok_ppc_tm_cvmx): Likewise. + (elfcore_grok_ppc_tm_cvsx): Likewise. + (elfcore_grok_ppc_tm_spr): Likewise. + (elfcore_grok_ppc_tm_ctar): Likewise. + (elfcore_grok_ppc_tm_cppr): Likewise. + (elfcore_grok_ppc_tm_cdscr): Likewise. + (elfcore_grok_note): Call them. + +diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h +--- a/bfd/elf-bfd.h ++++ b/bfd/elf-bfd.h +@@ -2569,6 +2569,32 @@ extern char *elfcore_write_ppc_vmx + (bfd *, char *, int *, const void *, int); + extern char *elfcore_write_ppc_vsx + (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tar ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_ppr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_dscr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_ebb ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_pmu ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_cgpr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_cfpr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_cvmx ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_cvsx ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_spr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_ctar ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_cppr ++ (bfd *, char *, int *, const void *, int); ++extern char *elfcore_write_ppc_tm_cdscr ++ (bfd *, char *, int *, const void *, int); + extern char *elfcore_write_s390_timer + (bfd *, char *, int *, const void *, int); + extern char *elfcore_write_s390_todcmp +diff --git a/bfd/elf.c b/bfd/elf.c +--- a/bfd/elf.c ++++ b/bfd/elf.c +@@ -9239,6 +9239,84 @@ elfcore_grok_ppc_vsx (bfd *abfd, Elf_Internal_Note *note) + } + + static bfd_boolean ++elfcore_grok_ppc_tar (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tar", note); ++} ++ ++static bfd_boolean ++elfcore_grok_ppc_ppr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-ppr", note); ++} ++ ++static bfd_boolean ++elfcore_grok_ppc_dscr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-dscr", note); ++} ++ ++static bfd_boolean ++elfcore_grok_ppc_ebb (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-ebb", note); ++} ++ ++static bfd_boolean ++elfcore_grok_ppc_pmu (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-pmu", note); ++} ++ ++static bfd_boolean ++elfcore_grok_ppc_tm_cgpr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cgpr", note); ++} ++ ++static bfd_boolean ++elfcore_grok_ppc_tm_cfpr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cfpr", note); ++} ++ ++static bfd_boolean ++elfcore_grok_ppc_tm_cvmx (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cvmx", note); ++} ++ ++static bfd_boolean ++elfcore_grok_ppc_tm_cvsx (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cvsx", note); ++} ++ ++static bfd_boolean ++elfcore_grok_ppc_tm_spr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-spr", note); ++} ++ ++static bfd_boolean ++elfcore_grok_ppc_tm_ctar (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-ctar", note); ++} ++ ++static bfd_boolean ++elfcore_grok_ppc_tm_cppr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cppr", note); ++} ++ ++static bfd_boolean ++elfcore_grok_ppc_tm_cdscr (bfd *abfd, Elf_Internal_Note *note) ++{ ++ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cdscr", note); ++} ++ ++static bfd_boolean + elfcore_grok_s390_high_gprs (bfd *abfd, Elf_Internal_Note *note) + { + return elfcore_make_note_pseudosection (abfd, ".reg-s390-high-gprs", note); +@@ -9717,6 +9795,97 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) + else + return TRUE; + ++ case NT_PPC_TAR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tar (abfd, note); ++ else ++ return TRUE; ++ ++ case NT_PPC_PPR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_ppr (abfd, note); ++ else ++ return TRUE; ++ ++ case NT_PPC_DSCR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_dscr (abfd, note); ++ else ++ return TRUE; ++ ++ case NT_PPC_EBB: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_ebb (abfd, note); ++ else ++ return TRUE; ++ ++ case NT_PPC_PMU: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_pmu (abfd, note); ++ else ++ return TRUE; ++ ++ case NT_PPC_TM_CGPR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_cgpr (abfd, note); ++ else ++ return TRUE; ++ ++ case NT_PPC_TM_CFPR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_cfpr (abfd, note); ++ else ++ return TRUE; ++ ++ case NT_PPC_TM_CVMX: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_cvmx (abfd, note); ++ else ++ return TRUE; ++ ++ case NT_PPC_TM_CVSX: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_cvsx (abfd, note); ++ else ++ return TRUE; ++ ++ case NT_PPC_TM_SPR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_spr (abfd, note); ++ else ++ return TRUE; ++ ++ case NT_PPC_TM_CTAR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_ctar (abfd, note); ++ else ++ return TRUE; ++ ++ case NT_PPC_TM_CPPR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_cppr (abfd, note); ++ else ++ return TRUE; ++ ++ case NT_PPC_TM_CDSCR: ++ if (note->namesz == 6 ++ && strcmp (note->namedata, "LINUX") == 0) ++ return elfcore_grok_ppc_tm_cdscr (abfd, note); ++ else ++ return TRUE; ++ + case NT_S390_HIGH_GPRS: + if (note->namesz == 6 + && strcmp (note->namedata, "LINUX") == 0) +@@ -10817,6 +10986,162 @@ elfcore_write_ppc_vsx (bfd *abfd, + note_name, NT_PPC_VSX, ppc_vsx, size); + } + ++char * ++elfcore_write_ppc_tar (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tar, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TAR, ppc_tar, size); ++} ++ ++char * ++elfcore_write_ppc_ppr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_ppr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_PPR, ppc_ppr, size); ++} ++ ++char * ++elfcore_write_ppc_dscr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_dscr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_DSCR, ppc_dscr, size); ++} ++ ++char * ++elfcore_write_ppc_ebb (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_ebb, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_EBB, ppc_ebb, size); ++} ++ ++char * ++elfcore_write_ppc_pmu (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_pmu, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_PMU, ppc_pmu, size); ++} ++ ++char * ++elfcore_write_ppc_tm_cgpr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_cgpr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CGPR, ppc_tm_cgpr, size); ++} ++ ++char * ++elfcore_write_ppc_tm_cfpr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_cfpr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CFPR, ppc_tm_cfpr, size); ++} ++ ++char * ++elfcore_write_ppc_tm_cvmx (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_cvmx, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CVMX, ppc_tm_cvmx, size); ++} ++ ++char * ++elfcore_write_ppc_tm_cvsx (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_cvsx, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CVSX, ppc_tm_cvsx, size); ++} ++ ++char * ++elfcore_write_ppc_tm_spr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_spr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_SPR, ppc_tm_spr, size); ++} ++ ++char * ++elfcore_write_ppc_tm_ctar (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_ctar, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CTAR, ppc_tm_ctar, size); ++} ++ ++char * ++elfcore_write_ppc_tm_cppr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_cppr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CPPR, ppc_tm_cppr, size); ++} ++ ++char * ++elfcore_write_ppc_tm_cdscr (bfd *abfd, ++ char *buf, ++ int *bufsiz, ++ const void *ppc_tm_cdscr, ++ int size) ++{ ++ char *note_name = "LINUX"; ++ return elfcore_write_note (abfd, buf, bufsiz, ++ note_name, NT_PPC_TM_CDSCR, ppc_tm_cdscr, size); ++} ++ + static char * + elfcore_write_s390_high_gprs (bfd *abfd, + char *buf, +@@ -11045,6 +11370,32 @@ elfcore_write_register_note (bfd *abfd, + return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size); + if (strcmp (section, ".reg-ppc-vsx") == 0) + return elfcore_write_ppc_vsx (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tar") == 0) ++ return elfcore_write_ppc_tar (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-ppr") == 0) ++ return elfcore_write_ppc_ppr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-dscr") == 0) ++ return elfcore_write_ppc_dscr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-ebb") == 0) ++ return elfcore_write_ppc_ebb (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-pmu") == 0) ++ return elfcore_write_ppc_pmu (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-cgpr") == 0) ++ return elfcore_write_ppc_tm_cgpr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-cfpr") == 0) ++ return elfcore_write_ppc_tm_cfpr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-cvmx") == 0) ++ return elfcore_write_ppc_tm_cvmx (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-cvsx") == 0) ++ return elfcore_write_ppc_tm_cvsx (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-spr") == 0) ++ return elfcore_write_ppc_tm_spr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-ctar") == 0) ++ return elfcore_write_ppc_tm_ctar (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-cppr") == 0) ++ return elfcore_write_ppc_tm_cppr (abfd, buf, bufsiz, data, size); ++ if (strcmp (section, ".reg-ppc-tm-cdscr") == 0) ++ return elfcore_write_ppc_tm_cdscr (abfd, buf, bufsiz, data, size); + if (strcmp (section, ".reg-s390-high-gprs") == 0) + return elfcore_write_s390_high_gprs (abfd, buf, bufsiz, data, size); + if (strcmp (section, ".reg-s390-timer") == 0) diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-03of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-03of15.patch new file mode 100644 index 0000000..d51265b --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-03of15.patch @@ -0,0 +1,61 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:13 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8.2-03of15.patch + +;; Zero-initialize linux note sections +;; Pedro Franco de Carvalho + + Zero-initialize linux note sections + + This patches changes linux-tdep.c so that the buffer used to write + note sections when generating a core file is zero-initialized. This + way, bytes that are not collected won't contain random + data (e.g. padding bytes). + + gdb/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * linux-tdep.c (linux_collect_regset_section_cb): Use + std::vector instead of char * and malloc for buf. + Remove xfree. + +diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c +--- a/gdb/linux-tdep.c ++++ b/gdb/linux-tdep.c +@@ -1584,7 +1584,6 @@ linux_collect_regset_section_cb (const char *sect_name, int supply_size, + int collect_size, const struct regset *regset, + const char *human_name, void *cb_data) + { +- char *buf; + struct linux_collect_regset_section_cb_data *data + = (struct linux_collect_regset_section_cb_data *) cb_data; + bool variable_size_section = (regset != NULL +@@ -1598,19 +1597,22 @@ linux_collect_regset_section_cb (const char *sect_name, int supply_size, + + gdb_assert (regset && regset->collect_regset); + +- buf = (char *) xmalloc (collect_size); +- regset->collect_regset (regset, data->regcache, -1, buf, collect_size); ++ /* This is intentionally zero-initialized by using std::vector, so ++ that any padding bytes in the core file will show as 0. */ ++ std::vector buf (collect_size); ++ ++ regset->collect_regset (regset, data->regcache, -1, buf.data (), ++ collect_size); + + /* PRSTATUS still needs to be treated specially. */ + if (strcmp (sect_name, ".reg") == 0) + data->note_data = (char *) elfcore_write_prstatus + (data->obfd, data->note_data, data->note_size, data->lwp, +- gdb_signal_to_host (data->stop_signal), buf); ++ gdb_signal_to_host (data->stop_signal), buf.data ()); + else + data->note_data = (char *) elfcore_write_register_note + (data->obfd, data->note_data, data->note_size, +- sect_name, buf, collect_size); +- xfree (buf); ++ sect_name, buf.data (), collect_size); + + if (data->note_data == NULL) + data->abort_iteration = 1; diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-04of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-04of15.patch new file mode 100644 index 0000000..aa7fd7d --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-04of15.patch @@ -0,0 +1,88 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:13 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8.2-04of15.patch + +;; [PowerPC] Don't zero-initialize vector register buffers +;; Pedro Franco de Carvalho + + [PowerPC] Don't zero-initialize vector register buffers + + Now that linux-tdep.c already zero-initializes the buffer used for + generating core file notes, there is no need to do this in the linux + collect functions for the vector regset. The memsets in gdbserver were + not useful to begin with. + + gdb/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * ppc-linux-tdep.c (ppc_linux_collect_vrregset): Remove. + (ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): Replace + ppc_linux_collect_vrregset by regcache_collect_regset. + + gdb/gdbserver/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * linux-ppc-low.c (ppc_fill_vrregset): Remove memset calls. + +diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c +--- a/gdb/gdbserver/linux-ppc-low.c ++++ b/gdb/gdbserver/linux-ppc-low.c +@@ -495,13 +495,9 @@ ppc_fill_vrregset (struct regcache *regcache, void *buf) + if (__BYTE_ORDER == __BIG_ENDIAN) + vscr_offset = 12; + +- /* Zero-pad the unused bytes in the fields for vscr and vrsave in +- case they get displayed somewhere. */ +- memset (®set[32 * 16], 0, 16); + collect_register_by_name (regcache, "vscr", + ®set[32 * 16 + vscr_offset]); + +- memset (®set[33 * 16], 0, 16); + collect_register_by_name (regcache, "vrsave", ®set[33 * 16]); + } + +diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c +--- a/gdb/ppc-linux-tdep.c ++++ b/gdb/ppc-linux-tdep.c +@@ -444,24 +444,6 @@ ppc_linux_collect_gregset (const struct regset *regset, + } + } + +-static void +-ppc_linux_collect_vrregset (const struct regset *regset, +- const struct regcache *regcache, +- int regnum, void *buf, size_t len) +-{ +- gdb_byte *vrregs = (gdb_byte *) buf; +- +- /* Zero-pad the unused bytes in the fields for vscr and vrsave +- in case they get displayed somewhere (e.g. in core files). */ +- if (regnum == PPC_VSCR_REGNUM || regnum == -1) +- memset (&vrregs[32 * 16], 0, 16); +- +- if (regnum == PPC_VRSAVE_REGNUM || regnum == -1) +- memset (&vrregs[33 * 16], 0, 16); +- +- regcache_collect_regset (regset, regcache, regnum, buf, len); +-} +- + /* Regset descriptions. */ + static const struct ppc_reg_offsets ppc32_linux_reg_offsets = + { +@@ -544,13 +526,13 @@ static const struct regcache_map_entry ppc32_be_linux_vrregmap[] = + static const struct regset ppc32_le_linux_vrregset = { + ppc32_le_linux_vrregmap, + regcache_supply_regset, +- ppc_linux_collect_vrregset ++ regcache_collect_regset + }; + + static const struct regset ppc32_be_linux_vrregset = { + ppc32_be_linux_vrregmap, + regcache_supply_regset, +- ppc_linux_collect_vrregset ++ regcache_collect_regset + }; + + static const struct regcache_map_entry ppc32_linux_vsxregmap[] = diff --git a/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-05of15.patch b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-05of15.patch new file mode 100644 index 0000000..bd5216f --- /dev/null +++ b/SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-05of15.patch @@ -0,0 +1,34 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Fri, 11 Jan 2019 17:02:14 -0500 +Subject: gdb-rhbz1187581-power8-regs-not-in-8.2-05of15.patch + +;; Add decfloat registers to float reggroup +;; Pedro Franco de Carvalho + + Add decfloat registers to float reggroup + + This patch changes default_register_reggroup_p to return true when the + register type is decimal floating point and the reggroup is + float_reggroup. + + gdb/ChangeLog: + 2018-10-26 Pedro Franco de Carvalho + + * reggroups.c (default_register_reggroup_p): Return true for + decfloat registers and float_reggroup. + +diff --git a/gdb/reggroups.c b/gdb/reggroups.c +--- a/gdb/reggroups.c ++++ b/gdb/reggroups.c +@@ -202,7 +202,9 @@ default_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + if (group == all_reggroup) + return 1; + vector_p = TYPE_VECTOR (register_type (gdbarch, regnum)); +- float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT; ++ float_p = (TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT ++ || (TYPE_CODE (register_type (gdbarch, regnum)) ++ == TYPE_CODE_DECFLOAT)); + raw_p = regnum < gdbarch_num_regs (gdbarch); + if (group == float_reggroup) + return float_p; diff --git a/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-1of5.patch b/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-1of5.patch new file mode 100644 index 0000000..1baa5e0 --- /dev/null +++ b/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-1of5.patch @@ -0,0 +1,747 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Sergio Durigan Junior +Date: Fri, 11 Jan 2019 10:52:17 -0500 +Subject: + gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-1of5.patch + +;; Fix 'Assertion `SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE (dict)->la_language' failed.' +;; Keith Seitz, RHBZ#1560010. + +gdb/23712: Introduce multidictionary's + +gdb/23712 is a new manifestation of the now-infamous (at least to me) +symtab/23010 assertion failure (DICT_LANGUAGE == SYMBOL_LANGAUGE). + +An example of the problem (using test case from symtab/23010): + +Reading symbols from /home/rdiez/rdiez/arduino/JtagDue/BuildOutput/JtagDue-obj-release/firmware.elf...done. +(gdb) p SysTick_Handler +dwarf2read.c:9715: internal-error: void dw2_add_symbol_to_list(symbol*, pending**): Assertion `(*listhead) == NULL || (SYMBOL_LANGUAGE ((*listhead)->symbol[0]) == SYMBOL_LANGUAGE (symbol))' failed. +A problem internal to GDB has been detected, +further debugging may prove unreliable. +Quit this debugging session? (y or n) + +This assertion was added specifically to catch this condition (of adding +symbols of different languages to a single pending list). + +The problems we're now seeing on systems utilizing DWARF debugging seem to +be caused by the use of LTO, which adds a CU with an artificial DIE of +language C99 which references DIEs in other CUs of language C++. + +Thus, we create a dictionary containing symbols of C99 but end up +stuffing C++ symbols into it, and the dw2_add_symbol_to_list triggers. + +The approach taken here to fix this is to introduce multi-language +dictionaries to "replace" the standard, single-language dictionaries +used today. + +Note to reviewers: This patch introduces some temporary functions to +aide with review. This and other artifacts (such as "See dictionary.h" +which appear incorrect) will all be valid at the end of the series. + +This first patch introduces the new multidictionary and its API (which +is, by design, identical to the old dictionary interface). It also +mutates dict_create_hashed and dict_create_linear so that they take +a std::vector instead of the usual struct pending linked list. This will +be needed later on. + +This patch does /not/ actually enable multidictionary's. That is left +for a subsequent patch in the series. + +I've done exhaustive performance testing with this approach, and I've +attempted to minimize the overhead for the (overwhelmingly) most common +one-language scenario. + +On average, a -g3 -O0 GDB (the one we developers use) will see +approximately a 4% slowdown when initially reading symbols. [I've +tested only GDB and firefox with -readnow.] When using -O2, this +difference shrinks to ~0.5%. Since a number of runs with these +patches actually run /faster/ than unpatched GDB, I conclude that +these tests have at least a 0.5% error margin. + +On our own gdb.perf test suite, again, results appear to be pretty +negligible. Differences to unpatched GDB range from -7.8% (yes, +patched version is again faster than unpatched) to 27%. All tests +lying outside "negligible," such as the 27% slowdown, involve a total +run time of 0.0007 (or less) with smaller numbers of CUs/DSOs (usually 10 +or 100). In all cases, the follow-up tests with more CUs/DSOs is never +more than 3% difference to the baseline, unpatched GDB. + +In my opinion, these results are satisfactory. + +gdb/ChangeLog: + + PR gdb/23712 + PR symtab/23010 + * dictionary.c: Include unordered_map. + (pending_to_vector): New function. + (dict_create_hashed_1, dict_create_linear_1, dict_add_pending_1): + Rewrite the non-"_1" functions to take vector instead + of linked list. + (dict_create_hashed, dict_create_linear, dict_add_pending): Use the + "new" _1 versions of the same name. + (multidictionary): Define. + (std::hash + + /* This file implements dictionaries, which are tables that associate + symbols to names. They are represented by an opaque type 'struct +@@ -341,53 +342,66 @@ static void insert_symbol_hashed (struct dictionary *dict, + + static void expand_hashtable (struct dictionary *dict); + ++/* A function to convert a linked list into a vector. */ ++ ++static std::vector ++pending_to_vector (const struct pending *symbol_list) ++{ ++ std::vector symlist; ++ ++ for (const struct pending *list_counter = symbol_list; ++ list_counter != nullptr; list_counter = list_counter->next) ++ { ++ for (int i = list_counter->nsyms - 1; i >= 0; --i) ++ symlist.push_back (list_counter->symbol[i]); ++ } ++ ++ return symlist; ++} ++ + /* The creation functions. */ + +-/* See dictionary.h. */ ++/* A function to transition dict_create_hashed to new API. */ + +-struct dictionary * +-dict_create_hashed (struct obstack *obstack, +- enum language language, +- const struct pending *symbol_list) ++static struct dictionary * ++dict_create_hashed_1 (struct obstack *obstack, ++ enum language language, ++ const std::vector &symbol_list) + { +- struct dictionary *retval; +- int nsyms = 0, nbuckets, i; +- struct symbol **buckets; +- const struct pending *list_counter; +- +- retval = XOBNEW (obstack, struct dictionary); ++ /* Allocate the dictionary. */ ++ struct dictionary *retval = XOBNEW (obstack, struct dictionary); + DICT_VECTOR (retval) = &dict_hashed_vector; + DICT_LANGUAGE (retval) = language_def (language); + +- /* Calculate the number of symbols, and allocate space for them. */ +- for (list_counter = symbol_list; +- list_counter != NULL; +- list_counter = list_counter->next) +- { +- nsyms += list_counter->nsyms; +- } +- nbuckets = DICT_HASHTABLE_SIZE (nsyms); ++ /* Allocate space for symbols. */ ++ int nsyms = symbol_list.size (); ++ int nbuckets = DICT_HASHTABLE_SIZE (nsyms); + DICT_HASHED_NBUCKETS (retval) = nbuckets; +- buckets = XOBNEWVEC (obstack, struct symbol *, nbuckets); ++ struct symbol **buckets = XOBNEWVEC (obstack, struct symbol *, nbuckets); + memset (buckets, 0, nbuckets * sizeof (struct symbol *)); + DICT_HASHED_BUCKETS (retval) = buckets; + + /* Now fill the buckets. */ +- for (list_counter = symbol_list; +- list_counter != NULL; +- list_counter = list_counter->next) +- { +- for (i = list_counter->nsyms - 1; i >= 0; --i) +- { +- insert_symbol_hashed (retval, list_counter->symbol[i]); +- } +- } ++ for (const auto &sym : symbol_list) ++ insert_symbol_hashed (retval, sym); + + return retval; + } + + /* See dictionary.h. */ + ++struct dictionary * ++dict_create_hashed (struct obstack *obstack, ++ enum language language, ++ const struct pending *symbol_list) ++{ ++ std::vector symlist = pending_to_vector (symbol_list); ++ ++ return dict_create_hashed_1 (obstack, language, symlist); ++} ++ ++/* See dictionary.h. */ ++ + extern struct dictionary * + dict_create_hashed_expandable (enum language language) + { +@@ -403,46 +417,27 @@ dict_create_hashed_expandable (enum language language) + return retval; + } + +-/* See dictionary.h. */ ++/* A function to transition dict_create_linear to new API. */ + +-struct dictionary * +-dict_create_linear (struct obstack *obstack, +- enum language language, +- const struct pending *symbol_list) ++static struct dictionary * ++dict_create_linear_1 (struct obstack *obstack, ++ enum language language, ++ const std::vector &symbol_list) + { +- struct dictionary *retval; +- int nsyms = 0, i, j; +- struct symbol **syms; +- const struct pending *list_counter; +- +- retval = XOBNEW (obstack, struct dictionary); ++ struct dictionary *retval = XOBNEW (obstack, struct dictionary); + DICT_VECTOR (retval) = &dict_linear_vector; + DICT_LANGUAGE (retval) = language_def (language); + +- /* Calculate the number of symbols, and allocate space for them. */ +- for (list_counter = symbol_list; +- list_counter != NULL; +- list_counter = list_counter->next) +- { +- nsyms += list_counter->nsyms; +- } ++ /* Allocate space for symbols. */ ++ int nsyms = symbol_list.size (); + DICT_LINEAR_NSYMS (retval) = nsyms; +- syms = XOBNEWVEC (obstack, struct symbol *, nsyms ); ++ struct symbol **syms = XOBNEWVEC (obstack, struct symbol *, nsyms); + DICT_LINEAR_SYMS (retval) = syms; + +- /* Now fill in the symbols. Start filling in from the back, so as +- to preserve the original order of the symbols. */ +- for (list_counter = symbol_list, j = nsyms - 1; +- list_counter != NULL; +- list_counter = list_counter->next) +- { +- for (i = list_counter->nsyms - 1; +- i >= 0; +- --i, --j) +- { +- syms[j] = list_counter->symbol[i]; +- } +- } ++ /* Now fill in the symbols. */ ++ int idx = nsyms - 1; ++ for (const auto &sym : symbol_list) ++ syms[idx--] = sym; + + return retval; + } +@@ -450,6 +445,18 @@ dict_create_linear (struct obstack *obstack, + /* See dictionary.h. */ + + struct dictionary * ++dict_create_linear (struct obstack *obstack, ++ enum language language, ++ const struct pending *symbol_list) ++{ ++ std::vector symlist = pending_to_vector (symbol_list); ++ ++ return dict_create_linear_1 (obstack, language, symlist); ++} ++ ++/* See dictionary.h. */ ++ ++struct dictionary * + dict_create_linear_expandable (enum language language) + { + struct dictionary *retval = XNEW (struct dictionary); +@@ -483,20 +490,26 @@ dict_add_symbol (struct dictionary *dict, struct symbol *sym) + (DICT_VECTOR (dict))->add_symbol (dict, sym); + } + ++/* A function to transition dict_add_pending to new API. */ ++ ++static void ++dict_add_pending_1 (struct dictionary *dict, ++ const std::vector &symbol_list) ++{ ++ /* Preserve ordering by reversing the list. */ ++ for (auto sym = symbol_list.rbegin (); sym != symbol_list.rend (); ++sym) ++ dict_add_symbol (dict, *sym); ++} ++ + /* Utility to add a list of symbols to a dictionary. + DICT must be an expandable dictionary. */ + + void + dict_add_pending (struct dictionary *dict, const struct pending *symbol_list) + { +- const struct pending *list; +- int i; ++ std::vector symlist = pending_to_vector (symbol_list); + +- for (list = symbol_list; list != NULL; list = list->next) +- { +- for (i = 0; i < list->nsyms; ++i) +- dict_add_symbol (dict, list->symbol[i]); +- } ++ dict_add_pending_1 (dict, symlist); + } + + /* Initialize ITERATOR to point at the first symbol in DICT, and +@@ -929,3 +942,408 @@ add_symbol_linear_expandable (struct dictionary *dict, + + DICT_LINEAR_SYM (dict, nsyms - 1) = sym; + } ++ ++/* Multi-language dictionary support. */ ++ ++/* The structure describing a multi-language dictionary. */ ++ ++struct multidictionary ++{ ++ /* An array of dictionaries, one per language. All dictionaries ++ must be of the same type. This should be free'd for expandable ++ dictionary types. */ ++ struct dictionary **dictionaries; ++ ++ /* The number of language dictionaries currently allocated. ++ Only used for expandable dictionaries. */ ++ unsigned short n_allocated_dictionaries; ++}; ++ ++/* A hasher for enum language. Injecting this into std is a convenience ++ when using unordered_map with C++11. */ ++ ++namespace std ++{ ++ template<> struct hash ++ { ++ typedef enum language argument_type; ++ typedef std::size_t result_type; ++ ++ result_type operator() (const argument_type &l) const noexcept ++ { ++ return static_cast (l); ++ } ++ }; ++} /* namespace std */ ++ ++/* A helper function to collate symbols on the pending list by language. */ ++ ++static std::unordered_map> ++collate_pending_symbols_by_language (const struct pending *symbol_list) ++{ ++ std::unordered_map> nsyms; ++ ++ for (const struct pending *list_counter = symbol_list; ++ list_counter != nullptr; list_counter = list_counter->next) ++ { ++ for (int i = list_counter->nsyms - 1; i >= 0; --i) ++ { ++ enum language language = SYMBOL_LANGUAGE (list_counter->symbol[i]); ++ nsyms[language].push_back (list_counter->symbol[i]); ++ } ++ } ++ ++ return nsyms; ++} ++ ++/* See dictionary.h. */ ++ ++struct multidictionary * ++mdict_create_hashed (struct obstack *obstack, ++ const struct pending *symbol_list) ++{ ++ struct multidictionary *retval ++ = XOBNEW (obstack, struct multidictionary); ++ std::unordered_map> nsyms ++ = collate_pending_symbols_by_language (symbol_list); ++ ++ /* Loop over all languages and create/populate dictionaries. */ ++ retval->dictionaries ++ = XOBNEWVEC (obstack, struct dictionary *, nsyms.size ()); ++ retval->n_allocated_dictionaries = nsyms.size (); ++ ++ int idx = 0; ++ for (const auto &pair : nsyms) ++ { ++ enum language language = pair.first; ++ std::vector symlist = pair.second; ++ ++ retval->dictionaries[idx++] ++ = dict_create_hashed_1 (obstack, language, symlist); ++ } ++ ++ return retval; ++} ++ ++/* See dictionary.h. */ ++ ++struct multidictionary * ++mdict_create_hashed_expandable (enum language language) ++{ ++ struct multidictionary *retval = XNEW (struct multidictionary); ++ ++ /* We have no symbol list to populate, but we create an empty ++ dictionary of the requested language to populate later. */ ++ retval->n_allocated_dictionaries = 1; ++ retval->dictionaries = XNEW (struct dictionary *); ++ retval->dictionaries[0] = dict_create_hashed_expandable (language); ++ ++ return retval; ++} ++ ++/* See dictionary.h. */ ++ ++struct multidictionary * ++mdict_create_linear (struct obstack *obstack, ++ const struct pending *symbol_list) ++{ ++ struct multidictionary *retval ++ = XOBNEW (obstack, struct multidictionary); ++ std::unordered_map> nsyms ++ = collate_pending_symbols_by_language (symbol_list); ++ ++ /* Loop over all languages and create/populate dictionaries. */ ++ retval->dictionaries ++ = XOBNEWVEC (obstack, struct dictionary *, nsyms.size ()); ++ retval->n_allocated_dictionaries = nsyms.size (); ++ ++ int idx = 0; ++ for (const auto &pair : nsyms) ++ { ++ enum language language = pair.first; ++ std::vector symlist = pair.second; ++ ++ retval->dictionaries[idx++] ++ = dict_create_linear_1 (obstack, language, symlist); ++ } ++ ++ return retval; ++} ++ ++/* See dictionary.h. */ ++ ++struct multidictionary * ++mdict_create_linear_expandable (enum language language) ++{ ++ struct multidictionary *retval = XNEW (struct multidictionary); ++ ++ /* We have no symbol list to populate, but we create an empty ++ dictionary to populate later. */ ++ retval->n_allocated_dictionaries = 1; ++ retval->dictionaries = XNEW (struct dictionary *); ++ retval->dictionaries[0] = dict_create_linear_expandable (language); ++ ++ return retval; ++} ++ ++/* See dictionary.h. */ ++ ++void ++mdict_free (struct multidictionary *mdict) ++{ ++ /* Grab the type of dictionary being used. */ ++ enum dict_type type = mdict->dictionaries[0]->vector->type; ++ ++ /* Loop over all dictionaries and free them. */ ++ for (unsigned short idx = 0; idx < mdict->n_allocated_dictionaries; ++idx) ++ dict_free (mdict->dictionaries[idx]); ++ ++ /* Free the dictionary list, if needed. */ ++ switch (type) ++ { ++ case DICT_HASHED: ++ case DICT_LINEAR: ++ /* Memory was allocated on an obstack when created. */ ++ break; ++ ++ case DICT_HASHED_EXPANDABLE: ++ case DICT_LINEAR_EXPANDABLE: ++ xfree (mdict->dictionaries); ++ break; ++ } ++} ++ ++/* Helper function to find the dictionary associated with LANGUAGE ++ or NULL if there is no dictionary of that language. */ ++ ++static struct dictionary * ++find_language_dictionary (const struct multidictionary *mdict, ++ enum language language) ++{ ++ for (unsigned short idx = 0; idx < mdict->n_allocated_dictionaries; ++idx) ++ { ++ if (DICT_LANGUAGE (mdict->dictionaries[idx])->la_language == language) ++ return mdict->dictionaries[idx]; ++ } ++ ++ return nullptr; ++} ++ ++/* Create a new language dictionary for LANGUAGE and add it to the ++ multidictionary MDICT's list of dictionaries. If MDICT is not ++ based on expandable dictionaries, this function throws an ++ internal error. */ ++ ++static struct dictionary * ++create_new_language_dictionary (struct multidictionary *mdict, ++ enum language language) ++{ ++ struct dictionary *retval = nullptr; ++ ++ /* We use the first dictionary entry to decide what create function ++ to call. Not optimal but sufficient. */ ++ gdb_assert (mdict->dictionaries[0] != nullptr); ++ switch (mdict->dictionaries[0]->vector->type) ++ { ++ case DICT_HASHED: ++ case DICT_LINEAR: ++ internal_error (__FILE__, __LINE__, ++ _("create_new_language_dictionary: attempted to expand " ++ "non-expandable multidictionary")); ++ ++ case DICT_HASHED_EXPANDABLE: ++ retval = dict_create_hashed_expandable (language); ++ break; ++ ++ case DICT_LINEAR_EXPANDABLE: ++ retval = dict_create_linear_expandable (language); ++ break; ++ } ++ ++ /* Grow the dictionary vector and save the new dictionary. */ ++ mdict->dictionaries ++ = (struct dictionary **) xrealloc (mdict->dictionaries, ++ (++mdict->n_allocated_dictionaries ++ * sizeof (struct dictionary *))); ++ mdict->dictionaries[mdict->n_allocated_dictionaries - 1] = retval; ++ ++ return retval; ++} ++ ++/* See dictionary.h. */ ++ ++void ++mdict_add_symbol (struct multidictionary *mdict, struct symbol *sym) ++{ ++ struct dictionary *dict ++ = find_language_dictionary (mdict, SYMBOL_LANGUAGE (sym)); ++ ++ if (dict == nullptr) ++ { ++ /* SYM is of a new language that we haven't previously seen. ++ Create a new dictionary for it. */ ++ dict = create_new_language_dictionary (mdict, SYMBOL_LANGUAGE (sym)); ++ } ++ ++ dict_add_symbol (dict, sym); ++} ++ ++/* See dictionary.h. */ ++ ++void ++mdict_add_pending (struct multidictionary *mdict, ++ const struct pending *symbol_list) ++{ ++ std::unordered_map> nsyms ++ = collate_pending_symbols_by_language (symbol_list); ++ ++ for (const auto &pair : nsyms) ++ { ++ enum language language = pair.first; ++ std::vector symlist = pair.second; ++ struct dictionary *dict = find_language_dictionary (mdict, language); ++ ++ if (dict == nullptr) ++ { ++ /* The language was not previously seen. Create a new dictionary ++ for it. */ ++ dict = create_new_language_dictionary (mdict, language); ++ } ++ ++ dict_add_pending_1 (dict, symlist); ++ } ++} ++ ++/* See dictionary.h. */ ++ ++struct symbol * ++mdict_iterator_first (const multidictionary *mdict, ++ struct mdict_iterator *miterator) ++{ ++ miterator->mdict = mdict; ++ miterator->current_idx = 0; ++ ++ for (unsigned short idx = miterator->current_idx; ++ idx < mdict->n_allocated_dictionaries; ++idx) ++ { ++ struct symbol *result ++ = dict_iterator_first (mdict->dictionaries[idx], &miterator->iterator); ++ ++ if (result != nullptr) ++ { ++ miterator->current_idx = idx; ++ return result; ++ } ++ } ++ ++ return nullptr; ++} ++ ++/* See dictionary.h. */ ++ ++struct symbol * ++mdict_iterator_next (struct mdict_iterator *miterator) ++{ ++ struct symbol *result = dict_iterator_next (&miterator->iterator); ++ ++ if (result != nullptr) ++ return result; ++ ++ /* The current dictionary had no matches -- move to the next ++ dictionary, if any. */ ++ for (unsigned short idx = ++miterator->current_idx; ++ idx < miterator->mdict->n_allocated_dictionaries; ++idx) ++ { ++ result ++ = dict_iterator_first (miterator->mdict->dictionaries[idx], ++ &miterator->iterator); ++ if (result != nullptr) ++ { ++ miterator->current_idx = idx; ++ return result; ++ } ++ } ++ ++ return nullptr; ++} ++ ++/* See dictionary.h. */ ++ ++struct symbol * ++mdict_iter_match_first (const struct multidictionary *mdict, ++ const lookup_name_info &name, ++ struct mdict_iterator *miterator) ++{ ++ miterator->mdict = mdict; ++ miterator->current_idx = 0; ++ ++ for (unsigned short idx = miterator->current_idx; ++ idx < mdict->n_allocated_dictionaries; ++idx) ++ { ++ struct symbol *result ++ = dict_iter_match_first (mdict->dictionaries[idx], name, ++ &miterator->iterator); ++ ++ if (result != nullptr) ++ return result; ++ } ++ ++ return nullptr; ++} ++ ++/* See dictionary.h. */ ++ ++struct symbol * ++mdict_iter_match_next (const lookup_name_info &name, ++ struct mdict_iterator *miterator) ++{ ++ /* Search the current dictionary. */ ++ struct symbol *result = dict_iter_match_next (name, &miterator->iterator); ++ ++ if (result != nullptr) ++ return result; ++ ++ /* The current dictionary had no matches -- move to the next ++ dictionary, if any. */ ++ for (unsigned short idx = ++miterator->current_idx; ++ idx < miterator->mdict->n_allocated_dictionaries; ++idx) ++ { ++ result ++ = dict_iter_match_first (miterator->mdict->dictionaries[idx], ++ name, &miterator->iterator); ++ if (result != nullptr) ++ { ++ miterator->current_idx = idx; ++ return result; ++ } ++ } ++ ++ return nullptr; ++} ++ ++/* See dictionary.h. */ ++ ++int ++mdict_size (const struct multidictionary *mdict) ++{ ++ int size = 0; ++ ++ for (unsigned short idx = 0; idx < mdict->n_allocated_dictionaries; ++idx) ++ size += dict_size (mdict->dictionaries[idx]); ++ ++ return size; ++} ++ ++/* See dictionary.h. */ ++ ++bool ++mdict_empty (const struct multidictionary *mdict) ++{ ++ for (unsigned short idx = 0; idx < mdict->n_allocated_dictionaries; ++idx) ++ { ++ if (!dict_empty (mdict->dictionaries[idx])) ++ return false; ++ } ++ ++ return true; ++} +diff --git a/gdb/dictionary.h b/gdb/dictionary.h +--- a/gdb/dictionary.h ++++ b/gdb/dictionary.h +@@ -113,6 +113,21 @@ struct dict_iterator + struct symbol *current; + }; + ++/* The multi-language dictionary iterator. Like dict_iterator above, ++ these contents should be considered private. */ ++ ++struct mdict_iterator ++{ ++ /* The multidictionary with whcih this iterator is associated. */ ++ const struct multidictionary *mdict; ++ ++ /* The iterator used to iterate through individual dictionaries. */ ++ struct dict_iterator iterator; ++ ++ /* The current index of the dictionary being iterated over. */ ++ unsigned short current_idx; ++}; ++ + /* Initialize ITERATOR to point at the first symbol in DICT, and + return that first symbol, or NULL if DICT is empty. */ + diff --git a/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-2of5.patch b/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-2of5.patch new file mode 100644 index 0000000..f86ce0b --- /dev/null +++ b/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-2of5.patch @@ -0,0 +1,644 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Sergio Durigan Junior +Date: Fri, 11 Jan 2019 11:25:11 -0500 +Subject: + gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-2of5.patch + +;; Fix 'Assertion `SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE (dict)->la_language' failed.' +;; Keith Seitz, RHBZ#1560010. + +gdb/23712: Use new multidictionary API + +This patch builds on the previous by enabling the `new' multidictionary +API. A lot of the hunks are simply textual replacements of "dict_" +with "mdict_" and similar transformations. + +A word of warning, even with the use of multidictionaries, the code +still does not satisfactorily fix the reported problems with gdb/23712 +(or gdb/23010). We still have additional changes to make before that +happens. + +gdb/ChangeLog: + + PR gdb/23712 + PR symtab/23010 + * dictionary.h (struct dictionary): Replace declaration with + multidictionary. + (dict_create_hashed, dict_create_hashed_expandable) + (dict_create_linear, dict_create_linear_expandable) + (dict_free, dict_add_symbol, dict_add_pending, dict_empty) + (dict_iterator_first, dict_iterator_next, dict_iter_match_first) + (dict_iter_match_next, dict_size): Rename to "mdict_" versions + taking multidictionary argument. + [ALL_DICT_SYMBOLS]: Update for multidictionary. + * block.h (struct block) : Change to multidictionary + and rename `multidict'. + * block.c, buildsym.c, jit.c, mdebugread.c, objfiles.c, + symmisc.c: Update all dictionary references to multidictionary. + +diff --git a/gdb/block.c b/gdb/block.c +--- a/gdb/block.c ++++ b/gdb/block.c +@@ -387,9 +387,9 @@ block_global_block (const struct block *block) + zero/NULL. This is useful for creating "dummy" blocks that don't + correspond to actual source files. + +- Warning: it sets the block's BLOCK_DICT to NULL, which isn't a ++ Warning: it sets the block's BLOCK_MULTIDICT to NULL, which isn't a + valid value. If you really don't want the block to have a +- dictionary, then you should subsequently set its BLOCK_DICT to ++ dictionary, then you should subsequently set its BLOCK_MULTIDICT to + dict_create_linear (obstack, NULL). */ + + struct block * +@@ -544,10 +544,11 @@ block_iterator_step (struct block_iterator *iterator, int first) + + block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), + iterator->which); +- sym = dict_iterator_first (BLOCK_DICT (block), &iterator->dict_iter); ++ sym = mdict_iterator_first (BLOCK_MULTIDICT (block), ++ &iterator->mdict_iter); + } + else +- sym = dict_iterator_next (&iterator->dict_iter); ++ sym = mdict_iterator_next (&iterator->mdict_iter); + + if (sym != NULL) + return sym; +@@ -569,7 +570,7 @@ block_iterator_first (const struct block *block, + initialize_block_iterator (block, iterator); + + if (iterator->which == FIRST_LOCAL_BLOCK) +- return dict_iterator_first (block->dict, &iterator->dict_iter); ++ return mdict_iterator_first (block->multidict, &iterator->mdict_iter); + + return block_iterator_step (iterator, 1); + } +@@ -580,7 +581,7 @@ struct symbol * + block_iterator_next (struct block_iterator *iterator) + { + if (iterator->which == FIRST_LOCAL_BLOCK) +- return dict_iterator_next (&iterator->dict_iter); ++ return mdict_iterator_next (&iterator->mdict_iter); + + return block_iterator_step (iterator, 0); + } +@@ -612,11 +613,11 @@ block_iter_match_step (struct block_iterator *iterator, + + block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), + iterator->which); +- sym = dict_iter_match_first (BLOCK_DICT (block), name, +- &iterator->dict_iter); ++ sym = mdict_iter_match_first (BLOCK_MULTIDICT (block), name, ++ &iterator->mdict_iter); + } + else +- sym = dict_iter_match_next (name, &iterator->dict_iter); ++ sym = mdict_iter_match_next (name, &iterator->mdict_iter); + + if (sym != NULL) + return sym; +@@ -639,7 +640,8 @@ block_iter_match_first (const struct block *block, + initialize_block_iterator (block, iterator); + + if (iterator->which == FIRST_LOCAL_BLOCK) +- return dict_iter_match_first (block->dict, name, &iterator->dict_iter); ++ return mdict_iter_match_first (block->multidict, name, ++ &iterator->mdict_iter); + + return block_iter_match_step (iterator, name, 1); + } +@@ -651,7 +653,7 @@ block_iter_match_next (const lookup_name_info &name, + struct block_iterator *iterator) + { + if (iterator->which == FIRST_LOCAL_BLOCK) +- return dict_iter_match_next (name, &iterator->dict_iter); ++ return mdict_iter_match_next (name, &iterator->mdict_iter); + + return block_iter_match_step (iterator, name, 0); + } +@@ -731,7 +733,7 @@ block_lookup_symbol_primary (const struct block *block, const char *name, + const domain_enum domain) + { + struct symbol *sym, *other; +- struct dict_iterator dict_iter; ++ struct mdict_iterator mdict_iter; + + lookup_name_info lookup_name (name, symbol_name_match_type::FULL); + +@@ -740,9 +742,10 @@ block_lookup_symbol_primary (const struct block *block, const char *name, + || BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL); + + other = NULL; +- for (sym = dict_iter_match_first (block->dict, lookup_name, &dict_iter); ++ for (sym ++ = mdict_iter_match_first (block->multidict, lookup_name, &mdict_iter); + sym != NULL; +- sym = dict_iter_match_next (lookup_name, &dict_iter)) ++ sym = mdict_iter_match_next (lookup_name, &mdict_iter)) + { + if (SYMBOL_DOMAIN (sym) == domain) + return sym; +diff --git a/gdb/block.h b/gdb/block.h +--- a/gdb/block.h ++++ b/gdb/block.h +@@ -111,7 +111,7 @@ struct block + + /* This is used to store the symbols in the block. */ + +- struct dictionary *dict; ++ struct multidictionary *multidict; + + /* Contains information about namespace-related info relevant to this block: + using directives and the current namespace scope. */ +@@ -143,7 +143,7 @@ struct global_block + #define BLOCK_END(bl) (bl)->endaddr + #define BLOCK_FUNCTION(bl) (bl)->function + #define BLOCK_SUPERBLOCK(bl) (bl)->superblock +-#define BLOCK_DICT(bl) (bl)->dict ++#define BLOCK_MULTIDICT(bl) (bl)->multidict + #define BLOCK_NAMESPACE(bl) (bl)->namespace_info + + /* Accessor for ranges field within block BL. */ +@@ -298,9 +298,9 @@ struct block_iterator + + enum block_enum which; + +- /* The underlying dictionary iterator. */ ++ /* The underlying multidictionary iterator. */ + +- struct dict_iterator dict_iter; ++ struct mdict_iterator mdict_iter; + }; + + /* Initialize ITERATOR to point at the first symbol in BLOCK, and +diff --git a/gdb/buildsym.c b/gdb/buildsym.c +--- a/gdb/buildsym.c ++++ b/gdb/buildsym.c +@@ -349,23 +349,21 @@ finish_block_internal (struct symbol *symbol, + + if (symbol) + { +- BLOCK_DICT (block) +- = dict_create_linear (&objfile->objfile_obstack, +- buildsym_compunit->language, *listhead); ++ BLOCK_MULTIDICT (block) ++ = mdict_create_linear (&objfile->objfile_obstack, *listhead); + } + else + { + if (expandable) + { +- BLOCK_DICT (block) +- = dict_create_hashed_expandable (buildsym_compunit->language); +- dict_add_pending (BLOCK_DICT (block), *listhead); ++ BLOCK_MULTIDICT (block) ++ = mdict_create_hashed_expandable (buildsym_compunit->language); ++ mdict_add_pending (BLOCK_MULTIDICT (block), *listhead); + } + else + { +- BLOCK_DICT (block) = +- dict_create_hashed (&objfile->objfile_obstack, +- buildsym_compunit->language, *listhead); ++ BLOCK_MULTIDICT (block) = ++ mdict_create_hashed (&objfile->objfile_obstack, *listhead); + } + } + +@@ -377,7 +375,7 @@ finish_block_internal (struct symbol *symbol, + if (symbol) + { + struct type *ftype = SYMBOL_TYPE (symbol); +- struct dict_iterator iter; ++ struct mdict_iterator miter; + SYMBOL_BLOCK_VALUE (symbol) = block; + BLOCK_FUNCTION (block) = symbol; + +@@ -391,7 +389,7 @@ finish_block_internal (struct symbol *symbol, + + /* Here we want to directly access the dictionary, because + we haven't fully initialized the block yet. */ +- ALL_DICT_SYMBOLS (BLOCK_DICT (block), iter, sym) ++ ALL_DICT_SYMBOLS (BLOCK_MULTIDICT (block), miter, sym) + { + if (SYMBOL_IS_ARGUMENT (sym)) + nparams++; +@@ -405,7 +403,7 @@ finish_block_internal (struct symbol *symbol, + iparams = 0; + /* Here we want to directly access the dictionary, because + we haven't fully initialized the block yet. */ +- ALL_DICT_SYMBOLS (BLOCK_DICT (block), iter, sym) ++ ALL_DICT_SYMBOLS (BLOCK_MULTIDICT (block), miter, sym) + { + if (iparams == nparams) + break; +@@ -1448,7 +1446,7 @@ end_symtab_with_blockvector (struct block *static_block, + { + struct block *block = BLOCKVECTOR_BLOCK (blockvector, block_i); + struct symbol *sym; +- struct dict_iterator iter; ++ struct mdict_iterator miter; + + /* Inlined functions may have symbols not in the global or + static symbol lists. */ +@@ -1459,7 +1457,7 @@ end_symtab_with_blockvector (struct block *static_block, + /* Note that we only want to fix up symbols from the local + blocks, not blocks coming from included symtabs. That is why + we use ALL_DICT_SYMBOLS here and not ALL_BLOCK_SYMBOLS. */ +- ALL_DICT_SYMBOLS (BLOCK_DICT (block), iter, sym) ++ ALL_DICT_SYMBOLS (BLOCK_MULTIDICT (block), miter, sym) + if (symbol_symtab (sym) == NULL) + symbol_set_symtab (sym, symtab); + } +@@ -1598,7 +1596,7 @@ augment_type_symtab (void) + to the primary symtab. */ + set_missing_symtab (file_symbols, cust); + +- dict_add_pending (BLOCK_DICT (block), file_symbols); ++ mdict_add_pending (BLOCK_MULTIDICT (block), file_symbols); + } + + if (global_symbols != NULL) +@@ -1609,7 +1607,7 @@ augment_type_symtab (void) + to the primary symtab. */ + set_missing_symtab (global_symbols, cust); + +- dict_add_pending (BLOCK_DICT (block), global_symbols); ++ mdict_add_pending (BLOCK_MULTIDICT (block), global_symbols); + } + + reset_symtab_globals (); +diff --git a/gdb/dictionary.h b/gdb/dictionary.h +--- a/gdb/dictionary.h ++++ b/gdb/dictionary.h +@@ -25,10 +25,10 @@ + + #include "symfile.h" + +-/* An opaque type for dictionaries; only dictionary.c should know +- about its innards. */ ++/* An opaque type for multi-language dictionaries; only dictionary.c should ++ know about its innards. */ + +-struct dictionary; ++struct multidictionary; + + /* Other types needed for declarations. */ + +@@ -38,65 +38,64 @@ struct pending; + struct language_defn; + + /* The creation functions for various implementations of +- dictionaries. */ ++ multi-language dictionaries. */ + +-/* Create a dictionary of symbols of language LANGUAGE implemented via ++/* Create a multi-language dictionary of symbols implemented via + a fixed-size hashtable. All memory it uses is allocated on + OBSTACK; the environment is initialized from SYMBOL_LIST. */ + +-extern struct dictionary *dict_create_hashed (struct obstack *obstack, +- enum language language, +- const struct pending +- *symbol_list); ++extern struct multidictionary * ++ mdict_create_hashed (struct obstack *obstack, ++ const struct pending *symbol_list); + +-/* Create a dictionary of symbols of language LANGUAGE, implemented +- via a hashtable that grows as necessary. The dictionary is +- initially empty; to add symbols to it, call dict_add_symbol(). +- Call dict_free() when you're done with it. */ ++/* Create a multi-language dictionary of symbols, implemented ++ via a hashtable that grows as necessary. The initial dictionary of ++ LANGUAGE is empty; to add symbols to it, call mdict_add_symbol(). ++ Call mdict_free() when you're done with it. */ + +-extern struct dictionary * +- dict_create_hashed_expandable (enum language language); ++extern struct multidictionary * ++ mdict_create_hashed_expandable (enum language language); + +-/* Create a dictionary of symbols of language LANGUAGE, implemented ++/* Create a multi-language dictionary of symbols, implemented + via a fixed-size array. All memory it uses is allocated on + OBSTACK; the environment is initialized from the SYMBOL_LIST. The + symbols are ordered in the same order that they're found in + SYMBOL_LIST. */ + +-extern struct dictionary *dict_create_linear (struct obstack *obstack, +- enum language language, +- const struct pending +- *symbol_list); ++extern struct multidictionary * ++ mdict_create_linear (struct obstack *obstack, ++ const struct pending *symbol_list); + +-/* Create a dictionary of symbols of language LANGUAGE, implemented +- via an array that grows as necessary. The dictionary is initially +- empty; to add symbols to it, call dict_add_symbol(). Call +- dict_free() when you're done with it. */ ++/* Create a multi-language dictionary of symbols, implemented ++ via an array that grows as necessary. The multidictionary initially ++ contains a single empty dictionary of LANGUAGE; to add symbols to it, ++ call mdict_add_symbol(). Call mdict_free() when you're done with it. */ + +-extern struct dictionary * +- dict_create_linear_expandable (enum language language); ++extern struct multidictionary * ++ mdict_create_linear_expandable (enum language language); + +-/* The functions providing the interface to dictionaries. Note that +- the most common parts of the interface, namely symbol lookup, are +- only provided via iterator functions. */ ++/* The functions providing the interface to multi-language dictionaries. ++ Note that the most common parts of the interface, namely symbol lookup, ++ are only provided via iterator functions. */ + +-/* Free the memory used by a dictionary that's not on an obstack. (If ++/* Free the memory used by a multidictionary that's not on an obstack. (If + any.) */ + +-extern void dict_free (struct dictionary *dict); ++extern void mdict_free (struct multidictionary *mdict); + +-/* Add a symbol to an expandable dictionary. */ ++/* Add a symbol to an expandable multidictionary. */ + +-extern void dict_add_symbol (struct dictionary *dict, struct symbol *sym); ++extern void mdict_add_symbol (struct multidictionary *mdict, ++ struct symbol *sym); + +-/* Utility to add a list of symbols to a dictionary. */ ++/* Utility to add a list of symbols to a multidictionary. */ + +-extern void dict_add_pending (struct dictionary *dict, +- const struct pending *symbol_list); ++extern void mdict_add_pending (struct multidictionary *mdict, ++ const struct pending *symbol_list); + +-/* Is the dictionary empty? */ ++/* Is the multidictionary empty? */ + +-extern int dict_empty (struct dictionary *dict); ++extern int mdict_empty (struct multidictionary *mdict); + + /* A type containing data that is used when iterating over all symbols + in a dictionary. Don't ever look at its innards; this type would +@@ -128,44 +127,46 @@ struct mdict_iterator + unsigned short current_idx; + }; + +-/* Initialize ITERATOR to point at the first symbol in DICT, and +- return that first symbol, or NULL if DICT is empty. */ ++/* Initialize ITERATOR to point at the first symbol in MDICT, and ++ return that first symbol, or NULL if MDICT is empty. */ + +-extern struct symbol *dict_iterator_first (const struct dictionary *dict, +- struct dict_iterator *iterator); ++extern struct symbol * ++ mdict_iterator_first (const struct multidictionary *mdict, ++ struct mdict_iterator *miterator); + +-/* Advance ITERATOR, and return the next symbol, or NULL if there are ++/* Advance MITERATOR, and return the next symbol, or NULL if there are + no more symbols. Don't call this if you've previously received +- NULL from dict_iterator_first or dict_iterator_next on this ++ NULL from mdict_iterator_first or mdict_iterator_next on this + iteration. */ + +-extern struct symbol *dict_iterator_next (struct dict_iterator *iterator); ++extern struct symbol *mdict_iterator_next (struct mdict_iterator *miterator); + +-/* Initialize ITERATOR to point at the first symbol in DICT whose ++/* Initialize MITERATOR to point at the first symbol in MDICT whose + SYMBOL_SEARCH_NAME is NAME, as tested using COMPARE (which must use + the same conventions as strcmp_iw and be compatible with any + dictionary hashing function), and return that first symbol, or NULL + if there are no such symbols. */ + +-extern struct symbol *dict_iter_match_first (const struct dictionary *dict, +- const lookup_name_info &name, +- struct dict_iterator *iterator); ++extern struct symbol * ++ mdict_iter_match_first (const struct multidictionary *mdict, ++ const lookup_name_info &name, ++ struct mdict_iterator *miterator); + +-/* Advance ITERATOR to point at the next symbol in DICT whose ++/* Advance MITERATOR to point at the next symbol in MDICT whose + SYMBOL_SEARCH_NAME is NAME, as tested using COMPARE (see + dict_iter_match_first), or NULL if there are no more such symbols. + Don't call this if you've previously received NULL from +- dict_iterator_match_first or dict_iterator_match_next on this +- iteration. And don't call it unless ITERATOR was created by a +- previous call to dict_iter_match_first with the same NAME and COMPARE. */ ++ mdict_iterator_match_first or mdict_iterator_match_next on this ++ iteration. And don't call it unless MITERATOR was created by a ++ previous call to mdict_iter_match_first with the same NAME and COMPARE. */ + +-extern struct symbol *dict_iter_match_next (const lookup_name_info &name, +- struct dict_iterator *iterator); ++extern struct symbol *mdict_iter_match_next (const lookup_name_info &name, ++ struct mdict_iterator *miterator); + +-/* Return some notion of the size of the dictionary: the number of ++/* Return some notion of the size of the multidictionary: the number of + symbols if we have that, the number of hash buckets otherwise. */ + +-extern int dict_size (const struct dictionary *dict); ++extern int mdict_size (const struct multidictionary *mdict); + + /* Macro to loop through all symbols in a dictionary DICT, in no + particular order. ITER is a struct dict_iterator (NOTE: __not__ a +@@ -175,8 +176,8 @@ extern int dict_size (const struct dictionary *dict); + early by a break if you desire. */ + + #define ALL_DICT_SYMBOLS(dict, iter, sym) \ +- for ((sym) = dict_iterator_first ((dict), &(iter)); \ ++ for ((sym) = mdict_iterator_first ((dict), &(iter)); \ + (sym); \ +- (sym) = dict_iterator_next (&(iter))) ++ (sym) = mdict_iterator_next (&(iter))) + + #endif /* DICTIONARY_H */ +diff --git a/gdb/jit.c b/gdb/jit.c +--- a/gdb/jit.c ++++ b/gdb/jit.c +@@ -651,14 +651,12 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) + size_t blockvector_size; + CORE_ADDR begin, end; + struct blockvector *bv; +- enum language language; + + actual_nblocks = FIRST_LOCAL_BLOCK + stab->nblocks; + + cust = allocate_compunit_symtab (objfile, stab->file_name); + allocate_symtab (cust, stab->file_name); + add_compunit_symtab_to_objfile (cust); +- language = compunit_language (cust); + + /* JIT compilers compile in memory. */ + COMPUNIT_DIRNAME (cust) = NULL; +@@ -702,8 +700,8 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) + TARGET_CHAR_BIT, + "void"); + +- BLOCK_DICT (new_block) = dict_create_linear (&objfile->objfile_obstack, +- language, NULL); ++ BLOCK_MULTIDICT (new_block) ++ = mdict_create_linear (&objfile->objfile_obstack, NULL); + /* The address range. */ + BLOCK_START (new_block) = (CORE_ADDR) gdb_block_iter->begin; + BLOCK_END (new_block) = (CORE_ADDR) gdb_block_iter->end; +@@ -740,8 +738,8 @@ finalize_symtab (struct gdb_symtab *stab, struct objfile *objfile) + new_block = (i == GLOBAL_BLOCK + ? allocate_global_block (&objfile->objfile_obstack) + : allocate_block (&objfile->objfile_obstack)); +- BLOCK_DICT (new_block) = dict_create_linear (&objfile->objfile_obstack, +- language, NULL); ++ BLOCK_MULTIDICT (new_block) ++ = mdict_create_linear (&objfile->objfile_obstack, NULL); + BLOCK_SUPERBLOCK (new_block) = block_iter; + block_iter = new_block; + +diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c +--- a/gdb/mdebugread.c ++++ b/gdb/mdebugread.c +@@ -4534,7 +4534,7 @@ static void + add_symbol (struct symbol *s, struct symtab *symtab, struct block *b) + { + symbol_set_symtab (s, symtab); +- dict_add_symbol (BLOCK_DICT (b), s); ++ mdict_add_symbol (BLOCK_MULTIDICT (b), s); + } + + /* Add a new block B to a symtab S. */ +@@ -4762,7 +4762,7 @@ new_bvect (int nblocks) + } + + /* Allocate and zero a new block of language LANGUAGE, and set its +- BLOCK_DICT. If function is non-zero, assume the block is ++ BLOCK_MULTIDICT. If function is non-zero, assume the block is + associated to a function, and make sure that the symbols are stored + linearly; otherwise, store them hashed. */ + +@@ -4775,9 +4775,9 @@ new_block (enum block_type type, enum language language) + struct block *retval = XCNEW (struct block); + + if (type == FUNCTION_BLOCK) +- BLOCK_DICT (retval) = dict_create_linear_expandable (language); ++ BLOCK_MULTIDICT (retval) = mdict_create_linear_expandable (language); + else +- BLOCK_DICT (retval) = dict_create_hashed_expandable (language); ++ BLOCK_MULTIDICT (retval) = mdict_create_hashed_expandable (language); + + return retval; + } +diff --git a/gdb/objfiles.c b/gdb/objfiles.c +--- a/gdb/objfiles.c ++++ b/gdb/objfiles.c +@@ -813,40 +813,40 @@ objfile_relocate1 (struct objfile *objfile, + } + + ALL_OBJFILE_COMPUNITS (objfile, cust) +- { +- const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust); +- int block_line_section = COMPUNIT_BLOCK_LINE_SECTION (cust); +- +- if (BLOCKVECTOR_MAP (bv)) +- addrmap_relocate (BLOCKVECTOR_MAP (bv), +- ANOFFSET (delta, block_line_section)); +- +- for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i) +- { +- struct block *b; +- struct symbol *sym; +- struct dict_iterator iter; +- +- b = BLOCKVECTOR_BLOCK (bv, i); +- BLOCK_START (b) += ANOFFSET (delta, block_line_section); +- BLOCK_END (b) += ANOFFSET (delta, block_line_section); +- +- if (BLOCK_RANGES (b) != nullptr) +- for (int j = 0; j < BLOCK_NRANGES (b); j++) ++ { ++ const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust); ++ int block_line_section = COMPUNIT_BLOCK_LINE_SECTION (cust); ++ ++ if (BLOCKVECTOR_MAP (bv)) ++ addrmap_relocate (BLOCKVECTOR_MAP (bv), ++ ANOFFSET (delta, block_line_section)); ++ ++ for (int i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i) ++ { ++ struct block *b; ++ struct symbol *sym; ++ struct mdict_iterator miter; ++ ++ b = BLOCKVECTOR_BLOCK (bv, i); ++ BLOCK_START (b) += ANOFFSET (delta, block_line_section); ++ BLOCK_END (b) += ANOFFSET (delta, block_line_section); ++ ++ if (BLOCK_RANGES (b) != nullptr) ++ for (int j = 0; j < BLOCK_NRANGES (b); j++) ++ { ++ BLOCK_RANGE_START (b, j) ++ += ANOFFSET (delta, block_line_section); ++ BLOCK_RANGE_END (b, j) += ANOFFSET (delta, block_line_section); ++ } ++ ++ /* We only want to iterate over the local symbols, not any ++ symbols in included symtabs. */ ++ ALL_DICT_SYMBOLS (BLOCK_MULTIDICT (b), miter, sym) + { +- BLOCK_RANGE_START (b, j) +- += ANOFFSET (delta, block_line_section); +- BLOCK_RANGE_END (b, j) += ANOFFSET (delta, block_line_section); ++ relocate_one_symbol (sym, objfile, delta); + } +- +- /* We only want to iterate over the local symbols, not any +- symbols in included symtabs. */ +- ALL_DICT_SYMBOLS (BLOCK_DICT (b), iter, sym) +- { +- relocate_one_symbol (sym, objfile, delta); +- } +- } +- } ++ } ++ } + } + + /* Relocate isolated symbols. */ +diff --git a/gdb/symmisc.c b/gdb/symmisc.c +--- a/gdb/symmisc.c ++++ b/gdb/symmisc.c +@@ -275,7 +275,7 @@ dump_symtab_1 (struct symtab *symtab, struct ui_file *outfile) + struct objfile *objfile = SYMTAB_OBJFILE (symtab); + struct gdbarch *gdbarch = get_objfile_arch (objfile); + int i; +- struct dict_iterator iter; ++ struct mdict_iterator miter; + int len; + struct linetable *l; + const struct blockvector *bv; +@@ -331,7 +331,7 @@ dump_symtab_1 (struct symtab *symtab, struct ui_file *outfile) + even if we're using a hashtable, but nothing else but this message + wants it. */ + fprintf_filtered (outfile, ", %d syms/buckets in ", +- dict_size (BLOCK_DICT (b))); ++ mdict_size (BLOCK_MULTIDICT (b))); + fputs_filtered (paddress (gdbarch, BLOCK_START (b)), outfile); + fprintf_filtered (outfile, ".."); + fputs_filtered (paddress (gdbarch, BLOCK_END (b)), outfile); +@@ -349,7 +349,7 @@ dump_symtab_1 (struct symtab *symtab, struct ui_file *outfile) + /* Now print each symbol in this block (in no particular order, if + we're using a hashtable). Note that we only want this + block, not any blocks from included symtabs. */ +- ALL_DICT_SYMBOLS (BLOCK_DICT (b), iter, sym) ++ ALL_DICT_SYMBOLS (BLOCK_MULTIDICT (b), miter, sym) + { + TRY + { diff --git a/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-3of5.patch b/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-3of5.patch new file mode 100644 index 0000000..25b8320 --- /dev/null +++ b/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-3of5.patch @@ -0,0 +1,232 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Sergio Durigan Junior +Date: Fri, 11 Jan 2019 11:26:59 -0500 +Subject: + gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-3of5.patch + +;; Fix 'Assertion `SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE (dict)->la_language' failed.' +;; Keith Seitz, RHBZ#1560010. + +gdb/23712: Cleanup/Remove temporary dictionary functions + +Now that multidictionary's are being used, there is no longer any need +to retain the four temporary functions introduced in the beginning of +this series. + +This patch removes them. + +As an additional cleanup, since the single-language dictionaries are +no longer used outside dictionary.c, make all of those functions +static. + +gdb/ChangeLog: + + PR gdb/23712 + PR symtab/23010 + * dictionary.c (pending_to_vector): Remove. + (dict_create_hashed_1, dict_create_linear_1, dict_add_pending_1): + Remove _1 suffix, replacing functions of the same name. Update + all callers. + (dict_create_hashed, dict_create_hashed_expandable) + (dict_create_linear, dict_create_linear_expandable, dict_free) + (dict_add_symbol, dict_add_pending, dict_size, dict_empty): + Make functions static. + +diff --git a/gdb/dictionary.c b/gdb/dictionary.c +--- a/gdb/dictionary.c ++++ b/gdb/dictionary.c +@@ -342,31 +342,14 @@ static void insert_symbol_hashed (struct dictionary *dict, + + static void expand_hashtable (struct dictionary *dict); + +-/* A function to convert a linked list into a vector. */ +- +-static std::vector +-pending_to_vector (const struct pending *symbol_list) +-{ +- std::vector symlist; +- +- for (const struct pending *list_counter = symbol_list; +- list_counter != nullptr; list_counter = list_counter->next) +- { +- for (int i = list_counter->nsyms - 1; i >= 0; --i) +- symlist.push_back (list_counter->symbol[i]); +- } +- +- return symlist; +-} +- + /* The creation functions. */ + +-/* A function to transition dict_create_hashed to new API. */ ++/* Create a hashed dictionary of a given language. */ + + static struct dictionary * +-dict_create_hashed_1 (struct obstack *obstack, +- enum language language, +- const std::vector &symbol_list) ++dict_create_hashed (struct obstack *obstack, ++ enum language language, ++ const std::vector &symbol_list) + { + /* Allocate the dictionary. */ + struct dictionary *retval = XOBNEW (obstack, struct dictionary); +@@ -388,21 +371,9 @@ dict_create_hashed_1 (struct obstack *obstack, + return retval; + } + +-/* See dictionary.h. */ +- +-struct dictionary * +-dict_create_hashed (struct obstack *obstack, +- enum language language, +- const struct pending *symbol_list) +-{ +- std::vector symlist = pending_to_vector (symbol_list); +- +- return dict_create_hashed_1 (obstack, language, symlist); +-} ++/* Create an expandable hashed dictionary of a given language. */ + +-/* See dictionary.h. */ +- +-extern struct dictionary * ++static struct dictionary * + dict_create_hashed_expandable (enum language language) + { + struct dictionary *retval = XNEW (struct dictionary); +@@ -417,12 +388,12 @@ dict_create_hashed_expandable (enum language language) + return retval; + } + +-/* A function to transition dict_create_linear to new API. */ ++/* Create a linear dictionary of a given language. */ + + static struct dictionary * +-dict_create_linear_1 (struct obstack *obstack, +- enum language language, +- const std::vector &symbol_list) ++dict_create_linear (struct obstack *obstack, ++ enum language language, ++ const std::vector &symbol_list) + { + struct dictionary *retval = XOBNEW (obstack, struct dictionary); + DICT_VECTOR (retval) = &dict_linear_vector; +@@ -442,21 +413,9 @@ dict_create_linear_1 (struct obstack *obstack, + return retval; + } + +-/* See dictionary.h. */ +- +-struct dictionary * +-dict_create_linear (struct obstack *obstack, +- enum language language, +- const struct pending *symbol_list) +-{ +- std::vector symlist = pending_to_vector (symbol_list); +- +- return dict_create_linear_1 (obstack, language, symlist); +-} +- +-/* See dictionary.h. */ ++/* Create an expandable linear dictionary of a given language. */ + +-struct dictionary * ++static struct dictionary * + dict_create_linear_expandable (enum language language) + { + struct dictionary *retval = XNEW (struct dictionary); +@@ -476,7 +435,7 @@ dict_create_linear_expandable (enum language language) + /* Free the memory used by a dictionary that's not on an obstack. (If + any.) */ + +-void ++static void + dict_free (struct dictionary *dict) + { + (DICT_VECTOR (dict))->free (dict); +@@ -484,34 +443,24 @@ dict_free (struct dictionary *dict) + + /* Add SYM to DICT. DICT had better be expandable. */ + +-void ++static void + dict_add_symbol (struct dictionary *dict, struct symbol *sym) + { + (DICT_VECTOR (dict))->add_symbol (dict, sym); + } + +-/* A function to transition dict_add_pending to new API. */ ++/* Utility to add a list of symbols to a dictionary. ++ DICT must be an expandable dictionary. */ + + static void +-dict_add_pending_1 (struct dictionary *dict, +- const std::vector &symbol_list) ++dict_add_pending (struct dictionary *dict, ++ const std::vector &symbol_list) + { + /* Preserve ordering by reversing the list. */ + for (auto sym = symbol_list.rbegin (); sym != symbol_list.rend (); ++sym) + dict_add_symbol (dict, *sym); + } + +-/* Utility to add a list of symbols to a dictionary. +- DICT must be an expandable dictionary. */ +- +-void +-dict_add_pending (struct dictionary *dict, const struct pending *symbol_list) +-{ +- std::vector symlist = pending_to_vector (symbol_list); +- +- dict_add_pending_1 (dict, symlist); +-} +- + /* Initialize ITERATOR to point at the first symbol in DICT, and + return that first symbol, or NULL if DICT is empty. */ + +@@ -548,7 +497,7 @@ dict_iter_match_next (const lookup_name_info &name, + ->iter_match_next (name, iterator); + } + +-int ++static int + dict_size (const struct dictionary *dict) + { + return (DICT_VECTOR (dict))->size (dict); +@@ -560,7 +509,7 @@ dict_size (const struct dictionary *dict) + + /* Test to see if DICT is empty. */ + +-int ++static int + dict_empty (struct dictionary *dict) + { + struct dict_iterator iter; +@@ -1019,7 +968,7 @@ mdict_create_hashed (struct obstack *obstack, + std::vector symlist = pair.second; + + retval->dictionaries[idx++] +- = dict_create_hashed_1 (obstack, language, symlist); ++ = dict_create_hashed (obstack, language, symlist); + } + + return retval; +@@ -1064,7 +1013,7 @@ mdict_create_linear (struct obstack *obstack, + std::vector symlist = pair.second; + + retval->dictionaries[idx++] +- = dict_create_linear_1 (obstack, language, symlist); ++ = dict_create_linear (obstack, language, symlist); + } + + return retval; +@@ -1210,7 +1159,7 @@ mdict_add_pending (struct multidictionary *mdict, + dict = create_new_language_dictionary (mdict, language); + } + +- dict_add_pending_1 (dict, symlist); ++ dict_add_pending (dict, symlist); + } + } + diff --git a/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-4of5.patch b/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-4of5.patch new file mode 100644 index 0000000..354c494 --- /dev/null +++ b/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-4of5.patch @@ -0,0 +1,90 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Sergio Durigan Junior +Date: Fri, 11 Jan 2019 11:29:25 -0500 +Subject: + gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-4of5.patch + +;; Fix 'Assertion `SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE (dict)->la_language' failed.' +;; Keith Seitz, RHBZ#1560010. + +gdb/23712: Remove dw2_add_symbol_to_list + +Finally, we can remove dw2_add_symbol_to_list since the wrapper function +originally introduced to catch this multi-language scenario is no longer +needed. With multi-language dictionaries, we can now support adding +symbols of multiple languages, negating the need for the assertion +entirely. + +This patch should now fix gdb/23712 (and symtab/23010). At least it will +if the NULL buildsym_compunit problem doesn't strike first (see gdb/23773). + +gdb/ChangeLog: + + PR gdb/23712 + PR symtab/23010 + * dwarf2read.c (dw2_add_symbol_to_list): Remove. + (fixup_go_packaging, new_symbol): Use add_symbol_to_list. + +diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c +--- a/gdb/dwarf2read.c ++++ b/gdb/dwarf2read.c +@@ -9715,23 +9715,6 @@ compute_delayed_physnames (struct dwarf2_cu *cu) + cu->method_list.clear (); + } + +-/* A wrapper for add_symbol_to_list to ensure that SYMBOL's language is +- the same as all other symbols in LISTHEAD. If a new symbol is added +- with a different language, this function asserts. */ +- +-static inline void +-dw2_add_symbol_to_list (struct symbol *symbol, struct pending **listhead) +-{ +- /* Only assert if LISTHEAD already contains symbols of a different +- language (dict_create_hashed/insert_symbol_hashed requires that all +- symbols in this list are of the same language). */ +- gdb_assert ((*listhead) == NULL +- || (SYMBOL_LANGUAGE ((*listhead)->symbol[0]) +- == SYMBOL_LANGUAGE (symbol))); +- +- add_symbol_to_list (symbol, listhead); +-} +- + /* Go objects should be embedded in a DW_TAG_module DIE, + and it's not clear if/how imported objects will appear. + To keep Go support simple until that's worked out, +@@ -9803,7 +9786,7 @@ fixup_go_packaging (struct dwarf2_cu *cu) + SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF; + SYMBOL_TYPE (sym) = type; + +- dw2_add_symbol_to_list (sym, &global_symbols); ++ add_symbol_to_list (sym, &global_symbols); + + xfree (package_name); + } +@@ -21387,7 +21370,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu, + SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_core_addr; + SYMBOL_DOMAIN (sym) = LABEL_DOMAIN; + SYMBOL_ACLASS_INDEX (sym) = LOC_LABEL; +- dw2_add_symbol_to_list (sym, cu->list_in_scope); ++ add_symbol_to_list (sym, cu->list_in_scope); + break; + case DW_TAG_subprogram: + /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by +@@ -21645,7 +21628,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu, + case DW_TAG_common_block: + SYMBOL_ACLASS_INDEX (sym) = LOC_COMMON_BLOCK; + SYMBOL_DOMAIN (sym) = COMMON_BLOCK_DOMAIN; +- dw2_add_symbol_to_list (sym, cu->list_in_scope); ++ add_symbol_to_list (sym, cu->list_in_scope); + break; + default: + /* Not a tag we recognize. Hopefully we aren't processing +@@ -21665,7 +21648,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu, + } + + if (list_to_add != NULL) +- dw2_add_symbol_to_list (sym, list_to_add); ++ add_symbol_to_list (sym, list_to_add); + + /* For the benefit of old versions of GCC, check for anonymous + namespaces based on the demangled name. */ diff --git a/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-5of5.patch b/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-5of5.patch new file mode 100644 index 0000000..959b577 --- /dev/null +++ b/SOURCES/gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-5of5.patch @@ -0,0 +1,183 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Sergio Durigan Junior +Date: Fri, 11 Jan 2019 11:31:59 -0500 +Subject: + gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-5of5.patch + +;; Fix 'Assertion `SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE (dict)->la_language' failed.' +;; Keith Seitz, RHBZ#1560010. + +gdb/23712: Test case for multidictionary + +This is a test derived from one of the reproducers in symtab/23010. +The DIE tree used here is typical of compilations with LTO, where an +artificial parent DIE of language C99 imports DIEs of other languages. + +gdb/testsuite/ChangeLog: + + PR gdb/23712 + PR symtab/23010 + * gdb.dwarf2/multidictionary.exp: New file. + +diff --git a/gdb/testsuite/gdb.dwarf2/multidictionary.exp b/gdb/testsuite/gdb.dwarf2/multidictionary.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/multidictionary.exp +@@ -0,0 +1,157 @@ ++# Copyright 2019 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 . ++ ++# A test of multi-language dictionaries, a solution to symtab/23010 et al. ++ ++load_lib dwarf.exp ++ ++# This test can only be run on targets which support DWARF. ++if {![dwarf2_support]} { ++ return 0 ++} ++ ++standard_testfile main.c .S ++ ++# Create the DWARF. This is derived from the reproducer in the bug ++# mentioned above. This DIE tree is typical of compilations wtih ++# LTO enabled. ++ ++set asm_file [standard_output_file $srcfile2] ++Dwarf::assemble $asm_file { ++ declare_labels D45d9 D5079 D5080 D50a9 D50af D5ab2 D5ac2 D5ace D5acf ++ declare_labels D2135f D2216a D22171 D226c4 D226ca D244ca \ ++ D245da D245e6 ++ declare_labels D41c21 D42025 D42045 D42038 D42045 D420b5 ++ ++ cu {} { ++ D45d9: compile_unit { ++ {language @DW_LANG_C_plus_plus} ++ {name "SerialPortUtils.cpp"} ++ } { ++ D5079: base_type { ++ {byte_size 1 sdata} ++ {encoding @DW_ATE_unsigned} ++ {name "char"} ++ } ++ ++ D5080: const_type { ++ {type :$D5079} ++ } ++ ++ D50a9: pointer_type { ++ {byte_size 4 sdata} ++ {type :$D5080} ++ } ++ ++ D50af: const_type { ++ {type :$D50a9} ++ } ++ ++ D5ab2: subprogram { ++ {external 1 flag} ++ {linkage_name "_Z18SerialSyncWriteStrPKc"} ++ } { ++ D5ac2: formal_parameter { ++ {name "msg"} ++ {type :$D50af} ++ } ++ D5ace: lexical_block {} { ++ D5acf: DW_TAG_variable { ++ {name "p"} ++ {type :$D50a9} ++ } ++ } ++ } ++ } ++ } ++ ++ cu {} { ++ D2135f: compile_unit { ++ {language @DW_LANG_C_plus_plus} ++ {name "Main.cpp"} ++ } { ++ D2216a: base_type { ++ {byte_size 1 sdata} ++ {encoding @DW_ATE_unsigned_char} ++ {name "char"} ++ } ++ ++ D22171: const_type { ++ {type :$D2216a} ++ } ++ ++ D226c4: pointer_type { ++ {byte_size 4 sdata} ++ {type :$D22171} ++ } ++ ++ D226ca: const_type { ++ {type :$D226c4} ++ } ++ ++ D245da: subprogram { ++ {name "PrintPanicMsg"} ++ } { ++ D245e6: formal_parameter { ++ {name "msg"} ++ {type :$D226ca} ++ } ++ } ++ } ++ } ++ ++ cu {} { ++ D41c21: compile_unit { ++ {language @DW_LANG_C99} ++ {name ""} ++ } { ++ D42025: subprogram { ++ {abstract_origin %$D245da} ++ {low_pc 0x80b60 addr} ++ {high_pc 0x6c data4} ++ } { ++ D42038: formal_parameter { ++ {abstract_origin %$D245e6} ++ } ++ ++ D42045: inlined_subroutine { ++ {abstract_origin %$D5ab2} ++ {low_pc 0x8060 addr} ++ {high_pc 0xc data4} ++ } { ++ D420b5: formal_parameter { ++ {abstract_origin %$D5ac2} ++ } ++ } ++ } ++ } ++ } ++} ++ ++# Build the test executable. ++if {[build_executable $testfile.exp $testfile [list $asm_file $srcfile] {}] \ ++ == -1} { ++ return -1 ++} ++ ++# We force the DIEs above to be read in via "-readnow". ++gdb_spawn_with_cmdline_opts "-readnow" ++gdb_load $binfile ++ ++# All we need to do is check whether GDB is alive. Without ++# multidictionaries, it will either crash, assert, or throw an ++# internal_error. ++gdb_test "p 1" "= 1" "GDB is alive" ++ diff --git a/SOURCES/gdb-rhbz1639242-fix-dwarf2_find_containing_comp_unit-binary-search.patch b/SOURCES/gdb-rhbz1639242-fix-dwarf2_find_containing_comp_unit-binary-search.patch new file mode 100644 index 0000000..b56aee1 --- /dev/null +++ b/SOURCES/gdb-rhbz1639242-fix-dwarf2_find_containing_comp_unit-binary-search.patch @@ -0,0 +1,176 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Sergio Durigan Junior +Date: Fri, 30 Nov 2018 15:20:27 -0500 +Subject: + gdb-rhbz1639242-fix-dwarf2_find_containing_comp_unit-binary-search.patch + +;; Fix for 'py-bt is broken, results in exception'. +;; RHBZ 1639242 + +Fix dwarf2read.c:dwarf2_find_containing_comp_unit's binary search + +First of all, I would like to express my gratitude to Keith Seitz, Jan +Kratochvil and Tom Tromey, who were really kind and helped a lot with +this bug. The patch itself was authored by Jan. + +This all began with: + + https://bugzilla.redhat.com/show_bug.cgi?id=1639242 + py-bt is broken, results in exception + +In summary, the error reported by the bug above is: + + $ gdb -args python3 + GNU gdb (GDB) Fedora 8.1.1-3.fc28 + (...) + Reading symbols from python3...Reading symbols from /usr/lib/debug/usr/bin/python3.6-3.6.6-1.fc28.x86_64.debug...done. + done. + Dwarf Error: could not find partial DIE containing offset 0x316 [in module /usr/lib/debug/usr/bin/python3.6-3.6.6-1.fc28.x86_64.debug] + +After a long investigation, and after thinking that the problem might +actually be on DWZ's side, we were able to determine that there's +something wrong going on when +dwarf2read.c:dwarf2_find_containing_comp_unit performs a binary search +over all of the CUs belonging to an objfile in order to find the CU +which contains a DIE at an specific offset. The current algorithm is: + + static struct dwarf2_per_cu_data * + dwarf2_find_containing_comp_unit (sect_offset sect_off, + unsigned int offset_in_dwz, + struct dwarf2_per_objfile *dwarf2_per_objfile) + { + struct dwarf2_per_cu_data *this_cu; + int low, high; + const sect_offset *cu_off; + + low = 0; + high = dwarf2_per_objfile->all_comp_units.size () - 1; + while (high > low) + { + struct dwarf2_per_cu_data *mid_cu; + int mid = low + (high - low) / 2; + + mid_cu = dwarf2_per_objfile->all_comp_units[mid]; + cu_off = &mid_cu->sect_off; + if (mid_cu->is_dwz > offset_in_dwz + || (mid_cu->is_dwz == offset_in_dwz && *cu_off >= sect_off)) + high = mid; + else + low = mid + 1; + } + +For the sake of this example, let's consider that "sect_off = +0x7d". + +There are a few important things going on here. First, +"dwarf2_per_objfile->all_comp_units ()" will be sorted first by +whether the CU is a DWZ CU, and then by cu->sect_off. In this +specific bug, "offset_in_dwz" is false, which means that, for the most +part of the loop, we're going to do "high = mid" (i.e, we'll work with +the lower part of the vector). + +In our particular case, when we reach the part where "mid_cu->is_dwz +== offset_in_dwz" (i.e, both are false), we end up with "high = 2" and +"mid = 1". I.e., there are only 2 elements in the vector who are not +DWZ. The vector looks like this: + + #0: cu->sect_off = 0; length = 114; is_dwz = false <-- low + #1: cu->sect_off = 114; length = 7796; is_dwz = false <-- mid + #2: cu->sect_off = 0; length = 28; is_dwz = true <-- high + ... + +The CU we want is #1, which is exactly where "mid" is. Also, #1 is +not DWZ, which is also exactly what we want. So we perform the second +comparison: + + (mid_cu->is_dwz == offset_in_dwz && *cu_off >= sect_off) + ^^^^^^^^^^^^^^^^^^^ + +Because "*cu_off = 114" and "sect_off = 0x7d", this evaluates to +false, so we end up with "low = mid + 1 = 2", which actually gives us +the wrong CU (i.e., a CU that is DWZ). Next in the code, GDB does: + + gdb_assert (low == high); + this_cu = dwarf2_per_objfile->all_comp_units[low]; + cu_off = &this_cu->sect_off; + if (this_cu->is_dwz != offset_in_dwz || *cu_off > sect_off) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + { + if (low == 0 || this_cu->is_dwz != offset_in_dwz) + error (_("Dwarf Error: could not find partial DIE containing " + "offset %s [in module %s]"), + sect_offset_str (sect_off), + bfd_get_filename (dwarf2_per_objfile->objfile->obfd)); + ... + +Triggering the error we saw in the original bug report. + +It's important to notice that we see the error message because the +selected CU is a DWZ one, but we're looking for a non-DWZ CU here. +However, even when the selected CU is *not* a DWZ (and we don't see +any error message), we still end up with the wrong CU. For example, +suppose that the vector had: + + #0: cu->sect_off = 0; length = 114; is_dwz = false + #1: cu->sect_off = 114; length = 7796; is_dwz = false + #2: cu->sect_off = 7910; length = 28; is_dwz = false + ... + +I.e., #2's "is_dwz" is false instead of true. In this case, we still +want #1, because that's where the DIE is located. After the loop ends +up in #2, we have "is_dwz" as false, which is what we wanted, so we +compare offsets. In this case, "7910 >= 0x7d", so we set "mid = high += 2". Next iteration, we have "mid = 0 + (2 - 0) / 2 = 1", and thus +we examining #1. "is_dwz" is still false, but "114 >= 0x7d" also +evaluates to false, so "low = mid + 1 = 2", which makes the loop stop. +Therefore, we end up choosing #2 as our CU, even though #1 is the +right one. + +The problem here is happening because we're comparing "sect_off" +directly against "*cu_off", while we should actually be comparing +against "*cu_off + mid_cu->length" (i.e., the end offset): + + ... + || (mid_cu->is_dwz == offset_in_dwz + && *cu_off + mid_cu->length >= sect_off)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ... + +And this is what the patch does. The idea is that if GDB is searching +for an offset that falls above the *end* of the CU being +analyzed (i.e., "mid"), then the next iteration should try a +higher-offset CU next. The previous algorithm was using +the *beginning* of the CU. + +Unfortunately, I could not devise a testcase for this problem, so I am +proposing a fix with this huge explanation attached to it in the hope +that it is sufficient. After talking a bit to Keith (our testcase +guru), it seems that one would have to create an objfile with both DWZ +and non-DWZ sections, which may prove very hard to do, I think. + +I ran this patch on our BuildBot, and no regressions were detected. + +gdb/ChangeLog: +2018-11-30 Jan Kratochvil + Keith Seitz + Tom Tromey + Sergio Durigan Junior + + https://bugzilla.redhat.com/show_bug.cgi?id=1613614 + * dwarf2read.c (dwarf2_find_containing_comp_unit): Add + 'mid_cu->length' to '*cu_off' when checking if 'sect_off' is + inside the CU. + +diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c +--- a/gdb/dwarf2read.c ++++ b/gdb/dwarf2read.c +@@ -25039,7 +25039,8 @@ dwarf2_find_containing_comp_unit (sect_offset sect_off, + mid_cu = dwarf2_per_objfile->all_comp_units[mid]; + cu_off = &mid_cu->sect_off; + if (mid_cu->is_dwz > offset_in_dwz +- || (mid_cu->is_dwz == offset_in_dwz && *cu_off >= sect_off)) ++ || (mid_cu->is_dwz == offset_in_dwz ++ && *cu_off + mid_cu->length >= sect_off)) + high = mid; + else + low = mid + 1; diff --git a/SOURCES/gdb-rhbz1653410-avoid-crash-when-calling-warning-too-early.patch b/SOURCES/gdb-rhbz1653410-avoid-crash-when-calling-warning-too-early.patch new file mode 100644 index 0000000..59bb698 --- /dev/null +++ b/SOURCES/gdb-rhbz1653410-avoid-crash-when-calling-warning-too-early.patch @@ -0,0 +1,145 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Tom Tromey +Date: Fri, 5 Oct 2018 14:54:35 -0600 +Subject: gdb-rhbz1653410-avoid-crash-when-calling-warning-too-early.patch + +;; Fix for 'GDB crashes when running from a deleted directory' +;; (Tom Tromey, RHBZ#1653410) + +Avoid crash when calling warning too early + +I noticed that if you pass the name of an existing file (not a +directory) as the argument to --data-directory, gdb will crash: + + $ ./gdb -nx --data-directory ./gdb + ../../binutils-gdb/gdb/target.c:590:56: runtime error: member call on null pointer of type 'struct target_ops' + +This was later reported as PR gdb/23838. + +This happens because warning ends up calling +target_supports_terminal_ours, which calls current_top_target, which +returns nullptr this early. + +This fixes the problem by handling this case specially in +target_supports_terminal_ours. I also changed +target_supports_terminal_ours to return bool. + +gdb/ChangeLog +2018-11-08 Tom Tromey + + PR gdb/23555: + PR gdb/23838: + * target.h (target_supports_terminal_ours): Return bool. + * target.c (target_supports_terminal_ours): Handle case where + current_top_target returns nullptr. Return bool. + +gdb/testsuite/ChangeLog +2018-11-08 Tom Tromey + + PR gdb/23555: + PR gdb/23838: + * gdb.base/warning.exp: New file. + +diff --git a/gdb/ChangeLog b/gdb/ChangeLog +--- a/gdb/ChangeLog ++++ b/gdb/ChangeLog +@@ -1,3 +1,11 @@ ++2018-11-08 Tom Tromey ++ ++ PR gdb/23555: ++ PR gdb/23838: ++ * target.h (target_supports_terminal_ours): Return bool. ++ * target.c (target_supports_terminal_ours): Handle case where ++ current_top_target returns nullptr. Return bool. ++ + 2018-08-16 Gary Benson + + PR gdb/13000: +diff --git a/gdb/target.c b/gdb/target.c +--- a/gdb/target.c ++++ b/gdb/target.c +@@ -584,10 +584,16 @@ target_terminal::info (const char *arg, int from_tty) + + /* See target.h. */ + +-int ++bool + target_supports_terminal_ours (void) + { +- return current_top_target ()->supports_terminal_ours (); ++ /* This can be called before there is any target, so we must check ++ for nullptr here. */ ++ target_ops *top = current_top_target (); ++ ++ if (top == nullptr) ++ return false; ++ return top->supports_terminal_ours (); + } + + static void +diff --git a/gdb/target.h b/gdb/target.h +--- a/gdb/target.h ++++ b/gdb/target.h +@@ -1576,7 +1576,7 @@ extern int target_remove_breakpoint (struct gdbarch *gdbarch, + /* Return true if the target stack has a non-default + "terminal_ours" method. */ + +-extern int target_supports_terminal_ours (void); ++extern bool target_supports_terminal_ours (void); + + /* Kill the inferior process. Make it go away. */ + +diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog +--- a/gdb/testsuite/ChangeLog ++++ b/gdb/testsuite/ChangeLog +@@ -1,3 +1,9 @@ ++2018-11-08 Tom Tromey ++ ++ PR gdb/23555: ++ PR gdb/23838: ++ * gdb.base/warning.exp: New file. ++ + 2018-09-04 Gary Benson + + * gdb.base/batch-exit-status.exp: Use gdb_test_multiple and expect +diff --git a/gdb/testsuite/gdb.base/warning.exp b/gdb/testsuite/gdb.base/warning.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/warning.exp +@@ -0,0 +1,36 @@ ++# Copyright 2018 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 . ++ ++# Test that an early warning does not cause a crash. ++ ++if {[is_remote host]} { ++ unsupported "warning.exp can only run on local host" ++ return ++} ++ ++set tname [standard_temp_file warning] ++set fd [open $tname w] ++puts $fd "anything" ++close $fd ++ ++set save $INTERNAL_GDBFLAGS ++set INTERNAL_GDBFLAGS "-nw -nx -data-directory $tname" ++ ++gdb_start ++ ++# Make sure gdb started up. ++gdb_test "echo 23\\n" "23" ++ ++set INTERNAL_GDBFLAGS $save diff --git a/SOURCES/gdb-vla-intel-fortran-strides.patch b/SOURCES/gdb-vla-intel-fortran-strides.patch index 7868efe..deaf404 100644 --- a/SOURCES/gdb-vla-intel-fortran-strides.patch +++ b/SOURCES/gdb-vla-intel-fortran-strides.patch @@ -988,14 +988,14 @@ diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h #define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \ (TYPE_HIGH_BOUND(TYPE_INDEX_TYPE((arraytype)))) -@@ -1892,6 +1907,7 @@ extern struct type *create_array_type_with_stride - struct dynamic_prop *, unsigned int); +@@ -1893,6 +1908,7 @@ extern struct type *create_array_type_with_stride extern struct type *create_range_type (struct type *, struct type *, -+ const struct dynamic_prop *, const struct dynamic_prop *, ++ const struct dynamic_prop *, const struct dynamic_prop *); + extern struct type *create_array_type (struct type *, struct type *, diff --git a/gdb/parse.c b/gdb/parse.c --- a/gdb/parse.c +++ b/gdb/parse.c @@ -1783,11 +1783,10 @@ diff --git a/gdb/valarith.c b/gdb/valarith.c diff --git a/gdb/valops.c b/gdb/valops.c --- a/gdb/valops.c +++ b/gdb/valops.c -@@ -3808,56 +3808,195 @@ value_of_this_silent (const struct language_defn *lang) - +@@ -3809,55 +3809,194 @@ value_of_this_silent (const struct language_defn *lang) struct value * value_slice (struct value *array, int lowbound, int length) -+{ + { + /* Pass unaltered arguments to VALUE_SLICE_1, plus a default stride + value of '1', which returns every element between LOWBOUND and + (LOWBOUND + LENGTH). We also provide a default CALL_COUNT of '1' @@ -1812,7 +1811,7 @@ diff --git a/gdb/valops.c b/gdb/valops.c +struct value * +value_slice_1 (struct value *array, int lowbound, int length, + int stride_length, int call_count) - { ++{ struct type *slice_range_type, *slice_type, *range_type; - LONGEST lowerbound, upperbound; - struct value *slice; diff --git a/SPECS/gdb.spec b/SPECS/gdb.spec index f18ea19..a0082be 100644 --- a/SPECS/gdb.spec +++ b/SPECS/gdb.spec @@ -26,7 +26,7 @@ Version: 8.2 # 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: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL Group: Development/Debuggers @@ -566,6 +566,8 @@ export CXXFLAGS="$CFLAGS" --with-separate-debug-dir=/usr/lib/debug \ --disable-sim \ --disable-rpath \ + --without-stage1-ldflags \ + --disable-libmcheck \ %if 0%{!?rhel:1} || 0%{?rhel} > 7 --with-babeltrace \ --with-guile \ @@ -1022,6 +1024,20 @@ fi %endif %changelog +* Fri Jan 11 2019 Keith Seitz - 8.2-3.el7 +- Merge from Fedora 29: + gdb-rhbz1560010-fix-assertion-symbol-language-dict-language-?of5.patch + (Keith Seitz, RHBZ 1664456). +- Update gdb.spec for RHEL supported architectures and multilibs. +- Merge from Fedora 29: + gdb-rhbz1639242-fix-dwarf2_find_containing_comp_unit-binary-search.patch + [RHEL RHBZ#1660220] + gdb-rhbz1653410-avoid-crash-when-calling-warning-too-early.patch + [RHEL RHBZ#1660221] +- Fix annobin complaints (RH BZ 1630564): + --without-stage1-ldflags: Disable static libstdc++ and libgcc linking. + --disable-libmcheck: That is a distro-level decision, not package decision. + * Thu Sep 6 2018 Sergio Durigan Junior - 8.2-2.fc29 - Backport "Use pulongest in aarch64-linux-tdep.c" (Tom Tromey), needed to unbreak the compilation on 32-bit architectures.