diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index fb8e1a8d82..06c6240dd4 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -36,6 +36,7 @@ local debugAnalyzerSources = [ FDirName $(HAIKU_TOP) src apps debuganalyzer ] ; SubDirHdrs [ FDirName $(SUBDIR) demangler ] ; +SubDirHdrs [ FDirName $(SUBDIR) dwarf ] ; SubDirHdrs [ FDirName $(HAIKU_TOP) src bin debug ] ; SubDirHdrs [ FDirName $(debugAnalyzerSources) gui ] ; diff --git a/src/apps/debugger/arch/Architecture.cpp b/src/apps/debugger/arch/Architecture.cpp index 414347d098..5df0a7da57 100644 --- a/src/apps/debugger/arch/Architecture.cpp +++ b/src/apps/debugger/arch/Architecture.cpp @@ -10,11 +10,14 @@ #include #include +#include "CfaContext.h" #include "CpuState.h" #include "FunctionInstance.h" #include "Image.h" #include "ImageDebugInfo.h" #include "ImageDebugInfoProvider.h" +#include "Register.h" +#include "RegisterMap.h" #include "SpecificImageDebugInfo.h" #include "StackTrace.h" #include "Team.h" @@ -42,6 +45,52 @@ Architecture::Init() } +status_t +Architecture::InitRegisterRules(CfaContext& context) const +{ + // Init the initial register rules. The DWARF 3 specs on the + // matter: "The default rule for all columns before + // interpretation of the initial instructions is the undefined + // rule. However, an ABI authoring body or a compilation system + // authoring body may specify an alternate default value for any + // or all columns." + // GCC's assumes the "same value" rule for all callee preserved + // registers. We set them respectively. + // the stack pointer is initialized to + // CFA offset 0 by default. + const Register* registers = Registers(); + RegisterMap* toDwarf = NULL; + status_t result = GetDwarfRegisterMaps(&toDwarf, NULL); + if (result != B_OK) + return result; + + BReference toDwarfMapReference(toDwarf, true); + for (int32 i = 0; i < CountRegisters(); i++) { + int32 dwarfReg = toDwarf->MapRegisterIndex(i); + if (dwarfReg < 0 || dwarfReg > CountRegisters() - 1) + continue; + + switch (registers[i].Type()) { + case REGISTER_TYPE_STACK_POINTER: + { + // TODO: determine why this fails to retrieve the + // correct values. +// context.RegisterRule(dwarfReg)->SetToLocationOffset(0); + break; + } + default: + { + if (registers[i].IsCalleePreserved()) + context.RegisterRule(dwarfReg)->SetToSameValue(); + break; + } + } + } + + return result; +} + + status_t Architecture::CreateStackTrace(Team* team, ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState, diff --git a/src/apps/debugger/arch/Architecture.h b/src/apps/debugger/arch/Architecture.h index 6102a5a7f8..59f3e3dc25 100644 --- a/src/apps/debugger/arch/Architecture.h +++ b/src/apps/debugger/arch/Architecture.h @@ -15,6 +15,7 @@ #include "Types.h" +class CfaContext; class CpuState; class DisassembledCode; class FunctionDebugInfo; @@ -45,6 +46,7 @@ public: virtual int32 CountRegisters() const = 0; virtual const Register* Registers() const = 0; + virtual status_t InitRegisterRules(CfaContext& context) const; virtual status_t GetDwarfRegisterMaps(RegisterMap** _toDwarf, RegisterMap** _fromDwarf) const = 0; diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.cpp b/src/apps/debugger/arch/x86/ArchitectureX86.cpp index 3b8c2ccb0b..d72a3cc410 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.cpp +++ b/src/apps/debugger/arch/x86/ArchitectureX86.cpp @@ -12,6 +12,7 @@ #include +#include "CfaContext.h" #include "CpuStateX86.h" #include "DisassembledCode.h" #include "FunctionDebugInfo.h" @@ -193,6 +194,20 @@ ArchitectureX86::Registers() const } +status_t +ArchitectureX86::InitRegisterRules(CfaContext& context) const +{ + status_t error = Architecture::InitRegisterRules(context); + if (error != B_OK) + return error; + + // set up rule for EIP register + context.RegisterRule(fToDwarfRegisterMap->MapRegisterIndex( + X86_REGISTER_EIP))->SetToLocationOffset(-4); + + return B_OK; +} + status_t ArchitectureX86::GetDwarfRegisterMaps(RegisterMap** _toDwarf, RegisterMap** _fromDwarf) const diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.h b/src/apps/debugger/arch/x86/ArchitectureX86.h index ba20101a35..0f5bba0975 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.h +++ b/src/apps/debugger/arch/x86/ArchitectureX86.h @@ -23,6 +23,7 @@ public: virtual int32 CountRegisters() const; virtual const Register* Registers() const; + virtual status_t InitRegisterRules(CfaContext& context) const; virtual status_t GetDwarfRegisterMaps(RegisterMap** _toDwarf, RegisterMap** _fromDwarf) const; diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp index 1301d744b7..097de4f6c4 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp @@ -99,6 +99,11 @@ struct DwarfImageDebugInfo::BasicTargetInterface : DwarfTargetInterface { return reg != NULL && reg->IsCalleePreserved(); } + virtual status_t InitRegisterRules(CfaContext& context) const + { + return fArchitecture->InitRegisterRules(context); + } + virtual bool ReadMemory(target_addr_t address, void* buffer, size_t size) const { diff --git a/src/apps/debugger/dwarf/DwarfFile.cpp b/src/apps/debugger/dwarf/DwarfFile.cpp index d006f85f14..439f4b0e55 100644 --- a/src/apps/debugger/dwarf/DwarfFile.cpp +++ b/src/apps/debugger/dwarf/DwarfFile.cpp @@ -645,18 +645,9 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit, if (error != B_OK) return error; - // Init the initial register rules. The DWARF 3 specs on the - // matter: "The default rule for all columns before - // interpretation of the initial instructions is the undefined - // rule. However, an ABI authoring body or a compilation system - // authoring body may specify an alternate default value for any - // or all columns." - // GCC's assumes the "same value" rule for all callee preserved - // registers. We set them respectively. - for (uint32 i = 0; i < registerCount; i++) { - if (outputInterface->IsCalleePreservedRegister(i)) - context.RegisterRule(i)->SetToSameValue(); - } + error = outputInterface->InitRegisterRules(context); + if (error != B_OK) + return error; // process the CIE CIEAugmentation cieAugmentation; @@ -1613,7 +1604,7 @@ DwarfFile::_ParseCIE(CompilationUnit* unit, CfaContext& context, if (remaining < 0) return B_BAD_DATA; - return _ParseFrameInfoInstructions(unit, context, + return _ParseFrameInfoInstructions(unit, context, cieOffset + dataReader.Offset(), remaining); } diff --git a/src/apps/debugger/dwarf/DwarfTargetInterface.h b/src/apps/debugger/dwarf/DwarfTargetInterface.h index a999a71cad..ac6b873069 100644 --- a/src/apps/debugger/dwarf/DwarfTargetInterface.h +++ b/src/apps/debugger/dwarf/DwarfTargetInterface.h @@ -12,6 +12,7 @@ #include "Types.h" +class CfaContext; class Register; @@ -28,6 +29,8 @@ public: const BVariant& value) = 0; virtual bool IsCalleePreservedRegister(uint32 index) const = 0; + virtual status_t InitRegisterRules(CfaContext& context) const + = 0; virtual bool ReadMemory(target_addr_t address, void* buffer, size_t size) const = 0;