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