Blame SOURCES/gdb-rhbz1187581-power8-regs-not-in-8.2-12of15.patch

689258
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
689258
From: Keith Seitz <keiths@redhat.com>
689258
Date: Fri, 11 Jan 2019 17:02:17 -0500
689258
Subject: gdb-rhbz1187581-power8-regs-not-in-8.2-12of15.patch
689258
689258
;; [PowerPC] Add support for EBB and PMU registers
689258
;; Edjunior Barbosa Machado and Pedro Franco de Carvalho, RH BZ 1187581m
689258
689258
[PowerPC] Add support for EBB and PMU registers
689258
689258
This patch adds support for registers of the Event Based Branching and
689258
Performance Monitoring Units for the powerpc linux native and core
689258
file targets, and for the powerpc linux server stub.
689258
689258
All three EBB registers are accessible.  Only a subset of the PMU
689258
registers can be accessed through ptrace.  Because of this, the PMU
689258
registers are enumerated individually in gdbarch_tdep, as opposed to
689258
having a single "have_pmu" flag.  This is intended to make it easier
689258
to add additional PMU registers in the future, since checking a
689258
"have_pmu" flag elsewhere in the code would no longer be correct.  The
689258
tdesc feature is named org.gnu.gdb.power.linux.pmu because of this.
689258
689258
It's unclear if it makes sense to save and restore these registers
689258
across function calls, since some of them can be modified
689258
asynchronously.  They are also not tracked in record-replay mode.
689258
689258
The kernel can return ENODATA when ptrace is used to get the EBB
689258
registers, unless a linux performance event that uses EBB is open in
689258
the inferior.  For this reason, the "fill" functions in the server
689258
stub for the ebb register sets is not implemented.
689258
689258
Since gdbserver writes all registers in one go before resuming the
689258
inferior, this error would not be detected at the time the user tries
689258
to write to one of the registers on the client side, and gdbserver
689258
would print out warnings every time it resumes the inferior when no
689258
ebb performance event is opened, so there is currently no
689258
straightforward way to handle this case.  This means the ebb registers
689258
in the client-side regcache can become dirty when the user tries to
689258
write to them, until the inferior is resumed and stopped again.
689258
689258
A related issue is that 'G' packets used to write to unrelated
689258
registers will include bad data for the EBB registers if they are
689258
unavailable, since no register status information is included in the
689258
'G' packet.  This data won't be written to the inferior by the
689258
gdbserver stub because the "fill" functions are not implemented, and
689258
currently the gdbserver stub doesn't change the status of the
689258
registers in its own regcache in response to 'G' packets.
689258
689258
Another limitation for the ebb registers is that traceframes don't
689258
record if registers are available or not, so if these registers are
689258
collected when a tracepoint is hit and the inferior has no ebb event
689258
opened, the user will see zero values for all of them, instead of the
689258
usual <unavailable>.
689258
689258
Because these registers are often unavailable, trying to store them
689258
with target_store_registers with -1 for the regno argument (all
689258
registers) would almost always fail, so they are ignored in this case.
689258
689258
gdb/ChangeLog:
689258
2018-10-26  Edjunior Barbosa Machado  <emachado@linux.vnet.ibm.com>
689258
        Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
689258
689258
    * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_EBBREGSET)
689258
    (PPC_LINUX_SIZEOF_PMUREGSET): Declare.
689258
    * nat/ppc-linux.h (PPC_FEATURE2_EBB, NT_PPC_EBB, NT_PPC_PMU):
689258
    Define if not already defined.
689258
    * features/rs6000/power-ebb.xml: New file.
689258
    * features/rs6000/power-linux-pmu.xml: New file.
689258
    * features/rs6000/powerpc-isa207-vsx32l.xml: Include ebb and pmu
689258
    features.
689258
    * features/rs6000/powerpc-isa207-vsx64l.xml: Likewise.
689258
    * features/rs6000/powerpc-isa207-vsx32l.c: Re-generate.
689258
    * features/rs6000/powerpc-isa207-vsx64l.c: Re-generate.
689258
    * regformats/rs6000/powerpc-isa207-vsx32l.dat: Re-generate.
689258
    * regformats/rs6000/powerpc-isa207-vsx64l.dat: Re-generate.
689258
    * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call
689258
    fetch_regset with ebb and pmu regsets.
689258
    (store_register, store_ppc_registers): Call store_regset with ebb
689258
    and pmu regsets.
689258
    (ppc_linux_nat_target::read_description): Set isa207 field in the
689258
    features struct if ebb and pmu are avaiable.
689258
    * ppc-linux-tdep.c (ppc32_regmap_ebb, ppc32_regmap_pmu)
689258
    (ppc32_linux_ebbregset, ppc32_linux_pmuregset): New globals.
689258
    (ppc_linux_iterate_over_regset_sections): Call back with the ebb
689258
    and pmu regsets.
689258
    (ppc_linux_core_read_description): Check if the pmu section is
689258
    present and set isa207 in the features struct.
