summaryrefslogtreecommitdiff
path: root/Source/Core/Common
diff options
context:
space:
mode:
authorhrydgard <hrydgard@gmail.com>2009-06-21 08:39:21 +0000
committerhrydgard <hrydgard@gmail.com>2009-06-21 08:39:21 +0000
commitaecaf271f1fe98cba1ebc8228ff9eff3e39e72c5 (patch)
tree4c82001793b35149ae81fcb483f13b22d3b6fa11 /Source/Core/Common
parent80217a6ed718d15c75784090340cd3ddd9432f96 (diff)
New DSP debugger: step one. (not ready yet, but try loading zelda WW and look at the dsp debugger..).
Had to shuffle around quite a lot of code to be able to extract the CodeView into a library nicely so it can be used from both the main dolphin and the LLE plugin... also extracted the symboldb code. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3517 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/Common')
-rw-r--r--Source/Core/Common/Common.vcproj12
-rw-r--r--Source/Core/Common/Src/DebugInterface.h35
-rw-r--r--Source/Core/Common/Src/StringUtil.cpp29
-rw-r--r--Source/Core/Common/Src/StringUtil.h2
-rw-r--r--Source/Core/Common/Src/SymbolDB.cpp59
-rw-r--r--Source/Core/Common/Src/SymbolDB.h122
6 files changed, 259 insertions, 0 deletions
diff --git a/Source/Core/Common/Common.vcproj b/Source/Core/Common/Common.vcproj
index 542fb97b34..bfd4fbfe2c 100644
--- a/Source/Core/Common/Common.vcproj
+++ b/Source/Core/Common/Common.vcproj
@@ -605,6 +605,10 @@
>
</File>
<File
+ RelativePath=".\Src\DebugInterface.h"
+ >
+ </File>
+ <File
RelativePath=".\Src\DynamicLibrary.cpp"
>
</File>
@@ -781,6 +785,14 @@
>
</File>
<File
+ RelativePath=".\Src\SymbolDB.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Src\SymbolDB.h"
+ >
+ </File>
+ <File
RelativePath=".\Src\Thread.cpp"
>
</File>
diff --git a/Source/Core/Common/Src/DebugInterface.h b/Source/Core/Common/Src/DebugInterface.h
new file mode 100644
index 0000000000..804125b8dd
--- /dev/null
+++ b/Source/Core/Common/Src/DebugInterface.h
@@ -0,0 +1,35 @@
+#ifndef _DEBUGINTERFACE_H
+#define _DEBUGINTERFACE_H
+
+#include <string>
+#include <string.h>
+
+class DebugInterface
+{
+protected:
+ virtual ~DebugInterface() {}
+
+public:
+ virtual void disasm(unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");}
+ virtual void getRawMemoryString(int memory, unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");}
+ virtual int getInstructionSize(int /*instruction*/) {return 1;}
+ virtual bool isAlive() {return true;}
+ virtual bool isBreakpoint(unsigned int /*address*/) {return false;}
+ virtual void setBreakpoint(unsigned int /*address*/){}
+ virtual void clearBreakpoint(unsigned int /*address*/){}
+ virtual void clearAllBreakpoints() {}
+ virtual void toggleBreakpoint(unsigned int /*address*/){}
+ virtual unsigned int readMemory(unsigned int /*address*/){return 0;}
+ virtual void writeExtraMemory(int memory, unsigned int value, unsigned int /*address*/) {}
+ virtual unsigned int readExtraMemory(int memory, unsigned int address){return 0;}
+ virtual unsigned int readInstruction(unsigned int /*address*/){return 0;}
+ virtual unsigned int getPC() {return 0;}
+ virtual void setPC(unsigned int /*address*/) {}
+ virtual void step() {}
+ virtual void runToBreakpoint() {}
+ virtual void insertBLR(unsigned int /*address*/, unsigned int) {}
+ virtual int getColor(unsigned int /*address*/){return 0xFFFFFFFF;}
+ virtual std::string getDescription(unsigned int /*address*/) = 0;
+};
+
+#endif
diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp
index 0233c5e841..b7cb1adb1c 100644
--- a/Source/Core/Common/Src/StringUtil.cpp
+++ b/Source/Core/Common/Src/StringUtil.cpp
@@ -460,3 +460,32 @@ void NormalizeDirSep(std::string* str)
}
#endif
}
+
+std::string TabsToSpaces(int tab_size, const std::string &in)
+{
+ std::string out;
+ int len = 0;
+ // First, compute the size of the new string.
+ for (int i = 0; i < in.size(); i++)
+ {
+ if (in[i] == '\t')
+ len += tab_size;
+ else
+ len += 1;
+ }
+ out.resize(len);
+ int out_ctr = 0;
+ for (int i = 0; i < in.size(); i++)
+ {
+ if (in[i] == '\t')
+ {
+ for (int j = 0; j < tab_size; j++)
+ out[out_ctr++] = ' ';
+ }
+ else
+ {
+ out[out_ctr++] = in[i];
+ }
+ }
+ return out;
+} \ No newline at end of file
diff --git a/Source/Core/Common/Src/StringUtil.h b/Source/Core/Common/Src/StringUtil.h
index 4dbcc7ff8e..44d56b32f7 100644
--- a/Source/Core/Common/Src/StringUtil.h
+++ b/Source/Core/Common/Src/StringUtil.h
@@ -66,6 +66,8 @@ bool AsciiToHex(const char* _szValue, u32& result);
u32 Ascii2Hex(std::string _Text);
std::string Hex2Ascii(u32 _Text);
+std::string TabsToSpaces(int tab_size, const std::string &in);
+
void SplitString(const std::string& str, const std::string& delim, std::vector<std::string>& output);
int ChooseStringFrom(const char* str, const char* * items);
diff --git a/Source/Core/Common/Src/SymbolDB.cpp b/Source/Core/Common/Src/SymbolDB.cpp
new file mode 100644
index 0000000000..86161b6b9c
--- /dev/null
+++ b/Source/Core/Common/Src/SymbolDB.cpp
@@ -0,0 +1,59 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "SymbolDB.h"
+
+
+void SymbolDB::List()
+{
+ for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
+ {
+ DEBUG_LOG(HLE,"%s @ %08x: %i bytes (hash %08x) : %i calls", iter->second.name.c_str(), iter->second.address, iter->second.size, iter->second.hash,iter->second.numCalls);
+ }
+ INFO_LOG(HLE,"%i functions known in this program above.", functions.size());
+}
+
+void SymbolDB::Clear(const char *prefix)
+{
+ // TODO: honor prefix
+ functions.clear();
+ checksumToFunction.clear();
+}
+
+void SymbolDB::Index()
+{
+ int i = 0;
+ for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
+ {
+ iter->second.index = i++;
+ }
+}
+
+Symbol *SymbolDB::GetSymbolFromName(const char *name)
+{
+ for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
+ {
+ if (!strcmp(iter->second.name.c_str(), name))
+ return &iter->second;
+ }
+ return 0;
+}
+
+void SymbolDB::AddCompleteSymbol(const Symbol &symbol)
+{
+ functions.insert(std::pair<u32, Symbol>(symbol.address, symbol));
+}
diff --git a/Source/Core/Common/Src/SymbolDB.h b/Source/Core/Common/Src/SymbolDB.h
new file mode 100644
index 0000000000..dc6ba56f23
--- /dev/null
+++ b/Source/Core/Common/Src/SymbolDB.h
@@ -0,0 +1,122 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+
+// This file contains a generic symbol map implementation. For CPU-specific
+// magic, derive and extend.
+
+#ifndef _SYMBOL_DB_H
+#define _SYMBOL_DB_H
+
+#include <string>
+#include <map>
+
+#include "Common.h"
+
+struct SCall
+{
+ SCall(u32 a, u32 b) :
+ function(a),
+ callAddress(b)
+ {}
+ u32 function;
+ u32 callAddress;
+};
+
+struct Symbol
+{
+ enum {
+ SYMBOL_FUNCTION = 0,
+ SYMBOL_DATA = 1,
+ };
+
+ Symbol() :
+ hash(0),
+ address(0),
+ flags(0),
+ size(0),
+ numCalls(0),
+ type(SYMBOL_FUNCTION),
+ analyzed(0)
+ {}
+
+ std::string name;
+ std::vector<SCall> callers; //addresses of functions that call this function
+ std::vector<SCall> calls; //addresses of functions that are called by this function
+ u32 hash; //use for HLE function finding
+ u32 address;
+ u32 flags;
+ int size;
+ int numCalls;
+ int type;
+ int index; // only used for coloring the disasm view
+ int analyzed;
+};
+
+enum
+{
+ FFLAG_TIMERINSTRUCTIONS=(1<<0),
+ FFLAG_LEAF=(1<<1),
+ FFLAG_ONLYCALLSNICELEAFS=(1<<2),
+ FFLAG_EVIL=(1<<3),
+ FFLAG_RFI=(1<<4),
+ FFLAG_STRAIGHT=(1<<5)
+};
+
+
+
+class SymbolDB
+{
+public:
+ typedef std::map<u32, Symbol> XFuncMap;
+ typedef std::map<u32, Symbol*> XFuncPtrMap;
+
+protected:
+ XFuncMap functions;
+ XFuncPtrMap checksumToFunction;
+
+public:
+ SymbolDB() {}
+ virtual ~SymbolDB() {}
+ virtual Symbol *GetSymbolFromAddr(u32 addr) { return 0; }
+ virtual Symbol *AddFunction(u32 startAddr) { return 0;}
+
+ void AddCompleteSymbol(const Symbol &symbol);
+
+ Symbol *GetSymbolFromName(const char *name);
+ Symbol *GetSymbolFromHash(u32 hash) {
+ XFuncPtrMap::iterator iter = checksumToFunction.find(hash);
+ if (iter != checksumToFunction.end())
+ return iter->second;
+ else
+ return 0;
+ }
+
+ const XFuncMap &Symbols() const {return functions;}
+ XFuncMap &AccessSymbols() {return functions;}
+
+ // deprecated
+ XFuncMap::iterator GetIterator() { return functions.begin(); }
+ XFuncMap::const_iterator GetConstIterator() { return functions.begin(); }
+ XFuncMap::iterator End() { return functions.end(); }
+
+ void Clear(const char *prefix = "");
+ void List();
+ void Index();
+};
+
+#endif