//------------------------------------------------------------------------ // pSymbol의 데이타 길이를 리턴한다. //------------------------------------------------------------------------ ULONGLONG dia::GetSymbolLength(IDiaSymbol *pSymbol) { ULONGLONG len = 0; SymbolState state; IDiaSymbol *pTypeSymbol = GetBaseTypeSymbol(pSymbol, 1, state); if (!pTypeSymbol) return 0; enum SymTagEnum symTag; HRESULT hr = pTypeSymbol->get_symTag((DWORD*)&symTag); switch (symTag) { case SymTagPointerType: case SymTagArrayType: { IDiaSymbol *pBaseType; hr = pTypeSymbol->get_type(&pBaseType); if (NEW_SYMBOL == state) SAFE_RELEASE(pTypeSymbol); pTypeSymbol = pBaseType; } break; } hr = pTypeSymbol->get_length(&len); if (NEW_SYMBOL == state) SAFE_RELEASE(pTypeSymbol); return len; }
//------------------------------------------------------------------------ // pSymbol 타입의 정보를 srcPtr 주소에서 가져온다. // pSymbol 은 srcPtr 에 저장된 심볼의 타입을 가르킨다. // pSymbol 은 SymTagData 이거나 SymTagBaseType 타입이어야 한다. // isApplyOffset : false 이면 변수의 offset을 적용하지 않는다. // 이미 계산된 상태라면 할필요 없음 //------------------------------------------------------------------------ _variant_t dia::GetValueFromSymbol(void *srcPtr, IDiaSymbol *pSymbol ) { _variant_t value; void *ptr = (BYTE*)srcPtr; enum SymTagEnum symTag; HRESULT hr = pSymbol->get_symTag((DWORD*)&symTag); ASSERT_RETV((S_OK == hr), value); bool isReleaseBaseType=false; IDiaSymbol *pBaseType; if (SymTagData == symTag) { hr = pSymbol->get_type(&pBaseType); ASSERT_RETV((S_OK == hr), value); pSymbol = pBaseType; isReleaseBaseType = true; } else { pBaseType = pSymbol; } enum SymTagEnum baseSymTag; hr = pBaseType->get_symTag((DWORD*)&baseSymTag); ASSERT_RETV(S_OK==hr, value); BasicType btype; switch (baseSymTag) { case SymTagBaseType: hr = pBaseType->get_baseType((DWORD*)&btype); ASSERT_RETV((S_OK == hr), value ); break; case SymTagPointerType: btype = btULong; break; default: if (isReleaseBaseType) pBaseType->Release(); return value; } ULONGLONG length = 0; hr = pBaseType->get_length(&length); ASSERT_RETV((S_OK == hr), value ); value = dia::GetValueFromAddress(ptr, btype, length); if (isReleaseBaseType) pBaseType->Release(); return value; }
static void DumpSymbol(IDiaSymbol *symbol) { DWORD section, offset, rva; DWORD dwTag; enum SymTagEnum tag; ULONGLONG length = 0; const char * typeName = NULL; char * dataTypeName = NULL; const char * thunkTypeName = NULL; symbol->get_symTag(&dwTag); tag = (enum SymTagEnum)dwTag; typeName = GetSymTypeName(tag); symbol->get_relativeVirtualAddress(&rva); symbol->get_addressSection(§ion); symbol->get_addressOffset(&offset); // for data, get length from type if (SymTagData == tag) { IDiaSymbol *type = NULL; if (symbol->get_type(&type) == S_OK) // no SUCCEEDED test as may return S_FALSE! { type->get_length(&length); const char *s = GetUndecoratedSymbolName(type, ""); if (s && *s) dataTypeName = str::Dup(s); type->Release(); } } if (SymTagThunk == tag) { DWORD dwThunkKind; if (S_OK == symbol->get_thunkOrdinal(&dwThunkKind)) thunkTypeName = GetThunkTypeName(dwThunkKind); } else { symbol->get_length(&length); } const char *nameStr = GetUndecoratedSymbolName(symbol); if (SymTagData == tag) { // type | section | length | offset | rva | name | dataTypeName char *tmp = dataTypeName ? dataTypeName : ""; g_report.AppendFmt("%s|%d|%d|%d|%d|%s|%s\n", typeName, (int)section, (int)length, (int)offset, (int)rva, nameStr, tmp); free(dataTypeName); } else if (SymTagThunk == tag) { const char *tmp = thunkTypeName ? thunkTypeName : ""; // type | section | length | offset | rva | name | thunkTypeName g_report.AppendFmt("%s|%d|%d|%d|%d|%s|%s\n", typeName, (int)section, (int)length, (int)offset, (int)rva, nameStr, tmp); } else { // type | section | length | offset | rva | name g_report.AppendFmt("%s|%d|%d|%d|%d|%s\n", typeName, (int)section, (int)length, (int)offset, (int)rva, nameStr); } }
//---------------------------------------------------------------------- size_t get_symbol_length(IDiaSymbol *sym) { DWORD64 size = 0; DWORD tag = 0; sym->get_symTag(&tag); if ( tag == SymTagData ) { IDiaSymbol *pType; if ( sym->get_type(&pType) == S_OK ) { pType->get_length(&size); pType->Release(); } } else { sym->get_length(&size); } return size_t(size); }
void PDBFileReader::ProcessSymbol(IDiaSymbol *symbol,DebugInfo &to) { DWORD section,offset,rva; enum SymTagEnum tag; ULONGLONG length = 0; sU32 compilandId; IDiaSymbol *compiland = 0; BSTR name = 0, sourceName = 0; sBool codeFlag; symbol->get_symTag((DWORD *) &tag); symbol->get_relativeVirtualAddress(&rva); symbol->get_length(&length); symbol->get_addressSection(§ion); symbol->get_addressOffset(&offset); // is the previous symbol desperately looking for a length? we can help! if(DanglingLengthStart) { to.Symbols[to.Symbols.Count - 1].Size = rva - DanglingLengthStart; DanglingLengthStart = 0; } // get length from type for data if(tag == SymTagData) { IDiaSymbol *type; if(symbol->get_type(&type) == S_OK) { type->get_length(&length); type->Release(); } // if length still zero, just guess and take number of bytes between // this symbol and the next one. if(!length) DanglingLengthStart = rva; } compilandId = CompilandFromSectionOffset(section,offset,codeFlag); Session->symbolById(compilandId,&compiland); if(compiland) compiland->get_name(&sourceName); symbol->get_name(&name); // fill out structure sChar *nameStr = BStrToString(name,"<no name>"); sChar *sourceStr = BStrToString(sourceName,"<no source>"); if(tag == SymTagPublicSymbol) { length = 0; DanglingLengthStart = rva; } DISymbol *outSym = to.Symbols.Add(); outSym->Name.Index = outSym->MangledName.Index = to.MakeString(nameStr); outSym->FileNum = to.GetFileByName(sourceStr); outSym->VA = rva; outSym->Size = (sU32) length; outSym->Class = codeFlag ? DIC_CODE : DIC_DATA; outSym->NameSpNum = to.GetNameSpaceByName(nameStr); // clean up delete[] nameStr; delete[] sourceStr; if(compiland) compiland->Release(); if(sourceName) SysFreeString(sourceName); if(name) SysFreeString(name); }
void PDBFileReader::ProcessSymbol(IDiaSymbol *symbol,DebugInfo &to) { // print a dot for each 1000 symbols processed static int counter = 0; ++counter; if( counter == 1000 ) { fputc( '.', stderr ); counter = 0; } DWORD section,offset,rva; enum SymTagEnum tag; ULONGLONG length = 0; BSTR name = 0, srcFileName = 0; symbol->get_symTag((DWORD *) &tag); symbol->get_relativeVirtualAddress(&rva); symbol->get_length(&length); symbol->get_addressSection(§ion); symbol->get_addressOffset(&offset); // get length from type for data if( tag == SymTagData ) { IDiaSymbol *type = NULL; if( symbol->get_type(&type) == S_OK ) // no SUCCEEDED test as may return S_FALSE! { if( FAILED(type->get_length(&length)) ) length = 0; type->Release(); } else length = 0; } const SectionContrib *contrib = ContribFromSectionOffset(section,offset); sInt objFile = 0; sInt sectionType = DIC_UNKNOWN; if(contrib) { objFile = contrib->ObjFile; sectionType = contrib->Type; } symbol->get_name(&name); // fill out structure sChar *nameStr = BStrToString( name, "<noname>", true); to.Symbols.push_back( DISymbol() ); DISymbol *outSym = &to.Symbols.back(); outSym->name = outSym->mangledName = to.MakeString(nameStr); outSym->objFileNum = objFile; outSym->VA = rva; outSym->Size = (sU32) length; outSym->Class = sectionType; outSym->NameSpNum = to.GetNameSpaceByName(nameStr); // clean up delete[] nameStr; if(name) SysFreeString(name); }
bool LoadDIASymbols(const wxString &strPDBFile, wxInt32 modulenum, std::list<CFunctionDescription> & llFuncs, stdext::hash_map<BasedAddress,int> & addressmap ) { // Create DIA80 Data Source Object IDiaDataSource *pDataSource; HRESULT hr = NoRegCoCreate( L"msdia80.dll", _uuidof( DiaSource ), _uuidof( IDiaDataSource ), (void **) &(pDataSource)); if(!SUCCEEDED(hr)) { return false; } /* HMODULE mod=LoadLibrary(L"msdia80.dll"); if(!mod) { return false; } TYPEOF_DllGetClassObject *pGetClassObject=(TYPEOF_DllGetClassObject *)GetProcAddress(mod,"DllGetClassObject"); if(!pGetClassObject) { FreeLibrary(mod); return false; } IClassFactory *pcf; HRESULT hr=(*pGetClassObject)(CLSID_DiaSource,IID_IClassFactory,(void **)&pcf); if(!SUCCEEDED(hr)) { FreeLibrary(mod); return false; } IDiaDataSource *pDataSource; hr=pcf->CreateInstance(NULL,_uuidof(IDiaDataSource),(void **)&pDataSource); if(!SUCCEEDED(hr)) { pcf->Release(); FreeLibrary(mod); return false; } pcf->Release(); */ // Load the executable's debug symbols hr=pDataSource->loadDataFromPdb(strPDBFile); if(!SUCCEEDED(hr)) { pDataSource->Release(); return false; } // Open a symbol session IDiaSession *pDIASession; hr=pDataSource->openSession(&pDIASession); if(!SUCCEEDED(hr)) { pDataSource->Release(); return false; } // Set the UNBASED address on the session, for resolving BasedAddress addrs hr=pDIASession->put_loadAddress(0); if(!SUCCEEDED(hr)) { pDIASession->Release(); pDataSource->Release(); return false; } // Get addresses for this module std::list<BasedAddress> addresses; for(stdext::hash_map<BasedAddress,int>::iterator iter=addressmap.begin();iter!=addressmap.end();iter++) { if(iter->first.nModule==modulenum) { addresses.push_back(iter->first); } } stdext::hash_map<DWORD,wxInt32> functions; int curidx=(int)llFuncs.size(); for(std::list<BasedAddress>::iterator itera=addresses.begin();itera!=addresses.end();itera++) { // Get the symbol for this thing IDiaSymbol* pFunc; if(FAILED(pDIASession->findSymbolByVA(itera->nAddr, SymTagFunction, &pFunc)) || pFunc==NULL) { continue; } // Get the unique symbol index id DWORD indexId; if(FAILED(pFunc->get_symIndexId(&indexId))) { pFunc->Release(); continue; } // See if we have this function already stdext::hash_map<DWORD,int>::iterator iterf=functions.find(indexId); if(iterf!=functions.end()) { addressmap[*itera]=iterf->second; } else { CFunctionDescription func; ////// ULONGLONG addr; if(FAILED(pFunc->get_virtualAddress(&addr))) { pFunc->Release(); continue; } ////// ULONGLONG length; if(FAILED(pFunc->get_length(&length))) { pFunc->Release(); continue; } ///////// BSTR pName; if(FAILED(pFunc->get_name(&pName))) { pFunc->Release(); continue; } func.strMangledName=(const LPWSTR)pName; LocalFree(pName); char mangled[512]; WideCharToMultiByte(CP_UTF8,0,func.strMangledName,-1,mangled,512,NULL,NULL); ///////// char outbase[512]; __unDName(outbase,mangled,512,&malloc,&free,0x1000); wchar_t outbasew[512]; MultiByteToWideChar(CP_UTF8,0,outbase,-1,outbasew,512); func.strBaseName=(const wchar_t *)(outbasew); ///////// char outfull[512]; __unDName(outfull,mangled,512,&malloc,&free,0); wchar_t outfullw[512]; MultiByteToWideChar(CP_UTF8,0,outfull,-1,outfullw,512); func.strFullName=(const wchar_t *)(outfullw); ////////// func.nAddress=BasedAddress(addr,modulenum); func.nByteLength=length; ///////// IDiaEnumLineNumbers *pdeln; func.strSourceFile=wxT("<unknown>"); func.nFirstSourceLine=0; func.nLastSourceLine=0; bool bGotFile=false; if(SUCCEEDED(pDIASession->findLinesByVA(addr,length,&pdeln))) { IDiaLineNumber *pdln; int nLineItem=0; while(SUCCEEDED(pdeln->Item(nLineItem,&pdln))) { DWORD dwLineNumber; IDiaSourceFile *pdsf; if(SUCCEEDED(pdln->get_lineNumber(&dwLineNumber)) && SUCCEEDED(pdln->get_sourceFile(&pdsf))) { BSTR filename; if(SUCCEEDED(pdsf->get_fileName(&filename))) { if(bGotFile) { if(filename==func.strSourceFile) { if(dwLineNumber<func.nFirstSourceLine) { func.nFirstSourceLine=dwLineNumber; } if(dwLineNumber>func.nLastSourceLine) { func.nLastSourceLine=dwLineNumber; } } } else { bGotFile=true; func.strSourceFile=filename; func.nFirstSourceLine=dwLineNumber; func.nLastSourceLine=dwLineNumber; } LocalFree(filename); } pdsf->Release(); } pdln->Release(); nLineItem++; } pdeln->Release(); } llFuncs.push_back(func); functions[indexId]=curidx; addressmap[*itera]=curidx; curidx++; } } pDIASession->Release(); pDataSource->Release(); // FreeLibrary(mod); return true; }