689258
    * ppc-linux-tdep.h (ppc32_linux_ebbregset)
689258
    (ppc32_linux_pmuregset): Declare.
689258
    * ppc-tdep.h (struct gdbarch_tdep) <ppc_mmcr0_regnum>: New field.
689258
    <ppc_mmcr2_regnum, ppc_siar_regnum, ppc_sdar_regnum>: New fields.
689258
    <ppc_sier_regnum>: New field.
689258
    (enum): <PPC_BESCR_REGNUM, PPC_EBBHR_REGNUM, PPC_EBBRR_REGNUM>:
689258
    New enum values.
689258
    <PPC_MMCR0_REGNUM, PPC_MMCR2_REGNUM, PPC_SIAR_REGNUM>: New enum
689258
    values.
689258
    <PPC_SDAR_REGNUM, PPC_SIER_REGNUM>: New enum values.
689258
    (PPC_IS_EBB_REGNUM, PPC_IS_PMU_REGNUM): Define.
689258
    * rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate the
689258
    ebb and pmu features.
689258
689258
gdb/gdbserver/ChangeLog:
689258
2018-10-26  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
689258
689258
    * configure.srv (powerpc*-*-linux*): Add rs6000/power-ebb.xml and
689258
    rs6000/power-linux-pmu.xml to srv_xmlfiles.
689258
    * linux-ppc-low.c (ppc_store_ebbregset, ppc_fill_pmuregset)
689258
    (ppc_store_pmuregset): New functions.
689258
    (ppc_regsets): Add entries for ebb and pmu regsets.
689258
    (ppc_arch_setup): Set isa207 in features struct if the ebb and
689258
    pmu regsets are available.  Set sizes for these regsets.
689258
689258
gdb/doc/ChangeLog:
689258
2018-10-26  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
689258
689258
    * gdb.texinfo (PowerPC Features): Describe new features
689258
    "org.gnu.gdb.power.ebb" and "org.gnu.gdb.power.linux.pmu".
689258
689258
diff --git a/gdb/arch/ppc-linux-common.h b/gdb/arch/ppc-linux-common.h
689258
--- a/gdb/arch/ppc-linux-common.h
689258
+++ b/gdb/arch/ppc-linux-common.h
689258
@@ -33,6 +33,8 @@ struct target_desc;
689258
 #define PPC_LINUX_SIZEOF_PPRREGSET 8
689258
 #define PPC_LINUX_SIZEOF_DSCRREGSET 8
689258
 #define PPC_LINUX_SIZEOF_TARREGSET 8
689258
+#define PPC_LINUX_SIZEOF_EBBREGSET (3*8)
689258
+#define PPC_LINUX_SIZEOF_PMUREGSET (5*8)
689258
 
689258
 /* Check if the hwcap auxv entry indicates that isa205 is supported.  */
689258
 bool ppc_linux_has_isa205 (CORE_ADDR hwcap);
689258
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
689258
--- a/gdb/doc/gdb.texinfo
689258
+++ b/gdb/doc/gdb.texinfo
689258
@@ -42564,6 +42564,15 @@ contain the 64-bit register @samp{dscr}.
689258
 The @samp{org.gnu.gdb.power.tar} feature is optional.  It should
689258
 contain the 64-bit register @samp{tar}.
689258
 
689258
+The @samp{org.gnu.gdb.power.ebb} feature is optional.  It should
689258
+contain registers @samp{bescr}, @samp{ebbhr} and @samp{ebbrr}, all
689258
+64-bit wide.
689258
+
689258
+The @samp{org.gnu.gdb.power.linux.pmu} feature is optional.  It should
689258
+contain registers @samp{mmcr0}, @samp{mmcr2}, @samp{siar}, @samp{sdar}
689258
+and @samp{sier}, all 64-bit wide.  This is the subset of the isa 2.07
689258
+server PMU registers provided by @sc{gnu}/Linux.
689258
+
689258
 @node S/390 and System z Features
689258
 @subsection S/390 and System z Features
689258
 @cindex target descriptions, S/390 features
