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

kjdf at users.sourceforge.net kjdf at users.sourceforge.net
Wed Jun 10 14:47:29 CEST 2009


Revision: 41426
          http://scummvm.svn.sourceforge.net/scummvm/?rev=41426&view=rev
Author:   kjdf
Date:     2009-06-10 12:47:29 +0000 (Wed, 10 Jun 2009)

Log Message:
-----------
decompiler: control flow graph visualization

Modified Paths:
--------------
    tools/branches/gsoc2009-decompiler/decompiler/cfg.h
    tools/branches/gsoc2009-decompiler/decompiler/decompiler.cc
    tools/branches/gsoc2009-decompiler/decompiler/instruction.h
    tools/branches/gsoc2009-decompiler/decompiler/reader.h

Modified: tools/branches/gsoc2009-decompiler/decompiler/cfg.h
===================================================================
--- tools/branches/gsoc2009-decompiler/decompiler/cfg.h	2009-06-10 12:47:19 UTC (rev 41425)
+++ tools/branches/gsoc2009-decompiler/decompiler/cfg.h	2009-06-10 12:47:29 UTC (rev 41426)
@@ -21,6 +21,7 @@
 		_id = _g_id++;
 	}
 	void printInsns(vector<Instruction*> &v) {
+		printHeader(v);
 		printf(" in(");
 		for (unsigned i = 0; i < _in.size(); i++)
 			printf("%d%s", _in[i]->_id, i == _in.size()-1 ? "" : ",");
@@ -42,6 +43,9 @@
 	}
 	virtual void printOuts() {
 	};
+	void printHeader(vector<Instruction*> &v) {
+		printf("%d (%04x..%04x)", _id, v[_start]->_addr-8, v[_end-1]->_addr-8);
+	}
 	virtual void print(vector<Instruction*> &v) = 0;
 	virtual ~BasicBlock() {
 	}
@@ -54,7 +58,7 @@
 	BB2Way(uint32 start, uint32 end) : BasicBlock(start, end) {
 	}
 	void print(vector<Instruction*> &v) {
-		printf("=== BB2Way %d [%d,%d)", _id, _start, _end);
+		printf("=== BB2Way #");
 		printInsns(v);
 		printf("===\n\n");
 	}
@@ -68,7 +72,7 @@
 	BBFall(uint32 start, uint32 end) : BasicBlock(start, end) {
 	}
 	void print(vector<Instruction*> &v) {
-		printf("=== BBFall #%d [%d,%d)", _id, _start, _end);
+		printf("=== BBFall #");
 		printInsns(v);
 		printf("===\n\n");
 	}
@@ -81,7 +85,7 @@
 	BBEnd(uint32 start, uint32 end) : BasicBlock(start, end) {
 	}
 	void print(vector<Instruction*> &v) {
-		printf("=== BBEnd #%d [%d,%d)", _id, _start, _end);
+		printf("=== BBEnd #");
 		printInsns(v);
 		printf("===\n\n");
 	}
@@ -92,7 +96,41 @@
 
 	vector<BasicBlock*> _blocks;
 	vector<uint32> _targets;
+	vector<Instruction*> *_v;
 
