blob: 7aa311745efc356aea766d4e9be02abe1e235646 [file] [log] [blame]
/* Every class defined here represents a single bit value of a variable.
Every variable will be represented as a vector of these classes which later
will be used for bit-level symbolic execution.
Copyright (C) 2022-2025 Free Software Foundation, Inc.
Contributed by Matevos Mehrabyan <matevosmehrabyan@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 SYM_EXEC_EXPRESSION_H
#define SYM_EXEC_EXPRESSION_H
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "hwint.h"
#include "gimple-pretty-print.h"
#include "is-a.h"
#include "vec.h"
#include "hash-map.h"
#include "hash-set.h"
#include "stddef.h"
/* Enum used for identifying the class of the bit. */
enum value_type {
SYMBOLIC_BIT,
BIT,
BIT_XOR_EXPRESSION,
BIT_AND_EXPRESSION,
BIT_OR_EXPRESSION,
BIT_COMPLEMENT_EXPRESSION,
SHIFT_RIGHT_EXPRESSION,
SHIFT_LEFT_EXPRESSION,
ADD_EXPRESSION,
SUB_EXPRESSION,
BIT_CONDITION
};
/* Base class for single bit value. */
class value_bit {
protected:
/* This will help us to understand where is moved the bit
from its initial position. */
const size_t m_index;
/* Type of the bit. Used by type checkers. */
value_type m_type;
public:
/* Default constructor. Sets m_index 0. */
value_bit () : m_index (0)
{};
/* Constructor that sets m_index to the specified value. */
value_bit (size_t i) : m_index (i)
{};
/* Copy constructor for value_bit. */
value_bit (const value_bit &val) : m_index (val.m_index)
{};
/* Returns the bit's initial index in bit-vector. */
size_t get_index () const;
/* Returns type of the bit. */
value_type get_type () const;
/* This will support deep copy of objects' values. */
virtual value_bit *copy () const = 0;
/* Prints the bit. Inherited classes must implement it. */
virtual void print () = 0;
/* Destructor. */
virtual ~value_bit () = default;
};
/* Represents value of a single bit of symbolic marked variables. */
class symbolic_bit : public value_bit {
/* The Origin of the bit. */
tree m_origin = nullptr;
public:
/* Constructor that sets the bit's initial position and its origin. */
symbolic_bit (size_t i, tree orig);
/* Copy constructor for symbolic_bit. */
symbolic_bit (const symbolic_bit &sym_bit) : symbolic_bit (sym_bit.m_index,
sym_bit.m_origin)
{};
/* Returns a copy of the bit. */
value_bit *copy () const;
/* Prints the bit. */
void print ();
/* Returns the origin of the bit, to whom it belongs. */
tree get_origin ();
};
/* Represents value of a single bit. */
class bit : public value_bit {
private:
/* This is the value of a bit. It must be either 1 or 0. */
unsigned char m_val = 0;
public:
/* Constructor that sets m_val to the specified value. */
bit (unsigned char i);
/* Copy constructor for bit. */
bit (const bit &b) : bit (b.m_val)
{};
/* Returns the value of the bit. */
unsigned char get_val () const;
/* Sets the value of the bit. */
void set_val (unsigned char new_val);
/* Return a copy of the bit. */
value_bit *copy () const;
/* Prints the bit. */
void print ();
};
/* Bit-level base expression class. In general expressions consist of
two operands. Here we named them m_left and m_right. */
class bit_expression : public value_bit {
protected:
/* The bit left to the expression sign. */
value_bit *m_left = nullptr;
/* The bit right to the expression sign. */
value_bit *m_right = nullptr;
/* Copies the given expression to it by copying
the left and right operands. */
void copy (const bit_expression *expr);
/* Depending on the expression, prints its sign. */
virtual void print_expr_sign ();
public:
/* Returns left operand of the expression. */
value_bit *get_left ();
/* Returns right operand of the expression. */
value_bit *get_right ();
/* Destructor for bit_expression. */
~bit_expression ();
/* Sets left operand of the expression. */
void set_left (value_bit *expr);
/* Sets right operand of the expression. */
void set_right (value_bit *expr);
/* Returns a deep copy of the expression. */
value_bit *copy () const = 0;
/* Prints the expression. */
void print ();
};
/* Bit-level XOR expression. XOR operation on two variables (when one of
them is symbolic) can be represented by XOR operations on
each of their bits. */
class bit_xor_expression : public bit_expression {
public:
/* Constructor that sets the left and right side bits
of the bit_xor_expression sign. */
bit_xor_expression (value_bit *left, value_bit *right);
/* Copy constructor for bit_xor_expression. */
bit_xor_expression (const bit_xor_expression &expr);
/* Returns a copy of the expression. */
value_bit *copy () const;
};
/* Bit-level AND expression. AND operation on two variables (when one of
them is symbolic) can be represented by AND operations on
each of their bits. */
class bit_and_expression : public bit_expression {
public:
/* Constructor that sets the left and right side bits
of the bit_and_expression sign. */
bit_and_expression (value_bit *left, value_bit *right);
/* Copy constructor for bit_and_expression. */
bit_and_expression (const bit_and_expression &expr);
/* Returns a copy of the expression. */
value_bit *copy () const;
};
/* Bit-level OR expression. OR operation on two variables (when one of
them is symbolic) can be represented by OR operations on
each of their bits. */
class bit_or_expression : public bit_expression {
public:
/* Constructor that sets the left and right side bits
of the bit_or_expression sign. */
bit_or_expression (value_bit *left, value_bit *right);
/* Copy constructor for bit_or_expression. */
bit_or_expression (const bit_or_expression &expr);
/* Returns a copy of the expression. */
value_bit *copy () const;
};
/* SHIFT_RIGHT expression. Result must be stored bit by bit. */
class shift_right_expression : public bit_expression {
public:
/* Constructor that sets the left and right side bits
of the shift_right_expression sign. */
shift_right_expression (value_bit *left, value_bit *right);
/* Copy constructor for shift_right_expression. */
shift_right_expression (const shift_right_expression &expr);
/* Returns a copy of the expression. */
value_bit *copy () const;
};
/* SHIFT_LEFT expression. Result must be stored bit by bit. */
class shift_left_expression : public bit_expression {
public:
/* Constructor that sets the left and right side bits
of the shift_left_expression sign. */
shift_left_expression (value_bit *left, value_bit *right);
/* Copy constructor for shift_left_expression. */
shift_left_expression (const shift_left_expression &expr);
/* Returns a copy of the expression. */
value_bit *copy () const;
};
/* ADD expression. Result must be stored bit by bit. */
class add_expression : public bit_expression {
public:
/* Constructor that sets the left and right side bits
of the add_expression sign. */
add_expression (value_bit *left, value_bit *right);
/* Copy constructor for add_expression. */
add_expression (const add_expression &expr);
/* Returns a copy of the expression. */
value_bit *copy () const;
};
/* SUB expression. Result must be stored bit by bit. */
class sub_expression : public bit_expression {
public:
/* Constructor that sets the left and right side bits
of the sub_expression sign. */
sub_expression (value_bit *left, value_bit *right);
/* Copy constructor for sub_expression. */
sub_expression (const sub_expression &expr);
/* Returns a copy of the expression. */
value_bit *copy () const;
};
/* Bit-level negation expression. */
class bit_complement_expression : public bit_expression {
public:
/* Constructor that sets the left and right side bits
of the bit_complement_expression sign. */
bit_complement_expression (value_bit *right);
/* Copy constructor for bit_complement_expression. */
bit_complement_expression (const bit_complement_expression &expr);
/* Returns a copy of the expression. */
value_bit *copy () const;
/* Prints the expression. */
void print ();
};
#endif /* SYM_EXEC_EXPRESSION_H. */