689258
diff --git a/gdb/features/rs6000/power-ebb.xml b/gdb/features/rs6000/power-ebb.xml
689258
new file mode 100644
689258
--- /dev/null
689258
+++ b/gdb/features/rs6000/power-ebb.xml
689258
@@ -0,0 +1,14 @@
689258
+
689258
+
689258
+
689258
+     Copying and distribution of this file, with or without modification,
689258
+     are permitted in any medium without royalty provided the copyright
689258
+     notice and this notice are preserved.  -->
689258
+
689258
+
689258
+
689258
+<feature name="org.gnu.gdb.power.ebb">
689258
+  <reg name="bescr" bitsize="64" type="uint64" save-restore="no"/>
689258
+  <reg name="ebbhr" bitsize="64" type="uint64" save-restore="no"/>
689258
+  <reg name="ebbrr" bitsize="64" type="uint64" save-restore="no"/>
689258
+</feature>
689258
diff --git a/gdb/features/rs6000/power-linux-pmu.xml b/gdb/features/rs6000/power-linux-pmu.xml
689258
new file mode 100644
689258
--- /dev/null
689258
+++ b/gdb/features/rs6000/power-linux-pmu.xml
689258
@@ -0,0 +1,17 @@
689258
+
689258
+
689258
+
689258
+     Copying and distribution of this file, with or without modification,
689258
+     are permitted in any medium without royalty provided the copyright
689258
+     notice and this notice are preserved.  -->
689258
+
689258
+
689258
+     provided by Linux.  -->
689258
+
689258
+<feature name="org.gnu.gdb.power.linux.pmu">
689258
+  <reg name="mmcr0" bitsize="64" type="uint64" save-restore="no"/>
689258
+  <reg name="mmcr2" bitsize="64" type="uint64" save-restore="no"/>
689258
+  <reg name="siar" bitsize="64" type="uint64" save-restore="no"/>
689258
+  <reg name="sdar" bitsize="64" type="uint64" save-restore="no"/>
689258
+  <reg name="sier" bitsize="64" type="uint64" save-restore="no"/>
689258
+</feature>
689258
diff --git a/gdb/features/rs6000/powerpc-isa207-vsx32l.c b/gdb/features/rs6000/powerpc-isa207-vsx32l.c
689258
--- a/gdb/features/rs6000/powerpc-isa207-vsx32l.c
689258
+++ b/gdb/features/rs6000/powerpc-isa207-vsx32l.c
689258
@@ -199,5 +199,17 @@ initialize_tdesc_powerpc_isa207_vsx32l (void)
689258
   feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar");
689258
   tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64");
689258
 
689258
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb");
689258
+  tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64");
689258
+  tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64");
689258
+  tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64");
689258
+
689258
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu");
689258
+  tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64");
689258
+  tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64");
689258
+  tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64");
689258
+  tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64");
689258
+  tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64");
689258
+
689258
   tdesc_powerpc_isa207_vsx32l = result;
689258
 }
689258
diff --git a/gdb/features/rs6000/powerpc-isa207-vsx32l.xml b/gdb/features/rs6000/powerpc-isa207-vsx32l.xml
689258
--- a/gdb/features/rs6000/powerpc-isa207-vsx32l.xml
689258
+++ b/gdb/features/rs6000/powerpc-isa207-vsx32l.xml
689258
@@ -16,4 +16,6 @@
689258
   <xi:include href="power-ppr.xml"/>
689258
   <xi:include href="power-dscr.xml"/>
689258
   <xi:include href="power-tar.xml"/>
689258
+  <xi:include href="power-ebb.xml"/>
689258
+  <xi:include href="power-linux-pmu.xml"/>
689258
 </target>
689258
diff --git a/gdb/features/rs6000/powerpc-isa207-vsx64l.c b/gdb/features/rs6000/powerpc-isa207-vsx64l.c
689258
--- a/gdb/features/rs6000/powerpc-isa207-vsx64l.c
689258
+++ b/gdb/features/rs6000/powerpc-isa207-vsx64l.c
689258
@@ -199,5 +199,17 @@ initialize_tdesc_powerpc_isa207_vsx64l (void)
689258
   feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar");
689258
   tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64");
689258
 
689258
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb");
689258
+  tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64");
689258
+  tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64");
689258
+  tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64");
689258
+
689258
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu");
689258
+  tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64");
689258
+  tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64");
689258
+  tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64");
689258
+  tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64");
689258
+  tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64");
689258
+
689258
   tdesc_powerpc_isa207_vsx64l = result;
689258
 }
689258
diff --git a/gdb/features/rs6000/powerpc-isa207-vsx64l.xml b/gdb/features/rs6000/powerpc-isa207-vsx64l.xml
689258
--- a/gdb/features/rs6000/powerpc-isa207-vsx64l.xml
689258
+++ b/gdb/features/rs6000/powerpc-isa207-vsx64l.xml
689258
@@ -16,4 +16,6 @@
689258
   <xi:include href="power-ppr.xml"/>
689258
   <xi:include href="power-dscr.xml"/>
689258
   <xi:include href="power-tar.xml"/>
689258
+  <xi:include href="power-ebb.xml"/>
689258
+  <xi:include href="power-linux-pmu.xml"/>
689258
 </target>
689258
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
689258
--- a/gdb/gdbserver/configure.srv
689258
+++ b/gdb/gdbserver/configure.srv
689258
@@ -249,6 +249,8 @@ case "${target}" in
689258
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-dscr.xml"
689258
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-ppr.xml"
689258
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-tar.xml"
689258
+			srv_xmlfiles="${srv_xmlfiles} rs6000/power-ebb.xml"
689258
+			srv_xmlfiles="${srv_xmlfiles} rs6000/power-linux-pmu.xml"
689258
 			srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-e500l.xml"
689258
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-spe.xml"
689258
 			srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-64l.xml"
