CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
259 lines
8.6 KiB
C++
259 lines
8.6 KiB
C++
/*
|
|
* See the dyninst/COPYRIGHT file for copyright information.
|
|
*
|
|
* We provide the Paradyn Tools (below described as "Paradyn")
|
|
* on an AS IS basis, and do not warrant its validity or performance.
|
|
* We reserve the right to update, modify, or discontinue this
|
|
* software at any time. We shall have no obligation to supply such
|
|
* updates or modifications or any other form of support to you.
|
|
*
|
|
* By your use of Paradyn, you understand and agree that we (or any
|
|
* other person or entity with proprietary rights in Paradyn) are
|
|
* under no obligation to provide either maintenance services,
|
|
* update services, notices of latent defects, or correction of
|
|
* defects for Paradyn.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#if !defined(AST_H)
|
|
#define AST_H
|
|
|
|
#include <assert.h>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <iostream>
|
|
#include <map>
|
|
#include "util.h"
|
|
#include "dyncompat/enable_shared_from_this.hpp"
|
|
|
|
namespace Dyninst {
|
|
|
|
// We fully template the three types of nodes we have so that
|
|
// users can specify their own. This basically makes the AST
|
|
// a fully generic class.
|
|
//
|
|
// TODO: do we want Variable and Constant to be different classes?
|
|
// I'm using the Absloc case as the basis here; EAX and '5' are
|
|
// very different things...
|
|
//
|
|
// Possible fourth template type: Type
|
|
// though I'm currently arguing that Type is an artifact of the
|
|
// Eval method you apply here.
|
|
// ... and are Eval methods independent of Operation/Variable/Constant?
|
|
// I think they are...x
|
|
|
|
class ASTVisitor;
|
|
|
|
// For this to work, the ASTVisitor has to have a virtual
|
|
// visit() method for every instantiation of an AST-typed
|
|
// class. Yes, this means that if you add an AST class
|
|
// somewhere else you have to come back and put it in here.
|
|
// Well, if you want to run a visitor over it, that is.
|
|
class AST;
|
|
|
|
// SymEval...
|
|
namespace DataflowAPI {
|
|
class BottomAST;
|
|
class ConstantAST;
|
|
class VariableAST;
|
|
class RoseAST;
|
|
}
|
|
// Stack analysis...
|
|
class StackAST;
|
|
|
|
// InsnAPI...
|
|
|
|
// Codegen...
|
|
|
|
// Concolic execution...
|
|
class InputVariableAST;
|
|
class ReferenceAST;
|
|
class StpAST;
|
|
class YicesAST;
|
|
class SemanticsAST;
|
|
|
|
#define DEF_AST_LEAF_TYPE(name, type) \
|
|
class name : public AST { \
|
|
public: \
|
|
typedef dyncompat::shared_ptr<name> Ptr; \
|
|
static Ptr create(type t) { return Ptr(new name(t)); } \
|
|
virtual ~name() {} \
|
|
virtual const std::string format() const { \
|
|
std::stringstream ret; \
|
|
ret << "<" << t_ << ">"; \
|
|
return ret.str(); \
|
|
} \
|
|
virtual AST::Ptr accept(ASTVisitor *v) { return v->visit(this); } \
|
|
virtual ID getID() const { return V_##name; } \
|
|
static Ptr convert(AST::Ptr a) { \
|
|
return ((a->getID() == V_##name) ? dyncompat::static_pointer_cast<name>(a) : Ptr()); \
|
|
} \
|
|
const type &val() const { return t_; } \
|
|
private: \
|
|
name(type t) : t_(t) {} \
|
|
virtual bool isStrictEqual(const AST &rhs) const { \
|
|
const name &other(dynamic_cast<const name&>(rhs)); \
|
|
return t_ == other.t_; \
|
|
} \
|
|
const type t_; \
|
|
} \
|
|
|
|
#define DEF_AST_INTERNAL_TYPE(name, type) \
|
|
class name : public AST { \
|
|
public: \
|
|
typedef dyncompat::shared_ptr<name> Ptr; \
|
|
virtual ~name() {} \
|
|
static Ptr create(type t, AST::Ptr a) { return Ptr(new name(t, a)); } \
|
|
static Ptr create(type t, AST::Ptr a, AST::Ptr b) { return Ptr(new name(t, a, b)); } \
|
|
static Ptr create(type t, AST::Ptr a, AST::Ptr b, AST::Ptr c) { return Ptr(new name(t, a, b, c)); } \
|
|
static Ptr create(type t, Children c) { return Ptr(new name(t, c)); } \
|
|
virtual const std::string format() const { \
|
|
std::stringstream ret; \
|
|
ret << t_ << "("; \
|
|
for (Children::const_iterator i = kids_.begin(); i != kids_.end(); ++i) { \
|
|
ret << (*i)->format() << ","; \
|
|
} \
|
|
ret << ")"; \
|
|
return ret.str(); \
|
|
} \
|
|
virtual AST::Ptr child(unsigned i) const { return kids_[i];} \
|
|
virtual unsigned numChildren() const { return kids_.size();} \
|
|
virtual AST::Ptr accept(ASTVisitor *v) { return v->visit(this); } \
|
|
virtual ID getID() const { return V_##name; } \
|
|
static Ptr convert(AST::Ptr a) { \
|
|
return ((a->getID() == V_##name) ? dyncompat::static_pointer_cast<name>(a) : Ptr()); \
|
|
} \
|
|
const type &val() const { return t_; } \
|
|
void setChild(int i, AST::Ptr a) { kids_[i] = a; } \
|
|
private: \
|
|
name(type t, AST::Ptr a) : t_(t) { kids_.push_back(a); } \
|
|
name(type t, AST::Ptr a, AST::Ptr b) : t_(t) { \
|
|
kids_.push_back(a); \
|
|
kids_.push_back(b); \
|
|
} \
|
|
name(type t, AST::Ptr a, AST::Ptr b, AST::Ptr c) : t_(t) { \
|
|
kids_.push_back(a); \
|
|
kids_.push_back(b); \
|
|
kids_.push_back(c); \
|
|
} \
|
|
name(type t, Children kids) : t_(t), kids_(kids) {} \
|
|
virtual bool isStrictEqual(const AST &rhs) const { \
|
|
const name &other(dynamic_cast<const name&>(rhs)); \
|
|
if (!(t_ == other.t_)) return false; \
|
|
if (kids_.size() != other.kids_.size()) return false; \
|
|
for (unsigned i = 0; i < kids_.size(); ++i) \
|
|
if (!(kids_[i]->equals(other.kids_[i]))) return false; \
|
|
return true; \
|
|
} \
|
|
const type t_; \
|
|
Children kids_; \
|
|
} \
|
|
|
|
class COMMON_EXPORT AST : public dyncompat::enable_shared_from_this<AST> {
|
|
public:
|
|
|
|
// This is a global list of all AST types, including those that are not
|
|
// yet implemented. The format is a "V_" string prepending the class name.
|
|
// If you add an AST type you should update this list.
|
|
|
|
typedef enum {
|
|
V_AST,
|
|
// SymEval
|
|
V_BottomAST,
|
|
V_ConstantAST,
|
|
V_VariableAST,
|
|
V_RoseAST,
|
|
// Stack analysis
|
|
V_StackAST,
|
|
// Concolic execution
|
|
V_InputVariableAST,
|
|
V_ReferenceAST,
|
|
V_StpAST,
|
|
V_YicesAST,
|
|
V_SemanticsAST } ID;
|
|
|
|
typedef dyncompat::shared_ptr<AST> Ptr;
|
|
typedef std::vector<AST::Ptr> Children;
|
|
|
|
AST() {}
|
|
virtual ~AST() {}
|
|
|
|
bool operator==(const AST &rhs) const {
|
|
// make sure rhs and this have the same type
|
|
return((typeid(*this) == typeid(rhs)) && isStrictEqual(rhs));
|
|
}
|
|
|
|
virtual unsigned numChildren() const { return 0; }
|
|
|
|
virtual AST::Ptr child(unsigned) const {
|
|
assert(0);
|
|
return Ptr();
|
|
}
|
|
|
|
bool equals(AST::Ptr rhs) {
|
|
if (!rhs) return false;
|
|
return *this == (*rhs);
|
|
}
|
|
|
|
virtual const std::string format() const = 0;
|
|
|
|
// Substitutes every occurrence of a with b in
|
|
// AST in. Returns a new AST.
|
|
|
|
static AST::Ptr substitute(AST::Ptr in, AST::Ptr a, AST::Ptr b);
|
|
|
|
// breaks execution if the tree has a cycle. visited should be an empty map.
|
|
static void hasCycle(AST::Ptr in,std::map<AST::Ptr, int> &visited);
|
|
|
|
virtual ID getID() const { return V_AST; }
|
|
|
|
// VISITOR wooo....
|
|
virtual Ptr accept(ASTVisitor *);
|
|
|
|
Ptr ptr() { return shared_from_this(); }
|
|
|
|
virtual void setChild(int, AST::Ptr) {
|
|
assert(0);
|
|
}
|
|
|
|
protected:
|
|
virtual bool isStrictEqual(const AST &rhs) const = 0;
|
|
};
|
|
|
|
class COMMON_EXPORT ASTVisitor {
|
|
public:
|
|
typedef dyncompat::shared_ptr<AST> ASTPtr;
|
|
|
|
virtual ASTPtr visit(AST *) {return AST::Ptr();}
|
|
virtual ASTPtr visit(DataflowAPI::BottomAST *) {return AST::Ptr();}
|
|
virtual ASTPtr visit(DataflowAPI::ConstantAST *) {return AST::Ptr();}
|
|
virtual ASTPtr visit(DataflowAPI::VariableAST *) {return AST::Ptr();}
|
|
virtual ASTPtr visit(DataflowAPI::RoseAST *) {return AST::Ptr();}
|
|
virtual ASTPtr visit(StackAST *) {return AST::Ptr();}
|
|
virtual ASTPtr visit(InputVariableAST *) {return AST::Ptr();}
|
|
virtual ASTPtr visit(ReferenceAST *) {return AST::Ptr();}
|
|
virtual ASTPtr visit(StpAST *) {return AST::Ptr();}
|
|
virtual ASTPtr visit(YicesAST *) {return AST::Ptr();}
|
|
virtual ASTPtr visit(SemanticsAST *) {return AST::Ptr();}
|
|
|
|
virtual ~ASTVisitor() {}
|
|
};
|
|
|
|
}
|
|
#endif // AST_H
|
|
|