示例#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
//------------------------------------------------------------------------
// 
//------------------------------------------------------------------------
IDiaSymbol* dia::FindType(const std::string &typeName)
{
	RETV(!m_pGlobalSymbol, NULL);

	CComPtr<IDiaEnumSymbols> pEnumSymbols;
	if (FAILED(m_pGlobalSymbol->findChildren(SymTagNull, memmonitor::str2wstr(typeName).c_str(), 
		nsRegularExpression, &pEnumSymbols))) 
		return NULL;

	std::list<IDiaSymbol *> childSymbols;
	IDiaSymbol *pSymbol = NULL;
	ULONG celt = 0;
	// 첫번째로 발견되는 정보만 찾아서 리턴한다.
	while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) 
	{
		childSymbols.push_back(pSymbol);

		enum SymTagEnum symTag;
		HRESULT hr = pSymbol->get_symTag((DWORD*)&symTag);
		if (SymTagData == symTag || SymTagUDT == symTag)
			break;
	}

	if (childSymbols.empty())
		return NULL;

	// SymTagEnum 값이 SymTagData 이거나 SymTagUDT 을 먼저 선택하도록 한다.
	// 가장 나중에 추가된 것을 제외하고 나머지는 제거한다.
	while (childSymbols.size() > 1)
	{
		childSymbols.front()->Release();
		childSymbols.pop_front();
	}
	
	return childSymbols.back();
}
示例#4
0
DDR_RC
PdbScanner::setType(IDiaSymbol *symbol, Type **type, Modifiers *modifiers, NamespaceUDT *outerUDT)
{
	DDR_RC rc = DDR_RC_OK;
	/* Get all type information, such as type and modifiers, for abort
	 * field symbol.
	 */
	IDiaSymbol *typeSymbol = NULL;
	HRESULT hr = symbol->get_type(&typeSymbol);
	if (FAILED(hr)) {
		ERRMSG("get_type failed with HRESULT = %08lX", hr);
		rc = DDR_RC_ERROR;
	}

	if (DDR_RC_OK == rc) {
		rc = setTypeModifier(typeSymbol, modifiers);
	}

	DWORD symTag = 0;
	if (DDR_RC_OK == rc) {
		hr = typeSymbol->get_symTag(&symTag);
		if (FAILED(hr)) {
			ERRMSG("get_symTag failed with HRESULT = %08lX", hr);
			rc = DDR_RC_ERROR;
		}
	}

	if (DDR_RC_OK == rc) {
		switch (symTag) {
		case SymTagEnum:
		case SymTagUDT:
			rc = setTypeUDT(typeSymbol, type, outerUDT);
			break;
		case SymTagArrayType:
		{
			DWORD size = 0;
			if (FAILED(typeSymbol->get_count(&size))) {
				ERRMSG("Failed to get array dimensions.");
				rc = DDR_RC_ERROR;
			} else {
				modifiers->addArrayDimension(size);
				rc = setType(typeSymbol, type, modifiers, outerUDT);
			}
			break;
		}
		case SymTagPointerType:
			rc = setPointerType(symbol, modifiers);
			if (DDR_RC_OK == rc) {
				rc = setType(typeSymbol, type, modifiers, outerUDT);
			}
			break;
		case SymTagBaseType:
			rc = setBaseType(typeSymbol, type);
			break;
		case SymTagFunctionType:
			*type = getType("void");
			break;
		default:
			ERRMSG("unknown symtag: %lu", symTag);
			rc = DDR_RC_ERROR;
			break;
		}
	}

	if (NULL != typeSymbol) {
		typeSymbol->Release();
	}

	return rc;
}
示例#5
0
//------------------------------------------------------------------------
// pParentSymbol 에서 자식중에 symbolName 인 심볼을 리턴한다.
// 찾은 심볼의 Offset값을 리턴한다.
// pParentSymbol 은 Data, UDT, TypeDef 타입이어야 한다.
//------------------------------------------------------------------------
IDiaSymbol* dia::FindChildSymbol( const std::string &symbolName, 
								 IDiaSymbol *pParentSymbol, OUT LONG *pOffset ) // pOffset =NULL
{
	RETV( !pParentSymbol, NULL );

	const string name = GetSymbolName(pParentSymbol); //debug용
	const wstring searchSymbolName = memmonitor::str2wstr(symbolName).c_str();

	// 데이타 심볼이면, 타입 심볼로 교체한다.
	enum SymTagEnum symTag;
	HRESULT hr = pParentSymbol->get_symTag((DWORD*)&symTag);

	bool isNewTypeSymbol = false;
	IDiaSymbol* pTypeSymbol = NULL;
	switch (symTag)
	{
	case SymTagData:
		isNewTypeSymbol = true;
		hr = pParentSymbol->get_type(&pTypeSymbol);
		break;
	case SymTagTypedef:
		{
			hr = pParentSymbol->get_type(&pTypeSymbol);
			IDiaSymbol *reval = FindChildSymbol(symbolName, pTypeSymbol, pOffset);
			if (pTypeSymbol)
				pTypeSymbol->Release();
			return reval;
		}
		break;
	default:
		{
			pTypeSymbol = pParentSymbol;
		}
		break;
	}

	// Enumeration
	CComPtr<IDiaEnumSymbols> pEnumSymbols;
	if (FAILED(pTypeSymbol->findChildren(SymTagNull, searchSymbolName.c_str(), 
		nsRegularExpression, &pEnumSymbols)))
	{
		if (isNewTypeSymbol)
			pTypeSymbol->Release();
		return NULL;
	}

	IDiaSymbol *pFindSymbol;
	ULONG celt = 0;
	pEnumSymbols->Next(1, &pFindSymbol, &celt);
	// 찾았다면 리턴 
	if (1 == celt)
	{
		if (isNewTypeSymbol)
			pTypeSymbol->Release();
		if (pOffset)
			hr = pFindSymbol->get_offset(pOffset);
		return pFindSymbol;
	}

	// 못찾았다면, 자식 중에서 찾아본다. enum  으로 선언된 값은 이렇게 찾아야함
	CComPtr<IDiaEnumSymbols> pAnotherEnumSymbols;
	if (FAILED(pTypeSymbol->findChildren(SymTagNull, NULL, nsNone, &pAnotherEnumSymbols)))
	{
		if (isNewTypeSymbol)
			pTypeSymbol->Release();
		return NULL;
	}

	pFindSymbol = NULL;
	IDiaSymbol* pChildSymbol;
	celt = 0;
	while (SUCCEEDED(pAnotherEnumSymbols->Next(1, &pChildSymbol, &celt)) && (celt == 1)) 
	{
		enum SymTagEnum symTag;
		pChildSymbol->get_symTag((DWORD*)&symTag);

		if (SymTagBaseClass == symTag)
		{
			LONG childOffset = 0;
			pFindSymbol = FindChildSymbol( symbolName, pChildSymbol, &childOffset );
			if (pFindSymbol)
			{
				LONG baseClassOffset = 0;
				hr = pChildSymbol->get_offset(&baseClassOffset);
				if (pOffset)
					*pOffset = baseClassOffset + childOffset;
				break;
			}
		}

		if (SymTagEnum != symTag) 
		{ 
			pChildSymbol->Release(); 
			continue; 
		}

		CComPtr<IDiaEnumSymbols> pSubEnumSymbols;
		if (FAILED(pChildSymbol->findChildren(SymTagNull, searchSymbolName.c_str(), 
			nsRegularExpression, &pSubEnumSymbols)))
		{
			pChildSymbol->Release(); 
			continue; 
		}

		celt = 0;
		pSubEnumSymbols->Next( 1, &pFindSymbol, &celt );
		if (1 == celt)
		{
			pChildSymbol->Release();
			const string name = GetSymbolName(pFindSymbol); //debug용
			if (pOffset)
				*pOffset = 0; // 상수값은 offset이 없다.
			break; // 찾았으니 종료
		}
	}

	if (isNewTypeSymbol)
		pTypeSymbol->Release();
	return pFindSymbol;
}