[Scummvm-cvs-logs] SF.net SVN: scummvm:[53646] scummvm/trunk/engines/sci

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Wed Oct 20 19:31:30 CEST 2010


Revision: 53646
          http://scummvm.svn.sourceforge.net/scummvm/?rev=53646&view=rev
Author:   thebluegr
Date:     2010-10-20 17:31:29 +0000 (Wed, 20 Oct 2010)

Log Message:
-----------
SCI: Added a new debug command, "find_callk"

This command can be used to find the object methods (including their
corresponding objects and owner scripts) that call a specific kernel
call. This shall aid us track all the spots where a particular kernel
function is called from, therefore it'll be a bit easier to find
examples where unimplemented kernel functions are called

Modified Paths:
--------------
    scummvm/trunk/engines/sci/console.cpp
    scummvm/trunk/engines/sci/console.h
    scummvm/trunk/engines/sci/engine/kernel.cpp
    scummvm/trunk/engines/sci/engine/kernel.h
    scummvm/trunk/engines/sci/engine/segment.h

Modified: scummvm/trunk/engines/sci/console.cpp
===================================================================
--- scummvm/trunk/engines/sci/console.cpp	2010-10-20 15:39:08 UTC (rev 53645)
+++ scummvm/trunk/engines/sci/console.cpp	2010-10-20 17:31:29 UTC (rev 53646)
@@ -166,6 +166,7 @@
 	DCmd_Register("snk",				WRAP_METHOD(Console, cmdStepCallk));	// alias
 	DCmd_Register("disasm",				WRAP_METHOD(Console, cmdDisassemble));
 	DCmd_Register("disasm_addr",		WRAP_METHOD(Console, cmdDisassembleAddress));
+	DCmd_Register("find_callk",			WRAP_METHOD(Console, cmdFindKernelFunctionCall));
 	DCmd_Register("send",				WRAP_METHOD(Console, cmdSend));
 	DCmd_Register("go",					WRAP_METHOD(Console, cmdGo));
 	DCmd_Register("logkernel",          WRAP_METHOD(Console, cmdLogKernel));
@@ -2637,11 +2638,88 @@
 	return true;
 }
 
