Remove ptid_match
[deliverable/binutils-gdb.git] / gdb / regcache.c
index 371322d9a1e9c1283ffb7e9b9bc64e95bf4827ba..bc916f352eb28f6ad4b2fa1ef3ed38a508bceadf 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "defs.h"
 #include "inferior.h"
+#include "gdbthread.h"
 #include "target.h"
 #include "gdbarch.h"
 #include "gdbcmd.h"
@@ -185,14 +186,15 @@ reg_buffer::reg_buffer (gdbarch *gdbarch, bool has_pseudo)
 
   if (has_pseudo)
     {
-      m_registers = XCNEWVEC (gdb_byte, m_descr->sizeof_cooked_registers);
-      m_register_status = XCNEWVEC (signed char,
-                                   m_descr->nr_cooked_registers);
+      m_registers.reset (new gdb_byte[m_descr->sizeof_cooked_registers] ());
+      m_register_status.reset
+       (new register_status[m_descr->nr_cooked_registers] ());
     }
   else
     {
-      m_registers = XCNEWVEC (gdb_byte, m_descr->sizeof_raw_registers);
-      m_register_status = XCNEWVEC (signed char, gdbarch_num_regs (gdbarch));
+      m_registers.reset (new gdb_byte[m_descr->sizeof_raw_registers] ());
+      m_register_status.reset
+       (new register_status[gdbarch_num_regs (gdbarch)] ());
     }
 }
 
@@ -204,16 +206,12 @@ regcache::regcache (gdbarch *gdbarch, const address_space *aspace_)
   m_ptid = minus_one_ptid;
 }
 
-static enum register_status
-do_cooked_read (void *src, int regnum, gdb_byte *buf)
-{
-  struct regcache *regcache = (struct regcache *) src;
-
-  return regcache->cooked_read (regnum, buf);
-}
-
-readonly_detached_regcache::readonly_detached_regcache (const regcache &src)
-  : readonly_detached_regcache (src.arch (), do_cooked_read, (void *) &src)
+readonly_detached_regcache::readonly_detached_regcache (regcache &src)
+  : readonly_detached_regcache (src.arch (),
+                               [&src] (int regnum, gdb_byte *buf)
+                                 {
+                                   return src.cooked_read (regnum, buf);
+                                 })
 {
 }
 
@@ -238,7 +236,7 @@ public:
   ~regcache_invalidator ()
   {
     if (m_regcache != nullptr)
-      regcache_invalidate (m_regcache, m_regnum);
+      m_regcache->invalidate (m_regnum);
   }
 
   DISABLE_COPY_AND_ASSIGN (regcache_invalidator);
@@ -259,12 +257,11 @@ private:
 gdb_byte *
 reg_buffer::register_buffer (int regnum) const
 {
-  return m_registers + m_descr->register_offset[regnum];
+  return m_registers.get () + m_descr->register_offset[regnum];
 }
 
 void
