From e22b5e319fd30a2cd075c20d99694a1dc8ff7ee2 Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Thu, 27 Dec 2012 05:38:27 +0000
Subject: [PATCH] [0.2.x] added: if there is no symbol information, symbols
 construct from module exports

git-svn-id: https://pykd.svn.codeplex.com/svn@82047 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/dia/diawrapper.h |  2 +-
 pykd/module.cpp       | 32 +++++++++++++++++++++++++-------
 pykd/module.h         |  8 +++++++-
 pykd/symengine.h      |  8 +++++---
 4 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/pykd/dia/diawrapper.h b/pykd/dia/diawrapper.h
index 906a37d..9bda0d8 100644
--- a/pykd/dia/diawrapper.h
+++ b/pykd/dia/diawrapper.h
@@ -228,7 +228,7 @@ public:
         m_session( session )
         {}
 
-    SymbolPtr& getSymbolScope() {
+    SymbolPtr getSymbolScope() {
         return m_globalSymbol;
     }
 
diff --git a/pykd/module.cpp b/pykd/module.cpp
index 6537914..4dc0bf7 100644
--- a/pykd/module.cpp
+++ b/pykd/module.cpp
@@ -55,11 +55,14 @@ SymbolSessionPtr& Module::getSymSession()
     if (m_symSession)
         return m_symSession;
 
-    SymbolMapKey cacheKey = { m_size, m_timeDataStamp, m_checkSum };
+    SymbolMapKey cacheKey = { m_name, m_size, m_timeDataStamp, m_checkSum };
     SymbolSessionCache::iterator found = m_symSessionCache.find( cacheKey );
     if ( found != m_symSessionCache.end() )
     {
         m_symSession = found->second;
+        if ( !m_symSession )
+            throw SymbolException( "failed to load symbol file" );
+
         return m_symSession;
     }
 
@@ -79,12 +82,27 @@ SymbolSessionPtr& Module::getSymSession()
     // TODO: read image file path and load using IDiaReadExeAtOffsetCallback
 
     m_symfile = getModuleSymbolFileName(m_base);
-    if (m_symfile.empty())
-         throw SymbolException( "failed to find symbol file" );
+    if (!m_symfile.empty() )
+    {
+        try
+        {
+            m_symSession = loadSymbolFile(m_symfile, m_base);
+        }
+        catch(const SymbolException&)
+        {
+        }
+
+        if (m_symSession)
+        {
+            m_symSessionCache.insert( std::make_pair( cacheKey, m_symSession ) );
+            return m_symSession;
+        }
+    }
 
     try
     {
-        m_symSession = loadSymbolFile(m_symfile, m_base);
+        m_symSession = loadSymbolFromExports(m_base);
+        m_symfile = "export symbols";
     }
     catch(const SymbolException&)
     {
@@ -96,14 +114,14 @@ SymbolSessionPtr& Module::getSymSession()
         return m_symSession;
     }
 
-    m_symfile.clear();
+    m_symSessionCache.insert( std::make_pair( cacheKey, SymbolSessionPtr() ) );
 
     throw SymbolException( "failed to load symbol file" );
 }
 
 /////////////////////////////////////////////////////////////////////////////////////
 
-SymbolPtr& Module::getSymScope()
+SymbolPtr Module::getSymScope()
 {
     return getSymSession()->getSymbolScope();
 }
@@ -112,7 +130,7 @@ SymbolPtr& Module::getSymScope()
 
 void Module::reloadSymbols()
 {
-    SymbolMapKey cacheKey = { m_size, m_timeDataStamp, m_checkSum };
+    SymbolMapKey cacheKey = { m_name, m_size, m_timeDataStamp, m_checkSum };
     m_symSessionCache.erase( cacheKey );
 
     m_symSession.reset();
diff --git a/pykd/module.h b/pykd/module.h
index b9a219b..6a66bfe 100644
--- a/pykd/module.h
+++ b/pykd/module.h
@@ -27,12 +27,18 @@ public:
 private:
 
     struct SymbolMapKey{
+        std::string name;
         ULONG  size;
         ULONG  timeStamp;
         ULONG  checkSum;
 
         bool operator < ( const SymbolMapKey& key ) const
         {
+            if ( name < key.name )
+                return true;
+            if ( name > key.name )
+                return false;
+
             if ( size < key.size )
                 return true;
             if ( size > key.size )
@@ -143,7 +149,7 @@ public:
 
 private:
 
-    SymbolPtr& getSymScope();
+    SymbolPtr getSymScope();
 
     SymbolSessionPtr& getSymSession();
 
diff --git a/pykd/symengine.h b/pykd/symengine.h
index 78093dc..7c79157 100644
--- a/pykd/symengine.h
+++ b/pykd/symengine.h
@@ -161,7 +161,7 @@ class SymbolSession {
 
 public:
 
-    virtual SymbolPtr& getSymbolScope() = 0;
+    virtual SymbolPtr getSymbolScope() = 0;
 
     virtual SymbolPtr findByRva( ULONG rva, ULONG symTag = SymTagNull, LONG* displacement = NULL ) = 0;
 
@@ -183,6 +183,8 @@ SymbolSessionPtr loadSymbolFile(
 
 void setSymSrvDir(const std::wstring &symSrvDirectory);
 
-////////////////////////////////////////////////////////////////////////////////
+SymbolSessionPtr loadSymbolFromExports(ULONGLONG loadBase); 
 
-}; // end pykd endpoint
\ No newline at end of file
+///////////////////////////////////////////////////////////////////////////////
+
+}; // end pykd namespace
\ No newline at end of file