[Scummvm-cvs-logs] SF.net SVN: scummvm:[49630] tools/branches/gsoc2010-decompiler/decompiler

pidgeot at users.sourceforge.net pidgeot at users.sourceforge.net
Sun Jun 13 14:58:20 CEST 2010


Revision: 49630
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49630&view=rev
Author:   pidgeot
Date:     2010-06-13 12:58:19 +0000 (Sun, 13 Jun 2010)

Log Message:
-----------
Add handling of jumps to CFG generation

Modified Paths:
--------------
    tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
    tools/branches/gsoc2010-decompiler/decompiler/control_flow.h
    tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp
    tools/branches/gsoc2010-decompiler/decompiler/engine.h
    tools/branches/gsoc2010-decompiler/decompiler/graph.h
    tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.cpp
    tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.h

Modified: tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp	2010-06-13 10:50:54 UTC (rev 49629)
+++ tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp	2010-06-13 12:58:19 UTC (rev 49630)
@@ -22,18 +22,37 @@
 
 #include "control_flow.h"
 
-ControlFlow::ControlFlow(std::vector<Instruction> &insts) {
+#include <cstdio>
+
+ControlFlow::ControlFlow(std::vector<Instruction> &insts, Engine *engine) {
+	_engine = engine;
 	GraphVertex last;
+	bool addEdge = false;
 
 	std::map<uint32, GraphVertex> addrMap;
 	for (InstIterator it = insts.begin(); it != insts.end(); ++it) {
 		GraphVertex cur = boost::add_vertex(_g);
+		addrMap[it->_address] = cur;
 		boost::put(boost::vertex_name, _g, cur, Group(it, it));
 
-		if (it != insts.begin())
+		if (addEdge)
 			boost::add_edge(last, cur, _g);
 		last = cur;
+		addEdge = (it->_type != kJump && it->_type != kJumpRel);
 	}
+
+	for (InstIterator it = insts.begin(); it != insts.end(); ++it) {
+		switch(it->_type) {
+		case kJump:
+		case kCondJump:
+		case kJumpRel:
+		case kCondJumpRel:
+			boost::add_edge(addrMap[it->_address], addrMap[_engine->getDestAddress(it)], _g);
+			break;
+		default:
+			break;
+		}
+	}
 }
 
 void ControlFlow::createGroups() {

Modified: tools/branches/gsoc2010-decompiler/decompiler/control_flow.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/control_flow.h	2010-06-13 10:50:54 UTC (rev 49629)
+++ tools/branches/gsoc2010-decompiler/decompiler/control_flow.h	2010-06-13 12:58:19 UTC (rev 49630)
@@ -24,20 +24,23 @@
 #define DEC_CONTROL_FLOW_H
 
 #include "graph.h"
+#include "engine.h"
 
 /**
  * Class for doing code flow analysis.
  */
 class ControlFlow {
 private:
-	Graph _g; ///< The control flow graph.
+	Graph _g;        ///< The control flow graph.
+	Engine *_engine; ///< Pointer to the Engine used for the script.
 
 public:
 	/**
 	 * Constructor for the control flow graph.
 	 * @param insts std::vector containing the instructions to analyze control flow for.
+	 * @param engine Pointer to the Engine used for the script.
 	 */
-	ControlFlow(std::vector<Instruction> &insts);
+	ControlFlow(std::vector<Instruction> &insts, Engine *engine);
 
 	/**
 	 * Creates groups suitable for a stack-based machine.

Modified: tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp	2010-06-13 10:50:54 UTC (rev 49629)
+++ tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp	2010-06-13 12:58:19 UTC (rev 49630)
@@ -119,7 +119,7 @@
 		delete disassembler;
 
 		//Control flow analysis
-		ControlFlow *cf = new ControlFlow(insts);
+		ControlFlow *cf = new ControlFlow(insts, engine);
 		Graph g = cf->analyze();
 
 		if (vm.count("dump-graph")) {
@@ -133,7 +133,7 @@
 				buf = std::cout.rdbuf(); 
 			} 
  			std::ostream out(buf); 
-			boost::write_graphviz(out, g, boost::make_label_writer(get(boost::vertex_name, g)));
+			boost::write_graphviz(out, g, boost::make_label_writer(get(boost::vertex_name, g)), boost::default_writer(), GraphProperties());
 		}
 
 		delete cf;

Modified: tools/branches/gsoc2010-decompiler/decompiler/engine.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/engine.h	2010-06-13 10:50:54 UTC (rev 49629)
+++ tools/branches/gsoc2010-decompiler/decompiler/engine.h	2010-06-13 12:58:19 UTC (rev 49630)
@@ -37,6 +37,12 @@
 	 * @return Pointer to a Disassembler for the engine.
 	 */
 	virtual Disassembler *getDisassembler() const = 0;
+
+	/**
+	 * Decode a jump-instruction to get the destination address.
+	 * @param it Iterator pointing to the instruction to decode.
+	 */
+	virtual uint32 getDestAddress(InstIterator it) const = 0;
 };
 
 #endif

Modified: tools/branches/gsoc2010-decompiler/decompiler/graph.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/graph.h	2010-06-13 10:50:54 UTC (rev 49629)
+++ tools/branches/gsoc2010-decompiler/decompiler/graph.h	2010-06-13 12:58:19 UTC (rev 49630)
@@ -79,4 +79,18 @@
 typedef Graph::vertex_descriptor GraphVertex; ///< Type representing a vertex in the graph
 typedef Graph::edge_descriptor GraphEdge; ///< Type representing an edge in the graph
 
+/**
+ * Type used to set properties for dot output.
+ */
+struct GraphProperties {
+
+	/**
+	 * Called by write_graphviz from Boost.Graph to print properties of the graph.
+	 * @param out The std::ostream write_graphviz is writing to.
+	 */
+	void operator()(std::ostream& out) const {
+		out << "node [shape=box]" << std::endl;
+	}
+};
+
 #endif

Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.cpp	2010-06-13 10:50:54 UTC (rev 49629)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.cpp	2010-06-13 12:58:19 UTC (rev 49630)
@@ -26,3 +26,16 @@
 ::Disassembler *Scumm::v6::Engine::getDisassembler() const {
 	return new Disassembler();
 }
+
+uint32 Scumm::v6::Engine::getDestAddress(InstIterator it) const {
+	switch(it->_type) {
+	case kJump:
+	case kCondJump:
+		return it->_params[0].getUnsigned();
+	case kJumpRel:
+	case kCondJumpRel:
+		return it->_params[0].getSigned() + it->_address + 3;
+	default:
+		return 0;
+	}
+}

Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.h	2010-06-13 10:50:54 UTC (rev 49629)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.h	2010-06-13 12:58:19 UTC (rev 49630)
@@ -35,6 +35,7 @@
 class Engine : public ::Engine {
 public:
 	::Disassembler *getDisassembler() const;
+	uint32 getDestAddress(InstIterator it) const;
 };
 
 } //End of namespace Scumm::v6


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list