-reg_buffer::save (regcache_cooked_read_ftype *cooked_read,
-                 void *src)
+reg_buffer::save (register_read_ftype cooked_read)
 {
   struct gdbarch *gdbarch = m_descr->gdbarch;
   int regnum;
@@ -272,8 +269,8 @@ reg_buffer::save (regcache_cooked_read_ftype *cooked_read,
   /* It should have pseudo registers.  */
   gdb_assert (m_has_pseudo);
   /* Clear the dest.  */
-  memset (m_registers, 0, m_descr->sizeof_cooked_registers);
-  memset (m_register_status, 0, m_descr->nr_cooked_registers);
+  memset (m_registers.get (), 0, m_descr->sizeof_cooked_registers);
+  memset (m_register_status.get (), REG_UNKNOWN, m_descr->nr_cooked_registers);
   /* Copy over any registers (identified by their membership in the
      save_reggroup) and mark them as valid.  The full [0 .. gdbarch_num_regs +
      gdbarch_num_pseudo_regs) range is checked since some architectures need
@@ -283,7 +280,7 @@ reg_buffer::save (regcache_cooked_read_ftype *cooked_read,
       if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
        {
          gdb_byte *dst_buf = register_buffer (regnum);
-         enum register_status status = cooked_read (src, regnum, dst_buf);
+         enum register_status status = cooked_read (regnum, dst_buf);
 
          gdb_assert (status != REG_UNKNOWN);
 
@@ -320,23 +317,18 @@ regcache::restore (readonly_detached_regcache *src)
     }
 }
 
+/* See common/common-regcache.h.  */
+
 enum register_status
 reg_buffer::get_register_status (int regnum) const
 {
   assert_regnum (regnum);
 
-  return (enum register_status) m_register_status[regnum];
-}
-
-void
-regcache_invalidate (struct regcache *regcache, int regnum)
-{
-  gdb_assert (regcache != NULL);
-  regcache->invalidate (regnum);
+  return m_register_status[regnum];
 }
 
 void
-detached_regcache::invalidate (int regnum)
+reg_buffer::invalidate (int regnum)
 {
   assert_regnum (regnum);
   m_register_status[regnum] = REG_UNKNOWN;
@@ -399,10 +391,18 @@ get_thread_regcache (ptid_t ptid)
   return get_thread_arch_regcache (ptid, current_thread_arch);
 }
 
+/* See regcache.h.  */
+
+struct regcache *
+get_thread_regcache (thread_info *thread)
+{
+  return get_thread_regcache (thread->ptid);
+}
+
 struct regcache *
 get_current_regcache (void)
 {
-  return get_thread_regcache (inferior_ptid);
+  return get_thread_regcache (inferior_thread ());
 }
 
 /* See common/common-regcache.h.  */
@@ -452,7 +452,7 @@ registers_changed_ptid (ptid_t ptid)
        it != regcache::current_regcache.end ();
        )
     {
-      if (ptid_match ((*it)->ptid (), ptid))
+      if ((*it)->ptid ().matches (ptid))
        {
          delete *it;
          it = regcache::current_regcache.erase_after (oit);
@@ -461,13 +461,13 @@ registers_changed_ptid (ptid_t ptid)
        oit = it++;
     }
 
-  if (ptid_match (current_thread_ptid, ptid))
+  if (current_thread_ptid.matches (ptid))
     {
       current_thread_ptid = null_ptid;
       current_thread_arch = NULL;
     }
 
-  if (ptid_match (inferior_ptid, ptid))
+  if (inferior_ptid.matches (ptid))
     {
       /* We just deleted the regcache of the current thread.  Need to
         forget about any frames we have cached, too.  */
@@ -475,6 +475,14 @@ registers_changed_ptid (ptid_t ptid)
     }
 }
 
+/* See regcache.h.  */
+
+void
+registers_changed_thread (thread_info *thread)
+{
+  registers_changed_ptid (thread->ptid);
+}
+
 void
 registers_changed (void)
 {
@@ -522,7 +530,7 @@ readable_regcache::raw_read (int regnum, gdb_byte *buf)
     memcpy (buf, register_buffer (regnum),
            m_descr->sizeof_register[regnum]);
 
-  return (enum register_status) m_register_status[regnum];
+  return m_register_status[regnum];
 }
 
 enum register_status
@@ -616,7 +624,7 @@ readable_regcache::cooked_read (int regnum, gdb_byte *buf)
       else
        memset (buf, 0, m_descr->sizeof_register[regnum]);
 
-      return (enum register_status) m_register_status[regnum];
+      return m_register_status[regnum];
     }
   else if (gdbarch_pseudo_register_read_value_p (m_descr->gdbarch))
     {
@@ -645,12 +653,6 @@ readable_regcache::cooked_read (int regnum, gdb_byte *buf)
                                         regnum, buf);
 }
 
-struct value *
-regcache_cooked_read_value (struct regcache *regcache, int regnum)
-{
-  return regcache->cooked_read_value (regnum);
-}
-
 struct value *
 readable_regcache::cooked_read_value (int regnum)
 {
@@ -778,13 +780,6 @@ regcache::raw_write (int regnum, const gdb_byte *buf)
   invalidator.release ();
 }
 
-void
-regcache_cooked_write (struct regcache *regcache, int regnum,
-                      const gdb_byte *buf)
-{
-  regcache->cooked_write (regnum, buf);
-}
-
 void
 regcache::cooked_write (int regnum, const gdb_byte *buf)
 {
@@ -797,77 +792,149 @@ regcache::cooked_write (int regnum, const gdb_byte *buf)
                                   regnum, buf);
 }
 
