Ejemplo n.º 1
0
bool
CpuStateX8664::SetRegisterValue(const Register* reg, const BVariant& value)
{
	int32 index = reg->Index();
	if (index >= X86_64_XMM_REGISTER_END)
		return false;

	if (index < X86_64_INT_REGISTER_END)
		fIntRegisters[index] = value.ToUInt64();
	else if (index >= X86_64_REGISTER_ST0 && index < X86_64_FP_REGISTER_END)
		fFloatRegisters[index - X86_64_REGISTER_ST0] = value.ToDouble();
	else if (index >= X86_64_REGISTER_MM0 && index < X86_64_MMX_REGISTER_END) {
		if (value.Size() > sizeof(int64))
			return false;
		memset(&fMMXRegisters[index - X86_64_REGISTER_MM0], 0,
			sizeof(x86_64_fp_register));
		memcpy(fMMXRegisters[index - X86_64_REGISTER_MM0].value,
			value.ToPointer(), value.Size());
	} else if (index >= X86_64_REGISTER_XMM0
			&& index < X86_64_XMM_REGISTER_END) {
		if (value.Size() > sizeof(x86_64_xmm_register))
			return false;

		memset(&fXMMRegisters[index - X86_64_REGISTER_XMM0], 0,
			sizeof(x86_64_xmm_register));
		memcpy(fXMMRegisters[index - X86_64_REGISTER_XMM0].value,
			value.ToPointer(), value.Size());
	} else
		return false;

	fSetRegisters[index] = 1;
	return true;
}
Ejemplo n.º 2
0
bool
CpuStateX8664::SetRegisterValue(const Register* reg, const BVariant& value)
{
	int32 index = reg->Index();
	if (index >= X86_64_INT_REGISTER_END)
		return false;

	fIntRegisters[index] = value.ToUInt64();
	fSetRegisters[index] = 1;
	return true;
}
Ejemplo n.º 3
0
status_t
DwarfImageDebugInfo::CreateFrame(Image* image,
	FunctionInstance* functionInstance, CpuState* cpuState,
	bool getFullFrameInfo, ReturnValueInfoList* returnValueInfos,
	StackFrame*& _frame, CpuState*& _previousCpuState)
{
	DwarfFunctionDebugInfo* function = dynamic_cast<DwarfFunctionDebugInfo*>(
		functionInstance->GetFunctionDebugInfo());

	FunctionID* functionID = functionInstance->GetFunctionID();
	BReference<FunctionID> functionIDReference;
	if (functionID != NULL)
		functionIDReference.SetTo(functionID, true);

	DIESubprogram* entry = function != NULL
		? function->SubprogramEntry() : NULL;

	TRACE_CFI("DwarfImageDebugInfo::CreateFrame(): subprogram DIE: %p, "
		"function: %s\n", entry,
		functionID->FunctionName().String());

	int32 registerCount = fArchitecture->CountRegisters();
	const Register* registers = fArchitecture->Registers();

	// get the DWARF <-> architecture register maps
	RegisterMap* toDwarfMap;
	RegisterMap* fromDwarfMap;
	status_t error = fArchitecture->GetDwarfRegisterMaps(&toDwarfMap,
		&fromDwarfMap);
	if (error != B_OK)
		return error;
	BReference<RegisterMap> toDwarfMapReference(toDwarfMap, true);
	BReference<RegisterMap> fromDwarfMapReference(fromDwarfMap, true);

	// create a clean CPU state for the previous frame
	CpuState* previousCpuState;
	error = fArchitecture->CreateCpuState(previousCpuState);
	if (error != B_OK)
		return error;
	BReference<CpuState> previousCpuStateReference(previousCpuState, true);

	// create the target interfaces
	UnwindTargetInterface* inputInterface
		= new(std::nothrow) UnwindTargetInterface(registers, registerCount,
			fromDwarfMap, toDwarfMap, cpuState, fArchitecture,
			fDebuggerInterface);
	if (inputInterface == NULL)
		return B_NO_MEMORY;
	BReference<UnwindTargetInterface> inputInterfaceReference(inputInterface,
		true);

	UnwindTargetInterface* outputInterface
		= new(std::nothrow) UnwindTargetInterface(registers, registerCount,
			fromDwarfMap, toDwarfMap, previousCpuState, fArchitecture,
			fDebuggerInterface);
	if (outputInterface == NULL)
		return B_NO_MEMORY;
	BReference<UnwindTargetInterface> outputInterfaceReference(outputInterface,
		true);

	// do the unwinding
	target_addr_t instructionPointer
		= cpuState->InstructionPointer() - fRelocationDelta;
	target_addr_t framePointer;
	CompilationUnit* unit = function != NULL ? function->GetCompilationUnit()
			: NULL;
	error = fFile->UnwindCallFrame(unit, fArchitecture->AddressSize(), entry,
		instructionPointer, inputInterface, outputInterface, framePointer);

	if (error != B_OK) {
		TRACE_CFI("Failed to unwind call frame: %s\n", strerror(error));
		return B_UNSUPPORTED;
	}

	TRACE_CFI_ONLY(
		TRACE_CFI("unwound registers:\n");
		for (int32 i = 0; i < registerCount; i++) {
			const Register* reg = registers + i;
			BVariant value;
			if (previousCpuState->GetRegisterValue(reg, value)) {
				TRACE_CFI("  %3s: %#" B_PRIx64 "\n", reg->Name(),
					value.ToUInt64());
			} else
				TRACE_CFI("  %3s: undefined\n", reg->Name());
		}
	)
Ejemplo n.º 4
0
void
InspectorWindow::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case MSG_THREAD_STATE_CHANGED:
		{
			::Thread* thread;
			if (message->FindPointer("thread",
					reinterpret_cast<void**>(&thread)) != B_OK) {
				break;
			}

			BReference< ::Thread> threadReference(thread, true);
			if (thread->State() == THREAD_STATE_STOPPED) {
				if (fCurrentBlock != NULL) {
					_SetCurrentBlock(NULL);
					_SetToAddress(fCurrentAddress);
				}
			}
			break;
		}
		case MSG_INSPECT_ADDRESS:
		{
			target_addr_t address = 0;
			if (message->FindUInt64("address", &address) != B_OK) {
				if (fAddressInput->TextView()->TextLength() == 0)
					break;

				fExpressionInfo->SetTo(fAddressInput->Text());

				fListener->ExpressionEvaluationRequested(fLanguage,
					fExpressionInfo);
			} else
				_SetToAddress(address);
			break;
		}
		case MSG_EXPRESSION_EVALUATED:
		{
			BString errorMessage;
			BReference<ExpressionResult> reference;
			ExpressionResult* value = NULL;
			if (message->FindPointer("value",
					reinterpret_cast<void**>(&value)) == B_OK) {
				reference.SetTo(value, true);
				if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) {
					Value* primitive = value->PrimitiveValue();
					BVariant variantValue;
					primitive->ToVariant(variantValue);
					if (variantValue.Type() == B_STRING_TYPE) {
						errorMessage.SetTo(variantValue.ToString());
					} else {
						_SetToAddress(variantValue.ToUInt64());
						break;
					}
				}
			} else {
				status_t result = message->FindInt32("result");
				errorMessage.SetToFormat("Failed to evaluate expression: %s",
					strerror(result));
			}

			BAlert* alert = new(std::nothrow) BAlert("Inspect Address",
				errorMessage.String(), "Close");
			if (alert != NULL)
				alert->Go();
			break;
		}

		case MSG_NAVIGATE_PREVIOUS_BLOCK:
		case MSG_NAVIGATE_NEXT_BLOCK:
		{
			if (fCurrentBlock != NULL) {
				target_addr_t address = fCurrentBlock->BaseAddress();
				if (message->what == MSG_NAVIGATE_PREVIOUS_BLOCK)
					address -= fCurrentBlock->Size();
				else
					address += fCurrentBlock->Size();

				BMessage setMessage(MSG_INSPECT_ADDRESS);
				setMessage.AddUInt64("address", address);
				PostMessage(&setMessage);
			}
			break;
		}
		case MSG_MEMORY_BLOCK_RETRIEVED:
		{
			TeamMemoryBlock* block = NULL;
			status_t result;
			if (message->FindPointer("block",
					reinterpret_cast<void **>(&block)) != B_OK
				|| message->FindInt32("result", &result) != B_OK) {
				break;
			}

			if (result == B_OK) {
				_SetCurrentBlock(block);
				fPreviousBlockButton->SetEnabled(true);
				fNextBlockButton->SetEnabled(true);
			} else {
				BString errorMessage;
				errorMessage.SetToFormat("Unable to read address 0x%" B_PRIx64
					": %s", block->BaseAddress(), strerror(result));

				BAlert* alert = new(std::nothrow) BAlert("Inspect address",
					errorMessage.String(), "Close");
				if (alert == NULL)
					break;

				alert->Go(NULL);
				block->ReleaseReference();
			}
			break;
		}
		case MSG_EDIT_CURRENT_BLOCK:
		{
			_SetEditMode(true);
			break;
		}
		case MSG_MEMORY_DATA_CHANGED:
		{
			if (fCurrentBlock == NULL)
				break;

			target_addr_t address;
			if (message->FindUInt64("address", &address) == B_OK
				&& address >= fCurrentBlock->BaseAddress()
				&& address < fCurrentBlock->BaseAddress()
					+ fCurrentBlock->Size()) {
				fCurrentBlock->Invalidate();
				_SetEditMode(false);
				fListener->InspectRequested(address, this);
			}
			break;
		}
		case MSG_COMMIT_MODIFIED_BLOCK:
		{
			// TODO: this could conceivably be extended to detect the
			// individual modified regions and only write those back.
			// That would require potentially submitting multiple separate
			// write requests, and thus require tracking all the writes being
			// waited upon for completion.
			fListener->MemoryWriteRequested(fCurrentBlock->BaseAddress(),
				fMemoryView->GetEditedData(), fCurrentBlock->Size());
			break;
		}
		case MSG_REVERT_MODIFIED_BLOCK:
		{
			_SetEditMode(false);
			break;
		}
		default:
		{
			BWindow::MessageReceived(message);
			break;
		}
	}
}
Ejemplo n.º 5
0
status_t
DwarfCompoundType::ResolveDataMemberLocation(DataMember* _member,
	const ValueLocation& parentLocation, ValueLocation*& _location)
{
	DwarfDataMember* member = dynamic_cast<DwarfDataMember*>(_member);
	if (member == NULL)
		return B_BAD_VALUE;
	DwarfTypeContext* typeContext = TypeContext();

	bool isBitField = true;
	DIEMember* memberEntry = member->Entry();
	// TODO: handle DW_AT_data_bit_offset
	if (!memberEntry->ByteSize()->IsValid()
		&& !memberEntry->BitOffset()->IsValid()
		&& !memberEntry->BitSize()->IsValid()) {
		isBitField = false;
	}

	ValueLocation* location;
	status_t error = _ResolveDataMemberLocation(member->GetDwarfType(),
		member->Entry()->Location(), parentLocation, isBitField, location);
	if (error != B_OK)
		return error;

	// If the member isn't a bit field, we're done.
	if (!isBitField) {
		_location = location;
		return B_OK;
	}

	BReference<ValueLocation> locationReference(location);

	// get the byte size
	target_addr_t byteSize;
	if (memberEntry->ByteSize()->IsValid()) {
		BVariant value;
		error = typeContext->File()->EvaluateDynamicValue(
			typeContext->GetCompilationUnit(), typeContext->AddressSize(),
			typeContext->SubprogramEntry(), memberEntry->ByteSize(),
			typeContext->TargetInterface(), typeContext->InstructionPointer(),
			typeContext->FramePointer(), value);
		if (error != B_OK)
			return error;
		byteSize = value.ToUInt64();
	} else
		byteSize = ByteSize();

	// get the bit offset
	uint64 bitOffset = 0;
	if (memberEntry->BitOffset()->IsValid()) {
		BVariant value;
		error = typeContext->File()->EvaluateDynamicValue(
			typeContext->GetCompilationUnit(), typeContext->AddressSize(),
			typeContext->SubprogramEntry(), memberEntry->BitOffset(),
			typeContext->TargetInterface(), typeContext->InstructionPointer(),
			typeContext->FramePointer(), value);
		if (error != B_OK)
			return error;
		bitOffset = value.ToUInt64();
	}

	// get the bit size
	uint64 bitSize = byteSize * 8;
	if (memberEntry->BitSize()->IsValid()) {
		BVariant value;
		error = typeContext->File()->EvaluateDynamicValue(
			typeContext->GetCompilationUnit(), typeContext->AddressSize(),
			typeContext->SubprogramEntry(), memberEntry->BitSize(),
			typeContext->TargetInterface(), typeContext->InstructionPointer(),
			typeContext->FramePointer(), value);
		if (error != B_OK)
			return error;
		bitSize = value.ToUInt64();
	}

	TRACE_LOCALS("bit field: byte size: %" B_PRIu64 ", bit offset/size: %"
		B_PRIu64 "/%" B_PRIu64 "\n", byteSize, bitOffset, bitSize);

	if (bitOffset + bitSize > byteSize * 8)
		return B_BAD_VALUE;

	// create the bit field value location
	ValueLocation* bitFieldLocation = new(std::nothrow) ValueLocation;
	if (bitFieldLocation == NULL)
		return B_NO_MEMORY;
	BReference<ValueLocation> bitFieldLocationReference(bitFieldLocation, true);

	if (!bitFieldLocation->SetTo(*location, bitOffset, bitSize))
		return B_NO_MEMORY;

	_location = bitFieldLocationReference.Detach();
	return B_OK;
}