1 /*
2 * Copyright 2012-2016, Rene Gollent, rene@gollent.com.
3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Distributed under the terms of the MIT License.
5 */
6
7 #include "Jobs.h"
8
9 #include <AutoLocker.h>
10
11 #include "Architecture.h"
12 #include "DebuggerInterface.h"
13 #include "DisassembledCode.h"
14 #include "Function.h"
15 #include "FunctionInstance.h"
16 #include "FileSourceCode.h"
17 #include "Team.h"
18 #include "TeamDebugInfo.h"
19
20
LoadSourceCodeJob(DebuggerInterface * debuggerInterface,Architecture * architecture,Team * team,FunctionInstance * functionInstance,bool loadForFunction)21 LoadSourceCodeJob::LoadSourceCodeJob(
22 DebuggerInterface* debuggerInterface, Architecture* architecture,
23 Team* team, FunctionInstance* functionInstance, bool loadForFunction)
24 :
25 fKey(functionInstance, JOB_TYPE_LOAD_SOURCE_CODE),
26 fDebuggerInterface(debuggerInterface),
27 fArchitecture(architecture),
28 fTeam(team),
29 fFunctionInstance(functionInstance),
30 fLoadForFunction(loadForFunction)
31 {
32 fFunctionInstance->AcquireReference();
33
34 SetDescription("Loading source code for function %s",
35 fFunctionInstance->PrettyName().String());
36 }
37
38
~LoadSourceCodeJob()39 LoadSourceCodeJob::~LoadSourceCodeJob()
40 {
41 fFunctionInstance->ReleaseReference();
42 }
43
44
45 const JobKey&
Key() const46 LoadSourceCodeJob::Key() const
47 {
48 return fKey;
49 }
50
51
52 status_t
Do()53 LoadSourceCodeJob::Do()
54 {
55 // if requested, try loading the source code for the function
56 Function* function = fFunctionInstance->GetFunction();
57 if (fLoadForFunction) {
58 FileSourceCode* sourceCode;
59 status_t error = fTeam->DebugInfo()->LoadSourceCode(
60 function->SourceFile(), sourceCode);
61
62 AutoLocker<Team> locker(fTeam);
63
64 if (error == B_OK) {
65 function->SetSourceCode(sourceCode, FUNCTION_SOURCE_LOADED);
66 sourceCode->ReleaseReference();
67 return B_OK;
68 }
69
70 function->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);
71 }
72
73 // Only try to load the function instance code, if it's not overridden yet.
74 AutoLocker<Team> locker(fTeam);
75 if (fFunctionInstance->SourceCodeState() != FUNCTION_SOURCE_LOADING)
76 return B_OK;
77 locker.Unlock();
78
79 // disassemble the function
80 DisassembledCode* sourceCode = NULL;
81 status_t error = fTeam->DebugInfo()->DisassembleFunction(fFunctionInstance,
82 sourceCode);
83
84 // set the result
85 locker.Lock();
86 if (error == B_OK) {
87 if (fFunctionInstance->SourceCodeState() == FUNCTION_SOURCE_LOADING) {
88 // various parts of the debugger expect functions to have only
89 // one of source or disassembly available. As such, if the current
90 // function had source code previously active, unset it when
91 // explicitly asked for disassembly. This needs to be done first
92 // since Function will clear the disassembled code states of all
93 // its child instances.
94 function_source_state state
95 = fLoadForFunction ? FUNCTION_SOURCE_LOADED
96 : FUNCTION_SOURCE_SUPPRESSED;
97 if (function->SourceCodeState() == FUNCTION_SOURCE_LOADED) {
98 FileSourceCode* functionSourceCode = function->GetSourceCode();
99 function->SetSourceCode(functionSourceCode, state);
100 }
101
102 fFunctionInstance->SetSourceCode(sourceCode, state);
103 sourceCode->ReleaseReference();
104 }
105 } else
106 fFunctionInstance->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);
107
108 return error;
109 }
110