aboutsummaryrefslogtreecommitdiff
path: root/gcc/crc-verification.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/crc-verification.h')
-rw-r--r--gcc/crc-verification.h162
1 files changed, 162 insertions, 0 deletions
diff --git a/gcc/crc-verification.h b/gcc/crc-verification.h
new file mode 100644
index 0000000..d802f4d
--- /dev/null
+++ b/gcc/crc-verification.h
@@ -0,0 +1,162 @@
+/* Execute symbolically all paths of the loop.
+ Copyright (C) 2022-2024 Free Software Foundation, Inc.
+ Contributed by Mariam Arutunian <mariamarutunian@gmail.com>
+
+This file is part of GCC.
+
+GCC 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, or (at your option) any later
+version.
+
+GCC 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 GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_CRC_VERIFICATION
+#define GCC_CRC_VERIFICATION
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "cfgloop.h"
+#include "sym-exec/sym-exec-state.h"
+
+class crc_symbolic_execution {
+
+ private:
+ /* A vector of states to keep the current state of each executed path. */
+ vec<state *> m_states;
+
+ /* A vector of final states
+ to keep the returned_value and path conditions. */
+ vec<state *> m_final_states;
+
+ /* Potential CRC loop, which must be executed symbolically,
+ to check whether it calculates CRC. */
+ class loop *m_crc_loop;
+
+ /* Output CRC from the last block of the loop. */
+ gphi *m_output_crc;
+
+ /* Indicates whether the loop execution brought to loop exit.
+ I.e. the condition of the loop is false. */
+ bool m_is_last_iteration;
+
+ /* Returns true if the variable is used outside the loop.
+ Otherwise, returns false. */
+ bool is_used_outside_the_loop (tree);
+
+ /* Add next basic blocks of the conditional block
+ for the execution path into the stack.
+ If the condition depends on symbolic values, keep both edges.
+ If the condition is true, keep true edge, else - false edge.
+ Returns true if addition succeed. Otherwise - false. */
+ bool add_next_bbs (basic_block, state *, auto_vec<edge> &);
+
+ /* Keep conditions depending on symbolic variables in the states. */
+ static bool add_condition (const gcond *, state *, state *);
+
+ /* The function adds E edge into the STACK if it doesn't have an immediate
+ successor back edge.
+
+ When loop counter is checked in the if condition,
+ we mustn't continue on real path as we want to stop the execution before
+ the second iteration. */
+ bool add_edge (edge, auto_vec<edge> &);
+
+ /* Create new state for true and false branch.
+ Keep conditions in new created states. */
+ bool resolve_condition (const gcond *, auto_vec<edge> &);
+
+ /* If final states are less than two, adds new FINAL_STATE and returns true.
+ Otherwise, returns false.
+ In CRC cases we detect may not occur more than two final states. */
+ bool add_final_state (state *);
+
+ /* Keep the state of the executed path in final states. */
+ bool keep_states ();
+
+ bool execute_assign_statement (const gassign *);
+
+ /* Execute gimple statements of the basic block.
+ Keeping values of variables in the state. */
+ bool execute_bb_gimple_statements (basic_block, auto_vec<edge> &);
+
+ /* Assign values of phi instruction to its result.
+ Keep updated values in the state. */
+ bool execute_bb_phi_statements (basic_block, edge);
+
+ /* Execute all statements of the basic block.
+ Keeping values of variables in the state. */
+ bool execute_bb_statements (basic_block, edge, auto_vec<edge> &);
+
+ /* Create initial state of the loop's header BB variables which have constant
+ values.
+ If it is the first iteration of the loop, initialise variables with the
+ initial values, otherwise initialise the variable with the value calculated
+ during the previous execution. */
+ state *create_initial_state (class loop *);
+
+/* Traverse function fun's all paths from the first basic block to the last.
+ Each time iterate loops only once.
+ Symbolically execute statements of each path. */
+ bool traverse_function (function *);
+
+ /* Execute the loop, which calculates crc with initial values,
+ to calculate the polynomial. */
+ bool execute_crc_loop (gphi *, gphi *, bool);
+
+ public:
+
+ /* Returns calculated polynomial by executing the loop
+ with concrete values.
+ First value of the pair is the tree containing the value of the polynomial,
+ second is the calculated polynomial. The pair may contain nullptr. */
+ std::pair <tree, value *>
+ extract_polynomial (gphi *, gphi *, tree, bool);
+
+ /* Symbolically execute the CRC loop, doing one iteration. */
+ bool symb_execute_crc_loop ();
+
+ const vec<state *> &get_final_states ()
+ {
+ return m_final_states;
+ }
+
+ bool is_last_iteration ()
+ {
+ return m_is_last_iteration;
+ }
+
+ crc_symbolic_execution (class loop *loop, gphi * output_crc) :
+ m_crc_loop (loop), m_output_crc (output_crc), m_is_last_iteration (false)
+ {
+ /* Reserve memory for the vectors of states. */
+ int max_states = 2;
+ m_states.create (max_states);
+ m_final_states.create (max_states);
+ }
+
+ ~crc_symbolic_execution ()
+ {
+ /* Free memory. */
+ state::clear_states (&m_states);
+ state::clear_states (&m_final_states);
+ }
+};
+
+
+/**************************** LFSR MATCHING *********************************/
+
+/* Returns true if all states match the LFSR, otherwise - false. */
+bool all_states_match_lfsr (value *, bool, tree, const vec<state *> &);
+
+
+#endif //GCC_CRC_VERIFICATION