xref: /haiku/src/kits/debugger/dwarf/DwarfManager.cpp (revision bb83316a5811a550c4f850d07fa8e328e7ac0a94)
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