689258
diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c
689258
--- a/gdb/gdbserver/linux-ppc-low.c
689258
+++ b/gdb/gdbserver/linux-ppc-low.c
689258
@@ -545,6 +545,61 @@ ppc_store_tarregset (struct regcache *regcache, const void *buf)
689258
   supply_register_by_name (regcache, "tar", tar);
689258
 }
689258
 
689258
+/* Event-Based Branching regset store function.  Unless the inferior
689258
+   has a perf event open, ptrace can return in error when reading and
689258
+   writing to the regset, with ENODATA.  For reading, the registers
689258
+   will correctly show as unavailable.  For writing, gdbserver
689258
+   currently only caches any register writes from P and G packets and
689258
+   the stub always tries to write all the regsets when resuming the
689258
+   inferior, which would result in frequent warnings.  For this
689258
+   reason, we don't define a fill function.  This also means that the
689258
+   client-side regcache will be dirty if the user tries to write to
689258
+   the EBB registers.  G packets that the client sends to write to
689258
+   unrelated registers will also include data for EBB registers, even
689258
+   if they are unavailable.  */
689258
+
689258
+static void
689258
+ppc_store_ebbregset (struct regcache *regcache, const void *buf)
689258
+{
689258
+  const char *regset = (const char *) buf;
689258
+
689258
+  /* The order in the kernel regset is: EBBRR, EBBHR, BESCR.  In the
689258
+     .dat file is BESCR, EBBHR, EBBRR.  */
689258
+  supply_register_by_name (regcache, "ebbrr", &regset[0]);
689258
+  supply_register_by_name (regcache, "ebbhr", &regset[8]);
689258
+  supply_register_by_name (regcache, "bescr", &regset[16]);
689258
+}
689258
+
689258
+/* Performance Monitoring Unit regset fill function.  */
689258
+
689258
+static void
689258
+ppc_fill_pmuregset (struct regcache *regcache, void *buf)
689258
+{
689258
+  char *regset = (char *) buf;
689258
+
689258
+  /* The order in the kernel regset is SIAR, SDAR, SIER, MMCR2, MMCR0.
689258
+     In the .dat file is MMCR0, MMCR2, SIAR, SDAR, SIER.  */
689258
+  collect_register_by_name (regcache, "siar", &regset[0]);
689258
+  collect_register_by_name (regcache, "sdar", &regset[8]);
689258
+  collect_register_by_name (regcache, "sier", &regset[16]);
689258
+  collect_register_by_name (regcache, "mmcr2", &regset[24]);
689258
+  collect_register_by_name (regcache, "mmcr0", &regset[32]);
689258
+}
689258
+
689258
+/* Performance Monitoring Unit regset store function.  */
689258
+
689258
+static void
689258
+ppc_store_pmuregset (struct regcache *regcache, const void *buf)
689258
+{
689258
+  const char *regset = (const char *) buf;
689258
+
689258
+  supply_register_by_name (regcache, "siar", &regset[0]);
689258
+  supply_register_by_name (regcache, "sdar", &regset[8]);
689258
+  supply_register_by_name (regcache, "sier", &regset[16]);
689258
+  supply_register_by_name (regcache, "mmcr2", &regset[24]);
689258
+  supply_register_by_name (regcache, "mmcr0", &regset[32]);
689258
+}
689258
+
689258
 static void
689258
 ppc_fill_vsxregset (struct regcache *regcache, void *buf)
689258
 {
689258
@@ -654,6 +709,10 @@ static struct regset_info ppc_regsets[] = {
689258
      fetch them every time, but still fall back to PTRACE_PEEKUSER for the
689258
      general registers.  Some kernels support these, but not the newer
689258
      PPC_PTRACE_GETREGS.  */
689258
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_EBB, 0, EXTENDED_REGS,
689258
+    NULL, ppc_store_ebbregset },
689258
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PMU, 0, EXTENDED_REGS,
689258
+    ppc_fill_pmuregset, ppc_store_pmuregset },
689258
   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TAR, 0, EXTENDED_REGS,
689258
     ppc_fill_tarregset, ppc_store_tarregset },
689258
   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PPR, 0, EXTENDED_REGS,
689258
@@ -734,8 +793,13 @@ ppc_arch_setup (void)
689258
       features.ppr_dscr = true;
689258
       if ((ppc_hwcap2 & PPC_FEATURE2_ARCH_2_07)
689258
 	  && (ppc_hwcap2 & PPC_FEATURE2_TAR)
689258
+	  && (ppc_hwcap2 & PPC_FEATURE2_EBB)
689258
 	  && ppc_check_regset (tid, NT_PPC_TAR,
689258
-			       PPC_LINUX_SIZEOF_TARREGSET))
689258
+			       PPC_LINUX_SIZEOF_TARREGSET)
689258
+	  && ppc_check_regset (tid, NT_PPC_EBB,
689258
+			       PPC_LINUX_SIZEOF_EBBREGSET)
689258
+	  && ppc_check_regset (tid, NT_PPC_PMU,
689258
+			       PPC_LINUX_SIZEOF_PMUREGSET))
689258
 	features.isa207 = true;
