1174604Sscottl/*
2174604Sscottl * Copyright 2012-2016, Rene Gollent, rene@gollent.com.
3174604Sscottl * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
4174604Sscottl * Distributed under the terms of the MIT License.
5174604Sscottl */
6174604Sscottl
7174604Sscottl#include "Jobs.h"
8174604Sscottl
9174604Sscottl#include <AutoLocker.h>
10174604Sscottl
11174604Sscottl#include "Architecture.h"
12174604Sscottl#include "DebuggerInterface.h"
13174604Sscottl#include "DisassembledCode.h"
14174604Sscottl#include "Function.h"
15174604Sscottl#include "FunctionInstance.h"
16174604Sscottl#include "FileSourceCode.h"
17174604Sscottl#include "Team.h"
18174604Sscottl#include "TeamDebugInfo.h"
19174604Sscottl
20174604Sscottl
21174604SscottlLoadSourceCodeJob::LoadSourceCodeJob(
22174604Sscottl	DebuggerInterface* debuggerInterface, Architecture* architecture,
23174604Sscottl	Team* team, FunctionInstance* functionInstance, bool loadForFunction)
24174604Sscottl	:
25174604Sscottl	fKey(functionInstance, JOB_TYPE_LOAD_SOURCE_CODE),
26174604Sscottl	fDebuggerInterface(debuggerInterface),
27174604Sscottl	fArchitecture(architecture),
28174604Sscottl	fTeam(team),
29174604Sscottl	fFunctionInstance(functionInstance),
30174604Sscottl	fLoadForFunction(loadForFunction)
31174604Sscottl{
32174604Sscottl	fFunctionInstance->AcquireReference();
33174604Sscottl
34174604Sscottl	SetDescription("Loading source code for function %s",
35174604Sscottl		fFunctionInstance->PrettyName().String());
36174604Sscottl}
37174604Sscottl
38174604Sscottl
39174604SscottlLoadSourceCodeJob::~LoadSourceCodeJob()
40174604Sscottl{
41174604Sscottl	fFunctionInstance->ReleaseReference();
42174604Sscottl}
43174604Sscottl
44174604Sscottl
45174604Sscottlconst JobKey&
46174604SscottlLoadSourceCodeJob::Key() const
47174604Sscottl{
48174604Sscottl	return fKey;
49174604Sscottl}
50174604Sscottl
51174604Sscottl
52174604Sscottlstatus_t
53174604SscottlLoadSourceCodeJob::Do()
54174604Sscottl{
55174604Sscottl	// if requested, try loading the source code for the function
56174604Sscottl	Function* function = fFunctionInstance->GetFunction();
57174604Sscottl	if (fLoadForFunction) {
58174604Sscottl		FileSourceCode* sourceCode;
59174604Sscottl		status_t error = fTeam->DebugInfo()->LoadSourceCode(
60174604Sscottl			function->SourceFile(), sourceCode);
61174604Sscottl
62174604Sscottl		AutoLocker<Team> locker(fTeam);
63174604Sscottl
64174604Sscottl		if (error == B_OK) {
65174604Sscottl			function->SetSourceCode(sourceCode, FUNCTION_SOURCE_LOADED);
66174604Sscottl			sourceCode->ReleaseReference();
67174604Sscottl			return B_OK;
68174604Sscottl		}
69174604Sscottl
70174604Sscottl		function->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);
71174604Sscottl	}
72174604Sscottl
73174604Sscottl	// Only try to load the function instance code, if it's not overridden yet.
74174604Sscottl	AutoLocker<Team> locker(fTeam);
75174604Sscottl	if (fFunctionInstance->SourceCodeState() != FUNCTION_SOURCE_LOADING)
76174604Sscottl		return B_OK;
77174604Sscottl	locker.Unlock();
78174604Sscottl
79174604Sscottl	// disassemble the function
80174604Sscottl	DisassembledCode* sourceCode = NULL;
81174604Sscottl	status_t error = fTeam->DebugInfo()->DisassembleFunction(fFunctionInstance,
82174604Sscottl		sourceCode);
83174604Sscottl
84174604Sscottl	// set the result
85174604Sscottl	locker.Lock();
86174604Sscottl	if (error == B_OK) {
87174604Sscottl		if (fFunctionInstance->SourceCodeState() == FUNCTION_SOURCE_LOADING) {
88174604Sscottl			// various parts of the debugger expect functions to have only
89174604Sscottl			// one of source or disassembly available. As such, if the current
90174604Sscottl			// function had source code previously active, unset it when
91174604Sscottl			// explicitly asked for disassembly. This needs to be done first
92174604Sscottl			// since Function will clear the disassembled code states of all
93174604Sscottl			// its child instances.
94174604Sscottl			function_source_state state
95174604Sscottl				= fLoadForFunction ? FUNCTION_SOURCE_LOADED
96174604Sscottl					: FUNCTION_SOURCE_SUPPRESSED;
97174604Sscottl			if (function->SourceCodeState() == FUNCTION_SOURCE_LOADED) {
98174604Sscottl				FileSourceCode* functionSourceCode = function->GetSourceCode();
99174604Sscottl				function->SetSourceCode(functionSourceCode, state);
100174604Sscottl			}
101174604Sscottl
102174604Sscottl			fFunctionInstance->SetSourceCode(sourceCode, state);
103174604Sscottl			sourceCode->ReleaseReference();
104174604Sscottl		}
105174604Sscottl	} else
106174604Sscottl		fFunctionInstance->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);
107174604Sscottl
108174604Sscottl	return error;
109174604Sscottl}
110174604Sscottl