public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aoliva/heads/testme)] hardcfr: check excess visited bits
@ 2023-10-20  3:48 Alexandre Oliva
  0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2023-10-20  3:48 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:d68f7b46d9555ab4e9fb1aa683ea19036eaaaf69

commit d68f7b46d9555ab4e9fb1aa683ea19036eaaaf69
Author: Alexandre Oliva <oliva@gnu.org>
Date:   Thu Oct 19 02:53:17 2023 -0300

    hardcfr: check excess visited bits

Diff:
---
 gcc/gimple-harden-control-flow.cc |  8 +++++-
 libgcc/hardcfr.c                  | 51 +++++++++++++++++++++++++++------------
 2 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/gcc/gimple-harden-control-flow.cc b/gcc/gimple-harden-control-flow.cc
index 05878c978433..5c28fd07f332 100644
--- a/gcc/gimple-harden-control-flow.cc
+++ b/gcc/gimple-harden-control-flow.cc
@@ -493,7 +493,13 @@ class rt_bb_visited
     if (bitp)
       {
 	unsigned bit = idx % vword_bits;
-	if (BITS_BIG_ENDIAN)
+	/* We don't need to adjust shifts to follow native bit
+	   endianness here, all of our uses of the CFG and visited
+	   bitmaps, whether at compile or runtime, are shifted bits on
+	   full words.  This adjustment here would require a
+	   corresponding adjustment at runtime, which would be nothing
+	   but undesirable overhead for us.  */
+	if (0 /* && BITS_BIG_ENDIAN */)
 	  bit = vword_bits - bit - 1;
 	wide_int wbit = wi::set_bit_in_zero (bit, vword_bits);
 	*bitp = wide_int_to_tree (vword_type, wbit);
diff --git a/libgcc/hardcfr.c b/libgcc/hardcfr.c
index 55f6b995f2f6..7496095b8666 100644
--- a/libgcc/hardcfr.c
+++ b/libgcc/hardcfr.c
@@ -32,7 +32,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 /* This should be kept in sync with gcc/gimple-harden-control-flow.cc.  */
 #if __CHAR_BIT__ >= 28
 # define VWORDmode __QI__
-#elif __CHHAR_BIT__ >= 14
+#elif __CHAR_BIT__ >= 14
 # define VWORDmode __HI__
 #else
 # define VWORDmode __SI__
@@ -81,6 +81,19 @@ visited_p (size_t const block, vword const *const visited)
   return (w & mask) != 0;
 }
 
+/* Check whether any VISITED bits that would correspond to blocks after BLOCKS
+   are set.  */
+static inline bool
+excess_bits_set_p (size_t const blocks, vword const *const visited)
+{
+  vword mask;
+  size_t wordidx;
+  block2mask (blocks - 1, &mask, &wordidx);
+  mask = -mask - mask;
+  vword w = visited[wordidx];
+  return (w & mask) != 0;
+}
+
 /* Read and consume a mask from **CFG_IT.  (Consume meaning advancing the
    iterator to the next word).  If the mask is zero, return FALSE.  Otherwise,
    also read and consume an index, and set *MASK and/or *WORDIDX, whichever are
@@ -195,38 +208,43 @@ __hardcfr_debug_cfg (size_t const blocks,
    */
 static inline void
 __hardcfr_check_fail (size_t const blocks ATTRIBUTE_UNUSED,
-		      vword const *const visited,
+		      vword const *const visited ATTRIBUTE_UNUSED,
 		      vword const *const cfg ATTRIBUTE_UNUSED,
 		      size_t const block ATTRIBUTE_UNUSED,
 		      int const part ATTRIBUTE_UNUSED,
 		      void const *const caller ATTRIBUTE_UNUSED)
 {
 #if HARDCFR_VERBOSE_FAIL
-  static const char *parts[] = { "preds", "succs" };
+  static const char *parts[] = { "preds", "succs", "no excess" };
 
   vword mask; size_t wordidx;
   block2mask (block, &mask, &wordidx);
+  if (part == 2)
+    mask = -mask - mask;
   __builtin_printf ("hardcfr fail at %p block %lu (%lu/0x%lx), expected %s:",
 		    caller, (unsigned long)block,
 		    (unsigned long)wordidx, (unsigned long)mask,
 		    parts[part]);
 
-  /* Skip data for previous blocks.  */
-  vword const *cfg_it = cfg;
-  for (size_t i = block; i--; )
+  if (part != 2)
     {
-      consume_seq (&cfg_it);
-      consume_seq (&cfg_it);
-    }
-  for (size_t i = part; i--; )
-    consume_seq (&cfg_it);
+      /* Skip data for previous blocks.  */
+      vword const *cfg_it = cfg;
+      for (size_t i = block; i--; )
+	{
+	  consume_seq (&cfg_it);
+	  consume_seq (&cfg_it);
+	}
+      for (size_t i = part; i--; )
+	consume_seq (&cfg_it);
 
-  while (next_pair (&cfg_it, &mask, &wordidx))
-    __builtin_printf (" (%lu/0x%lx)",
-		      (unsigned long)wordidx, (unsigned long)mask);
+      while (next_pair (&cfg_it, &mask, &wordidx))
+	__builtin_printf (" (%lu/0x%lx)",
+			  (unsigned long)wordidx, (unsigned long)mask);
+    }
 
   __builtin_printf ("\nvisited:");