689258
     }
689258
 
689258
@@ -798,6 +862,14 @@ ppc_arch_setup (void)
689258
 	    regset->size = (features.isa207 ?
689258
 			    PPC_LINUX_SIZEOF_TARREGSET : 0);
689258
 	    break;
689258
+	  case NT_PPC_EBB:
689258
+	    regset->size = (features.isa207 ?
689258
+			    PPC_LINUX_SIZEOF_EBBREGSET : 0);
689258
+	    break;
689258
+	  case NT_PPC_PMU:
689258
+	    regset->size = (features.isa207 ?
689258
+			    PPC_LINUX_SIZEOF_PMUREGSET : 0);
689258
+	    break;
689258
 	  default:
689258
 	    break;
689258
 	  }
689258
diff --git a/gdb/nat/ppc-linux.h b/gdb/nat/ppc-linux.h
689258
--- a/gdb/nat/ppc-linux.h
689258
+++ b/gdb/nat/ppc-linux.h
689258
@@ -60,6 +60,9 @@
689258
 #ifndef PPC_FEATURE2_TAR
689258
 #define PPC_FEATURE2_TAR 0x04000000
689258
 #endif
689258
+#ifndef PPC_FEATURE2_EBB
689258
+#define PPC_FEATURE2_EBB 0x10000000
689258
+#endif
689258
 
689258
 /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a
689258
    configure time check.  Some older glibc's (for instance 2.2.1)
689258
@@ -106,6 +109,16 @@
689258
 #define NT_PPC_DSCR 0x105
689258
 #endif
689258
 
689258
+/* Event Based Branch Registers.  */
689258
+#ifndef NT_PPC_EBB
689258
+#define NT_PPC_EBB 0x106
689258
+#endif
689258
+
689258
+/* Performance Monitor Registers.  */
689258
+#ifndef NT_PPC_PMU
689258
+#define NT_PPC_PMU 0x107
689258
+#endif
689258
+
689258
 /* Return the wordsize of the target, either 4 or 8 bytes.  */
689258
 int ppc_linux_target_wordsize (int tid);
689258
 
689258
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
689258
--- a/gdb/ppc-linux-nat.c
689258
+++ b/gdb/ppc-linux-nat.c
689258
@@ -667,6 +667,24 @@ fetch_register (struct regcache *regcache, int tid, int regno)
689258
 		    &ppc32_linux_tarregset);
689258
       return;
689258
     }
689258
+  else if (PPC_IS_EBB_REGNUM (regno))
689258
+    {
689258
+      gdb_assert (tdep->have_ebb);
689258
+
689258
+      fetch_regset (regcache, tid, NT_PPC_EBB,
689258
+		    PPC_LINUX_SIZEOF_EBBREGSET,
689258
+		    &ppc32_linux_ebbregset);
689258
+      return;
689258
+    }
689258
+  else if (PPC_IS_PMU_REGNUM (regno))
689258
+    {
689258
+      gdb_assert (tdep->ppc_mmcr0_regnum != -1);
689258
+
689258
+      fetch_regset (regcache, tid, NT_PPC_PMU,
689258
+		    PPC_LINUX_SIZEOF_PMUREGSET,
689258
+		    &ppc32_linux_pmuregset);
689258
+      return;
689258
+    }
689258
 
689258
   if (regaddr == -1)
689258
     {
689258
@@ -875,6 +893,14 @@ fetch_ppc_registers (struct regcache *regcache, int tid)
689258
     fetch_regset (regcache, tid, NT_PPC_TAR,
689258
 		  PPC_LINUX_SIZEOF_TARREGSET,
689258
 		  &ppc32_linux_tarregset);
689258
+  if (tdep->have_ebb)
689258
+    fetch_regset (regcache, tid, NT_PPC_EBB,
689258
+		  PPC_LINUX_SIZEOF_EBBREGSET,
689258
+		  &ppc32_linux_ebbregset);
689258
+  if (tdep->ppc_mmcr0_regnum != -1)
689258
+    fetch_regset (regcache, tid, NT_PPC_PMU,
689258
+		  PPC_LINUX_SIZEOF_PMUREGSET,
689258
+		  &ppc32_linux_pmuregset);
689258
 }
689258
 
