[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