-  block2mask (blocks, &mask, &wordidx);
+  block2mask (blocks - 1, &mask, &wordidx);
   for (size_t i = 0; i <= wordidx; i++)
     __builtin_printf (" (%lu/0x%lx)",
 		      (unsigned long)i, (unsigned long)visited[i]);
@@ -276,4 +294,7 @@ __hardcfr_check (size_t const blocks,
 				  __builtin_return_address (0));
 	}
     }
+  if (excess_bits_set_p (blocks, visited))
+    __hardcfr_check_fail (blocks, visited, cfg, blocks - 1, 2,
+			  __builtin_return_address (0));
 }

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] hardcfr: check excess visited bits
@ 2023-10-10  4:14 Alexandre Oliva
  0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2023-10-10  4:14 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:c16b8011e0035cee5024749ccf326456f0ab464f

commit c16b8011e0035cee5024749ccf326456f0ab464f
Author: Alexandre Oliva <oliva@gnu.org>
Date:   Sat Oct 7 01:01:22 2023 -0300

    hardcfr: check excess visited bits

Diff:
---
 gcc/gimple-harden-control-flow.cc |  8 +++++-
 libgcc/hardcfr.c                  | 51 +++++++++++++++++++++++++++------------
 2 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/gcc/gimple-harden-control-flow.cc b/gcc/gimple-harden-control-flow.cc
index 05878c97843..5c28fd07f33 100644
--- a/gcc/gimple-harden-control-flow.cc
+++ b/gcc/gimple-harden-control-flow.cc
@@ -493,7 +493,13 @@ class rt_bb_visited
     if (bitp)
       {
 	unsigned bit = idx % vword_bits;
-	if (BITS_BIG_ENDIAN)
+	/* We don't need to adjust shifts to follow native bit
+	   endianness here, all of our uses of the CFG and visited
+	   bitmaps, whether at compile or runtime, are shifted bits on
+	   full words.  This adjustment here would require a
+	   corresponding adjustment at runtime, which would be nothing
+	   but undesirable overhead for us.  */
+	if (0 /* && BITS_BIG_ENDIAN */)
 	  bit = vword_bits - bit - 1;
 	wide_int wbit = wi::set_bit_in_zero (bit, vword_bits);
 	*bitp = wide_int_to_tree (vword_type, wbit);
diff --git a/libgcc/hardcfr.c b/libgcc/hardcfr.c
index 55f6b995f2f..7496095b866 100644
--- a/libgcc/hardcfr.c
+++ b/libgcc/hardcfr.c
@@ -32,7 +32,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 /* This should be kept in sync with gcc/gimple-harden-control-flow.cc.  */
 #if __CHAR_BIT__ >= 28
 # define VWORDmode __QI__
-#elif __CHHAR_BIT__ >= 14
+#elif __CHAR_BIT__ >= 14
 # define VWORDmode __HI__
 #else
 # define VWORDmode __SI__
@@ -81,6 +81,19 @@ visited_p (size_t const block, vword const *const visited)
   return (w & mask) != 0;
 }
 
