Esempio n. 1
0
status_t
LoadSourceCodeJob::Do()
{
	// if requested, try loading the source code for the function
	Function* function = fFunctionInstance->GetFunction();
	if (fLoadForFunction) {
		FileSourceCode* sourceCode;
		status_t error = fTeam->DebugInfo()->LoadSourceCode(
			function->SourceFile(), sourceCode);

		AutoLocker<Team> locker(fTeam);

		if (error == B_OK) {
			function->SetSourceCode(sourceCode, FUNCTION_SOURCE_LOADED);
			sourceCode->ReleaseReference();
			return B_OK;
		}

		function->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);
	}

	// Only try to load the function instance code, if it's not overridden yet.
	AutoLocker<Team> locker(fTeam);
	if (fFunctionInstance->SourceCodeState() != FUNCTION_SOURCE_LOADING)
		return B_OK;
	locker.Unlock();

	// disassemble the function
	DisassembledCode* sourceCode = NULL;
	status_t error = fTeam->DebugInfo()->DisassembleFunction(fFunctionInstance,
		sourceCode);

	// set the result
	locker.Lock();
	if (error == B_OK) {
		if (fFunctionInstance->SourceCodeState() == FUNCTION_SOURCE_LOADING) {
			// various parts of the debugger expect functions to have only
			// one of source or disassembly available. As such, if the current
			// function had source code previously active, unset it when
			// explicitly asked for disassembly. This needs to be done first
			// since Function will clear the disassembled code states of all
			// its child instances.
			if (function->SourceCodeState() == FUNCTION_SOURCE_LOADED) {
				FileSourceCode* sourceCode = function->GetSourceCode();
				function->SetSourceCode(sourceCode,
					FUNCTION_SOURCE_NOT_LOADED);
			}

			fFunctionInstance->SetSourceCode(sourceCode,
				FUNCTION_SOURCE_LOADED);
			sourceCode->ReleaseReference();
		}
	} else
		fFunctionInstance->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);

	return error;
}
Esempio n. 2
0
status_t
LoadSourceCodeJob::Do()
{
	// if requested, try loading the source code for the function
	Function* function = fFunctionInstance->GetFunction();
	if (fLoadForFunction) {
		FileSourceCode* sourceCode;
		status_t error = fTeam->DebugInfo()->LoadSourceCode(
			function->SourceFile(), sourceCode);

		AutoLocker<Team> locker(fTeam);

		if (error == B_OK) {
			function->SetSourceCode(sourceCode, FUNCTION_SOURCE_LOADED);
			sourceCode->ReleaseReference();
			return B_OK;
		}

		function->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);
	}

	// Only try to load the function instance code, if it's not overridden yet.
	AutoLocker<Team> locker(fTeam);
	if (fFunctionInstance->SourceCodeState() != FUNCTION_SOURCE_LOADING)
		return B_OK;
	locker.Unlock();

	// disassemble the function
	DisassembledCode* sourceCode = NULL;
	status_t error = fTeam->DebugInfo()->DisassembleFunction(fFunctionInstance,
		sourceCode);

	// set the result
	locker.Lock();
	if (error == B_OK) {
		if (fFunctionInstance->SourceCodeState() == FUNCTION_SOURCE_LOADING) {
			fFunctionInstance->SetSourceCode(sourceCode,
				FUNCTION_SOURCE_LOADED);
			sourceCode->ReleaseReference();
		}
	} else
		fFunctionInstance->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);

	return error;
}
Esempio n. 3
0
status_t
ArchitectureX8664::DisassembleCode(FunctionDebugInfo* function,
	const void* buffer, size_t bufferSize, DisassembledCode*& _sourceCode)
{
	DisassembledCode* source = new(std::nothrow) DisassembledCode(
		fAssemblyLanguage);
	if (source == NULL)
		return B_NO_MEMORY;
	BReference<DisassembledCode> sourceReference(source, true);

	// init disassembler
	DisassemblerX8664 disassembler;
	status_t error = disassembler.Init(function->Address(), buffer, bufferSize);
	if (error != B_OK)
		return error;

	// add a function name line
	BString functionName(function->PrettyName());
	if (!source->AddCommentLine((functionName << ':').String()))
		return B_NO_MEMORY;

	// disassemble the instructions
	BString line;
	target_addr_t instructionAddress;
	target_size_t instructionSize;
	bool breakpointAllowed;
	while (disassembler.GetNextInstruction(line, instructionAddress,
				instructionSize, breakpointAllowed) == B_OK) {
// TODO: Respect breakpointAllowed!
		if (!source->AddInstructionLine(line, instructionAddress,
				instructionSize)) {
			return B_NO_MEMORY;
		}
	}

	_sourceCode = sourceReference.Detach();
	return B_OK;
}
Esempio n. 4
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;
}