Commits

Carl Pulley committed a6144f8

Added in code to get SSA returning to python

Comments (0)

Files changed (2)

 
 let _ = Callback.register "edge_label" Cfg.AST.G.E.label
 
+type py_ssa
+external ssa_node_to_python: Cfg.SSA.G.t -> Cfg.SSA.G.V.t -> py_ssa -> py_ssa = "ssa_node_to_python"
+external ssa_edge_to_python: Cfg.SSA.G.E.t -> py_ssa -> py_ssa = "ssa_edge_to_python"
+
+let _ = Callback.register "ssa_fold_nodes" (fun g -> Cfg.SSA.G.fold_vertex (ssa_node_to_python g) g)
+
+let _ = Callback.register "ssa_fold_edges" (Cfg.SSA.G.fold_edges_e ssa_edge_to_python)
+
+let _ = Callback.register "ssa_node_hash" Cfg.SSA.G.V.hash
+
+let _ = Callback.register "ssa_node_label" Cfg.SSA.G.V.label
+
+let _ = Callback.register "ssa_node_stmts" Cfg.SSA.get_stmts
+
+let _ = Callback.register "ssa_edge_source" (fun e -> Cfg.SSA.G.V.hash(Cfg.SSA.G.E.src e))
+
+let _ = Callback.register "ssa_edge_target" (fun e -> Cfg.SSA.G.V.hash(Cfg.SSA.G.E.dst e))
+
+let _ = Callback.register "ssa_edge_label" Cfg.SSA.G.E.label
+
 let str_to_arch = function
   | "x86" -> Libbfd.Bfd_arch_i386
   | "arm" -> Libbfd.Bfd_arch_arm
     item3 = Field(arg, 2);
     result = Py_BuildValue("{s(OOO)}", "ite", exp_to_python(item1), exp_to_python(item2), exp_to_python(item3));
   } else if (Is_block(exp) && Tag_val(exp) == 11 && Wosize_val(arg) == 3) {
-    // Extract of (big_int * big_int * exp) -> { "extract": [big_int, big_int, typ] }
+    // Extract of (big_int * big_int * exp) -> { "extract": [big_int, big_int, exp] }
     item1 = Field(arg, 0);
     item2 = Field(arg, 1);
     item3 = Field(arg, 2);
-    result = Py_BuildValue("{s(OOO)}", "extract", big_int_to_python(item1), big_int_to_python(item2), typ_to_python(item3));
+    result = Py_BuildValue("{s(OOO)}", "extract", big_int_to_python(item1), big_int_to_python(item2), exp_to_python(item3));
   } else if (Is_block(exp) && Tag_val(exp) == 12 && Wosize_val(arg) == 2) {
     // Concat of (exp * exp) -> { "concat": [exp, exp] }
     item1 = Field(arg, 0);
   CAMLreturnT(PyObject*, result);
 }
 
