feat: extract typeIndex from PDB symbols and add symbols.importType MCP tool

extractPdbSymbols() was reading S_GDATA32/S_GTHREAD32 records which
contain a typeIndex field linking the symbol to its type definition in
the TPI stream, but this field was discarded — only name + RVA were
kept. This meant loading symbols gave you address resolution but no
way to automatically import the type associated with a global variable.

Changes:
- PdbSymbol now carries typeIndex (0 = no type info / public symbol)
- extractPdbSymbols() captures typeIndex from all global data symbols
- PdbSymbolSet stores nameToTypeIndex mapping alongside nameToRva
- New importTypeForSymbol() follows LF_POINTER/LF_MODIFIER chains to
  find the underlying UDT/enum and imports it with full recursive children
- New symbols.importType MCP tool: given "ntdll!g_pShimEngineModule",
  resolves its typeIndex, imports the type definition from the PDB, and
  merges it into the active project
- loadPdbIntoStore() helper consolidates the extract+store pattern with
  type index support
This commit is contained in:
IChooseYou
2026-03-14 18:11:57 -06:00
committed by IChooseYou
parent cb10bc8a82
commit dc6963e0d5
8 changed files with 643 additions and 26 deletions

View File

@@ -52,6 +52,26 @@ int SymbolStore::addModule(const QString& moduleName, const QString& pdbPath,
return count;
}
void SymbolStore::addModuleTypeIndices(const QString& moduleName,
const QHash<QString, uint32_t>& nameToTypeIndex) {
QString canonical = resolveAlias(moduleName);
auto it = m_modules.find(canonical);
if (it == m_modules.end()) return;
it->nameToTypeIndex = nameToTypeIndex;
}
uint32_t SymbolStore::typeIndexForSymbol(const QString& qualifiedSymbol) const {
int bangIdx = qualifiedSymbol.indexOf('!');
if (bangIdx <= 0 || bangIdx >= qualifiedSymbol.size() - 1)
return 0;
QString modPart = qualifiedSymbol.left(bangIdx);
QString symPart = qualifiedSymbol.mid(bangIdx + 1);
QString canonical = resolveAlias(modPart);
auto modIt = m_modules.find(canonical);
if (modIt == m_modules.end()) return 0;
return modIt->nameToTypeIndex.value(symPart, 0);
}
void SymbolStore::unloadModule(const QString& moduleName) {
QString canonical = resolveAlias(moduleName);
m_modules.remove(canonical);