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 */
6
7 #include "ImageDebugInfo.h"
8
9 #include <new>
10
11 #include "DebuggerInterface.h"
12 #include "FunctionDebugInfo.h"
13 #include "FunctionInstance.h"
14 #include "SpecificImageDebugInfo.h"
15 #include "SymbolInfo.h"
16
17
ImageDebugInfo(const ImageInfo & imageInfo)18 ImageDebugInfo::ImageDebugInfo(const ImageInfo& imageInfo)
19 :
20 fImageInfo(imageInfo),
21 fMainFunction(NULL)
22 {
23 }
24
25
~ImageDebugInfo()26 ImageDebugInfo::~ImageDebugInfo()
27 {
28 for (int32 i = 0; FunctionInstance* function = fFunctions.ItemAt(i); i++)
29 function->ReleaseReference();
30
31 for (int32 i = 0; SpecificImageDebugInfo* info = fSpecificInfos.ItemAt(i);
32 i++) {
33 info->ReleaseReference();
34 }
35 }
36
37
38 bool
AddSpecificInfo(SpecificImageDebugInfo * info)39 ImageDebugInfo::AddSpecificInfo(SpecificImageDebugInfo* info)
40 {
41 // NB: on success we take over the caller's reference to the info object
42 return fSpecificInfos.AddItem(info);
43 }
44
45
46 status_t
FinishInit(DebuggerInterface * interface)47 ImageDebugInfo::FinishInit(DebuggerInterface* interface)
48 {
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);
55
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;
64
65 for (int32 k = 0; FunctionDebugInfo* function = functions.ItemAt(k);
66 k++) {
67 if (FunctionAtAddress(function->Address()) != NULL)
68 continue;
69
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;
77 }
78
79 if (function->IsMain())
80 fMainFunction = instance;
81 }
82
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();
88 }
89
90 if (error != B_OK)
91 return error;
92 }
93
94 return B_OK;
95 }
96
97
98 status_t
GetType(GlobalTypeCache * cache,const BString & name,const TypeLookupConstraints & constraints,Type * & _type)99 ImageDebugInfo::GetType(GlobalTypeCache* cache, const BString& name,
100 const TypeLookupConstraints& constraints, Type*& _type)
101 {
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;
108 }
109
110 return B_ENTRY_NOT_FOUND;
111 }
112
113
114 bool
HasType(const BString & name,const TypeLookupConstraints & constraints) const115 ImageDebugInfo::HasType(const BString& name,
116 const TypeLookupConstraints& constraints) const
117 {
118 for (int32 i = 0; SpecificImageDebugInfo* specificInfo
119 = fSpecificInfos.ItemAt(i); i++) {
120 if (specificInfo->HasType(name, constraints))
121 return true;
122 }
123
124 return false;
125 }
126
127
128 AddressSectionType
GetAddressSectionType(target_addr_t address) const129 ImageDebugInfo::GetAddressSectionType(target_addr_t address) const
130 {
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;
137 }
138
139 return type;
140 }
141
142
143 int32
CountFunctions() const144 ImageDebugInfo::CountFunctions() const
145 {
146 return fFunctions.CountItems();
147 }
148
149
150 FunctionInstance*
FunctionAt(int32 index) const151 ImageDebugInfo::FunctionAt(int32 index) const
152 {
153 return fFunctions.ItemAt(index);
154 }
155
156
157 FunctionInstance*
FunctionAtAddress(target_addr_t address) const158 ImageDebugInfo::FunctionAtAddress(target_addr_t address) const
159 {
160 return fFunctions.BinarySearchByKey(address, &_CompareAddressFunction);
161 }
162
163
164 FunctionInstance*
FunctionByName(const char * name) const165 ImageDebugInfo::FunctionByName(const char* name) const
166 {
167 // TODO: Not really optimal.
168 for (int32 i = 0; FunctionInstance* function = fFunctions.ItemAt(i); i++) {
169 if (function->Name() == name)
170 return function;
171 }
172
173 return NULL;
174 }
175
176
177 status_t
AddSourceCodeInfo(LocatableFile * file,FileSourceCode * sourceCode) const178 ImageDebugInfo::AddSourceCodeInfo(LocatableFile* file,
179 FileSourceCode* sourceCode) const
180 {
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;
188 }
189
190 return addedAny ? B_OK : B_ENTRY_NOT_FOUND;
191 }
192
193
194 /*static*/ int
_CompareFunctions(const FunctionInstance * a,const FunctionInstance * b)195 ImageDebugInfo::_CompareFunctions(const FunctionInstance* a,
196 const FunctionInstance* b)
197 {
198 return a->Address() < b->Address()
199 ? -1 : (a->Address() == b->Address() ? 0 : 1);
200 }
201
202
203 /*static*/ int
_CompareAddressFunction(const target_addr_t * address,const FunctionInstance * function)204 ImageDebugInfo::_CompareAddressFunction(const target_addr_t* address,
205 const FunctionInstance* function)
206 {
207 if (*address < function->Address())
208 return -1;
209 return *address < function->Address() + function->Size() ? 0 : 1;
210 }
211
212
213 /*static*/ int
_CompareSymbols(const SymbolInfo * a,const SymbolInfo * b)214 ImageDebugInfo::_CompareSymbols(const SymbolInfo* a, const SymbolInfo* b)
215 {
216 return a->Address() < b->Address()
217 ? -1 : (a->Address() == b->Address() ? 0 : 1);
218 }
219