+/* Check whether any VISITED bits that would correspond to blocks after BLOCKS
+   are set.  */
+static inline bool
+excess_bits_set_p (size_t const blocks, vword const *const visited)
+{
+  vword mask;
+  size_t wordidx;
+  block2mask (blocks - 1, &mask, &wordidx);
+  mask = -mask - mask;
+  vword w = visited[wordidx];
+  return (w & mask) != 0;
+}
+
 /* Read and consume a mask from **CFG_IT.  (Consume meaning advancing the
    iterator to the next word).  If the mask is zero, return FALSE.  Otherwise,
    also read and consume an index, and set *MASK and/or *WORDIDX, whichever are
@@ -195,38 +208,43 @@ __hardcfr_debug_cfg (size_t const blocks,
    */
 static inline void
 __hardcfr_check_fail (size_t const blocks ATTRIBUTE_UNUSED,
-		      vword const *const visited,
+		      vword const *const visited ATTRIBUTE_UNUSED,
 		      vword const *const cfg ATTRIBUTE_UNUSED,
 		      size_t const block ATTRIBUTE_UNUSED,
 		      int const part ATTRIBUTE_UNUSED,
 		      void const *const caller ATTRIBUTE_UNUSED)
 {
 #if HARDCFR_VERBOSE_FAIL
-  static const char *parts[] = { "preds", "succs" };
+  static const char *parts[] = { "preds", "succs", "no excess" };
 
   vword mask; size_t wordidx;
   block2mask (block, &mask, &wordidx);
+  if (part == 2)
+    mask = -mask - mask;
   __builtin_printf ("hardcfr fail at %p block %lu (%lu/0x%lx), expected %s:",
 		    caller, (unsigned long)block,
 		    (unsigned long)wordidx, (unsigned long)mask,
 		    parts[part]);
 
-  /* Skip data for previous blocks.  */
-  vword const *cfg_it = cfg;
-  for (size_t i = block; i--; )
+  if (part != 2)
     {
-      consume_seq (&cfg_it);
-      consume_seq (&cfg_it);
-    }
-  for (size_t i = part; i--; )
-    consume_seq (&cfg_it);
+      /* Skip data for previous blocks.  */
+      vword const *cfg_it = cfg;
+      for (size_t i = block; i--; )
+	{
+	  consume_seq (&cfg_it);
+	  consume_seq (&cfg_it);
+	}
+      for (size_t i = part; i--; )
+	consume_seq (&cfg_it);
 
-  while (next_pair (&cfg_it, &mask, &wordidx))
-    __builtin_printf (" (%lu/0x%lx)",
-		      (unsigned long)wordidx, (unsigned long)mask);
+      while (next_pair (&cfg_it, &mask, &wordidx))
+	__builtin_printf (" (%lu/0x%lx)",
+			  (unsigned long)wordidx, (unsigned long)mask);
+    }
 
   __builtin_printf ("\nvisited:");
-  block2mask (blocks, &mask, &wordidx);
+  block2mask (blocks - 1, &mask, &wordidx);
   for (size_t i = 0; i <= wordidx; i++)
     __builtin_printf (" (%lu/0x%lx)",
 		      (unsigned long)i, (unsigned long)visited[i]);
@@ -276,4 +294,7 @@ __hardcfr_check (size_t const blocks,
 				  __builtin_return_address (0));
 	}
     }
+  if (excess_bits_set_p (blocks, visited))
+    __hardcfr_check_fail (blocks, visited, cfg, blocks - 1, 2,
+			  __builtin_return_address (0));
 }

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] hardcfr: check excess visited bits
@ 2023-10-07  7:36 Alexandre Oliva
  0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2023-10-07  7:36 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:4b085cd226e0e81cbc07a866b390d44b8f1dc7a8

commit 4b085cd226e0e81cbc07a866b390d44b8f1dc7a8
Author: Alexandre Oliva <oliva@gnu.org>
Date:   Sat Oct 7 01:01:22 2023 -0300

    hardcfr: check excess visited bits

Diff:
---
 gcc/gimple-harden-control-flow.cc |  8 +++++-
 libgcc/hardcfr.c                  | 51 +++++++++++++++++++++++++++------------
 2 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/gcc/gimple-harden-control-flow.cc b/gcc/gimple-harden-control-flow.cc
