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