-/* Perform a partial register transfer using a read, modify, write
-   operation.  */
+/* See regcache.h.  */
 
 enum register_status
-readable_regcache::read_part (int regnum, int offset, int len, void *in,
-                             bool is_raw)
+readable_regcache::read_part (int regnum, int offset, int len,
+                             gdb_byte *out, bool is_raw)
 {
-  struct gdbarch *gdbarch = arch ();
-  gdb_byte *reg = (gdb_byte *) alloca (register_size (gdbarch, regnum));
+  int reg_size = register_size (arch (), regnum);
+
+  gdb_assert (out != NULL);
+  gdb_assert (offset >= 0 && offset <= reg_size);
+  gdb_assert (len >= 0 && offset + len <= reg_size);
+
+  if (offset == 0 && len == 0)
+    {
+      /* Nothing to do.  */
+      return REG_VALID;
+    }
+
+  if (offset == 0 && len == reg_size)
+    {
+      /* Read the full register.  */
+      return (is_raw) ? raw_read (regnum, out) : cooked_read (regnum, out);
+    }
 
-  gdb_assert (in != NULL);
-  gdb_assert (offset >= 0 && offset <= m_descr->sizeof_register[regnum]);
-  gdb_assert (len >= 0 && offset + len <= m_descr->sizeof_register[regnum]);
-  /* Something to do?  */
-  if (offset + len == 0)
-    return REG_VALID;
-  /* Read (when needed) ...  */
   enum register_status status;
+  gdb_byte *reg = (gdb_byte *) alloca (reg_size);
 
-  if (is_raw)
-    status = raw_read (regnum, reg);
-  else
-    status = cooked_read (regnum, reg);
+  /* Read full register to buffer.  */
+  status = (is_raw) ? raw_read (regnum, reg) : cooked_read (regnum, reg);
   if (status != REG_VALID)
     return status;
 
-  /* ... modify ...  */
-  memcpy (in, reg + offset, len);
-
+  /* Copy out.  */
+  memcpy (out, reg + offset, len);
   return REG_VALID;
 }
 
+/* See regcache.h.  */
+
+void
+reg_buffer::raw_collect_part (int regnum, int offset, int len,
+                             gdb_byte *out) const
+{
+  int reg_size = register_size (arch (), regnum);
+
+  gdb_assert (out != nullptr);
+  gdb_assert (offset >= 0 && offset <= reg_size);
+  gdb_assert (len >= 0 && offset + len <= reg_size);
+
+  if (offset == 0 && len == 0)
+    {
+      /* Nothing to do.  */
+      return;
+    }
+
+  if (offset == 0 && len == reg_size)
+    {
+      /* Collect the full register.  */
+      return raw_collect (regnum, out);
+    }
+
+  /* Read to buffer, then write out.  */
+  gdb_byte *reg = (gdb_byte *) alloca (reg_size);
+  raw_collect (regnum, reg);
+  memcpy (out, reg + offset, len);
+}
+
+/* See regcache.h.  */
+
 enum register_status
 regcache::write_part (int regnum, int offset, int len,
-                    const void *out, bool is_raw)
+                     const gdb_byte *in, bool is_raw)
 {
-  struct gdbarch *gdbarch = arch ();
-  gdb_byte *reg = (gdb_byte *) alloca (register_size (gdbarch, regnum));
+  int reg_size = register_size (arch (), regnum);
 
-  gdb_assert (out != NULL);
-  gdb_assert (offset >= 0 && offset <= m_descr->sizeof_register[regnum]);
-  gdb_assert (len >= 0 && offset + len <= m_descr->sizeof_register[regnum]);
-  /* Something to do?  */
-  if (offset + len == 0)
-    return REG_VALID;
-  /* Read (when needed) ...  */
-  if (offset > 0
-      || offset + len < m_descr->sizeof_register[regnum])
+  gdb_assert (in != NULL);
+  gdb_assert (offset >= 0 && offset <= reg_size);
+  gdb_assert (len >= 0 && offset + len <= reg_size);
+
+  if (offset == 0 && len == 0)
     {
-      enum register_status status;
+      /* Nothing to do.  */
+      return REG_VALID;
+    }
 
-      if (is_raw)
-       status = raw_read (regnum, reg);
-      else
-       status = cooked_read (regnum, reg);
-      if (status != REG_VALID)
-       return status;
+  if (offset == 0 && len == reg_size)
+    {
+      /* Write the full register.  */
+      (is_raw) ? raw_write (regnum, in) : cooked_write (regnum, in);
+      return REG_VALID;
     }
 
-  memcpy (reg + offset, out, len);
-  /* ... write (when needed).  */
-  if (is_raw)
-    raw_write (regnum, reg);
-  else
-    cooked_write (regnum, reg);
+  enum register_status status;
+  gdb_byte *reg = (gdb_byte *) alloca (reg_size);
 
+  /* Read existing register to buffer.  */
+  status = (is_raw) ? raw_read (regnum, reg) : cooked_read (regnum, reg);
+  if (status != REG_VALID)
+    return status;
+
+  /* Update buffer, then write back to regcache.  */
+  memcpy (reg + offset, in, len);
+  is_raw ? raw_write (regnum, reg) : cooked_write (regnum, reg);
   return REG_VALID;
 }
 