index 05878c97843..5c28fd07f33 100644
--- a/gcc/gimple-harden-control-flow.cc
+++ b/gcc/gimple-harden-control-flow.cc
@@ -493,7 +493,13 @@ class rt_bb_visited
     if (bitp)
       {
 	unsigned bit = idx % vword_bits;
-	if (BITS_BIG_ENDIAN)
+	/* We don't need to adjust shifts to follow native bit
+	   endianness here, all of our uses of the CFG and visited
+	   bitmaps, whether at compile or runtime, are shifted bits on
+	   full words.  This adjustment here would require a
+	   corresponding adjustment at runtime, which would be nothing
+	   but undesirable overhead for us.  */
+	if (0 /* && BITS_BIG_ENDIAN */)
 	  bit = vword_bits - bit - 1;
 	wide_int wbit = wi::set_bit_in_zero (bit, vword_bits);
 	*bitp = wide_int_to_tree (vword_type, wbit);
diff --git a/libgcc/hardcfr.c b/libgcc/hardcfr.c
index 55f6b995f2f..a1c8d34e790 100644
--- a/libgcc/hardcfr.c
+++ b/libgcc/hardcfr.c
@@ -32,7 +32,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 /* This should be kept in sync with gcc/gimple-harden-control-flow.cc.  */
 #if __CHAR_BIT__ >= 28
 # define VWORDmode __QI__
-#elif __CHHAR_BIT__ >= 14
+#elif __CHAR_BIT__ >= 14
 # define VWORDmode __HI__
 #else
 # define VWORDmode __SI__
@@ -81,6 +81,19 @@ visited_p (size_t const block, vword const *const visited)
   return (w & mask) != 0;
 }
 
+/* Check whether any VISITED bits that would correspond to blocks after BLOCKS
+   are set.  */
+static inline bool
+excess_bits_set_p (size_t const blocks, vword const *const visited)
+{
+  vword mask;
+  size_t wordidx;
+  block2mask (blocks, &mask, &wordidx);
+  mask = -mask - mask;
+  vword w = visited[wordidx];
+  return (w & mask) != 0;
+}
+
 /* Read and consume a mask from **CFG_IT.  (Consume meaning advancing the
    iterator to the next word).  If the mask is zero, return FALSE.  Otherwise,
    also read and consume an index, and set *MASK and/or *WORDIDX, whichever are
@@ -195,38 +208,43 @@ __hardcfr_debug_cfg (size_t const blocks,
    */
 static inline void
 __hardcfr_check_fail (size_t const blocks ATTRIBUTE_UNUSED,
-		      vword const *const visited,
+		      vword const *const visited ATTRIBUTE_UNUSED,
 		      vword const *const cfg ATTRIBUTE_UNUSED,
 		      size_t const block ATTRIBUTE_UNUSED,
 		      int const part ATTRIBUTE_UNUSED,
 		      void const *const caller ATTRIBUTE_UNUSED)
 {
 #if HARDCFR_VERBOSE_FAIL
-  static const char *parts[] = { "preds", "succs" };
+  static const char *parts[] = { "preds", "succs", "no excess" };
 
   vword mask; size_t wordidx;
   block2mask (block, &mask, &wordidx);
+  if (part == 2)
+    mask = -mask - mask;
   __builtin_printf ("hardcfr fail at %p block %lu (%lu/0x%lx), expected %s:",
 		    caller, (unsigned long)block,
 		    (unsigned long)wordidx, (unsigned long)mask,
 		    parts[part]);
 
-  /* Skip data for previous blocks.  */
-  vword const *cfg_it = cfg;
-  for (size_t i = block; i--; )
+  if (part != 2)
     {
-      consume_seq (&cfg_it);
-      consume_seq (&cfg_it);
-    }
-  for (size_t i = part; i--; )
-    consume_seq (&cfg_it);
+      /* Skip data for previous blocks.  */
+      vword const *cfg_it = cfg;
+      for (size_t i = block; i--; )
+	{
+	  consume_seq (&cfg_it);
+	  consume_seq (&cfg_it);
+	}
+      for (size_t i = part; i--; )
+	consume_seq (&cfg_it);
 
-  while (next_pair (&cfg_it, &mask, &wordidx))
-    __builtin_printf (" (%lu/0x%lx)",
-		      (unsigned long)wordidx, (unsigned long)mask);
+      while (next_pair (&cfg_it, &mask, &wordidx))
+	__builtin_printf (" (%lu/0x%lx)",
+			  (unsigned long)wordidx, (unsigned long)mask);
+    }
 
   __builtin_printf ("\nvisited:");
-  block2mask (blocks, &mask, &wordidx);
+  block2mask (blocks - 1, &mask, &wordidx);
   for (size_t i = 0; i <= wordidx; i++)
     __builtin_printf (" (%lu/0x%lx)",
 		      (unsigned long)i, (unsigned long)visited[i]);
