1 /* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2014-2017, Rene Gollent, rene@gollent.com. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 #include "DwarfManager.h" 8 9 #include <new> 10 11 #include <AutoDeleter.h> 12 #include <AutoLocker.h> 13 14 #include "DwarfFile.h" 15 #include "DwarfFileLoadingState.h" 16 17 18 DwarfManager::DwarfManager(uint8 addressSize, bool isBigEndian) 19 : 20 fAddressSize(addressSize), fIsBigEndian(isBigEndian), 21 fLock("dwarf manager") 22 { 23 } 24 25 26 DwarfManager::~DwarfManager() 27 { 28 while (DwarfFile* file = fFiles.RemoveHead()) 29 file->ReleaseReference(); 30 } 31 32 33 status_t 34 DwarfManager::Init() 35 { 36 return fLock.InitCheck(); 37 } 38 39 40 status_t 41 DwarfManager::LoadFile(const char* fileName, DwarfFileLoadingState& _state) 42 { 43 AutoLocker<DwarfManager> locker(this); 44 45 DwarfFile* file = _state.dwarfFile; 46 BReference<DwarfFile> fileReference; 47 if (file == NULL) { 48 file = new(std::nothrow) DwarfFile; 49 if (file == NULL) 50 return B_NO_MEMORY; 51 fileReference.SetTo(file, true); 52 _state.dwarfFile = file; 53 } else 54 fileReference.SetTo(file); 55 56 status_t error; 57 if (_state.externalInfoFileName.IsEmpty()) { 58 error = file->StartLoading(fileName, _state.externalInfoFileName); 59 if (error != B_OK) { 60 // only preserve state in the failure case if an external 61 // debug information reference was found, but the corresponding 62 // file could not be located on disk. 63 _state.state = _state.externalInfoFileName.IsEmpty() 64 ? DWARF_FILE_LOADING_STATE_FAILED 65 : DWARF_FILE_LOADING_STATE_USER_INPUT_NEEDED; 66 67 return error; 68 } 69 } 70 71 error = file->Load(fAddressSize, fIsBigEndian, _state.locatedExternalInfoPath); 72 if (error != B_OK) { 73 _state.state = DWARF_FILE_LOADING_STATE_FAILED; 74 return error; 75 } 76 77 fFiles.Add(file); 78 79 fileReference.Detach(); 80 // keep a reference for ourselves in the list. 81 82 _state.state = DWARF_FILE_LOADING_STATE_SUCCEEDED; 83 84 return B_OK; 85 } 86 87 88 status_t 89 DwarfManager::FinishLoading() 90 { 91 AutoLocker<DwarfManager> locker(this); 92 93 for (FileList::Iterator it = fFiles.GetIterator(); 94 DwarfFile* file = it.Next();) { 95 status_t error = file->FinishLoading(fAddressSize, fIsBigEndian); 96 if (error != B_OK) 97 return error; 98 } 99 100 return B_OK; 101 } 102