retdec
|
#include <symbolic_tree.h>
Public Member Functions | |
SymbolicTree (const SymbolicTree &other)=default | |
SymbolicTree (SymbolicTree &&other)=default | |
SymbolicTree & | operator= (SymbolicTree &&other) |
bool | operator== (const SymbolicTree &o) const |
bool | operator!= (const SymbolicTree &o) const |
std::string | print (unsigned indent=0) const |
bool | isNullary () const |
bool | isUnary () const |
bool | isBinary () const |
bool | isTernary () const |
bool | isNary (unsigned N) const |
unsigned | getLevel () const |
void | simplifyNode () |
void | solveMemoryLoads (FileImage *image) |
SymbolicTree * | getMaxIntValue () |
std::vector< SymbolicTree * > | getPreOrder () const |
std::vector< SymbolicTree * > | getPostOrder () const |
std::vector< SymbolicTree * > | getLevelOrder () const |
SymbolicTree (ReachingDefinitionsAnalysis *rda, llvm::Value *v, llvm::Value *u, unsigned nodeLevel, unsigned maxNodeLevel, std::map< llvm::Value *, llvm::Value * > *v2v, bool linear) | |
Static Public Member Functions | |
static SymbolicTree | PrecomputedRda (ReachingDefinitionsAnalysis &rda, llvm::Value *v, unsigned maxNodeLevel=10) |
static SymbolicTree | PrecomputedRdaWithValueMap (ReachingDefinitionsAnalysis &rda, llvm::Value *v, std::map< llvm::Value *, llvm::Value * > *val2val, unsigned maxNodeLevel=10) |
static SymbolicTree | OnDemandRda (llvm::Value *v, unsigned maxNodeLevel=10) |
static SymbolicTree | Linear (llvm::Value *v, unsigned maxNodeLevel=10) |
static void | clear () |
static bool | isVal2ValMapUsed () |
static void | setAbi (Abi *abi) |
static void | setConfig (Config *config) |
static void | setToDefaultConfiguration () |
static void | setTrackThroughAllocaLoads (bool b) |
static void | setTrackThroughGeneralRegisterLoads (bool b) |
static void | setTrackOnlyFlagRegisters (bool b) |
static void | setSimplifyAtCreation (bool b) |
static void | setNaryLimit (unsigned n) |
Public Attributes | |
llvm::Value * | value = nullptr |
llvm::Value * | user = nullptr |
std::vector< SymbolicTree > | ops |
Private Member Functions | |
void | expandNode (ReachingDefinitionsAnalysis *RDA, std::map< llvm::Value *, llvm::Value * > *val2val, unsigned maxNodeLevel, bool linear) |
void | _simplifyNode () |
void | fixLevel (unsigned level=0) |
void | _getPreOrder (std::vector< SymbolicTree * > &res) const |
void | _getPostOrder (std::vector< SymbolicTree * > &res) const |
Private Attributes | |
unsigned | _level = 1 |
Static Private Attributes | |
static Abi * | _abi = nullptr |
static Config * | _config = nullptr |
static bool | _val2valUsed = false |
static bool | _trackThroughAllocaLoads = true |
static bool | _trackThroughGeneralRegisterLoads = true |
static bool | _trackOnlyFlagRegisters = false |
static bool | _simplifyAtCreation = true |
static unsigned | _naryLimit = 3 |
Friends | |
std::ostream & | operator<< (std::ostream &out, const SymbolicTree &s) |
Tracking values through load/store operations using reaching definition analysis.
For optimization reasons, some data members of this structure are static, i.e. common for all instances. The typical usage of this class is: creation -> simplification -> pattern detection -> action based on pattern -> throwing away the current instance before creating and processing the new one. In such a case, global data members and global behaviour configuration is not a problem. If you, for whatever reason, want to store instances, keep this in mind.
|
default |
|
default |
retdec::bin2llvmir::SymbolicTree::SymbolicTree | ( | ReachingDefinitionsAnalysis * | rda, |
llvm::Value * | v, | ||
llvm::Value * | u, | ||
unsigned | nodeLevel, | ||
unsigned | maxNodeLevel, | ||
std::map< llvm::Value *, llvm::Value * > * | v2v, | ||
bool | linear | ||
) |
This is a private constructor, do not use it. It is made public only so it can be used in std::vector<>::emplace_back().
|
private |
|
private |
|
private |
|
static |
|
private |
|
private |
unsigned retdec::bin2llvmir::SymbolicTree::getLevel | ( | ) | const |
std::vector< SymbolicTree * > retdec::bin2llvmir::SymbolicTree::getLevelOrder | ( | ) | const |
SymbolicTree * retdec::bin2llvmir::SymbolicTree::getMaxIntValue | ( | ) |
std::vector< SymbolicTree * > retdec::bin2llvmir::SymbolicTree::getPostOrder | ( | ) | const |
getPreOrder()
. The same holds here – you may damage vector's consistency if you make changes to nodes as you iterate over them. However, thanks to the bottom-up nature of post-order traversal, this may not be a problem if you modify only the actual node and its children – they were already iterated over. std::vector< SymbolicTree * > retdec::bin2llvmir::SymbolicTree::getPreOrder | ( | ) | const |
bool retdec::bin2llvmir::SymbolicTree::isBinary | ( | ) | const |
bool retdec::bin2llvmir::SymbolicTree::isNary | ( | unsigned | N | ) | const |
bool retdec::bin2llvmir::SymbolicTree::isNullary | ( | ) | const |
bool retdec::bin2llvmir::SymbolicTree::isTernary | ( | ) | const |
bool retdec::bin2llvmir::SymbolicTree::isUnary | ( | ) | const |
|
static |
|
static |
A lightweight construction method where no RDA is used. Tree is successfully constructed only if it can be fully expanded using only linear control flow backtracking.
|
static |
SymbolicTree is constructed using on demand RDA features. I.e. RDA is not precomputed, but it is constructed as needed. This is useful if control flow changes between tree computations (i.e. RDA gets invalid), or if only a few trees need to be constructed. Otherwise, it is much more efficient to precompute RDA before trees are constructed.
bool retdec::bin2llvmir::SymbolicTree::operator!= | ( | const SymbolicTree & | o | ) | const |
SymbolicTree & retdec::bin2llvmir::SymbolicTree::operator= | ( | SymbolicTree && | other | ) |
bool retdec::bin2llvmir::SymbolicTree::operator== | ( | const SymbolicTree & | o | ) | const |
|
static |
The basic SymbolicTree construction method uses a precomputed Reaching Definition Analysis (RDA) in order to fully expand the value in question up to the maximal tree node level.
|
static |
The same as the basic SymbolicTree construction method, but an additional value to value mapping is used for node expansion. If the node to be expanded is a key in the map, an associated value is used as its expansion. Otherwise, the node is expanded as usual.
std::string retdec::bin2llvmir::SymbolicTree::print | ( | unsigned | indent = 0 | ) | const |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
void retdec::bin2llvmir::SymbolicTree::simplifyNode | ( | ) |
void retdec::bin2llvmir::SymbolicTree::solveMemoryLoads | ( | FileImage * | image | ) |
If at address 33888 in image is value 76092 then transform: >| u6_83f0 = load i32, i32* inttoptr (i32 33888 to i32*), align 32 >| i32 33888 Into: >| 76092
|
friend |
|
staticprivate |
|
staticprivate |
|
private |
|
staticprivate |
|
staticprivate |
|
staticprivate |
|
staticprivate |
|
staticprivate |
|
staticprivate |
std::vector<SymbolicTree> retdec::bin2llvmir::SymbolicTree::ops |
llvm::Value* retdec::bin2llvmir::SymbolicTree::user = nullptr |
llvm::Value* retdec::bin2llvmir::SymbolicTree::value = nullptr |