+/* See regcache.h.  */
+
+void
+reg_buffer::raw_supply_part (int regnum, int offset, int len,
+                            const gdb_byte *in)
+{
+  int reg_size = register_size (arch (), regnum);
+
+  gdb_assert (in != nullptr);
+  gdb_assert (offset >= 0 && offset <= reg_size);
+  gdb_assert (len >= 0 && offset + len <= reg_size);
+
+  if (offset == 0 && len == 0)
+    {
+      /* Nothing to do.  */
+      return;
+    }
+
+  if (offset == 0 && len == reg_size)
+    {
+      /* Supply the full register.  */
+      return raw_supply (regnum, in);
+    }
+
+  gdb_byte *reg = (gdb_byte *) alloca (reg_size);
+
+  /* Read existing value to buffer.  */
+  raw_collect (regnum, reg);
+
+  /* Write to buffer, then write out.  */
+  memcpy (reg + offset, in, len);
+  raw_supply (regnum, reg);
+}
+
 enum register_status
-readable_regcache::raw_read_part (int regnum, int offset, int len, gdb_byte *buf)
+readable_regcache::raw_read_part (int regnum, int offset, int len,
+                                 gdb_byte *buf)
 {
   assert_regnum (regnum);
   return read_part (regnum, offset, len, buf, true);
@@ -883,13 +950,7 @@ regcache::raw_write_part (int regnum, int offset, int len,
   write_part (regnum, offset, len, buf, true);
 }
 
-enum register_status
-regcache_cooked_read_part (struct regcache *regcache, int regnum,
-                          int offset, int len, gdb_byte *buf)
-{
-  return regcache->cooked_read_part (regnum, offset, len, buf);
-}
-
+/* See regcache.h.  */
 
 enum register_status
 readable_regcache::cooked_read_part (int regnum, int offset, int len,
@@ -899,12 +960,7 @@ readable_regcache::cooked_read_part (int regnum, int offset, int len,
   return read_part (regnum, offset, len, buf, false);
 }
 
-void
-regcache_cooked_write_part (struct regcache *regcache, int regnum,
-                           int offset, int len, const gdb_byte *buf)
-{
-  regcache->cooked_write_part (regnum, offset, len, buf);
-}
+/* See regcache.h.  */
 
 void
 regcache::cooked_write_part (int regnum, int offset, int len,
@@ -914,17 +970,10 @@ regcache::cooked_write_part (int regnum, int offset, int len,
   write_part (regnum, offset, len, buf, false);
 }
 
-/* Supply register REGNUM, whose contents are stored in BUF, to REGCACHE.  */
-
-void
-regcache_raw_supply (struct regcache *regcache, int regnum, const void *buf)
-{
-  gdb_assert (regcache != NULL);
-  regcache->raw_supply (regnum, buf);
-}
+/* See common/common-regcache.h.  */
 
 void
-detached_regcache::raw_supply (int regnum, const void *buf)
+reg_buffer::raw_supply (int regnum, const void *buf)
 {
   void *regbuf;
   size_t size;
@@ -949,15 +998,11 @@ detached_regcache::raw_supply (int regnum, const void *buf)
     }
 }
 
-/* Supply register REGNUM to REGCACHE.  Value to supply is an integer stored at
-   address ADDR, in target endian, with length ADDR_LEN and sign IS_SIGNED.  If
-   the register size is greater than ADDR_LEN, then the integer will be sign or
-   zero extended.  If the register size is smaller than the integer, then the
-   most significant bytes of the integer will be truncated.  */
+/* See regcache.h.  */
 
 void
-detached_regcache::raw_supply_integer (int regnum, const gdb_byte *addr,
-                                  int addr_len, bool is_signed)
+reg_buffer::raw_supply_integer (int regnum, const gdb_byte *addr,
+                               int addr_len, bool is_signed)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch);
   gdb_byte *regbuf;
@@ -973,12 +1018,10 @@ detached_regcache::raw_supply_integer (int regnum, const gdb_byte *addr,
   m_register_status[regnum] = REG_VALID;
 }
 
-/* Supply register REGNUM with zeroed value to REGCACHE.  This is not the same
-   as calling raw_supply with NULL (which will set the state to
-   unavailable).  */
+/* See regcache.h.  */
 
 void
-detached_regcache::raw_supply_zeroed (int regnum)
+reg_buffer::raw_supply_zeroed (int regnum)
 {
   void *regbuf;
   size_t size;
@@ -992,17 +1035,10 @@ detached_regcache::raw_supply_zeroed (int regnum)
   m_register_status[regnum] = REG_VALID;
 }
 
-/* Collect register REGNUM from REGCACHE and store its contents in BUF.  */
-
-void
-regcache_raw_collect (const struct regcache *regcache, int regnum, void *buf)
-{
-  gdb_assert (regcache != NULL && buf != NULL);
-  regcache->raw_collect (regnum, buf);
-}
+/* See common/common-regcache.h.  */
 
 void
-regcache::raw_collect (int regnum, void *buf) const
+reg_buffer::raw_collect (int regnum, void *buf) const
 {
   const void *regbuf;
   size_t size;
@@ -1015,19 +1051,11 @@ regcache::raw_collect (int regnum, void *buf) const
   memcpy (buf, regbuf, size);
 }
 
-/* Transfer a single or all registers belonging to a certain register
-   set to or from a buffer.  This is the main worker function for
-   regcache_supply_regset and regcache_collect_regset.  */
-
-/* Collect register REGNUM from REGCACHE.  Store collected value as an integer
-   at address ADDR, in target endian, with length ADDR_LEN and sign IS_SIGNED.
-   If ADDR_LEN is greater than the register size, then the integer will be sign
-   or zero extended.  If ADDR_LEN is smaller than the register size, then the
-   most significant bytes of the integer will be truncated.  */
+/* See regcache.h.  */
 
 void
-regcache::raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
-                              bool is_signed) const
+reg_buffer::raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
+                                bool is_signed) const
 {
   enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch);
   const gdb_byte *regbuf;
