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 18ImageDebugInfo::ImageDebugInfo(const ImageInfo& imageInfo) 19 : 20 fImageInfo(imageInfo), 21 fMainFunction(NULL) 22{ 23} 24 25 26ImageDebugInfo::~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 38bool 39ImageDebugInfo::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 46status_t 47ImageDebugInfo::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 98status_t 99ImageDebugInfo::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 114bool 115ImageDebugInfo::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 128AddressSectionType 129ImageDebugInfo::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 143int32 144ImageDebugInfo::CountFunctions() const 145{ 146 return fFunctions.CountItems(); 147} 148 149 150FunctionInstance* 151ImageDebugInfo::FunctionAt(int32 index) const 152{ 153 return fFunctions.ItemAt(index); 154} 155 156 157FunctionInstance* 158ImageDebugInfo::FunctionAtAddress(target_addr_t address) const 159{ 160 return fFunctions.BinarySearchByKey(address, &_CompareAddressFunction); 161} 162 163 164FunctionInstance* 165ImageDebugInfo::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 177status_t 178ImageDebugInfo::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 195ImageDebugInfo::_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 204ImageDebugInfo::_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 214ImageDebugInfo::_CompareSymbols(const SymbolInfo* a, const SymbolInfo* b) 215{ 216 return a->Address() < b->Address() 217 ? -1 : (a->Address() == b->Address() ? 0 : 1); 218} 219