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 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 39 LoadSourceCodeJob::~LoadSourceCodeJob() 40 { 41 fFunctionInstance->ReleaseReference(); 42 } 43 44 45 const JobKey& 46 LoadSourceCodeJob::Key() const 47 { 48 return fKey; 49 } 50 51 52 status_t 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