689258
 /* Fetch registers from the child process.  Fetch all registers if
689258
@@ -1082,6 +1108,24 @@ store_register (const struct regcache *regcache, int tid, int regno)
689258
 		    &ppc32_linux_tarregset);
689258
       return;
689258
     }
689258
+  else if (PPC_IS_EBB_REGNUM (regno))
689258
+    {
689258
+      gdb_assert (tdep->have_ebb);
689258
+
689258
+      store_regset (regcache, tid, regno, NT_PPC_EBB,
689258
+		    PPC_LINUX_SIZEOF_EBBREGSET,
689258
+		    &ppc32_linux_ebbregset);
689258
+      return;
689258
+    }
689258
+  else if (PPC_IS_PMU_REGNUM (regno))
689258
+    {
689258
+      gdb_assert (tdep->ppc_mmcr0_regnum != -1);
689258
+
689258
+      store_regset (regcache, tid, regno, NT_PPC_PMU,
689258
+		    PPC_LINUX_SIZEOF_PMUREGSET,
689258
+		    &ppc32_linux_pmuregset);
689258
+      return;
689258
+    }
689258
 
689258
   if (regaddr == -1)
689258
     return;
689258
@@ -1308,6 +1352,15 @@ store_ppc_registers (const struct regcache *regcache, int tid)
689258
     store_regset (regcache, tid, -1, NT_PPC_TAR,
689258
 		  PPC_LINUX_SIZEOF_TARREGSET,
689258
 		  &ppc32_linux_tarregset);
689258
+
689258
+  if (tdep->ppc_mmcr0_regnum != -1)
689258
+    store_regset (regcache, tid, -1, NT_PPC_PMU,
689258
+		  PPC_LINUX_SIZEOF_PMUREGSET,
689258
+		  &ppc32_linux_pmuregset);
689258
+
689258
+  /* Because the EBB registers can be unavailable, attempts to store
689258
+     them here would cause this function to fail most of the time, so
689258
+     we ignore them.  */
689258
 }
689258
 
689258
 /* Fetch the AT_HWCAP entry from the aux vector.  */
689258
@@ -2439,7 +2492,10 @@ ppc_linux_nat_target::read_description ()
689258
       features.ppr_dscr = true;
689258
       if ((hwcap2 & PPC_FEATURE2_ARCH_2_07)
689258
 	  && (hwcap2 & PPC_FEATURE2_TAR)
689258
-	  && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET))
689258
+	  && (hwcap2 & PPC_FEATURE2_EBB)
689258
+	  && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET)
689258
+	  && check_regset (tid, NT_PPC_EBB, PPC_LINUX_SIZEOF_EBBREGSET)
689258
+	  && check_regset (tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET))
689258
 	features.isa207 = true;
689258
     }
689258
 
689258
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
689258
--- a/gdb/ppc-linux-tdep.c
689258
+++ b/gdb/ppc-linux-tdep.c
689258
@@ -599,6 +599,44 @@ const struct regset ppc32_linux_tarregset = {
689258
   regcache_collect_regset
689258
 };
689258
 
689258
+/* Event-Based Branching regmap.  */
689258
+
689258
+static const struct regcache_map_entry ppc32_regmap_ebb[] =
689258
+  {
689258
+      { 1, PPC_EBBRR_REGNUM, 8 },
689258
+      { 1, PPC_EBBHR_REGNUM, 8 },
689258
+      { 1, PPC_BESCR_REGNUM, 8 },
689258
+      { 0 }
689258
+  };
689258
+
689258
+/* Event-Based Branching regset.  */
689258
+
689258
+const struct regset ppc32_linux_ebbregset = {
689258
+  ppc32_regmap_ebb,
689258
+  regcache_supply_regset,
689258
+  regcache_collect_regset
689258
+};
689258
+
689258
+/* Performance Monitoring Unit regmap.  */
689258
+
689258
+static const struct regcache_map_entry ppc32_regmap_pmu[] =
689258
+  {
689258
+      { 1, PPC_SIAR_REGNUM, 8 },
689258
+      { 1, PPC_SDAR_REGNUM, 8 },
689258
+      { 1, PPC_SIER_REGNUM, 8 },
689258
+      { 1, PPC_MMCR2_REGNUM, 8 },
689258
+      { 1, PPC_MMCR0_REGNUM, 8 },
689258
+      { 0 }
689258
+  };
689258
+
689258
+/* Performance Monitoring Unit regset.  */
689258
+
689258
+const struct regset ppc32_linux_pmuregset = {
689258
+  ppc32_regmap_pmu,
689258
+  regcache_supply_regset,
689258
+  regcache_collect_regset
689258
+};
689258
+
689258
 const struct regset *
689258
 ppc_linux_gregset (int wordsize)
689258
 {
689258
@@ -674,6 +712,22 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
689258
     cb (".reg-ppc-tar", PPC_LINUX_SIZEOF_TARREGSET,
689258
 	PPC_LINUX_SIZEOF_TARREGSET,
689258
 	&ppc32_linux_tarregset, "Target Address Register", cb_data);
689258
+
689258
+  /* EBB registers are unavailable when ptrace returns ENODATA.  Check
689258
+     availability when generating a core file (regcache != NULL).  */
689258
+  if (tdep->have_ebb)
689258
+    if (regcache == NULL
689258
+	|| REG_VALID == regcache->get_register_status (PPC_BESCR_REGNUM))
689258
+      cb (".reg-ppc-ebb", PPC_LINUX_SIZEOF_EBBREGSET,
689258
+	  PPC_LINUX_SIZEOF_EBBREGSET,
689258
+	  &ppc32_linux_ebbregset, "Event-based Branching Registers",
689258
+	  cb_data);
689258
+
689258
+  if (tdep->ppc_mmcr0_regnum != -1)
689258
+    cb (".reg-ppc-pmu", PPC_LINUX_SIZEOF_PMUREGSET,
689258
+	PPC_LINUX_SIZEOF_PMUREGSET,
689258
+	&ppc32_linux_pmuregset, "Performance Monitor Registers",
689258
+	cb_data);
689258
 }
