23 : astCtxt(astCtxt), symbolic(symbolic) {
33 for (
const auto& se : this->expressions) {
34 this->information[se.second->getAst().get()] = se.second.get();
37 return this->
liftToDot(stream, expr->getAst());
41 void LiftingToDot::spreadInformation(std::ostream& stream) {
42 for (
const auto& i : this->information) {
46 stream <<
"subgraph cluster_" <<
reinterpret_cast<size_t>(node) <<
" {" << std::endl;
47 stream <<
" rank=max;" << std::endl;
48 stream <<
" bgcolor=lightgrey;" << std::endl;
49 stream <<
" node [style=filled, color=black, fillcolor=white];" << std::endl;
50 stream <<
" label=\"" << se->getDisassembly() <<
"\";" << std::endl;
51 stream <<
" " <<
reinterpret_cast<size_t>(node) <<
";" << std::endl;
52 stream <<
"}" << std::endl;
57 void LiftingToDot::defineLegend(std::ostream& stream) {
59 if (this->expressions.empty())
63 std::vector<triton::usize> ssa;
64 for (
const auto& se : this->expressions) {
65 ssa.push_back(se.first);
69 std::sort(ssa.begin(), ssa.end());
71 stream <<
"legend [fontname=mono style=filled fillcolor=lightyellow color=black shape=box label=\"Instructions involved in the expression" << std::endl << std::endl;
72 for (
const auto&
id : ssa) {
73 const auto& se = this->expressions[id];
74 stream << se->getDisassembly() <<
"\\l";
76 stream << std::endl <<
"\"];" << std::endl;
83 for (
auto const& node : ttnodes) {
84 switch (node->getType()) {
87 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"MEMORY\"];"});
92 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"ASSERT\"];"});
97 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BSWAP\"];"});
102 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVADD\"];"});
107 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVAND\"];"});
112 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVASHR\"];"});
117 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVLSHR\"];"});
122 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVMUL\"];"});
127 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVNAND\"];"});
132 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVNEG\"];"});
137 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVNOR\"];"});
142 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVNOT\"];"});
147 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVOR\"];"});
152 auto RHS = node->getChildren()[1];
153 auto rot = triton::ast::getInteger<std::string>(RHS);
155 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVROL\"];"});
156 this->nodes.insert({
reinterpret_cast<size_t>(RHS.get()),
"[label=\"" + rot +
"-bit\"];"});
161 auto RHS = node->getChildren()[1];
162 auto rot = triton::ast::getInteger<std::string>(RHS);
164 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVROR\"];"});
165 this->nodes.insert({
reinterpret_cast<size_t>(RHS.get()),
"[label=\"" + rot +
"-bit\"];"});
170 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVSDIV\"];"});
175 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVSGE\"];"});
180 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVSGT\"];"});
185 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVSHL\"];"});
190 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVSLE\"];"});
195 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVSLT\"];"});
200 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVSMOD\"];"});
205 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVSREM\"];"});
210 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVSUB\"];"});
215 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVUDIV\"];"});
220 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVUGE\"];"});
225 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVUGT\"];"});
230 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVULE\"];"});
235 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVULT\"];"});
240 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVUREM\"];"});
245 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVXNOR\"];"});
250 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"BVXOR\"];"});
255 auto LHS = node->getChildren()[0];
256 auto RHS = node->getChildren()[1];
257 auto value = triton::ast::getInteger<triton::uint512>(LHS);
258 auto size = triton::ast::getInteger<triton::uint512>(RHS);
261 s <<
"[label=\"0x" << std::hex << value << std::dec <<
" : " << size <<
"-bit\" style=filled, color=black, fillcolor=lightblue];";
263 this->nodes.insert({
reinterpret_cast<size_t>(node.get()), s.str()});
268 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"COMPOUND\"];"});
273 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"CONCAT\"];"});
278 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"DECLARE\"];"});
283 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"!=\"];"});
288 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"==\"];"});
293 auto nhi = node->getChildren()[0];
294 auto nlo = node->getChildren()[1];
295 auto hi = triton::ast::getInteger<std::string>(nhi);
296 auto lo = triton::ast::getInteger<std::string>(nlo);
298 this->nodes.insert({
reinterpret_cast<size_t>(nhi.get()),
"[label=\"hi:" + hi +
"\"];"});
299 this->nodes.insert({
reinterpret_cast<size_t>(nlo.get()),
"[label=\"lo:" + lo +
"\"];"});
300 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"EXTRACT\"];"});
305 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"FORALL\"];"});
310 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"IFF\"];"});
315 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"ITE\"];"});
320 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"LAND\"];"});
325 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"LET\"];"});
330 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"LNOT\"];"});
335 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"LOR\"];"});
340 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"LXOR\"];"});
345 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"SELECT\"];"});
350 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"STORE\"];"});
356 s <<
"[label=\"" << node <<
"\"];";
357 this->nodes.insert({
reinterpret_cast<size_t>(node.get()), s.str()});
362 auto LHS = node->getChildren()[0];
363 auto sx = triton::ast::getInteger<std::string>(LHS);
365 this->nodes.insert({
reinterpret_cast<size_t>(LHS.get()),
"[label=\"" + sx +
"-bit\"];"});
366 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"SX\"];"});
371 auto LHS = node->getChildren()[0];
372 auto zx = triton::ast::getInteger<std::string>(LHS);
374 this->nodes.insert({
reinterpret_cast<size_t>(LHS.get()),
"[label=\"" + zx +
"-bit\"];"});
375 this->nodes.insert({
reinterpret_cast<size_t>(node.get()),
"[label=\"ZX\"];"});
385 this->nodes.insert({
reinterpret_cast<size_t>(ref),
"[label=\"Ref #" + std::to_string(refId) +
"\"];"});
386 this->edges.insert({
reinterpret_cast<size_t>(ptr),
reinterpret_cast<size_t>(next)});
407 for (
auto const& child : node->getChildren()) {
410 this->handleVariable(node, child);
414 this->edges.insert({
reinterpret_cast<size_t>(node.get()),
reinterpret_cast<size_t>(child.get())});
426 s <<
"[label=\"" << child <<
"\" rank=max style=filled, color=black, fillcolor=lightgreen];";
428 this->nodes.insert({this->uniqueid, s.str()});
429 this->edges.insert({
reinterpret_cast<size_t>(parent.get()), this->uniqueid});
435 stream <<
"digraph triton {" << std::endl;
436 stream <<
"ordering=\"out\";" << std::endl;
437 stream <<
"fontname=mono;" << std::endl;
440 this->defineLegend(stream);
441 this->spreadInformation(stream);
444 this->iterateNodes(root);
447 for (
const auto& node : this->nodes) {
448 stream << node.first <<
" " << node.second << std::endl;
452 for (
const auto& edge : this->edges) {
453 stream << edge.first <<
" -> " << edge.second << std::endl;
457 if (this->expressions.empty() ==
false) {
458 stream <<
"legend -> " <<
reinterpret_cast<size_t>(root.get()) <<
" [style=dotted];" << std::endl;
462 stream <<
"}" << std::endl;