示例#1
0
//------------------------------------------------------------------------
// 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;
}
示例#2
0
//------------------------------------------------------------------------
// 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;
}
示例#3
0
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(&section);
    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);
    }
}
示例#4
0
文件: common.cpp 项目: nealey/vera
//----------------------------------------------------------------------
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);
}
示例#5
0
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(&section);
    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);
}
示例#6
0
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(&section);
	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);
}
示例#7
0
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;
}