689258
 
689258
 static void
689258
@@ -1089,6 +1143,7 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch,
689258
   asection *ppr = bfd_get_section_by_name (abfd, ".reg-ppc-ppr");
689258
   asection *dscr = bfd_get_section_by_name (abfd, ".reg-ppc-dscr");
689258
   asection *tar = bfd_get_section_by_name (abfd, ".reg-ppc-tar");
689258
+  asection *pmu = bfd_get_section_by_name (abfd, ".reg-ppc-pmu");
689258
 
689258
   if (! section)
689258
     return NULL;
689258
@@ -1124,7 +1179,12 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch,
689258
   if (ppr && dscr)
689258
     {
689258
       features.ppr_dscr = true;
689258
-      if (tar)
689258
+
689258
+      /* We don't require the EBB note section to be present in the
689258
+	 core file to select isa207 because these registers could have
689258
+	 been unavailable when the core file was created.  They will
689258
+	 be in the tdep but will show as unavailable.  */
689258
+      if (tar && pmu)
689258
 	features.isa207 = true;
689258
     }
689258
 
689258
diff --git a/gdb/ppc-linux-tdep.h b/gdb/ppc-linux-tdep.h
689258
--- a/gdb/ppc-linux-tdep.h
689258
+++ b/gdb/ppc-linux-tdep.h
689258
@@ -48,5 +48,7 @@ int ppc_linux_trap_reg_p (struct gdbarch *gdbarch);
689258
 extern const struct regset ppc32_linux_pprregset;
689258
 extern const struct regset ppc32_linux_dscrregset;
689258
 extern const struct regset ppc32_linux_tarregset;
689258
+extern const struct regset ppc32_linux_ebbregset;
689258
+extern const struct regset ppc32_linux_pmuregset;
689258
 
689258
 #endif /* PPC_LINUX_TDEP_H */
689258
diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h
689258
--- a/gdb/ppc-tdep.h
689258
+++ b/gdb/ppc-tdep.h
689258
@@ -265,6 +265,15 @@ struct gdbarch_tdep
689258
     /* Decimal 128 registers.  */
689258
     int ppc_dl0_regnum;		/* First Decimal128 argument register pair.  */
689258
 
689258
+    int have_ebb;
689258
+
689258
+    /* PMU registers.  */
689258
+    int ppc_mmcr0_regnum;
689258
+    int ppc_mmcr2_regnum;
689258
+    int ppc_siar_regnum;
689258
+    int ppc_sdar_regnum;
689258
+    int ppc_sier_regnum;
689258
+
689258
     /* Offset to ABI specific location where link register is saved.  */
689258
     int lr_frame_offset;	
689258
 
689258
@@ -321,12 +330,31 @@ enum {
689258
   PPC_PPR_REGNUM = 172,
689258
   PPC_DSCR_REGNUM = 173,
689258
   PPC_TAR_REGNUM = 174,
689258
+
689258
+  /* EBB registers.  */
689258
+  PPC_BESCR_REGNUM = 175,
689258
+  PPC_EBBHR_REGNUM = 176,
689258
+  PPC_EBBRR_REGNUM = 177,
689258
+
689258
+  /* PMU registers.  */
689258
+  PPC_MMCR0_REGNUM = 178,
689258
+  PPC_MMCR2_REGNUM = 179,
689258
+  PPC_SIAR_REGNUM = 180,
689258
+  PPC_SDAR_REGNUM = 181,
689258
+  PPC_SIER_REGNUM = 182,
689258
+
689258
   PPC_NUM_REGS
689258
 };
689258
 
689258
 /* Big enough to hold the size of the largest register in bytes.  */
689258
 #define PPC_MAX_REGISTER_SIZE	64
689258
 
689258
+#define PPC_IS_EBB_REGNUM(i) \
689258
+	((i) >= PPC_BESCR_REGNUM && (i) <= PPC_EBBRR_REGNUM)
689258
+
689258
+#define PPC_IS_PMU_REGNUM(i) \
689258
+	((i) >= PPC_MMCR0_REGNUM && (i) <= PPC_SIER_REGNUM)
689258
+
689258
 /* An instruction to match.  */
689258
 
689258
 struct ppc_insn_pattern
689258
diff --git a/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat b/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat
689258
--- a/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat
689258
+++ b/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat
689258
@@ -145,3 +145,11 @@ expedite:r1,pc
689258
 64:ppr
689258
 64:dscr
689258
 64:tar