-//PyObject* ssa_to_python(value ssa) {
-//  // Graph(Ssa.stmt list)
-//  // TODO:
-//}
+PyObject* ssa_value_to_python(value val) {
+  PyObject* result;
+
+  CAMLparam1(val);
+
+  if (Is_block(val) && Tag_val(val) == 0 && Wosize_val(val) == 2) {
+    // Int of big_int * typ
+    result = Py_BuildValue("{s(sO)}", "pos", big_int_to_python(Field(val, 0)), typ_to_python(Field(val, 1)));
+  } else if (Is_block(val) && Tag_val(val) == 1 && Wosize_val(val) == 1) {
+    // Var of var
+    result = Py_BuildValue("{sO}", "var", var_to_python(Field(val, 0)));
+  } else if (Is_block(val) && Tag_val(val) == 2 && Wosize_val(val) == 1) {
+    // Lab of string
+    result = Py_BuildValue("{ss}", "lab", String_val(Field(val, 0)));
+  } else {
+    PyErr_SetString(PyExc_TypeError, "ssa_value_to_python: unexpected Ssa.value datatype value");
+
+    CAMLreturnT(PyObject*, NULL);
+  }
+
+  CAMLreturnT(PyObject*, result);
+}
+
+PyObject* ssa_exp_to_python(value exp) {
+  PyObject* result;
+
+  CAMLparam1(exp);
+  CAMLlocal5(item, item1, item2, item3, item4);
+  CAMLlocal1(item5);
+
+  if (Is_block(exp) && Tag_val(exp) == 0 && Wosize_val(exp) == 3) {
+    // Load of value * value * value * typ -> { "load": [value, value, value, typ] }
+    item1 = Field(exp, 0);
+    item2 = Field(exp, 1);
+    item3 = Field(exp, 2);
+    item4 = Field(exp, 3);
+    result = Py_BuildValue("{s(OOOO)}", "load", ssa_value_to_python(item1), ssa_value_to_python(item2), ssa_value_to_python(item3), typ_to_python(item4));
+  } else if (Is_block(exp) && Tag_val(exp) == 1 && Wosize_val(exp) == 5) {
+    // Store of value * value * value * value * typ -> { "store": [value, value, value, value, typ] }
+    item1 = Field(exp, 0);
+    item2 = Field(exp, 1);
+    item3 = Field(exp, 2);
+    item4 = Field(exp, 3);
+    item5 = Field(exp, 4);
+    result = Py_BuildValue("{s(OOOOO)}", "store", ssa_value_to_python(item1), ssa_value_to_python(item2), ssa_value_to_python(item3), ssa_value_to_python(item4), typ_to_python(item5));
+  } else if (Is_block(exp) && Tag_val(exp) == 2 && Wosize_val(exp) == 3) {
+    // Ite of value * value * value -> { "ite": [value, value, value] }
+    item1 = Field(exp, 0);
+    item2 = Field(exp, 1);
+    item3 = Field(exp, 2);
+    result = Py_BuildValue("{s(OOO)}", "ite", ssa_value_to_python(item1), ssa_value_to_python(item2), ssa_value_to_python(item3));
+  } else if (Is_block(exp) && Tag_val(exp) == 3 && Wosize_val(exp) == 3) {
+    // Extract of big_int * big_int * value -> { "extract": [big_int, big_int, value] }
+    item1 = Field(exp, 0);
+    item2 = Field(exp, 1);
+    item3 = Field(exp, 2);
+    result = Py_BuildValue("{s(OOO)}", "extract", big_int_to_python(item1), big_int_to_python(item2), ssa_value_to_python(item3));
+  } else if (Is_block(exp) && Tag_val(exp) == 4 && Wosize_val(exp) == 2) {
+    // Concat of value * value -> { "concat": [value, value] }
+    item1 = Field(exp, 0);
+    item2 = Field(exp, 1);
+    result = Py_BuildValue("{s(OO)}", "concat", ssa_value_to_python(item1), ssa_value_to_python(item2));
+  } else if (Is_block(exp) && Tag_val(exp) == 5 && Wosize_val(exp) == 3) {
+    // BinOp of binop_type * value * value -> { "binop": [binop_type, value, value] }
+    item1 = Field(exp, 0);
+    item2 = Field(exp, 1);
+    item3 = Field(exp, 2);
+    result = Py_BuildValue("{s(OOO)}", "binop", binop_to_python(item1), ssa_value_to_python(item2), ssa_value_to_python(item3));
+  } else if (Is_block(exp) && Tag_val(exp) == 6 && Wosize_val(exp) == 2) {
+    // UnOp of unop_type * value -> { "unop": [unop_type, value] }
+    item1 = Field(exp, 0);
+    item2 = Field(exp, 1);
+    result = Py_BuildValue("{s(OO)}", "unop", unop_to_python(item1), ssa_value_to_python(item2));
+  } else if (Is_block(exp) && Tag_val(exp) == 7 && Wosize_val(exp) == 1) {
+    // Val of value -> { "val": [value] }
+    item1 = Field(exp, 0);
+    result = Py_BuildValue("{sO}", "val", ssa_value_to_python(item1));
+  } else if (Is_block(exp) && Tag_val(exp) == 8 && Wosize_val(exp) == 3) {
+    // Cast of cast_type * typ * value -> { "cast": [cast_type, typ, value] }
+    item1 = Field(exp, 0);
+    item2 = Field(exp, 1);
+    item3 = Field(exp, 2);
+    result = Py_BuildValue("{s(OOO)}", "cast", cast_to_python(item1), typ_to_python(item2), ssa_value_to_python(item3));
+  } else if (Is_block(exp) && Tag_val(exp) == 9 && Wosize_val(exp) == 2) {
+    // Unknown of string * typ -> { "unknown": [string, typ] }
+    item1 = Field(exp, 1);
+    result = Py_BuildValue("{s(sO)}", "unknown", String_val(Field(exp, 0)), typ_to_python(item1));
+  } else if (Is_block(exp) && Tag_val(exp) == 5 && Wosize_val(exp) == 1) {
+    // Phi of var list -> { "phi": var list }
+    result = Py_BuildValue("{sO}", "phi", vars_to_python(Field(exp, 0)));
+  } else {
+    PyErr_SetString(PyExc_TypeError, "ssa_exp_to_python: unexpected Ssa.exp datatype value");
+
+    CAMLreturnT(PyObject*, NULL);
+  }
+
+  CAMLreturnT(PyObject*, result);
+}
+
+PyObject* ssa_stmt_to_python(value stmt) {
+  PyObject* result;
+
+  CAMLparam1(stmt);
+  CAMLlocal5(item, item1, item2, item3, item4);
+
+  if (Is_block(stmt) && Tag_val(stmt) == 0 && Wosize_val(stmt) == 3) {
+    // Move of var * exp * attrs -> { "move": [var, exp, attrs] }
+    item1 = Field(stmt, 0);
+    item2 = Field(stmt, 1);
+    item3 = Field(stmt, 2);
+    result = Py_BuildValue("{s(OOO)}", "move", var_to_python(item1), ssa_exp_to_python(item2), attrs_to_python(item3));
+  } else if (Is_block(stmt) && Tag_val(stmt) == 1 && Wosize_val(stmt) == 2) {
+    // Jmp of value * attrs -> { "jmp": [value, attrs] }
+    item1 = Field(stmt, 0);
+    item2 = Field(stmt, 1);
+    result = Py_BuildValue("{s(OO)}", "jmp", ssa_value_to_python(item1), attrs_to_python(item2));
+  } else if (Is_block(stmt) && Tag_val(stmt) == 2 && Wosize_val(stmt) == 4) {
+    // CJmp of value * value * value * attrs -> { "cjmp": [value, value, value, attrs] }
+    item1 = Field(stmt, 0);
+    item2 = Field(stmt, 1);
+    item3 = Field(stmt, 2);
+    item4 = Field(stmt, 3);
+    result = Py_BuildValue("{s(OOOO)}", "cjmp", ssa_value_to_python(item1), ssa_value_to_python(item2), ssa_value_to_python(item3), attrs_to_python(item4));
+  } else if (Is_block(stmt) && Tag_val(stmt) == 3 && Wosize_val(stmt) == 2) {
+    // Label of label * attrs -> { "label": [label, attrs] }
+    item1 = Field(stmt, 0);
+    item2 = Field(stmt, 1);
+    result = Py_BuildValue("{s(OO)}", "label", label_to_python(item1), attrs_to_python(item2));
+  } else if (Is_block(stmt) && Tag_val(stmt) == 4 && Wosize_val(stmt) == 2) {
+    // Halt of value * attrs -> { "halt": [value, attrs] }
+    item1 = Field(stmt, 0);
+    item2 = Field(stmt, 1);
+    result = Py_BuildValue("{s(OO)}", "halt", ssa_value_to_python(item1), attrs_to_python(item2));
+  } else if (Is_block(stmt) && Tag_val(stmt) == 5 && Wosize_val(stmt) == 2) {
+    // Assert of value * attrs -> { "assert": [value, attrs] }
+    item1 = Field(stmt, 0);
+    item2 = Field(stmt, 1);
+    result = Py_BuildValue("{s(OO)}", "assert", ssa_value_to_python(item1), attrs_to_python(item2));
+  } else if (Is_block(stmt) && Tag_val(stmt) == 6 && Wosize_val(stmt) == 2) {
+    // Assume of value * attrs -> { "assume": [value, attrs] }
+    item1 = Field(stmt, 0);
+    item2 = Field(stmt, 1);
+    result = Py_BuildValue("{s(OO)}", "assume", ssa_value_to_python(item1), attrs_to_python(item2));
+  } else if (Is_block(stmt) && Tag_val(stmt) == 7 && Wosize_val(stmt) == 2) {
+    // Comment of string * attrs -> { "comment": [string, attrs] }
+    item1 = Field(stmt, 0);
+    item2 = Field(stmt, 1);
+    result = Py_BuildValue("{s(sO)}", "comment", String_val(item1), attrs_to_python(item2));
+  } else {
+    PyErr_SetString(PyExc_TypeError, "ssa_stmt_to_python: unexpected Ssa.stmt datatype value");
+
+    CAMLreturnT(PyObject*, NULL);
+  }
+
+  CAMLreturnT(PyObject*, result);
+}
+
+PyObject* ssa_ast_to_python(value stmt_list) {
+  // stmt list -> [stmt,..]
+  PyObject* result;
+  PyObject* py_stmt;
+
+  CAMLparam1(stmt_list);
+  CAMLlocal1(stmt);
+
+  result = PyList_New(0);
+  while(stmt_list != Val_emptylist) {
+    stmt = Field(stmt_list, 0);
+    py_stmt = ssa_stmt_to_python(stmt);
+    if (!PyErr_Occurred() && PyList_Append(result, py_stmt) == 0) {
+      stmt_list = Field(stmt_list, 1);
+    } else {
+      // Deal with Python exception
+      Py_CLEAR(result);
+      CAMLreturnT(PyObject*, NULL);
+    }
+  }
+
+  CAMLreturnT(PyObject*, result);
+}
+
+PyObject* ssa_node_to_python(value ssa, value node, PyObject* py_nodes) {
+  PyObject* py_stmts;
+  PyObject* py_label;
+  PyObject* py_node;
+
+  CAMLparam1(node);
+  CAMLlocal3(stmts, label, hash);
+
+  stmts = caml_callback2(*caml_named_value("ssa_node_stmts"), ssa, node);
+  label = caml_callback(*caml_named_value("ssa_node_label"), node);
+  hash = caml_callback(*caml_named_value("ssa_node_hash"), node);
+  py_stmts = ssa_ast_to_python(stmts);
+  py_label = bbid_to_python(label);
+  py_node = Py_BuildValue("{sisOsO}", "hash", Int_val(hash), "label", py_label, "stmts", py_stmts);
+  if (!PyErr_Occurred() && PyList_Append(py_nodes, py_node) == 0) {
+    CAMLreturnT(PyObject*, py_nodes);
+  } else {
+    // Deal with Python exception
+    CAMLreturnT(PyObject*, NULL);
+  }
+}
+
+PyObject* ssa_edge_to_python(value edge, PyObject* py_edges) {
+  PyObject* py_label;
+  PyObject* py_edge;
+
+  CAMLparam1(edge);
+  CAMLlocal3(label, source, target);
+
+  label = caml_callback(*caml_named_value("ssa_edge_label"), edge);
+  source = caml_callback(*caml_named_value("ssa_edge_source"), edge);
+  target = caml_callback(*caml_named_value("ssa_edge_target"), edge);
+  if (Is_block(label)) {
+    // label == Some of bool
+    if (Bool_val(Field(label, 0)) == Val_true) {
+      py_label = Py_True;
+    } else {
+      py_label = Py_False;
+    }
+    py_edge = Py_BuildValue("{sisisO}", "source", Int_val(source), "target", Int_val(target), "label", py_label);
+  } else {
+    // label == None
+    py_edge = Py_BuildValue("{sisi}", "source", Int_val(source), "target", Int_val(target));
+  }
+  if (!PyErr_Occurred() && PyList_Append(py_edges, py_edge) == 0) {
+    CAMLreturnT(PyObject*, py_edges);
+  } else {
+    // Deal with Python exception
+    CAMLreturnT(PyObject*, NULL);
+  }
+}
+
+PyObject* ssa_to_python(value ssa) {
+  // Graph(Ssa.stmt list)
+  PyObject* py_nodes;
+  PyObject* py_edges;
+  PyObject* result;
+
+  CAMLparam1(ssa);
+  CAMLlocal2(nodes, edges);
+
+  py_nodes = PyList_New(0);
+  nodes = caml_callback2(*caml_named_value("ssa_fold_nodes"), ssa, py_nodes);
+
+  py_edges = PyList_New(0);
+  edges = caml_callback2(*caml_named_value("ssa_fold_edges"), ssa, py_edges);
+
+  result = Py_BuildValue("{sOsO}", "nodes", py_nodes, "edges", py_edges);
+  CAMLreturnT(PyObject*, result);
+}
 
 PyObject* bap_to_python(value prog_term) {
   CAMLparam1(prog_term);
     // AstCfg of Cfg.AST.G.t
     item = Field(prog_term, 0);
     CAMLreturnT(PyObject*, cfg_to_python(item));
-//  } else if (Is_block(prog_term) && Tag_val(prog_term) == 2 && Wosize_val(prog_term) == 1) {
-//    // Ssa of Cfg.SSA.G.t
-//    item = Field(prog_term, 0);
-//    CAMLreturnT(PyObject*, ssa_to_python(item));
+  } else if (Is_block(prog_term) && Tag_val(prog_term) == 2 && Wosize_val(prog_term) == 1) {
+    // Ssa of Cfg.SSA.G.t
+    item = Field(prog_term, 0);
+    CAMLreturnT(PyObject*, ssa_to_python(item));
   } else {
     PyErr_SetString(PyExc_TypeError, "bap_to_python: unexpected Iltrans.prog datatype value");