Debugger: Further work on memory leak hunting.
[haiku.git] / src / kits / debugger / debug_info / ImageDebugInfo.cpp
blob88f6cde123f359e0379c4b908f734db3ac611be9
1 /*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2010-2017, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
7 #include "ImageDebugInfo.h"
9 #include <new>
11 #include "DebuggerInterface.h"
12 #include "FunctionDebugInfo.h"
13 #include "FunctionInstance.h"
14 #include "SpecificImageDebugInfo.h"
15 #include "SymbolInfo.h"
18 ImageDebugInfo::ImageDebugInfo(const ImageInfo& imageInfo)
20 fImageInfo(imageInfo),
21 fMainFunction(NULL)
26 ImageDebugInfo::~ImageDebugInfo()
28 for (int32 i = 0; FunctionInstance* function = fFunctions.ItemAt(i); i++)
29 function->ReleaseReference();
31 for (int32 i = 0; SpecificImageDebugInfo* info = fSpecificInfos.ItemAt(i);
32 i++) {
33 info->ReleaseReference();
38 bool
39 ImageDebugInfo::AddSpecificInfo(SpecificImageDebugInfo* info)
41 // NB: on success we take over the caller's reference to the info object
42 return fSpecificInfos.AddItem(info);
46 status_t
47 ImageDebugInfo::FinishInit(DebuggerInterface* interface)
49 BObjectList<SymbolInfo> symbols(50, true);
50 status_t error = interface->GetSymbolInfos(fImageInfo.TeamID(),
51 fImageInfo.ImageID(), symbols);
52 if (error != B_OK)
53 return error;
54 symbols.SortItems(&_CompareSymbols);
56 // get functions -- get them from most expressive debug info first and add
57 // missing functions from less expressive debug infos
58 for (int32 i = 0; SpecificImageDebugInfo* specificInfo
59 = fSpecificInfos.ItemAt(i); i++) {
60 BObjectList<FunctionDebugInfo> functions;
61 error = specificInfo->GetFunctions(symbols, functions);
62 if (error != B_OK)
63 return error;
65 for (int32 k = 0; FunctionDebugInfo* function = functions.ItemAt(k);
66 k++) {
67 if (FunctionAtAddress(function->Address()) != NULL)
68 continue;
70 FunctionInstance* instance = new(std::nothrow) FunctionInstance(
71 this, function);
72 if (instance == NULL
73 || !fFunctions.BinaryInsert(instance, &_CompareFunctions)) {
74 delete instance;
75 error = B_NO_MEMORY;
76 break;
79 if (function->IsMain())
80 fMainFunction = instance;
83 // Remove references returned by the specific debug info -- the
84 // FunctionInstance objects have references, now.
85 for (int32 k = 0; FunctionDebugInfo* function = functions.ItemAt(k);
86 k++) {
87 function->ReleaseReference();
90 if (error != B_OK)
91 return error;
94 return B_OK;
98 status_t
99 ImageDebugInfo::GetType(GlobalTypeCache* cache, const BString& name,
100 const TypeLookupConstraints& constraints, Type*& _type)
102 for (int32 i = 0; SpecificImageDebugInfo* specificInfo
103 = fSpecificInfos.ItemAt(i); i++) {
104 status_t error = specificInfo->GetType(cache, name, constraints,
105 _type);
106 if (error == B_OK || error == B_NO_MEMORY)
107 return error;
110 return B_ENTRY_NOT_FOUND;
114 bool
115 ImageDebugInfo::HasType(const BString& name,
116 const TypeLookupConstraints& constraints) const
118 for (int32 i = 0; SpecificImageDebugInfo* specificInfo
119 = fSpecificInfos.ItemAt(i); i++) {
120 if (specificInfo->HasType(name, constraints))
121 return true;
124 return false;
128 AddressSectionType
129 ImageDebugInfo::GetAddressSectionType(target_addr_t address) const
131 AddressSectionType type = ADDRESS_SECTION_TYPE_UNKNOWN;
132 for (int32 i = 0; SpecificImageDebugInfo* specificInfo
133 = fSpecificInfos.ItemAt(i); i++) {
134 type = specificInfo->GetAddressSectionType(address);
135 if (type != ADDRESS_SECTION_TYPE_UNKNOWN)
136 break;
139 return type;
143 int32
144 ImageDebugInfo::CountFunctions() const
146 return fFunctions.CountItems();
150 FunctionInstance*
151 ImageDebugInfo::FunctionAt(int32 index) const
153 return fFunctions.ItemAt(index);
157 FunctionInstance*
158 ImageDebugInfo::FunctionAtAddress(target_addr_t address) const
160 return fFunctions.BinarySearchByKey(address, &_CompareAddressFunction);
164 FunctionInstance*
165 ImageDebugInfo::FunctionByName(const char* name) const
167 // TODO: Not really optimal.
168 for (int32 i = 0; FunctionInstance* function = fFunctions.ItemAt(i); i++) {
169 if (function->Name() == name)
170 return function;
173 return NULL;
177 status_t
178 ImageDebugInfo::AddSourceCodeInfo(LocatableFile* file,
179 FileSourceCode* sourceCode) const
181 bool addedAny = false;
182 for (int32 i = 0; SpecificImageDebugInfo* specificInfo
183 = fSpecificInfos.ItemAt(i); i++) {
184 status_t error = specificInfo->AddSourceCodeInfo(file, sourceCode);
185 if (error == B_NO_MEMORY)
186 return error;
187 addedAny |= error == B_OK;
190 return addedAny ? B_OK : B_ENTRY_NOT_FOUND;
194 /*static*/ int
195 ImageDebugInfo::_CompareFunctions(const FunctionInstance* a,
196 const FunctionInstance* b)
198 return a->Address() < b->Address()
199 ? -1 : (a->Address() == b->Address() ? 0 : 1);
203 /*static*/ int
204 ImageDebugInfo::_CompareAddressFunction(const target_addr_t* address,
205 const FunctionInstance* function)
207 if (*address < function->Address())
208 return -1;
209 return *address < function->Address() + function->Size() ? 0 : 1;
213 /*static*/ int
214 ImageDebugInfo::_CompareSymbols(const SymbolInfo* a, const SymbolInfo* b)
216 return a->Address() < b->Address()
217 ? -1 : (a->Address() == b->Address() ? 0 : 1);