Ejemplo n.º 1
0
status_t
Team::GetStatementAtAddress(target_addr_t address, FunctionInstance*& _function,
	Statement*& _statement)
{
	TRACE_CODE("Team::GetStatementAtAddress(%#" B_PRIx64 ")\n", address);

	// get the image at the address
	Image* image = ImageByAddress(address);
	if (image == NULL) {
		TRACE_CODE("  -> no image\n");
		return B_ENTRY_NOT_FOUND;
	}

	ImageDebugInfo* imageDebugInfo = image->GetImageDebugInfo();
	if (imageDebugInfo == NULL) {
		TRACE_CODE("  -> no image debug info\n");
		return B_ENTRY_NOT_FOUND;
	}

	// get the function
	FunctionInstance* functionInstance
		= imageDebugInfo->FunctionAtAddress(address);
	if (functionInstance == NULL) {
		TRACE_CODE("  -> no function instance\n");
		return B_ENTRY_NOT_FOUND;
	}

	// If the function instance has disassembled code attached, we can get the
	// statement directly.
	if (DisassembledCode* code = functionInstance->GetSourceCode()) {
		Statement* statement = code->StatementAtAddress(address);
		if (statement == NULL)
			return B_ENTRY_NOT_FOUND;

		statement->AcquireReference();
		_statement = statement;
		_function = functionInstance;
		return B_OK;
	}

	// get the statement from the image debug info
	FunctionDebugInfo* functionDebugInfo
		= functionInstance->GetFunctionDebugInfo();
	status_t error = functionDebugInfo->GetSpecificImageDebugInfo()
		->GetStatement(functionDebugInfo, address, _statement);
	if (error != B_OK) {
		TRACE_CODE("  -> no statement from the specific image debug info\n");
		return error;
	}

	_function = functionInstance;
	return B_OK;
}
Ejemplo n.º 2
0
status_t
DebugReportGenerator::_DumpFunctionDisassembly(BFile& _output,
	target_addr_t instructionPointer)
{
	AutoLocker< ::Team> teamLocker(fTeam);
	BString data;
	FunctionInstance* instance = NULL;
	Statement* statement = NULL;
	status_t error = fTeam->GetStatementAtAddress(instructionPointer, instance,
		statement);
	if (error != B_OK) {
		data.SetToFormat("Unable to retrieve disassembly for IP %#" B_PRIx64
				": %s\n", instructionPointer, strerror(error));
		WRITE_AND_CHECK(_output, data);
		return B_OK;
	}

	DisassembledCode* code = instance->GetSourceCode();
	Function* function = instance->GetFunction();
	if (code == NULL) {
		switch (function->SourceCodeState()) {
			case FUNCTION_SOURCE_NOT_LOADED:
			case FUNCTION_SOURCE_LOADED:
				// FUNCTION_SOURCE_LOADED is included since, if we entered
				// here, it implies that the high level source for the
				// function has been loaded, but the disassembly has not.
				function->AddListener(this);
				fSourceWaitingFunction = function;
				fListener->FunctionSourceCodeRequested(instance, true);
				// fall through
			case FUNCTION_SOURCE_LOADING:
			{
				teamLocker.Unlock();
				do {
					error = acquire_sem(fTeamDataSem);
				} while (error == B_INTERRUPTED);

				if (error != B_OK)
					return error;

				teamLocker.Lock();
				break;
			}
			default:
				return B_OK;
		}

		if (instance->SourceCodeState() == 	FUNCTION_SOURCE_UNAVAILABLE)
			return B_OK;

		error = fTeam->GetStatementAtAddress(instructionPointer, instance,
			statement);
		code = instance->GetSourceCode();
	}

	SourceLocation location = statement->StartSourceLocation();

	data = "\t\t\tDisassembly:\n";
	WRITE_AND_CHECK(_output, data);
	for (int32 i = 0; i <= location.Line(); i++) {
		data = "\t\t\t\t";
		data << code->LineAt(i);
		if (i == location.Line())
			data << " <--";
		data << "\n";
		WRITE_AND_CHECK(_output, data);
	}
	data = "\n";
	WRITE_AND_CHECK(_output, data);

	return B_OK;
}