+bool Console::cmdFindKernelFunctionCall(int argc, const char **argv) {
+	if (argc < 2) {
+		DebugPrintf("Finds the scripts and methods that call a specific kernel function.\n");
+		DebugPrintf("Usage: %s <kernel function>\n", argv[0]);
+		DebugPrintf("Example: %s Display\n", argv[0]);
+		return true;
+	}
+
+	// Find the number of the kernel function call
+	int kernelFuncNum = _engine->getKernel()->findKernelFuncPos(argv[1]);
+
+	if (kernelFuncNum < 0) {
+		DebugPrintf("Invalid kernel function requested");
+		return true;
+	}
+
+	Common::List<ResourceId> *resources = _engine->getResMan()->listResources(kResourceTypeScript);
+	Common::sort(resources->begin(), resources->end());
+	Common::List<ResourceId>::iterator itr = resources->begin();
+
+	DebugPrintf("%d scripts found, dissassembling...\n", resources->size());
+
+	int scriptSegment;
+	Script *script;
+	SegManager *segMan = _engine->getEngineState()->_segMan;
+
+	while (itr != resources->end()) {
+		// Load script
+		scriptSegment = segMan->instantiateScript(itr->getNumber());
+		script = segMan->getScript(scriptSegment);
+
+		// Iterate through all the script's objects
+		ObjMap::iterator it;
+		const ObjMap::iterator end = script->_objects.end();
+		for (it = script->_objects.begin(); it != end; ++it) {
+			const Object *obj = segMan->getObject(it->_value.getPos());
+			const char *objName = segMan->getObjectName(it->_value.getPos());
+
+			// Now dissassemble each method of the script object
+			for (uint16 i = 0; i < obj->getMethodCount(); i++) {
+				reg_t fptr = obj->getFunction(i);
+				uint16 offset = fptr.offset;
+				int16 opparams[4];
+				byte extOpcode;
+				byte opcode;
+
+				while (true) {
+					offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams);
+					opcode = extOpcode >> 1;
+
+					if (opcode == op_callk) {
+						uint16 kFuncNum = opparams[0];
+						uint16 argc = opparams[1];
+
+						if (kFuncNum == kernelFuncNum) {
+							DebugPrintf("Called from script %d, object %s, method %s(%d) with %d parameters\n", 
+								itr->getNumber(), objName, 
+								_engine->getKernel()->getSelectorName(obj->getFuncSelector(i)).c_str(), i, argc);
+						}
+					}
+
+					// Check for end of function/script
+					if (opcode == op_ret || offset >= script->getBufSize())
+						break;
+				}	// while (true)
+			}	// for (uint16 i = 0; i < obj->getMethodCount(); i++)
+		}	// for (it = script->_objects.begin(); it != end; ++it)
+
+		segMan->uninstantiateScript(itr->getNumber());
+		++itr;
+	}
+
+	delete resources;
+
+	return true;
+}
+
 bool Console::cmdSend(int argc, const char **argv) {
 	if (argc < 3) {
 		DebugPrintf("Sends a message to an object.\n");
 		DebugPrintf("Usage: %s <object> <selector name> <param1> <param2> ... <paramn>\n", argv[0]);
-		DebugPrintf("Example: send ?fooScript cue\n");
+		DebugPrintf("Example: %s ?fooScript cue\n", argv[0]);
 		return true;
 	}
 

Modified: scummvm/trunk/engines/sci/console.h
===================================================================
--- scummvm/trunk/engines/sci/console.h	2010-10-20 15:39:08 UTC (rev 53645)
+++ scummvm/trunk/engines/sci/console.h	2010-10-20 17:31:29 UTC (rev 53646)
@@ -128,6 +128,7 @@
 	bool cmdStepCallk(int argc, const char **argv);
 	bool cmdDisassemble(int argc, const char **argv);
 	bool cmdDisassembleAddress(int argc, const char **argv);
+	bool cmdFindKernelFunctionCall(int argc, const char **argv);
 	bool cmdSend(int argc, const char **argv);
 	bool cmdGo(int argc, const char **argv);
 	bool cmdLogKernel(int argc, const char **argv);

Modified: scummvm/trunk/engines/sci/engine/kernel.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.cpp	2010-10-20 15:39:08 UTC (rev 53645)
+++ scummvm/trunk/engines/sci/engine/kernel.cpp	2010-10-20 17:31:29 UTC (rev 53646)
@@ -88,6 +88,14 @@
 	return _kernelNames[number];
 }
 
+int Kernel::findKernelFuncPos(Common::String kernelFuncName) {
+	for (uint32 i = 0; i < _kernelNames.size(); i++)
+		if (_kernelNames[i] == kernelFuncName)
+			return i;
+
+	return -1;
+}
+
 int Kernel::findSelector(const char *selectorName) const {
 	for (uint pos = 0; pos < _selectorNames.size(); ++pos) {
 		if (_selectorNames[pos] == selectorName)

Modified: scummvm/trunk/engines/sci/engine/kernel.h
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.h	2010-10-20 15:39:08 UTC (rev 53645)
+++ scummvm/trunk/engines/sci/engine/kernel.h	2010-10-20 17:31:29 UTC (rev 53646)
@@ -151,6 +151,7 @@
 
 	uint getSelectorNamesSize() const;
 	const Common::String &getSelectorName(uint selector);
+	int findKernelFuncPos(Common::String kernelFuncName);
 
 	uint getKernelNamesSize() const;
 	const Common::String &getKernelName(uint number) const;

Modified: scummvm/trunk/engines/sci/engine/segment.h
===================================================================
--- scummvm/trunk/engines/sci/engine/segment.h	2010-10-20 15:39:08 UTC (rev 53645)
+++ scummvm/trunk/engines/sci/engine/segment.h	2010-10-20 17:31:29 UTC (rev 53646)
@@ -246,7 +246,7 @@
 	reg_t getInfoSelector() const { return _variables[_offset + 2]; }
 	void setInfoSelector(reg_t value) { _variables[_offset + 2] = value; }
 
-	reg_t getNameSelector() const { return _variables[_offset + 3]; }
+	reg_t getNameSelector() const { return _offset + 3 < (uint16)_variables.size() ? _variables[_offset + 3] : NULL_REG; }
 	void setNameSelector(reg_t value) { _variables[_offset + 3] = value; }
 
 	reg_t getPropDictSelector() const { return _variables[2]; }


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