144 lines
3.9 KiB
C++
144 lines
3.9 KiB
C++
#ifndef _SYMBOLSOURCEDIA_H_
|
|
#define _SYMBOLSOURCEDIA_H_
|
|
|
|
#include "_global.h"
|
|
|
|
#include "pdbdiafile.h"
|
|
#include "symbolsourcebase.h"
|
|
|
|
#include <thread>
|
|
#include <atomic>
|
|
#include <mutex>
|
|
|
|
class SymbolSourceDIA : public SymbolSourceBase
|
|
{
|
|
struct CachedLineInfo
|
|
{
|
|
uint32 rva;
|
|
uint32 lineNumber;
|
|
uint32 sourceFileIndex;
|
|
};
|
|
|
|
struct ScopedDecrement
|
|
{
|
|
private:
|
|
std::atomic<duint> & _counter;
|
|
public:
|
|
ScopedDecrement(const ScopedDecrement &) = delete;
|
|
ScopedDecrement & operator=(const ScopedDecrement &) = delete;
|
|
ScopedDecrement(std::atomic<duint> & counter) : _counter(counter) {}
|
|
~ScopedDecrement() { _counter--; }
|
|
};
|
|
|
|
private: //symbols
|
|
std::vector<SymbolInfo> _symData;
|
|
|
|
struct AddrIndex
|
|
{
|
|
duint addr;
|
|
size_t index;
|
|
|
|
bool operator<(const AddrIndex & b) const
|
|
{
|
|
return addr < b.addr;
|
|
}
|
|
};
|
|
|
|
std::vector<AddrIndex> _symAddrMap; //rva -> data index (sorted on rva)
|
|
std::vector<NameIndex> _symNameMap; //name -> data index (sorted on name)
|
|
|
|
private: //line info
|
|
std::vector<CachedLineInfo> _linesData;
|
|
std::vector<AddrIndex> _lineAddrMap; //addr -> line
|
|
std::vector<String> _sourceFiles; // uniqueId + name
|
|
|
|
struct LineIndex
|
|
{
|
|
uint32_t line;
|
|
uint32_t index;
|
|
|
|
bool operator<(const LineIndex & b) const
|
|
{
|
|
return line < b.line;
|
|
}
|
|
};
|
|
|
|
std::vector<std::vector<LineIndex>> _sourceLines; //uses index in _sourceFiles
|
|
|
|
private: //general
|
|
HANDLE _symbolsThread = nullptr;
|
|
HANDLE _sourceLinesThread = nullptr;
|
|
std::atomic<bool> _requiresShutdown;
|
|
std::atomic<duint> _loadCounter;
|
|
|
|
bool _isOpen;
|
|
std::string _path;
|
|
std::string _modname;
|
|
duint _imageBase;
|
|
duint _imageSize;
|
|
std::atomic<bool> _symbolsLoaded = false;
|
|
std::atomic<bool> _linesLoaded = false;
|
|
|
|
private:
|
|
static int hackicmp(const char* s1, const char* s2)
|
|
{
|
|
unsigned char c1, c2;
|
|
while((c1 = *s1++) == (c2 = *s2++))
|
|
if(c1 == '\0')
|
|
return 0;
|
|
s1--, s2--;
|
|
while((c1 = tolower(*s1++)) == (c2 = tolower(*s2++)))
|
|
if(c1 == '\0')
|
|
return 0;
|
|
return c1 - c2;
|
|
}
|
|
|
|
public:
|
|
static bool isLibraryAvailable()
|
|
{
|
|
return PDBDiaFile::initLibrary();
|
|
}
|
|
|
|
public:
|
|
SymbolSourceDIA();
|
|
|
|
virtual ~SymbolSourceDIA() override;
|
|
|
|
virtual bool isOpen() const override;
|
|
|
|
virtual bool isLoading() const override;
|
|
|
|
virtual bool cancelLoading() override;
|
|
|
|
virtual void waitUntilLoaded() override;
|
|
|
|
virtual bool findSymbolExact(duint rva, SymbolInfo & symInfo) override;
|
|
|
|
virtual bool findSymbolExactOrLower(duint rva, SymbolInfo & symInfo) override;
|
|
|
|
virtual void enumSymbols(const CbEnumSymbol & cbEnum) override;
|
|
|
|
virtual bool findSourceLineInfo(duint rva, LineInfo & lineInfo) override;
|
|
|
|
virtual bool findSourceLineInfo(const std::string & file, int line, LineInfo & lineInfo) override;
|
|
|
|
virtual bool findSymbolByName(const std::string & name, SymbolInfo & symInfo, bool caseSensitive) override;
|
|
|
|
virtual bool findSymbolsByPrefix(const std::string & prefix, const std::function<bool(const SymbolInfo &)> & cbSymbol, bool caseSensitive) override;
|
|
|
|
virtual std::string loadedSymbolPath() const override;
|
|
|
|
public:
|
|
bool loadPDB(const std::string & path, const std::string & modname, duint imageBase, duint imageSize, DiaValidationData_t* validationData);
|
|
|
|
private:
|
|
bool loadSymbolsAsync();
|
|
bool loadSourceLinesAsync();
|
|
uint32_t findSourceFile(const std::string & fileName) const;
|
|
|
|
static DWORD WINAPI SymbolsThread(void* parameter);
|
|
static DWORD WINAPI SourceLinesThread(void* parameter);
|
|
};
|
|
|
|
#endif // _SYMBOLSOURCEPDB_H_
|