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.
7 #include "ImageDebugInfo.h"
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
),
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
);
33 info
->ReleaseReference();
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
);
47 ImageDebugInfo::FinishInit(DebuggerInterface
* interface
)
49 BObjectList
<SymbolInfo
> symbols(50, true);
50 status_t error
= interface
->GetSymbolInfos(fImageInfo
.TeamID(),
51 fImageInfo
.ImageID(), symbols
);
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
);
65 for (int32 k
= 0; FunctionDebugInfo
* function
= functions
.ItemAt(k
);
67 if (FunctionAtAddress(function
->Address()) != NULL
)
70 FunctionInstance
* instance
= new(std::nothrow
) FunctionInstance(
73 || !fFunctions
.BinaryInsert(instance
, &_CompareFunctions
)) {
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
);
87 function
->ReleaseReference();
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
,
106 if (error
== B_OK
|| error
== B_NO_MEMORY
)
110 return B_ENTRY_NOT_FOUND
;
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
))
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
)
144 ImageDebugInfo::CountFunctions() const
146 return fFunctions
.CountItems();
151 ImageDebugInfo::FunctionAt(int32 index
) const
153 return fFunctions
.ItemAt(index
);
158 ImageDebugInfo::FunctionAtAddress(target_addr_t address
) const
160 return fFunctions
.BinarySearchByKey(address
, &_CompareAddressFunction
);
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
)
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
)
187 addedAny
|= error
== B_OK
;
190 return addedAny
? B_OK
: B_ENTRY_NOT_FOUND
;
195 ImageDebugInfo::_CompareFunctions(const FunctionInstance
* a
,
196 const FunctionInstance
* b
)
198 return a
->Address() < b
->Address()
199 ? -1 : (a
->Address() == b
->Address() ? 0 : 1);
204 ImageDebugInfo::_CompareAddressFunction(const target_addr_t
* address
,
205 const FunctionInstance
* function
)
207 if (*address
< function
->Address())
209 return *address
< function
->Address() + function
->Size() ? 0 : 1;
214 ImageDebugInfo::_CompareSymbols(const SymbolInfo
* a
, const SymbolInfo
* b
)
216 return a
->Address() < b
->Address()
217 ? -1 : (a
->Address() == b
->Address() ? 0 : 1);