@@ -1042,11 +1070,43 @@ regcache::raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
                        byte_order);
 }
 
+/* See regcache.h.  */
+
+void
+regcache::transfer_regset_register (struct regcache *out_regcache, int regnum,
+                                   const gdb_byte *in_buf, gdb_byte *out_buf,
+                                   int slot_size, int offs) const
+{
+  struct gdbarch *gdbarch = arch ();
+  int reg_size = std::min (register_size (gdbarch, regnum), slot_size);
+
+  /* Use part versions and reg_size to prevent possible buffer overflows when
+     accessing the regcache.  */
+
+  if (out_buf != nullptr)
+    {
+      raw_collect_part (regnum, 0, reg_size, out_buf + offs);
+
+      /* Ensure any additional space is cleared.  */
+      if (slot_size > reg_size)
+       memset (out_buf + offs + reg_size, 0, slot_size - reg_size);
+    }
+  else if (in_buf != nullptr)
+    out_regcache->raw_supply_part (regnum, 0, reg_size, in_buf + offs);
+  else
+    {
+      /* Invalidate the register.  */
+      out_regcache->raw_supply (regnum, nullptr);
+    }
+}
+
+/* See regcache.h.  */
+
 void
 regcache::transfer_regset (const struct regset *regset,
                           struct regcache *out_regcache,
-                          int regnum, const void *in_buf,
-                          void *out_buf, size_t size) const
+                          int regnum, const gdb_byte *in_buf,
+                          gdb_byte *out_buf, size_t size) const
 {
   const struct regcache_map_entry *map;
   int offs = 0, count;
@@ -1072,12 +1132,8 @@ regcache::transfer_regset (const struct regset *regset,
            if (offs + slot_size > size)
              break;
 
-           if (out_buf)
-             raw_collect (regno, (gdb_byte *) out_buf + offs);
-           else
-             out_regcache->raw_supply (regno, in_buf
-                                       ? (const gdb_byte *) in_buf + offs
-                                       : NULL);
+           transfer_regset_register (out_regcache, regno, in_buf, out_buf,
+                                     slot_size, offs);
          }
       else
        {
@@ -1086,12 +1142,8 @@ regcache::transfer_regset (const struct regset *regset,
          if (offs + slot_size > size)
            return;
 
-         if (out_buf)
-           raw_collect (regnum, (gdb_byte *) out_buf + offs);
-         else
-           out_regcache->raw_supply (regnum, in_buf
-                                     ? (const gdb_byte *) in_buf + offs
-                                     : NULL);
+         transfer_regset_register (out_regcache, regnum, in_buf, out_buf,
+                                   slot_size, offs);
          return;
        }
     }
@@ -1106,14 +1158,14 @@ regcache_supply_regset (const struct regset *regset,
                        struct regcache *regcache,
                        int regnum, const void *buf, size_t size)
 {
-  regcache->supply_regset (regset, regnum, buf, size);
+  regcache->supply_regset (regset, regnum, (const gdb_byte *) buf, size);
 }
 
 void
 regcache::supply_regset (const struct regset *regset,
                         int regnum, const void *buf, size_t size)
 {
-  transfer_regset (regset, this, regnum, buf, NULL, size);
+  transfer_regset (regset, this, regnum, (const gdb_byte *) buf, nullptr, size);
 }
 
 /* Collect register REGNUM from REGCACHE to BUF, using the register
@@ -1125,16 +1177,30 @@ regcache_collect_regset (const struct regset *regset,
                         const struct regcache *regcache,
                         int regnum, void *buf, size_t size)
 {
-  regcache->collect_regset (regset, regnum, buf, size);
+  regcache->collect_regset (regset, regnum, (gdb_byte *) buf, size);
 }
 
 void
 regcache::collect_regset (const struct regset *regset,
                         int regnum, void *buf, size_t size) const
 {
-  transfer_regset (regset, NULL, regnum, NULL, buf, size);
+  transfer_regset (regset, nullptr, regnum, nullptr, (gdb_byte *) buf, size);
 }
 
+/* See common/common-regcache.h.  */
+
+bool
+reg_buffer::raw_compare (int regnum, const void *buf, int offset) const
+{
+  gdb_assert (buf != NULL);
+  assert_regnum (regnum);
+
+  const char *regbuf = (const char *) register_buffer (regnum);
+  size_t size = m_descr->sizeof_register[regnum];
+  gdb_assert (size >= offset);
+
+  return (memcmp (buf, regbuf + offset, size - offset) == 0);
+}
 
 /* Special handling for register PC.  */
 
@@ -1497,7 +1563,7 @@ cooked_read_test (struct gdbarch *gdbarch)
 {
   /* Error out if debugging something, because we're going to push the
      test target, which would pop any existing target.  */
-  if (target_stack->to_stratum >= process_stratum)
+  if (current_top_target ()->to_stratum >= process_stratum)
     error (_("target already pushed"));
 
   /* Create a mock environment.  An inferior with a thread, with a
@@ -1671,7 +1737,7 @@ cooked_write_test (struct gdbarch *gdbarch)
 {
   /* Error out if debugging something, because we're going to push the
      test target, which would pop any existing target.  */
-  if (target_stack->to_stratum >= process_stratum)
+  if (current_top_target ()->to_stratum >= process_stratum)
     error (_("target already pushed"));
 
   /* Create a mock environment.  A process_stratum target pushed.  */
This page took 0.031619 seconds and 4 git commands to generate.