@@ -276,4 +294,7 @@ __hardcfr_check (size_t const blocks,
 				  __builtin_return_address (0));
 	}
     }
+  if (excess_bits_set_p (blocks, visited))
+    __hardcfr_check_fail (blocks, visited, cfg, blocks - 1, 2,
+			  __builtin_return_address (0));
 }

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] hardcfr: check excess visited bits
@ 2023-10-07  4:06 Alexandre Oliva
  0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2023-10-07  4:06 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a92570476e7eb8003134b7b1324660f71bb56bc4

commit a92570476e7eb8003134b7b1324660f71bb56bc4
Author: Alexandre Oliva <oliva@gnu.org>
Date:   Sat Oct 7 01:01:22 2023 -0300

    hardcfr: check excess visited bits

Diff:
---
 gcc/gimple-harden-control-flow.cc |  8 +++++++-
 libgcc/hardcfr.c                  | 20 +++++++++++++++++++-
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/gcc/gimple-harden-control-flow.cc b/gcc/gimple-harden-control-flow.cc
index 05878c97843..5c28fd07f33 100644
--- a/gcc/gimple-harden-control-flow.cc
+++ b/gcc/gimple-harden-control-flow.cc
@@ -493,7 +493,13 @@ class rt_bb_visited
     if (bitp)
       {
 	unsigned bit = idx % vword_bits;
-	if (BITS_BIG_ENDIAN)
+	/* We don't need to adjust shifts to follow native bit
+	   endianness here, all of our uses of the CFG and visited
+	   bitmaps, whether at compile or runtime, are shifted bits on
+	   full words.  This adjustment here would require a
+	   corresponding adjustment at runtime, which would be nothing
+	   but undesirable overhead for us.  */
+	if (0 /* && BITS_BIG_ENDIAN */)
 	  bit = vword_bits - bit - 1;
 	wide_int wbit = wi::set_bit_in_zero (bit, vword_bits);
 	*bitp = wide_int_to_tree (vword_type, wbit);
diff --git a/libgcc/hardcfr.c b/libgcc/hardcfr.c
index 55f6b995f2f..b7ce7dd15f1 100644
--- a/libgcc/hardcfr.c
+++ b/libgcc/hardcfr.c
@@ -81,6 +81,19 @@ visited_p (size_t const block, vword const *const visited)
   return (w & mask) != 0;
 }
 
+/* Check whether any VISITED bits that would correspond to blocks after BLOCKS
+   are set.  */
+static inline bool
+excess_bits_set_p (size_t const blocks, vword const *const visited)
+{
+  vword mask;
+  size_t wordidx;
+  block2mask (block, &mask, &wordidx);
+  mask = -mask - mask;
+  vword w = visited[wordidx];
+  return (w & mask) != 0;
+}
+
 /* Read and consume a mask from **CFG_IT.  (Consume meaning advancing the
    iterator to the next word).  If the mask is zero, return FALSE.  Otherwise,
    also read and consume an index, and set *MASK and/or *WORDIDX, whichever are
@@ -202,10 +215,12 @@ __hardcfr_check_fail (size_t const blocks ATTRIBUTE_UNUSED,
 		      void const *const caller ATTRIBUTE_UNUSED)
 {
 #if HARDCFR_VERBOSE_FAIL
-  static const char *parts[] = { "preds", "succs" };
+  static const char *parts[] = { "preds", "succs", "excess" };
 
   vword mask; size_t wordidx;
   block2mask (block, &mask, &wordidx);
+  if (parts == 2)
+    mask = -mask - mask;
   __builtin_printf ("hardcfr fail at %p block %lu (%lu/0x%lx), expected %s:",
 		    caller, (unsigned long)block,
 		    (unsigned long)wordidx, (unsigned long)mask,
@@ -276,4 +291,7 @@ __hardcfr_check (size_t const blocks,
 				  __builtin_return_address (0));
 	}
     }
+  if (excess_bits_set_p (blocks, visited))
+    __hardcfr_check_fail (blocks, visited, cfg, blocks - 1, 2,
+			  __builtin_return_address (0));
 }

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-10-20  3:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-20  3:48 [gcc(refs/users/aoliva/heads/testme)] hardcfr: check excess visited bits Alexandre Oliva
  -- strict thread matches above, loose matches on Subject: below --
2023-10-10  4:14 Alexandre Oliva
2023-10-07  7:36 Alexandre Oliva
2023-10-07  4:06 Alexandre Oliva

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).