Function* TeamDebugInfo::FunctionByID(FunctionID* functionID) const { if (SourceFunctionID* sourceFunctionID = dynamic_cast<SourceFunctionID*>(functionID)) { // get the source file LocatableFile* file = fFileManager->GetSourceFile( sourceFunctionID->SourceFilePath()); if (file == NULL) return NULL; BReference<LocatableFile> fileReference(file, true); if (SourceFileEntry* entry = fSourceFiles->Lookup(file)) return entry->FunctionByName(functionID->FunctionName()); return NULL; } ImageFunctionID* imageFunctionID = dynamic_cast<ImageFunctionID*>(functionID); if (imageFunctionID == NULL) return NULL; ImageDebugInfo* imageDebugInfo = ImageDebugInfoByName(imageFunctionID->ImageName()); if (imageDebugInfo == NULL) return NULL; FunctionInstance* functionInstance = imageDebugInfo->FunctionByName( functionID->FunctionName()); return functionInstance != NULL ? functionInstance->GetFunction() : NULL; }
status_t DwarfTeamDebugInfo::CreateImageDebugInfo(const ImageInfo& imageInfo, LocatableFile* imageFile, SpecificImageDebugInfo*& _imageDebugInfo) { // We only like images whose file we can play with. BString filePath; if (imageFile == NULL || !imageFile->GetLocatedPath(filePath)) return B_ENTRY_NOT_FOUND; // try to load the DWARF file DwarfFile* file; status_t error = fManager->LoadFile(filePath, file); if (error != B_OK) return error; BReference<DwarfFile> fileReference(file, true); error = fManager->FinishLoading(); if (error != B_OK) return error; // create the image debug info DwarfImageDebugInfo* debugInfo = new(std::nothrow) DwarfImageDebugInfo( imageInfo, fDebuggerInterface, fArchitecture, fFileManager, fTypeLookup, fTypeCache, file); if (debugInfo == NULL) return B_NO_MEMORY; error = debugInfo->Init(); if (error != B_OK) { delete debugInfo; return error; } _imageDebugInfo = debugInfo; return B_OK; }
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; }