1 /* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2010-2013, 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 18 ImageDebugInfo::ImageDebugInfo(const ImageInfo& imageInfo) 19 : 20 fImageInfo(imageInfo), 21 fMainFunction(NULL) 22 { 23 } 24 25 26 ImageDebugInfo::~ImageDebugInfo() 27 { 28 for (int32 i = 0; FunctionInstance* function = fFunctions.ItemAt(i); i++) 29 function->ReleaseReference(); 30 } 31 32 33 bool 34 ImageDebugInfo::AddSpecificInfo(SpecificImageDebugInfo* info) 35 { 36 return fSpecificInfos.AddItem(info); 37 } 38 39 40 status_t 41 ImageDebugInfo::FinishInit(DebuggerInterface* interface) 42 { 43 BObjectList<SymbolInfo> symbols(50, true); 44 status_t error = interface->GetSymbolInfos(fImageInfo.TeamID(), 45 fImageInfo.ImageID(), symbols); 46 if (error != B_OK) 47 return error; 48 symbols.SortItems(&_CompareSymbols); 49 50 // get functions -- get them from most expressive debug info first and add 51 // missing functions from less expressive debug infos 52 for (int32 i = 0; SpecificImageDebugInfo* specificInfo 53 = fSpecificInfos.ItemAt(i); i++) { 54 BObjectList<FunctionDebugInfo> functions; 55 error = specificInfo->GetFunctions(symbols, functions); 56 if (error != B_OK) 57 return error; 58 59 for (int32 k = 0; FunctionDebugInfo* function = functions.ItemAt(k); 60 k++) { 61 if (FunctionAtAddress(function->Address()) != NULL) 62 continue; 63 64 FunctionInstance* instance = new(std::nothrow) FunctionInstance( 65 this, function); 66 if (instance == NULL 67 || !fFunctions.BinaryInsert(instance, &_CompareFunctions)) { 68 delete instance; 69 error = B_NO_MEMORY; 70 break; 71 } 72 73 if (function->IsMain()) 74 fMainFunction = instance; 75 } 76 77 // Remove references returned by the specific debug info -- the 78 // FunctionInstance objects have references, now. 79 for (int32 k = 0; FunctionDebugInfo* function = functions.ItemAt(k); 80 k++) { 81 function->ReleaseReference(); 82 } 83 84 if (error != B_OK) 85 return error; 86 } 87 88 return B_OK; 89 } 90 91 92 status_t 93 ImageDebugInfo::GetType(GlobalTypeCache* cache, const BString& name, 94 const TypeLookupConstraints& constraints, Type*& _type) 95 { 96 for (int32 i = 0; SpecificImageDebugInfo* specificInfo 97 = fSpecificInfos.ItemAt(i); i++) { 98 status_t error = specificInfo->GetType(cache, name, constraints, 99 _type); 100 if (error == B_OK || error == B_NO_MEMORY) 101 return error; 102 } 103 104 return B_ENTRY_NOT_FOUND; 105 } 106 107 108 bool 109 ImageDebugInfo::HasType(const BString& name, 110 const TypeLookupConstraints& constraints) const 111 { 112 for (int32 i = 0; SpecificImageDebugInfo* specificInfo 113 = fSpecificInfos.ItemAt(i); i++) { 114 if (specificInfo->HasType(name, constraints)) 115 return true; 116 } 117 118 return false; 119 } 120 121 122 AddressSectionType 123 ImageDebugInfo::GetAddressSectionType(target_addr_t address) const 124 { 125 AddressSectionType type = ADDRESS_SECTION_TYPE_UNKNOWN; 126 for (int32 i = 0; SpecificImageDebugInfo* specificInfo 127 = fSpecificInfos.ItemAt(i); i++) { 128 type = specificInfo->GetAddressSectionType(address); 129 if (type != ADDRESS_SECTION_TYPE_UNKNOWN) 130 break; 131 } 132 133 return type; 134 } 135 136 137 int32 138 ImageDebugInfo::CountFunctions() const 139 { 140 return fFunctions.CountItems(); 141 } 142 143 144 FunctionInstance* 145 ImageDebugInfo::FunctionAt(int32 index) const 146 { 147 return fFunctions.ItemAt(index); 148 } 149 150 151 FunctionInstance* 152 ImageDebugInfo::FunctionAtAddress(target_addr_t address) const 153 { 154 return fFunctions.BinarySearchByKey(address, &_CompareAddressFunction); 155 } 156 157 158 FunctionInstance* 159 ImageDebugInfo::FunctionByName(const char* name) const 160 { 161 // TODO: Not really optimal. 162 for (int32 i = 0; FunctionInstance* function = fFunctions.ItemAt(i); i++) { 163 if (function->Name() == name) 164 return function; 165 } 166 167 return NULL; 168 } 169 170 171 status_t 172 ImageDebugInfo::AddSourceCodeInfo(LocatableFile* file, 173 FileSourceCode* sourceCode) const 174 { 175 bool addedAny = false; 176 for (int32 i = 0; SpecificImageDebugInfo* specificInfo 177 = fSpecificInfos.ItemAt(i); i++) { 178 status_t error = specificInfo->AddSourceCodeInfo(file, sourceCode); 179 if (error == B_NO_MEMORY) 180 return error; 181 addedAny |= error == B_OK; 182 } 183 184 return addedAny ? B_OK : B_ENTRY_NOT_FOUND; 185 } 186 187 188 /*static*/ int 189 ImageDebugInfo::_CompareFunctions(const FunctionInstance* a, 190 const FunctionInstance* b) 191 { 192 return a->Address() < b->Address() 193 ? -1 : (a->Address() == b->Address() ? 0 : 1); 194 } 195 196 197 /*static*/ int 198 ImageDebugInfo::_CompareAddressFunction(const target_addr_t* address, 199 const FunctionInstance* function) 200 { 201 if (*address < function->Address()) 202 return -1; 203 return *address < function->Address() + function->Size() ? 0 : 1; 204 } 205 206 207 /*static*/ int 208 ImageDebugInfo::_CompareSymbols(const SymbolInfo* a, const SymbolInfo* b) 209 { 210 return a->Address() < b->Address() 211 ? -1 : (a->Address() == b->Address() ? 0 : 1); 212 } 213