From 5bda396ef4e145db5dc4f4ba1eeb6d1e00a6231c Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sun, 16 Dec 2012 10:59:12 -0500 Subject: [PATCH] Refactor Dwarf*DebugInfo to be able to work with limited info. - DwarfImageDebugInfo and DwarfFile will now allow us to construct DWARF debug info objects even if the only section available for use is .eh_frame. This essentially allows us to use CFI-based unwinding even for release executables (assuming C++ is involved), which means we can properly unwind the stack even for binaries compiled with fomit-frame-pointer. This becomes more important for x86-64, since omit is the ABI default there. - Pull a GetFunctionsFromSymbols() out of DebuggerImageDebugInfo. This is shared between DebuggerImageDebugInfo and DwarfImageDebugInfo for creating debug information entries in the absence of debugging information. --- .../debug_info/DebuggerImageDebugInfo.cpp | 44 +-------- .../debug_info/DebuggerImageDebugInfo.h | 4 - .../debug_info/DwarfImageDebugInfo.cpp | 98 ++++++++++++------- .../debugger/debug_info/DwarfImageDebugInfo.h | 8 +- .../debug_info/DwarfTeamDebugInfo.cpp | 11 ++- .../debugger/debug_info/DwarfTeamDebugInfo.h | 5 +- .../debug_info/SpecificImageDebugInfo.cpp | 55 +++++++++++ .../debug_info/SpecificImageDebugInfo.h | 13 +++ src/apps/debugger/dwarf/DwarfFile.cpp | 40 +++++--- src/apps/debugger/dwarf/DwarfFile.h | 3 + 10 files changed, 174 insertions(+), 107 deletions(-) diff --git a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp index 490d6a6974..01467c789d 100644 --- a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp @@ -44,39 +44,8 @@ DebuggerImageDebugInfo::Init() status_t DebuggerImageDebugInfo::GetFunctions(BObjectList& functions) { - BObjectList symbols(20, true); - status_t error = fDebuggerInterface->GetSymbolInfos(fImageInfo.TeamID(), - fImageInfo.ImageID(), symbols); - if (error != B_OK) - return error; - - // sort the symbols -- not necessary, but a courtesy to ImageDebugInfo which - // will peform better when inserting functions at the end of a list - symbols.SortItems(&_CompareSymbols); - - // create the function infos - int32 functionsAdded = 0; - for (int32 i = 0; SymbolInfo* symbol = symbols.ItemAt(i); i++) { - if (symbol->Type() != B_SYMBOL_TYPE_TEXT) - continue; - - FunctionDebugInfo* function = new(std::nothrow) BasicFunctionDebugInfo( - this, symbol->Address(), symbol->Size(), symbol->Name(), - Demangler::Demangle(symbol->Name())); - if (function == NULL || !functions.AddItem(function)) { - delete function; - int32 index = functions.CountItems() - 1; - for (; functionsAdded >= 0; functionsAdded--, index--) { - function = functions.RemoveItemAt(index); - delete function; - } - return B_NO_MEMORY; - } - - functionsAdded++; - } - - return B_OK; + return SpecificImageDebugInfo::GetFunctionsFromSymbols(functions, + fDebuggerInterface, fImageInfo, this); } @@ -144,12 +113,3 @@ DebuggerImageDebugInfo::AddSourceCodeInfo(LocatableFile* file, { return B_UNSUPPORTED; } - - -/*static*/ int -DebuggerImageDebugInfo::_CompareSymbols(const SymbolInfo* a, - const SymbolInfo* b) -{ - return a->Address() < b->Address() - ? -1 : (a->Address() == b->Address() ? 0 : 1); -} diff --git a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h index dbf70e9c8d..043b4eae52 100644 --- a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h +++ b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h @@ -54,10 +54,6 @@ public: virtual status_t AddSourceCodeInfo(LocatableFile* file, FileSourceCode* sourceCode); -private: - static int _CompareSymbols(const SymbolInfo* a, - const SymbolInfo* b); - private: ImageInfo fImageInfo; DebuggerInterface* fDebuggerInterface; diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp index 3f570c64e3..6a68656f1d 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp @@ -18,11 +18,14 @@ #include #include "Architecture.h" +#include "BasicFunctionDebugInfo.h" #include "CLanguage.h" #include "CompilationUnit.h" #include "CppLanguage.h" #include "CpuState.h" +#include "DebuggerInterface.h" #include "DebugInfoEntries.h" +#include "Demangler.h" #include "Dwarf.h" #include "DwarfFile.h" #include "DwarfFunctionDebugInfo.h" @@ -44,6 +47,7 @@ #include "StackFrame.h" #include "Statement.h" #include "StringUtils.h" +#include "SymbolInfo.h" #include "TargetAddressRangeList.h" #include "TeamMemory.h" #include "Tracing.h" @@ -226,14 +230,14 @@ struct DwarfImageDebugInfo::EntryListWrapper { DwarfImageDebugInfo::DwarfImageDebugInfo(const ImageInfo& imageInfo, - Architecture* architecture, TeamMemory* teamMemory, + DebuggerInterface* interface, Architecture* architecture, FileManager* fileManager, GlobalTypeLookup* typeLookup, GlobalTypeCache* typeCache, DwarfFile* file) : fLock("dwarf image debug info"), fImageInfo(imageInfo), + fDebuggerInterface(interface), fArchitecture(architecture), - fTeamMemory(teamMemory), fFileManager(fileManager), fTypeLookup(typeLookup), fTypeCache(typeCache), @@ -245,6 +249,7 @@ DwarfImageDebugInfo::DwarfImageDebugInfo(const ImageInfo& imageInfo, fPLTSectionStart(0), fPLTSectionEnd(0) { + fDebuggerInterface->AcquireReference(); fFile->AcquireReference(); fTypeCache->AcquireReference(); } @@ -252,6 +257,7 @@ DwarfImageDebugInfo::DwarfImageDebugInfo(const ImageInfo& imageInfo, DwarfImageDebugInfo::~DwarfImageDebugInfo() { + fDebuggerInterface->ReleaseReference(); fFile->ReleaseReference(); fTypeCache->ReleaseReference(); } @@ -397,7 +403,13 @@ DwarfImageDebugInfo::GetFunctions(BObjectList& functions) } } - return B_OK; + 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 + return SpecificImageDebugInfo::GetFunctionsFromSymbols(functions, + fDebuggerInterface, fImageInfo, this); } @@ -419,7 +431,7 @@ DwarfImageDebugInfo::GetType(GlobalTypeCache* cache, // create the target interface BasicTargetInterface *inputInterface = new(std::nothrow) BasicTargetInterface(registers, registerCount, - fromDwarfMap, fArchitecture, fTeamMemory); + fromDwarfMap, fArchitecture, fDebuggerInterface); if (inputInterface == NULL) return B_NO_MEMORY; @@ -508,16 +520,17 @@ DwarfImageDebugInfo::CreateFrame(Image* image, { DwarfFunctionDebugInfo* function = dynamic_cast( functionInstance->GetFunctionDebugInfo()); - if (function == NULL) - return B_BAD_VALUE; FunctionID* functionID = functionInstance->GetFunctionID(); - if (functionID == NULL) - return B_NO_MEMORY; - BReference functionIDReference(functionID, true); + BReference functionIDReference; + if (functionID != NULL) + functionIDReference.SetTo(functionID, true); + + DIESubprogram* entry = function != NULL + ? function->SubprogramEntry() : NULL; TRACE_CFI("DwarfImageDebugInfo::CreateFrame(): subprogram DIE: %p, " - "function: %s\n", function->SubprogramEntry(), + "function: %s\n", entry, functionID->FunctionName().String()); int32 registerCount = fArchitecture->CountRegisters(); @@ -543,7 +556,8 @@ DwarfImageDebugInfo::CreateFrame(Image* image, // create the target interfaces UnwindTargetInterface* inputInterface = new(std::nothrow) UnwindTargetInterface(registers, registerCount, - fromDwarfMap, toDwarfMap, cpuState, fArchitecture, fTeamMemory); + fromDwarfMap, toDwarfMap, cpuState, fArchitecture, + fDebuggerInterface); if (inputInterface == NULL) return B_NO_MEMORY; BReference inputInterfaceReference(inputInterface, @@ -552,7 +566,7 @@ DwarfImageDebugInfo::CreateFrame(Image* image, UnwindTargetInterface* outputInterface = new(std::nothrow) UnwindTargetInterface(registers, registerCount, fromDwarfMap, toDwarfMap, previousCpuState, fArchitecture, - fTeamMemory); + fDebuggerInterface); if (outputInterface == NULL) return B_NO_MEMORY; BReference outputInterfaceReference(outputInterface, @@ -562,8 +576,9 @@ DwarfImageDebugInfo::CreateFrame(Image* image, target_addr_t instructionPointer = cpuState->InstructionPointer() - fRelocationDelta; target_addr_t framePointer; - CompilationUnit* unit = function->GetCompilationUnit(); - error = fFile->UnwindCallFrame(unit, function->SubprogramEntry(), + CompilationUnit* unit = function != NULL ? function->GetCompilationUnit() + : NULL; + error = fFile->UnwindCallFrame(unit, fArchitecture->AddressSize(), entry, instructionPointer, inputInterface, outputInterface, framePointer); if (error != B_OK) { @@ -585,7 +600,8 @@ DwarfImageDebugInfo::CreateFrame(Image* image, ) // create the stack frame debug info - DIESubprogram* subprogramEntry = function->SubprogramEntry(); + DIESubprogram* subprogramEntry = function != NULL ? + function->SubprogramEntry() : NULL; DwarfStackFrameDebugInfo* stackFrameDebugInfo = new(std::nothrow) DwarfStackFrameDebugInfo(fArchitecture, fImageInfo.ImageID(), fFile, unit, subprogramEntry, fTypeLookup, @@ -616,35 +632,41 @@ DwarfImageDebugInfo::CreateFrame(Image* image, // Note, this is correct, since we actually retrieved the return // address. Our caller will fix the IP for us. - // create function parameter objects - for (DebugInfoEntryList::ConstIterator it = subprogramEntry->Parameters() - .GetIterator(); DebugInfoEntry* entry = it.Next();) { - if (entry->Tag() != DW_TAG_formal_parameter) - continue; + // The subprogram entry may not be available since this may be a case + // where .eh_frame was used to unwind the stack without other DWARF + // info being available. + if (subprogramEntry != NULL) { + // create function parameter objects + for (DebugInfoEntryList::ConstIterator it + = subprogramEntry->Parameters().GetIterator(); + DebugInfoEntry* entry = it.Next();) { + if (entry->Tag() != DW_TAG_formal_parameter) + continue; - BString parameterName; - DwarfUtils::GetDIEName(entry, parameterName); - if (parameterName.Length() == 0) - continue; + BString parameterName; + DwarfUtils::GetDIEName(entry, parameterName); + if (parameterName.Length() == 0) + continue; - DIEFormalParameter* parameterEntry - = dynamic_cast(entry); - Variable* parameter; - if (stackFrameDebugInfo->CreateParameter(functionID, parameterEntry, - parameter) != B_OK) { - continue; + DIEFormalParameter* parameterEntry + = dynamic_cast(entry); + Variable* parameter; + if (stackFrameDebugInfo->CreateParameter(functionID, + parameterEntry, parameter) != B_OK) { + continue; + } + BReference parameterReference(parameter, true); + + if (!frame->AddParameter(parameter)) + return B_NO_MEMORY; } - BReference parameterReference(parameter, true); - if (!frame->AddParameter(parameter)) - return B_NO_MEMORY; + // create objects for the local variables + _CreateLocalVariables(unit, frame, functionID, *stackFrameDebugInfo, + instructionPointer, functionInstance->Address() - fRelocationDelta, + subprogramEntry->Variables(), subprogramEntry->Blocks()); } - // create objects for the local variables - _CreateLocalVariables(unit, frame, functionID, *stackFrameDebugInfo, - instructionPointer, functionInstance->Address() - fRelocationDelta, - subprogramEntry->Variables(), subprogramEntry->Blocks()); - _frame = frameReference.Detach(); _previousCpuState = previousCpuStateReference.Detach(); diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h index 4fde30c3f3..67b1cf1e1f 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2010, Rene Gollent, rene@gollent.com. + * Copyright 2010-2012, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DWARF_IMAGE_DEBUG_INFO_H @@ -19,6 +19,7 @@ class Architecture; class CompilationUnit; +class DebuggerInterface; class DIEType; class DwarfStackFrameDebugInfo; class DwarfFile; @@ -30,14 +31,13 @@ class GlobalTypeCache; class GlobalTypeLookup; class LocatableFile; class SourceCode; -class TeamMemory; class DwarfImageDebugInfo : public SpecificImageDebugInfo { public: DwarfImageDebugInfo(const ImageInfo& imageInfo, + DebuggerInterface* interface, Architecture* architecture, - TeamMemory* teamMemory, FileManager* fileManager, GlobalTypeLookup* typeLookup, GlobalTypeCache* typeCache, @@ -106,8 +106,8 @@ private: private: BLocker fLock; ImageInfo fImageInfo; + DebuggerInterface* fDebuggerInterface; Architecture* fArchitecture; - TeamMemory* fTeamMemory; FileManager* fFileManager; GlobalTypeLookup* fTypeLookup; GlobalTypeCache* fTypeCache; diff --git a/src/apps/debugger/debug_info/DwarfTeamDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfTeamDebugInfo.cpp index d4746a0513..331f0a3b4b 100644 --- a/src/apps/debugger/debug_info/DwarfTeamDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DwarfTeamDebugInfo.cpp @@ -9,6 +9,7 @@ #include +#include "DebuggerInterface.h" #include "DwarfFile.h" #include "DwarfImageDebugInfo.h" #include "DwarfManager.h" @@ -17,22 +18,24 @@ DwarfTeamDebugInfo::DwarfTeamDebugInfo(Architecture* architecture, - TeamMemory* teamMemory, FileManager* fileManager, + DebuggerInterface* interface, FileManager* fileManager, GlobalTypeLookup* typeLookup, GlobalTypeCache* typeCache) : fArchitecture(architecture), - fTeamMemory(teamMemory), + fDebuggerInterface(interface), fFileManager(fileManager), fManager(NULL), fTypeLookup(typeLookup), fTypeCache(typeCache) { + fDebuggerInterface->AcquireReference(); fTypeCache->AcquireReference(); } DwarfTeamDebugInfo::~DwarfTeamDebugInfo() { + fDebuggerInterface->ReleaseReference(); fTypeCache->ReleaseReference(); delete fManager; } @@ -75,8 +78,8 @@ DwarfTeamDebugInfo::CreateImageDebugInfo(const ImageInfo& imageInfo, // create the image debug info DwarfImageDebugInfo* debugInfo = new(std::nothrow) DwarfImageDebugInfo( - imageInfo, fArchitecture, fTeamMemory, fFileManager, fTypeLookup, - fTypeCache, file); + imageInfo, fDebuggerInterface, fArchitecture, fFileManager, + fTypeLookup, fTypeCache, file); if (debugInfo == NULL) return B_NO_MEMORY; diff --git a/src/apps/debugger/debug_info/DwarfTeamDebugInfo.h b/src/apps/debugger/debug_info/DwarfTeamDebugInfo.h index db855a0cde..90c243417a 100644 --- a/src/apps/debugger/debug_info/DwarfTeamDebugInfo.h +++ b/src/apps/debugger/debug_info/DwarfTeamDebugInfo.h @@ -9,6 +9,7 @@ class Architecture; +class DebuggerInterface; class DwarfManager; class FileManager; class ImageInfo; @@ -20,7 +21,7 @@ class TeamMemory; class DwarfTeamDebugInfo : public SpecificTeamDebugInfo { public: DwarfTeamDebugInfo(Architecture* architecture, - TeamMemory* teamMemory, + DebuggerInterface* interface, FileManager* fileManager, GlobalTypeLookup* typeLookup, GlobalTypeCache* typeCache); @@ -34,7 +35,7 @@ public: private: Architecture* fArchitecture; - TeamMemory* fTeamMemory; + DebuggerInterface* fDebuggerInterface; FileManager* fFileManager; DwarfManager* fManager; GlobalTypeLookup* fTypeLookup; diff --git a/src/apps/debugger/debug_info/SpecificImageDebugInfo.cpp b/src/apps/debugger/debug_info/SpecificImageDebugInfo.cpp index ef402cdf40..b2e363abf2 100644 --- a/src/apps/debugger/debug_info/SpecificImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/SpecificImageDebugInfo.cpp @@ -5,7 +5,62 @@ #include "SpecificImageDebugInfo.h" +#include "BasicFunctionDebugInfo.h" +#include "DebuggerInterface.h" +#include "Demangler.h" +#include "ImageInfo.h" +#include "SymbolInfo.h" + SpecificImageDebugInfo::~SpecificImageDebugInfo() { } + + +/*static*/ status_t +SpecificImageDebugInfo::GetFunctionsFromSymbols( + BObjectList& functions, DebuggerInterface* interface, + const ImageInfo& imageInfo, SpecificImageDebugInfo* info) +{ + BObjectList symbols(20, true); + status_t error = interface->GetSymbolInfos(imageInfo.TeamID(), + imageInfo.ImageID(), symbols); + if (error != B_OK) + return error; + + // sort the symbols -- not necessary, but a courtesy to ImageDebugInfo which + // will peform better when inserting functions at the end of a list + symbols.SortItems(&_CompareSymbols); + + // create the function infos + int32 functionsAdded = 0; + for (int32 i = 0; SymbolInfo* symbol = symbols.ItemAt(i); i++) { + if (symbol->Type() != B_SYMBOL_TYPE_TEXT) + continue; + + FunctionDebugInfo* function = new(std::nothrow) BasicFunctionDebugInfo( + info, symbol->Address(), symbol->Size(), symbol->Name(), + Demangler::Demangle(symbol->Name())); + if (function == NULL || !functions.AddItem(function)) { + delete function; + int32 index = functions.CountItems() - 1; + for (; functionsAdded >= 0; functionsAdded--, index--) { + function = functions.RemoveItemAt(index); + delete function; + } + return B_NO_MEMORY; + } + + functionsAdded++; + } + + return B_OK; +} + +/*static*/ int +SpecificImageDebugInfo::_CompareSymbols(const SymbolInfo* a, + const SymbolInfo* b) +{ + return a->Address() < b->Address() + ? -1 : (a->Address() == b->Address() ? 0 : 1); +} diff --git a/src/apps/debugger/debug_info/SpecificImageDebugInfo.h b/src/apps/debugger/debug_info/SpecificImageDebugInfo.h index ee141340c2..0f9f74ad68 100644 --- a/src/apps/debugger/debug_info/SpecificImageDebugInfo.h +++ b/src/apps/debugger/debug_info/SpecificImageDebugInfo.h @@ -23,11 +23,13 @@ class FunctionDebugInfo; class FunctionInstance; class GlobalTypeCache; class Image; +class ImageInfo; class LocatableFile; class SourceLanguage; class SourceLocation; class StackFrame; class Statement; +class SymbolInfo; class Type; class TypeLookupConstraints; class ValueLocation; @@ -76,6 +78,17 @@ public: virtual status_t AddSourceCodeInfo(LocatableFile* file, FileSourceCode* sourceCode) = 0; + +protected: + static status_t GetFunctionsFromSymbols( + BObjectList& functions, + DebuggerInterface* interface, + const ImageInfo& imageInfo, + SpecificImageDebugInfo* info); + +private: + static int _CompareSymbols(const SymbolInfo* a, + const SymbolInfo* b); }; diff --git a/src/apps/debugger/dwarf/DwarfFile.cpp b/src/apps/debugger/dwarf/DwarfFile.cpp index 80650ce13e..1ca733e90a 100644 --- a/src/apps/debugger/dwarf/DwarfFile.cpp +++ b/src/apps/debugger/dwarf/DwarfFile.cpp @@ -386,10 +386,16 @@ DwarfFile::Load(const char* fileName) // .eh_frame doesn't appear to get copied into separate debug // info files properly, therefore always use it off the main // executable image - fEHFrameSection = fElfFile->GetSection(".eh_frame"); + if (fEHFrameSection == NULL) + fEHFrameSection = fElfFile->GetSection(".eh_frame"); fDebugLocationSection = debugInfoFile->GetSection(".debug_loc"); fDebugPublicTypesSection = debugInfoFile->GetSection(".debug_pubtypes"); + if (fDebugInfoSection == NULL) { + fFinished = true; + return B_OK; + } + // iterate through the debug info section DataReader dataReader(fDebugInfoSection->Data(), fDebugInfoSection->Size(), 4); @@ -570,7 +576,7 @@ DwarfFile::ResolveRangeList(CompilationUnit* unit, uint64 offset) const status_t -DwarfFile::UnwindCallFrame(CompilationUnit* unit, +DwarfFile::UnwindCallFrame(CompilationUnit* unit, uint8 addressSize, DIESubprogram* subprogramEntry, target_addr_t location, const DwarfTargetInterface* inputInterface, DwarfTargetInterface* outputInterface, target_addr_t& _framePointer) @@ -579,15 +585,15 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit, // first try to find the FDE in .debug_frame if (fDebugFrameSection != NULL) { - result = _UnwindCallFrame(false, unit, subprogramEntry, location, - inputInterface, outputInterface, _framePointer); + result = _UnwindCallFrame(false, unit, addressSize, subprogramEntry, + location, inputInterface, outputInterface, _framePointer); } // if .debug_frame isn't present, or if the FDE wasn't found there, // try .eh_frame if (result == B_ENTRY_NOT_FOUND && fEHFrameSection != NULL) { - result = _UnwindCallFrame(true, unit, subprogramEntry, location, - inputInterface, outputInterface, _framePointer); + result = _UnwindCallFrame(true, unit, addressSize, subprogramEntry, + location, inputInterface, outputInterface, _framePointer); } return result; @@ -1329,7 +1335,7 @@ DwarfFile::_ParseLineInfo(CompilationUnit* unit) status_t DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit, - DIESubprogram* subprogramEntry, target_addr_t location, + uint8 addressSize, DIESubprogram* subprogramEntry, target_addr_t location, const DwarfTargetInterface* inputInterface, DwarfTargetInterface* outputInterface, target_addr_t& _framePointer) { @@ -1350,7 +1356,8 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit, TRACE_CFI("DwarfFile::_UnwindCallFrame(%#" B_PRIx64 ")\n", location); DataReader dataReader((uint8*)currentFrameSection->Data(), - currentFrameSection->Size(), unit->AddressSize()); + currentFrameSection->Size(), unit != NULL + ? unit->AddressSize() : addressSize); while (dataReader.BytesRemaining() > 0) { // length @@ -1448,7 +1455,7 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit, // process the CIE CIEAugmentation cieAugmentation; error = _ParseCIE(currentFrameSection, usingEHFrameSection, - unit, context, cieID, cieAugmentation); + unit, addressSize, context, cieID, cieAugmentation); if (error != B_OK) return error; @@ -1618,20 +1625,22 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit, status_t DwarfFile::_ParseCIE(ElfSection* debugFrameSection, bool usingEHFrameSection, - CompilationUnit* unit, CfaContext& context, off_t cieOffset, - CIEAugmentation& cieAugmentation) + CompilationUnit* unit, uint8 addressSize, CfaContext& context, + off_t cieOffset, CIEAugmentation& cieAugmentation) { if (cieOffset < 0 || cieOffset >= debugFrameSection->Size()) return B_BAD_DATA; DataReader dataReader((uint8*)debugFrameSection->Data() + cieOffset, - debugFrameSection->Size() - cieOffset, unit->AddressSize()); + debugFrameSection->Size() - cieOffset, unit != NULL + ? unit->AddressSize() : addressSize); // length bool dwarf64; uint64 length = dataReader.ReadInitialLength(dwarf64); if (length > (uint64)dataReader.BytesRemaining()) return B_BAD_DATA; + off_t lengthOffset = dataReader.Offset(); // CIE ID/CIE pointer @@ -2328,7 +2337,12 @@ DwarfFile::_LocateDebugInfo() if (fDebugInfoSection == NULL || fDebugAbbrevSection == NULL) { WARNING("DwarfManager::File::Load(\"%s\"): no " ".debug_info or .debug_abbrev.\n", fName); - return B_ERROR; + + // if we at least have an EH frame, use that for stack unwinding + // if nothing else. + fEHFrameSection = fElfFile->GetSection(".eh_frame"); + if (fEHFrameSection == NULL) + return B_ERROR; } return B_OK; diff --git a/src/apps/debugger/dwarf/DwarfFile.h b/src/apps/debugger/dwarf/DwarfFile.h index ba08a08ddd..429e98dde4 100644 --- a/src/apps/debugger/dwarf/DwarfFile.h +++ b/src/apps/debugger/dwarf/DwarfFile.h @@ -48,6 +48,7 @@ public: uint64 offset) const; status_t UnwindCallFrame(CompilationUnit* unit, + uint8 addressSize, DIESubprogram* subprogramEntry, target_addr_t location, const DwarfTargetInterface* inputInterface, @@ -115,6 +116,7 @@ private: status_t _UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit, + uint8 addressSize, DIESubprogram* subprogramEntry, target_addr_t location, const DwarfTargetInterface* inputInterface, @@ -124,6 +126,7 @@ private: status_t _ParseCIE(ElfSection* debugFrameSection, bool usingEHFrameSection, CompilationUnit* unit, + uint8 addressSize, CfaContext& context, off_t cieOffset, CIEAugmentation& cieAugmentation); status_t _ParseFrameInfoInstructions(