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 18DwarfManager::DwarfManager(uint8 addressSize, bool isBigEndian) 19 : 20 fAddressSize(addressSize), fIsBigEndian(isBigEndian), 21 fLock("dwarf manager") 22{ 23} 24 25 26DwarfManager::~DwarfManager() 27{ 28 while (DwarfFile* file = fFiles.RemoveHead()) 29 file->ReleaseReference(); 30} 31 32 33status_t 34DwarfManager::Init() 35{ 36 return fLock.InitCheck(); 37} 38 39 40status_t 41DwarfManager::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 88status_t 89DwarfManager::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