From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2140) id 2F64D3858436; Fri, 20 Oct 2023 03:48:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2F64D3858436 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1697773707; bh=o7/E5qISOrylLWJb5GIq41azfN1uHbFn6oWDRu2toHg=; h=From:To:Subject:Date:From; b=aOpNut897KvU5ZBggDGL0px6PqkRqqRCD8z1HaxHgGE5+h0ZjGcLIiufbYGrpEjEo i2LQrZqyBd6Oe5taHIJM3Gwe3ewW5k5OnqMc4IK+KieE3P1oQT2VwrmxLqBHZMGG7B 2yQ+ND3K9mHO4Uy4rOXLyn1KgQ4oIWhRASIF6YuM= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Alexandre Oliva To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/aoliva/heads/testme)] hardcfr: check excess visited bits X-Act-Checkin: gcc X-Git-Author: Alexandre Oliva X-Git-Refname: refs/users/aoliva/heads/testme X-Git-Oldrev: 3537621375e746a5eb46847bd832362ec484cfe2 X-Git-Newrev: d68f7b46d9555ab4e9fb1aa683ea19036eaaaf69 Message-Id: <20231020034827.2F64D3858436@sourceware.org> Date: Fri, 20 Oct 2023 03:48:27 +0000 (GMT) List-Id: https://gcc.gnu.org/g:d68f7b46d9555ab4e9fb1aa683ea19036eaaaf69 commit d68f7b46d9555ab4e9fb1aa683ea19036eaaaf69 Author: Alexandre Oliva 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)); }