Commits

spencercw committed cb7930f

Implement expression evaluation for expressions that take the address of a variable.

Comments (0)

Files changed (5)

gb_debugger_msvs/expression.cpp

 		}
 
 	case VARIABLE:
+	case VARIABLE_ADDRESS:
 		{
 			// Look for any local variables with the given name
 			if (!frame_->hasDebugInfo || !frame_->sourceLocation.function)
 				return E_FAIL;
 			}
 
-			// Get the variable value
-			uint32_t value;
-			unsigned size;
-			if (!CVariableProperty::GetValue(frame_, variable, value, size))
+			if (type_ == VARIABLE)
 			{
-				return E_FAIL;
+				// Get the variable value
+				uint32_t value;
+				unsigned size;
+				if (!CVariableProperty::GetValue(frame_, variable, value, size))
+				{
+					return E_FAIL;
+				}
+
+				// Create the property to represent the value
+				CComObject<CVariableProperty> *variableProperty;
+				CComObject<CVariableProperty>::CreateInstance(&variableProperty);
+				variableProperty->AddRef();
+				variableProperty->Init(frame_, variable);
+
+				*ppResult = variableProperty;
+			}
+			else
+			{
+				// Get the variable address
+				uint16_t address;
+				if (!CVariableProperty::GetAddress(frame_, variable, address))
+				{
+					return E_FAIL;
+				}
+
+				// Create the property to represent the value
+				CComObject<CMemoryContext> *memoryContext;
+				CComObject<CMemoryContext>::CreateInstance(&memoryContext);
+				memoryContext->AddRef();
+				memoryContext->Init(address);
+
+				CComObject<CExpressionProperty> *expressionProperty;
+				CComObject<CExpressionProperty>::CreateInstance(&expressionProperty);
+				expressionProperty->AddRef();
+				expressionProperty->Init(memoryContext);
+
+				*ppResult = expressionProperty;
+				memoryContext->Release();
 			}
 
-			// Create the property to represent the value
-			CComObject<CVariableProperty> *debugProperty;
-			CComObject<CVariableProperty>::CreateInstance(&debugProperty);
-			debugProperty->AddRef();
-			debugProperty->Init(frame_, variable);
-
-			*ppResult = debugProperty;
 			return S_OK;
 		}
 

gb_debugger_msvs/expression.h

 	enum Type
 	{
 		INTEGER,
-		VARIABLE
+		VARIABLE,
+		VARIABLE_ADDRESS
 	};
 
 	void Init(boost::shared_ptr<GbStackFrame> frame, Type type, const std::wstring &expression,

gb_debugger_msvs/expression_context.cpp

 	size_t index = str.find_first_not_of(validChars);
 	if (index != wstring::npos)
 	{
-		// Invalid integer charaters; check if it could be a variable name
+		// Invalid integer charaters; check if it could be a variable
+		bool isAddressOf = false;
+		if (str[0] == '&')
+		{
+			isAddressOf = true;
+			str = str.substr(1);
+		}
+
 		static const wstring validStartChars =
 			L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
 		validChars = L"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
 			return E_INVALIDARG;
 		}
 
-		type = CExpression::VARIABLE;
+		type = isAddressOf ? CExpression::VARIABLE_ADDRESS : CExpression::VARIABLE;
 	}
 
 	// Create the expression object

gb_debugger_msvs/properties/variable_property.cpp

 	}
 }
 
+bool CVariableProperty::GetAddress(shared_ptr<GbStackFrame> frame,
+	shared_ptr<CdbFile::Symbol> variable, uint16_t &address)
+{
+	switch (variable->type->chain[0].type)
+	{
+	case CdbFile::TypeEntry::GENERIC_POINTER:
+	case CdbFile::TypeEntry::CODE_POINTER:
+	case CdbFile::TypeEntry::EXTERNAL_RAM_POINTER:
+	case CdbFile::TypeEntry::INTERNAL_RAM_POINTER:
+	case CdbFile::TypeEntry::PAGED_POINTER:
+	case CdbFile::TypeEntry::UPPER_128_BYTE_POINTER:
+		address = static_cast<uint16_t>(frame->stackAddrMax + variable->stackOffset);
+		return true;
+
+	case CdbFile::TypeEntry::LONG:
+	case CdbFile::TypeEntry::INT:
+	case CdbFile::TypeEntry::CHAR:
+	case CdbFile::TypeEntry::SHORT:
+		switch (variable->addressSpace)
+		{
+		case CdbFile::INTERNAL_STACK:
+			address = static_cast<uint16_t>(frame->stackAddrMax + variable->stackOffset);
+			return true;
+
+		default:
+			return false;
+		}
+
+	default:
+		return false;
+	}
+}
+
 bool CVariableProperty::GetValue(shared_ptr<GbStackFrame> frame,
 	shared_ptr<CdbFile::Symbol> variable, uint32_t &value, unsigned &size, wstring *error)
 {

gb_debugger_msvs/properties/variable_property.h

 	void PopulatePropertyInfo(DEBUG_PROPERTY_INFO *propertyInfo, DEBUGPROP_INFO_FLAGS fields,
 		DWORD radix);
 
+	static bool GetAddress(boost::shared_ptr<GbStackFrame> frame,
+		boost::shared_ptr<CdbFile::Symbol> variable, uint16_t &address);
 	static bool GetValue(boost::shared_ptr<GbStackFrame> frame,
 		boost::shared_ptr<CdbFile::Symbol> variable, uint32_t &value, unsigned &size,
 		std::wstring *error = NULL);