Files
TheRock/rocm-systems/projects/rocprofiler-systems/external/dyninst/dataflowAPI/h/SymEval.h
T
derek.holloway 7502bf64a4
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
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

383 lines
9.0 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
*/
// Stubs for now
#if !defined(SymEval_h)
#define SymEval_h
#include <map>
#include <ostream>
#include <sstream>
#include <set>
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include "Absloc.h"
#include "DynAST.h"
#include "Graph.h"
#include "util.h"
#include "Node.h"
#include "Edge.h"
class SgAsmx86Instruction;
class SgAsmExpression;
class SgAsmPowerpcInstruction;
class SgAsmOperandList;
class SgAsmx86RegisterReferenceExpression;
class SgAsmPowerpcRegisterReferenceExpression;
namespace Dyninst {
namespace ParseAPI {
class Function;
class Block;
}
namespace DataflowAPI {
// The ROSE symbolic evaluation engine wants a data type that
// is template parametrized on the number of bits in the data
// type. However, our ASTs don't have this, and a shared_ptr
// to an AST _definitely_ doesn't have it. Instead, we use
// a wrapper class (Handle) that is parametrized appropriately
// and contains a shared pointer.
// This uses a pointer to a shared pointer. This is ordinarily a really
// bad idea, but stripping the pointer part makes the compiler allocate
// all available memory and crash. No idea why.
// Define the operations used by ROSE
struct Variable {
DATAFLOW_EXPORT Variable() : reg(), addr(0) {}
DATAFLOW_EXPORT Variable(AbsRegion r) : reg(r), addr(0) {}
DATAFLOW_EXPORT Variable(AbsRegion r, Address a) : reg(r), addr(a) {}
DATAFLOW_EXPORT bool operator==(const Variable &rhs) const {
return ((rhs.addr == addr) && (rhs.reg == reg));
}
DATAFLOW_EXPORT bool operator<(const Variable &rhs) const {
if (addr < rhs.addr) return true;
if (reg < rhs.reg) return true;
return false;
}
DATAFLOW_EXPORT const std::string format() const {
std::stringstream ret;
ret << "V(" << reg;
if (addr) ret << ":" << std::hex << addr << std::dec;
ret << ")";
return ret.str();
}
friend std::ostream& operator<<(std::ostream& stream, const Variable& c)
{
stream << c.format();
return stream;
}
AbsRegion reg;
Address addr;
};
struct Constant {
DATAFLOW_EXPORT Constant() : val(0), size(0) {}
DATAFLOW_EXPORT Constant(uint64_t v) : val(v), size(0) {}
DATAFLOW_EXPORT Constant(uint64_t v, size_t s) : val(v), size(s) {}
DATAFLOW_EXPORT bool operator==(const Constant &rhs) const {
return ((rhs.val == val) && (rhs.size == size));
}
DATAFLOW_EXPORT bool operator<(const Constant &rhs) const {
if (val < rhs.val) return true;
if (size < rhs.size) return true;
return false;
}
DATAFLOW_EXPORT const std::string format() const {
std::stringstream ret;
ret << val;
if (size) {
ret << ":" << size;
}
return ret.str();
}
friend std::ostream& operator<<(std::ostream& stream, const Constant& c)
{
stream << c.format();
return stream;
}
uint64_t val;
size_t size;
};
// Define the operations used by ROSE
struct ROSEOperation {
typedef enum {
nullOp,
extractOp,
invertOp,
negateOp,
signExtendOp,
equalToZeroOp,
generateMaskOp,
LSBSetOp,
MSBSetOp,
concatOp,
andOp,
orOp,
xorOp,
addOp,
rotateLOp,
rotateROp,
shiftLOp,
shiftROp,
shiftRArithOp,
derefOp,
writeRepOp,
writeOp,
ifOp,
sMultOp,
uMultOp,
sDivOp,
sModOp,
uDivOp,
uModOp,
extendOp,
extendMSBOp
} Op;
DATAFLOW_EXPORT ROSEOperation(Op o) : op(o), size(0) {}
DATAFLOW_EXPORT ROSEOperation(Op o, size_t s) : op(o), size(s) {}
DATAFLOW_EXPORT bool operator==(const ROSEOperation &rhs) const {
return ((rhs.op == op) && (rhs.size == size));
}
DATAFLOW_EXPORT const std::string format() const {
std::stringstream ret;
ret << "<";
switch(op) {
case nullOp:
ret << "null";
break;
case extractOp:
ret << "extract";
break;
case invertOp:
ret << "invert";
break;
case negateOp:
ret << "negate";
break;
case signExtendOp:
ret << "signExtend";
break;
case equalToZeroOp:
ret << "eqZero?";
break;
case generateMaskOp:
ret << "genMask";
break;
case LSBSetOp:
ret << "LSB?";
break;
case MSBSetOp:
ret << "MSB?";
break;
case concatOp:
ret << "concat";
break;
case andOp:
ret << "and";
break;
case orOp:
ret << "or";
break;
case xorOp:
ret << "xor";
break;
case addOp:
ret << "add";
break;
case rotateLOp:
ret << "rotL";
break;
case rotateROp:
ret << "rotR";
break;
case shiftLOp:
ret << "shl";
break;
case shiftROp:
ret << "shr";
break;
case shiftRArithOp:
ret << "shrA";
break;
case derefOp:
ret << "deref";
break;
case writeRepOp:
ret << "writeRep";
break;
case writeOp:
ret << "write";
break;
case ifOp:
ret << "if";
break;
case sMultOp:
ret << "sMult";
break;
case uMultOp:
ret << "uMult";
break;
case sDivOp:
ret << "sDiv";
break;
case sModOp:
ret << "sMod";
break;
case uDivOp:
ret << "uDiv";
break;
case uModOp:
ret << "uMod";
break;
case extendOp:
ret << "ext";
break;
case extendMSBOp:
ret << "extMSB";
break;
default:
ret << " ??? ";
break;
};
if (size) {
ret << ":" << size;
}
ret << ">";
return ret.str();
}
friend std::ostream& operator<<(std::ostream& stream, const ROSEOperation& c)
{
stream << c.format();
return stream;
}
Op op;
size_t size;
};
}
}
namespace Dyninst {
namespace InstructionAPI {
class Instruction;
}
class SliceNode;
namespace DataflowAPI {
// compare assignment shared pointers by value.
typedef std::map<Assignment::Ptr, AST::Ptr, AssignmentPtrValueComp> Result_t;
DEF_AST_LEAF_TYPE(BottomAST, bool);
DEF_AST_LEAF_TYPE(ConstantAST, Constant);
DEF_AST_LEAF_TYPE(VariableAST, Variable);
DEF_AST_INTERNAL_TYPE(RoseAST, ROSEOperation);
class SymEvalPolicy;
class SymEval {
public:
typedef dyncompat::shared_ptr<SliceNode> SliceNodePtr;
typedef dyncompat::shared_ptr<InstructionAPI::Instruction> InstructionPtr;
public:
typedef enum {
FAILED,
WIDEN_NODE,
FAILED_TRANSLATION,
SKIPPED_INPUT,
SUCCESS } Retval_t;
// Return type: mapping AbsRegions to ASTs
// We then can map Assignment::AbsRegions to
// SymEval::AbsRegions and come up with the answer
// static const AST::Ptr Placeholder;
//
// Single version: hand in an Assignment, get an AST
DATAFLOW_EXPORT static std::pair<AST::Ptr, bool> expand(const Assignment::Ptr &assignment, bool applyVisitors = true);
// Hand in a set of Assignments
// get back a map of Assignments->ASTs
// We assume the assignments are prepped in the input; whatever
// they point to is discarded.
DATAFLOW_EXPORT static bool expand(Result_t &res,
std::set<InstructionAPI::Instruction> &failedInsns,
bool applyVisitors = true);
// Hand in a Graph (of SliceNodes, natch) and get back a Result;
// prior results from the Graph
// are substituted into anything that uses them.
DATAFLOW_EXPORT static Retval_t expand(Dyninst::Graph::Ptr slice, DataflowAPI::Result_t &res);
private:
// Symbolically evaluate an instruction and assign
// an AST representation to every written absloc
static bool expandInsn(const InstructionAPI::Instruction &insn,
const uint64_t addr,
Result_t &res);
static Retval_t process(SliceNodePtr ptr, Result_t &dbase, std::set<Edge::Ptr> &skipEdges);
static AST::Ptr simplifyStack(AST::Ptr ast, Address addr, ParseAPI::Function *func, ParseAPI::Block *block);
};
}
}
#endif