689258
+64:bescr
689258
+64:ebbhr
689258
+64:ebbrr
689258
+64:mmcr0
689258
+64:mmcr2
689258
+64:siar
689258
+64:sdar
689258
+64:sier
689258
diff --git a/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat b/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat
689258
--- a/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat
689258
+++ b/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat
689258
@@ -145,3 +145,11 @@ expedite:r1,pc
689258
 64:ppr
689258
 64:dscr
689258
 64:tar
689258
+64:bescr
689258
+64:ebbhr
689258
+64:ebbrr
689258
+64:mmcr0
689258
+64:mmcr2
689258
+64:siar
689258
+64:sdar
689258
+64:sier
689258
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
689258
--- a/gdb/rs6000-tdep.c
689258
+++ b/gdb/rs6000-tdep.c
689258
@@ -5871,7 +5871,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
689258
   enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO;
689258
   int have_fpu = 0, have_spe = 0, have_mq = 0, have_altivec = 0;
689258
   int have_dfp = 0, have_vsx = 0, have_ppr = 0, have_dscr = 0;
689258
-  int have_tar = 0;
689258
+  int have_tar = 0, have_ebb = 0, have_pmu = 0;
689258
   int tdesc_wordsize = -1;
689258
   const struct target_desc *tdesc = info.target_desc;
689258
   struct tdesc_arch_data *tdesc_data = NULL;
689258
@@ -6211,6 +6211,64 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
689258
 	}
689258
       else
689258
 	have_tar = 0;
689258
+
689258
+      /* Event-based Branching Registers.  */
689258
+      feature = tdesc_find_feature (tdesc,
689258
+				    "org.gnu.gdb.power.ebb");
689258
+      if (feature != NULL)
689258
+	{
689258
+	  static const char *const ebb_regs[] = {
689258
+	    "bescr", "ebbhr", "ebbrr"
689258
+	  };
689258
+
689258
+	  valid_p = 1;
689258
+	  for (i = 0; i < ARRAY_SIZE (ebb_regs); i++)
689258
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
689258
+						PPC_BESCR_REGNUM + i,
689258
+						ebb_regs[i]);
689258
+	  if (!valid_p)
689258
+	    {
689258
+	      tdesc_data_cleanup (tdesc_data);
689258
+	      return NULL;
689258
+	    }
689258
+	  have_ebb = 1;
689258
+	}
689258
+      else
689258
+	have_ebb = 0;
689258
+
689258
+      /* Subset of the ISA 2.07 Performance Monitor Registers provided
689258
+	 by Linux.  */
689258
+      feature = tdesc_find_feature (tdesc,
689258
+				    "org.gnu.gdb.power.linux.pmu");
689258
+      if (feature != NULL)
689258
+	{
689258
+	  valid_p = 1;
689258
+
689258
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
689258
+					      PPC_MMCR0_REGNUM,
689258
+					      "mmcr0");
689258
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
689258
+					      PPC_MMCR2_REGNUM,
689258
+					      "mmcr2");
689258
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
689258
+					      PPC_SIAR_REGNUM,
689258
+					      "siar");
689258
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
689258
+					      PPC_SDAR_REGNUM,
689258
+					      "sdar");
689258
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
689258
+					      PPC_SIER_REGNUM,
689258
+					      "sier");
689258
+
689258
+	  if (!valid_p)
689258
+	    {
689258
+	      tdesc_data_cleanup (tdesc_data);
689258
+	      return NULL;
689258
+	    }
689258
+	  have_pmu = 1;
689258
+	}
689258
+      else
689258
+	have_pmu = 0;
689258
     }
689258
 
689258
   /* If we have a 64-bit binary on a 32-bit target, complain.  Also
689258
@@ -6408,6 +6466,20 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
689258
   tdep->ppc_ppr_regnum = have_ppr ? PPC_PPR_REGNUM : -1;
689258
   tdep->ppc_dscr_regnum = have_dscr ? PPC_DSCR_REGNUM : -1;
689258
   tdep->ppc_tar_regnum = have_tar ? PPC_TAR_REGNUM : -1;
689258
+  tdep->have_ebb = have_ebb;
689258
+
689258
+  /* If additional pmu registers are added, care must be taken when
689258
+     setting new fields in the tdep below, to maintain compatibility
689258
+     with features that only provide some of the registers.  Currently
689258
+     gdb access to the pmu registers is only supported in linux, and
689258
+     linux only provides a subset of the pmu registers defined in the
689258
+     architecture.  */
689258
+
689258
+  tdep->ppc_mmcr0_regnum = have_pmu ? PPC_MMCR0_REGNUM : -1;
689258
+  tdep->ppc_mmcr2_regnum = have_pmu ? PPC_MMCR2_REGNUM : -1;
689258
+  tdep->ppc_siar_regnum = have_pmu ? PPC_SIAR_REGNUM : -1;
689258
+  tdep->ppc_sdar_regnum = have_pmu ? PPC_SDAR_REGNUM : -1;
689258
+  tdep->ppc_sier_regnum = have_pmu ? PPC_SIER_REGNUM : -1;
689258
 
689258
   set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM);
689258
   set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1);