[0.2.x] - synthetic symbols src

git-svn-id: https://pykd.svn.codeplex.com/svn@80200 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\EreTIk_cp 2012-10-14 10:34:07 +00:00 committed by Mikhail I. Izmestev
parent 38b25e0ccc
commit b4564ca827
4 changed files with 0 additions and 648 deletions

View File

@ -1,248 +0,0 @@
#include "stdafx.h"
#include <boost/algorithm/string.hpp>
#include "dbgmem.h"
#include "dbgexcept.h"
#include "dbgclient.h"
#include "synsymhelpers.h"
namespace pykd {
////////////////////////////////////////////////////////////////////////////////
SyntheticSymbols::SyntheticSymbols(
IDebugSymbols3 &symbols,
DebugClient &dbgClient
) : m_symbols(symbols)
, m_dbgClient(dbgClient)
{
m_allSymbolsLock.reset(new boost::recursive_mutex);
}
////////////////////////////////////////////////////////////////////////////////
void SyntheticSymbols::add(
ULONG64 addr,
ULONG size,
const std::string &symName
)
{
addr = m_dbgClient.addr64(addr);
// add new synthetic symbol to debug engine
DEBUG_MODULE_AND_ID dbgModuleAndId = { 0 };
HRESULT hres =
m_symbols.AddSyntheticSymbol(
addr,
size,
symName.c_str(),
DEBUG_ADDSYNTHSYM_DEFAULT,
&dbgModuleAndId);
if ( FAILED( hres ) )
throw AddSyntheticSymbolException( hres );
// add/update symbol for target module (in internal map)
SymbolsScopedLock lock(*m_allSymbolsLock);
ModSymbols &modSymbols =
m_allSymbols[SynSymHelper(m_symbols).modByBase(dbgModuleAndId.ModuleBase)];
SymbolData &symData = modSymbols[addr - dbgModuleAndId.ModuleBase];
symData.m_name = symName;
symData.m_size = size;
}
////////////////////////////////////////////////////////////////////////////////
ULONG SyntheticSymbols::remove(ULONG64 addr)
{
addr = m_dbgClient.addr64(addr);
SynSymHelper synSymHelper(m_symbols);
// find target module
ULONG64 moduleBase;
SymbolsScopedLock lock(*m_allSymbolsLock);
AllSymbols::iterator itModSymbols =
m_allSymbols.find(synSymHelper.modByOffset(addr, moduleBase));
if (itModSymbols == m_allSymbols.end())
return 0;
// remove symbol from internal map
itModSymbols->second.erase(addr - moduleBase);
// remove symbol from debug engine
return synSymHelper.removeSyntheticSymbols(addr);
}
////////////////////////////////////////////////////////////////////////////////
ULONG SyntheticSymbols::removeByMask(
const std::string &moduleName,
const std::string &symName
)
{
SynSymHelper synSymHelper(m_symbols);
std::vector<DEBUG_MODULE_AND_ID> dbgSymbols;
HRESULT hres =
synSymHelper.getSymbolsByMaks(
moduleName + "!" + symName,
dbgSymbols);
if (FAILED(hres))
throw DbgException("IDebugSymbols3::GetSymbolEntriesByName", hres);
if (dbgSymbols.empty())
return 0;
ULONG removed = 0;
SymbolsScopedLock lock(*m_allSymbolsLock);
for (ULONG i =0; i < dbgSymbols.size(); ++i)
{
DEBUG_SYMBOL_ENTRY dbgSymbolInfo;
HRESULT hres =
m_symbols.GetSymbolEntryInformation(
&dbgSymbols[i],
&dbgSymbolInfo);
if (FAILED(hres))
continue;
// try find modules in internal map
AllSymbols::iterator itModSymbols =
m_allSymbols.find(synSymHelper.modByBase(dbgSymbolInfo.ModuleBase));
if (itModSymbols == m_allSymbols.end())
continue;
// try find symbol
ModSymbols::iterator itSymbol =
itModSymbols->second.find(dbgSymbolInfo.Offset - dbgSymbolInfo.ModuleBase);
if (itSymbol == itModSymbols->second.end())
continue;
// remove from debug engine
if (synSymHelper.removeSyntheticSymbols(dbgSymbols[i]))
++removed;
// remove from internal map
itModSymbols->second.erase(itSymbol);
if (itModSymbols->second.empty())
m_allSymbols.erase(itModSymbols);
}
return removed;
}
////////////////////////////////////////////////////////////////////////////////
void SyntheticSymbols::clear()
{
SymbolsScopedLock lock(*m_allSymbolsLock);
// clean symbols from debug engine
forEachLoadedModule( SynSymRemoveAll(m_symbols) );
// clean internal map
m_allSymbols.clear();
}
////////////////////////////////////////////////////////////////////////////////
void SyntheticSymbols::restoreForModule(ULONG64 moduleBase)
{
SymbolsScopedLock lock(*m_allSymbolsLock);
SynSymRestore restorer(m_symbols);
AllSymbols::iterator itFoundModule =
m_allSymbols.find( restorer.modByBase(moduleBase) );
if (itFoundModule == m_allSymbols.end())
return;
forEachFromModule(moduleBase, itFoundModule->second, restorer);
}
////////////////////////////////////////////////////////////////////////////////
void SyntheticSymbols::restoreAll()
{
SymbolsScopedLock lock(*m_allSymbolsLock);
// clean symbols from debug engine
forEachLoadedModule( SynSymRestore(m_symbols) );
}
////////////////////////////////////////////////////////////////////////////////
ULONG64 SyntheticSymbols::getRvaByName(
ULONG timeDataStamp,
ULONG checkSumm,
const std::string &symName
)
{
SymbolsScopedLock lock(*m_allSymbolsLock);
AllSymbols::iterator itFoundModule =
m_allSymbols.find( ModuleId(timeDataStamp, checkSumm) );
if (itFoundModule == m_allSymbols.end())
throw DbgException("Synthetic symbol is not found");
ModSymbols::iterator itSynSymbol = itFoundModule->second.begin();
while (itSynSymbol != itFoundModule->second.end())
{
if (boost::iequals(symName, itSynSymbol->second.m_name))
return itSynSymbol->first;
++itSynSymbol;
}
throw DbgException("Synthetic symbol is not found");
}
////////////////////////////////////////////////////////////////////////////////
void SyntheticSymbols::forEachFromModule(
ULONG64 moduleBase,
const ModSymbols &modSymbols,
ISynSymForEach &forEach
)
{
ModSymbols::const_iterator itSynSymbol = modSymbols.begin();
while (itSynSymbol != modSymbols.end())
{
forEach.symbol(moduleBase, itSynSymbol->first, itSynSymbol->second);
++itSynSymbol;
}
}
////////////////////////////////////////////////////////////////////////////////
void SyntheticSymbols::forEachLoadedModule(ISynSymForEach &forEach)
{
// for loaded and unloaded modules...
std::vector<DEBUG_MODULE_PARAMETERS> dbgModules;
if (!SUCCEEDED(forEach.getAllModules(dbgModules)) || dbgModules.empty())
{
SymbolsScopedLock lock(*m_allSymbolsLock);
m_allSymbols.clear();
return;
}
std::vector<DEBUG_MODULE_PARAMETERS>::iterator itModule = dbgModules.begin();
while (itModule != dbgModules.end())
{
// ...do it!
AllSymbols::const_iterator itFoundModule =
m_allSymbols.find( ModuleId(*itModule) );
if (itFoundModule != m_allSymbols.end())
forEachFromModule(itModule->Base, itFoundModule->second, forEach);
++itModule;
}
}
////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd

View File

@ -1,141 +0,0 @@
//
// Synthetic symbol
//
#pragma once
#include "dbgexcept.h"
#include <map>
namespace pykd {
////////////////////////////////////////////////////////////////////////////////
interface ISynSymForEach;
class DebugClient;
////////////////////////////////////////////////////////////////////////////////
class SyntheticSymbols {
public:
SyntheticSymbols(
IDebugSymbols3 &symbols,
DebugClient &dbgClient
);
////////////////////////////////////////////////////////////////////////////////
// Python API:
// add new synthetic symbol
void add(
ULONG64 addr,
ULONG size,
const std::string &symName
);
// remove synthetic symbols by address
ULONG remove(ULONG64 addr);
// remove synthetic symbols by module and symbol names
ULONG removeByMask(
const std::string &moduleName,
const std::string &symName
);
// remove all synthetic symbols from all modules
void clear();
////////////////////////////////////////////////////////////////////////////////
// Debug event callback manager API:
void restoreForModule(ULONG64 moduleBase);
void restoreAll();
////////////////////////////////////////////////////////////////////////////////
// Module API:
ULONG64 getRvaByName(
ULONG timeDataStamp,
ULONG checkSumm,
const std::string &symName
);
public:
// unique module ID
struct ModuleId {
ULONG m_timeDataStamp;
ULONG m_checkSumm;
ModuleId(ULONG timeDataStamp, ULONG checkSumm)
: m_timeDataStamp(timeDataStamp)
, m_checkSumm(checkSumm)
{
}
ModuleId(const DEBUG_MODULE_PARAMETERS &dbgModuleParameters)
: m_timeDataStamp(dbgModuleParameters.TimeDateStamp)
, m_checkSumm(dbgModuleParameters.Checksum)
{
}
bool operator < (const ModuleId &rhs) const
{
return makeQword() < rhs.makeQword();
}
private:
LONG64 makeQword() const {
return
static_cast<LONG64>(m_timeDataStamp) |
(static_cast<LONG64>(m_checkSumm) << 32);
}
};
// symbol data
struct SymbolData {
std::string m_name;
ULONG m_size;
};
// synthetic symbols of one module: offset -> name+size
typedef ULONG64 SYM_OFFSET;
typedef std::map<SYM_OFFSET, SymbolData> ModSymbols;
// synthetic symbols of all modules
typedef std::map<ModuleId, ModSymbols> AllSymbols;
private:
// lock of static map
typedef boost::shared_ptr<boost::recursive_mutex> SymbolsLock;
typedef boost::recursive_mutex::scoped_lock SymbolsScopedLock;
private:
// execute for all symbols from modules
void forEachFromModule(
ULONG64 moduleBase,
const ModSymbols &modSymbols,
ISynSymForEach &forEach
);
// execute for all symbols all loaded modules
void forEachLoadedModule(ISynSymForEach &forEach);
private:
SymbolsLock m_allSymbolsLock;
AllSymbols m_allSymbols;
DebugClient &m_dbgClient;
IDebugSymbols3 &m_symbols;
};
////////////////////////////////////////////////////////////////////////////////
typedef boost::shared_ptr<SyntheticSymbols> SynSymbolsPtr;
////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd

View File

@ -1,152 +0,0 @@
#include <stdafx.h>
#include "dbgexcept.h"
#include "synsymhelpers.h"
namespace pykd {
////////////////////////////////////////////////////////////////////////////////
bool SynSymHelper::removeSyntheticSymbols(
const DEBUG_MODULE_AND_ID &dbgSymbols
)
{
return SUCCEEDED(
m_symbols.RemoveSyntheticSymbol(
const_cast<DEBUG_MODULE_AND_ID *>(&dbgSymbols)
)
);
}
////////////////////////////////////////////////////////////////////////////////
ULONG SynSymHelper::removeSyntheticSymbols(
const std::vector<DEBUG_MODULE_AND_ID> &arrSymbols
)
{
ULONG countOfRemoved = 0;
for (ULONG i = 0; i < arrSymbols.size(); ++i)
{
if (removeSyntheticSymbols(arrSymbols[i]))
++countOfRemoved;
}
return countOfRemoved;
}
////////////////////////////////////////////////////////////////////////////////
ULONG SynSymHelper::removeSyntheticSymbols(ULONG64 addr)
{
ULONG entries = 0;
m_symbols.GetSymbolEntriesByOffset(addr, 0, NULL, NULL, 0, &entries);
if (!entries)
return 0;
std::vector<DEBUG_MODULE_AND_ID> arrSymbols(entries);
HRESULT hres = m_symbols.GetSymbolEntriesByOffset(
addr,
0,
&arrSymbols[0],
NULL,
(ULONG)arrSymbols.size(),
NULL);
if (SUCCEEDED(hres))
return removeSyntheticSymbols(arrSymbols);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
SyntheticSymbols::ModuleId SynSymHelper::modByBase(ULONG64 moduleBase)
{
DEBUG_MODULE_PARAMETERS dbgModuleParameters;
HRESULT hres =
m_symbols.GetModuleParameters(
1,
&moduleBase,
0,
&dbgModuleParameters);
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbols3::GetModuleParameters", hres );
return SyntheticSymbols::ModuleId(dbgModuleParameters);
}
////////////////////////////////////////////////////////////////////////////////
SyntheticSymbols::ModuleId SynSymHelper::modByOffset(
ULONG64 moduleOffset,
ULONG64 &moduleBase
)
{
HRESULT hres =
m_symbols.GetModuleByOffset(moduleOffset, 0, NULL, &moduleBase);
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbols3::GetModuleByOffset", hres );
return modByBase(moduleBase);
}
////////////////////////////////////////////////////////////////////////////////
HRESULT SynSymHelper::getAllModules(
std::vector<DEBUG_MODULE_PARAMETERS> &dbgModules
)
{
ULONG nLoaded;
ULONG nUnloaded;
HRESULT hres = m_symbols.GetNumberModules(&nLoaded, &nUnloaded);
if (FAILED(hres))
return hres;
if (!nLoaded && !nUnloaded)
{
dbgModules.clear();
return S_OK;
}
dbgModules.resize(nLoaded + nUnloaded);
return
m_symbols.GetModuleParameters(
nLoaded + nUnloaded,
NULL,
0,
&dbgModules[0]);
}
////////////////////////////////////////////////////////////////////////////////
HRESULT SynSymHelper::getSymbolsByMaks(
const std::string &symMask,
std::vector<DEBUG_MODULE_AND_ID> &dbgSymbols
)
{
ULONG entries = 0;
m_symbols.GetSymbolEntriesByName(
symMask.c_str(),
0,
NULL,
0,
&entries);
if (!entries)
{
dbgSymbols.clear();
return S_OK;
}
dbgSymbols.resize(entries);
return
m_symbols.GetSymbolEntriesByName(
symMask.c_str(),
0,
&dbgSymbols[0],
entries,
NULL);
}
////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd

View File

@ -1,107 +0,0 @@
//
// Synthetic symbol helpers
//
#pragma once
#include <vector>
#include "synsymbol.h"
namespace pykd {
////////////////////////////////////////////////////////////////////////////////
class SynSymHelper {
public:
SynSymHelper(IDebugSymbols3 &symbols) : m_symbols(symbols) {}
// remove array of synthetic symbols from debug engine
bool removeSyntheticSymbols(
const DEBUG_MODULE_AND_ID &dbgSymbols
);
ULONG removeSyntheticSymbols(
const std::vector<DEBUG_MODULE_AND_ID> &arrSymbols
);
ULONG removeSyntheticSymbols(ULONG64 addr);
// buid ModuleId by base of image
SyntheticSymbols::ModuleId modByBase(ULONG64 moduleBase);
// buid ModuleId by offset in image
SyntheticSymbols::ModuleId modByOffset(
ULONG64 moduleOffset,
ULONG64 &moduleBase
);
// get array of all modules
HRESULT getAllModules(std::vector<DEBUG_MODULE_PARAMETERS> &dbgModules);
// get symbols by mask
HRESULT getSymbolsByMaks(
const std::string &symMask,
std::vector<DEBUG_MODULE_AND_ID> &dbgSymbols
);
protected:
IDebugSymbols3 &m_symbols;
};
////////////////////////////////////////////////////////////////////////////////
// Enumerator all synthetic symbols for loaded modules
////////////////////////////////////////////////////////////////////////////////
interface ISynSymForEach : public SynSymHelper {
ISynSymForEach(IDebugSymbols3 &symbols) : SynSymHelper(symbols) {}
virtual void symbol(
const ULONG64 moduleBase,
SyntheticSymbols::SYM_OFFSET offset,
const SyntheticSymbols::SymbolData &symData
) = 0;
};
////////////////////////////////////////////////////////////////////////////////
// Remove symbols from loaded modules
////////////////////////////////////////////////////////////////////////////////
class SynSymRemoveAll : public ISynSymForEach
{
public:
SynSymRemoveAll(IDebugSymbols3 &symbols) : ISynSymForEach(symbols) {}
virtual void symbol(
const ULONG64 moduleBase,
SyntheticSymbols::SYM_OFFSET offset,
const SyntheticSymbols::SymbolData &/*symData*/
) override
{
removeSyntheticSymbols(moduleBase + offset);
}
};
////////////////////////////////////////////////////////////////////////////////
// Restore symbols for loaded modules
////////////////////////////////////////////////////////////////////////////////
class SynSymRestore : public ISynSymForEach
{
public:
SynSymRestore(IDebugSymbols3 &symbols) : ISynSymForEach(symbols) {}
virtual void symbol(
const ULONG64 moduleBase,
SyntheticSymbols::SYM_OFFSET offset,
const SyntheticSymbols::SymbolData &symData
) override
{
m_symbols.AddSyntheticSymbol(
moduleBase + offset,
symData.m_size,
symData.m_name.c_str(),
DEBUG_ADDSYNTHSYM_DEFAULT,
NULL);
}
};
////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd