status_t DwarfImageDebugInfo::GetFunctions(const BObjectList<SymbolInfo>& symbols, BObjectList<FunctionDebugInfo>& functions) { TRACE_IMAGES("DwarfImageDebugInfo::GetFunctions()\n"); TRACE_IMAGES(" %" B_PRId32 " compilation units\n", fFile->CountCompilationUnits()); for (int32 i = 0; CompilationUnit* unit = fFile->CompilationUnitAt(i); i++) { DIECompileUnitBase* unitEntry = unit->UnitEntry(); // printf(" %s:\n", unitEntry->Name()); // printf(" address ranges:\n"); // TargetAddressRangeList* rangeList = unitEntry->AddressRanges(); // if (rangeList != NULL) { // int32 count = rangeList->CountRanges(); // for (int32 i = 0; i < count; i++) { // TargetAddressRange range = rangeList->RangeAt(i); // printf(" %#llx - %#llx\n", range.Start(), range.End()); // } // } else { // printf(" %#llx - %#llx\n", (target_addr_t)unitEntry->LowPC(), // (target_addr_t)unitEntry->HighPC()); // } // printf(" functions:\n"); for (DebugInfoEntryList::ConstIterator it = unitEntry->OtherChildren().GetIterator(); DebugInfoEntry* entry = it.Next();) { if (entry->Tag() != DW_TAG_subprogram) continue; DIESubprogram* subprogramEntry = static_cast<DIESubprogram*>(entry); // ignore declarations and inlined functions if (subprogramEntry->IsDeclaration() || subprogramEntry->Inline() == DW_INL_inlined || subprogramEntry->Inline() == DW_INL_declared_inlined) { continue; } // get the name BString name; DwarfUtils::GetFullyQualifiedDIEName(subprogramEntry, name); if (name.Length() == 0) continue; // get the address ranges TargetAddressRangeList* rangeList = fFile->ResolveRangeList(unit, subprogramEntry->AddressRangesOffset()); if (rangeList == NULL) { target_addr_t lowPC = subprogramEntry->LowPC(); target_addr_t highPC = subprogramEntry->HighPC(); if (highPC <= lowPC) continue; rangeList = new(std::nothrow) TargetAddressRangeList( TargetAddressRange(lowPC, highPC - lowPC)); if (rangeList == NULL) return B_NO_MEMORY; // TODO: Clean up already added functions! } BReference<TargetAddressRangeList> rangeListReference(rangeList, true); // get the source location const char* directoryPath = NULL; const char* fileName = NULL; int32 line = -1; int32 column = -1; DwarfUtils::GetDeclarationLocation(fFile, subprogramEntry, directoryPath, fileName, line, column); LocatableFile* file = NULL; if (fileName != NULL) { file = fFileManager->GetSourceFile(directoryPath, fileName); } BReference<LocatableFile> fileReference(file, true); // create and add the functions DwarfFunctionDebugInfo* function = new(std::nothrow) DwarfFunctionDebugInfo(this, unit, subprogramEntry, rangeList, name, file, SourceLocation(line, std::max(column, (int32)0))); if (function == NULL || !functions.AddItem(function)) { delete function; return B_NO_MEMORY; // TODO: Clean up already added functions! } // BString name; // DwarfUtils::GetFullyQualifiedDIEName(subprogramEntry, name); // printf(" subprogram entry: %p, name: %s, declaration: %d\n", // subprogramEntry, name.String(), // subprogramEntry->IsDeclaration()); // // rangeList = subprogramEntry->AddressRanges(); // if (rangeList != NULL) { // int32 count = rangeList->CountRanges(); // for (int32 i = 0; i < count; i++) { // TargetAddressRange range = rangeList->RangeAt(i); // printf(" %#llx - %#llx\n", range.Start(), range.End()); // } // } else { // printf(" %#llx - %#llx\n", // (target_addr_t)subprogramEntry->LowPC(), // (target_addr_t)subprogramEntry->HighPC()); // } } } if (fFile->CountCompilationUnits() != 0) return B_OK; // if we had no compilation units, fall back to providing basic // debug infos with DWARF-supported call frame unwinding, // if available. if (fFile->HasFrameInformation()) { return SpecificImageDebugInfo::GetFunctionsFromSymbols(symbols, functions, fDebuggerInterface, fImageInfo, this); } return B_OK; }
void TeamDebugger::_HandleImageFileChanged(image_id imageID) { TRACE_IMAGES("TeamDebugger::_HandleImageFileChanged(%ld)\n", imageID); // TODO: Reload the debug info! }