+	void printBBs() {
+		for (uint32 i = 0; i < _blocks.size(); i++)
+			_blocks[i]->print(*_v);
+	}
+
+	void printDot() {
+		printf("digraph G {\n");
+		for (uint32 i = 0; i < _blocks.size(); i++) {
+			BB2Way *bb2way = dynamic_cast<BB2Way*>(_blocks[i]);
+			BBFall *bbfall = dynamic_cast<BBFall*>(_blocks[i]);
+			BBEnd  *bbend  = dynamic_cast<BBEnd*> (_blocks[i]);
+			if (bb2way) {
+				printf("\""); bb2way->printHeader(*_v); printf("\"");
+				printf(" -> ");
+				printf("\""); bb2way->_out1->printHeader(*_v); printf("\"");
+				printf(" [style=bold]\n");
+				printf("\""); bb2way->printHeader(*_v); printf("\"");
+				printf(" -> ");
+				printf("\""); bb2way->_out2->printHeader(*_v); printf("\"");
+				printf("\n");
+			} else if (bbfall) {
+				printf("\""); bbfall->printHeader(*_v); printf("\"");
+				printf(" -> ");
+				printf("\""); bbfall->_out->printHeader(*_v); printf("\"");
+				printf(" [style=bold]\n");
+			} else if (bbend) {
+				printf("\""); bbend->printHeader(*_v); printf("\"");
+				printf("\n");
+			}
+		}
+		printf("}\n");
+	}
+
 	bool isTarget(uint32 addr) {
 		for (uint32 i = 0; i < _targets.size(); i++)
 			if (_targets[i] == addr)
@@ -116,6 +154,7 @@
 
 	CFG(vector<Instruction*> &v) {
 		Script s(v);
+		_v = new vector<Instruction*>(v);
 		_targets.push_back(0);
 		for (uint32 i = 0; i < v.size(); i++) {
 			Jump *j = dynamic_cast<Jump*>(v[i]);

Modified: tools/branches/gsoc2009-decompiler/decompiler/decompiler.cc
===================================================================
--- tools/branches/gsoc2009-decompiler/decompiler/decompiler.cc	2009-06-10 12:47:19 UTC (rev 41425)
+++ tools/branches/gsoc2009-decompiler/decompiler/decompiler.cc	2009-06-10 12:47:29 UTC (rev 41426)
@@ -9,17 +9,27 @@
 #include "cfg.h"
 
 bool g_disasm = false;
-bool g_bbcuts = true;
+bool g_blocks = false;
+bool g_graph = false;
 
 int main(int argc, char **argv) {
 	int argno = 1;
 	if (argno >= argc) {
-		printf("decompiler [-disasm] file.dmp\n");
+		printf("decompiler [-disasm] [-blocks] [-graph] file.dmp\n");
 		return 0;
 	}
-	if (0 == strcmp("-disasm", argv[argno])) {
-		g_disasm = true;
-		argno++;
+	while (true) {
+		if (0 == strcmp("-disasm", argv[argno])) {
+			g_disasm = true;
+			argno++;
+		} else if (0 == strcmp("-blocks", argv[argno])) {
+			g_blocks = true;
+			argno++;
+		} else if (0 == strcmp("-graph", argv[argno])) {
+			g_graph = true;
+			argno++;
+		} else
+			break;
 	}
 	vector<Instruction*> v = Scumm6Parser().parseFile(argv[argno]);
 	if (g_disasm) {
@@ -31,7 +41,9 @@
 		}
 	}
 	CFG *cfg = new CFG(v);
-	for (uint32 i = 0; i < cfg->_blocks.size(); i++)
-		cfg->_blocks[i]->print(v);
+	if (g_blocks)
+		cfg->printBBs();
+	if (g_graph)
+		cfg->printDot();
 	return 0;
 }

Modified: tools/branches/gsoc2009-decompiler/decompiler/instruction.h
===================================================================
--- tools/branches/gsoc2009-decompiler/decompiler/instruction.h	2009-06-10 12:47:19 UTC (rev 41425)
+++ tools/branches/gsoc2009-decompiler/decompiler/instruction.h	2009-06-10 12:47:29 UTC (rev 41426)
@@ -40,7 +40,7 @@
 		for (uint32 i = 0; i < _v.size(); i++)
 			if (_v[i]->_addr == addr)
 				return i;
-		printf("!!! no instruction with address %x (%d)\n", addr, addr);
+		fprintf(stderr, "!!! no instruction with address %x (%d)\n", addr, addr);
 		return -1;
 	}
 

Modified: tools/branches/gsoc2009-decompiler/decompiler/reader.h
===================================================================
--- tools/branches/gsoc2009-decompiler/decompiler/reader.h	2009-06-10 12:47:19 UTC (rev 41425)
+++ tools/branches/gsoc2009-decompiler/decompiler/reader.h	2009-06-10 12:47:29 UTC (rev 41426)
@@ -63,7 +63,7 @@
 				ssret << '"';
 				break;
 			default:
-				printf("! unhandled format char '%c'\n", _format[i]);
+				fprintf(stderr, "! unhandled format char '%c'\n", _format[i]);
 				return false;
 			}
 		description = ssret.str();
@@ -118,11 +118,13 @@
 	}
 
 	bool readInstruction(ifstream& f, vector<Instruction*> &v, uint32 addr) {
+		//		if (f.tellg() >= 0x67)
+		//			return false;
 		uint8 opcode = f.get();
 		if (f.eof()) {
 			return false;
 		} else if (!_dispatchTable[opcode]) {
-			printf("! unhandled opcode 0x%02x (%d) at address 0x%02x (%d)\n", opcode, opcode, addr, addr);
+			fprintf(stderr, "! unhandled opcode 0x%02x (%d) at address 0x%02x (%d)\n", opcode, opcode, addr, addr);
 			return false;
 		} else {
 			return _dispatchTable[opcode]->readInstruction(f, v, addr);


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