From 87d85ea382bac0d2c83b5944ef807d4ec31fc111 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sat, 11 Dec 2010 19:05:54 +0000 Subject: [PATCH] - Refactor setting up the default register rules to happen in the Architecture class in order to allow us to set up architecture specific default rules for registers that aren't explicitly set by the CFI program. - Set up default rule for EIP on x86. - Theoretically set up a default rule for the stack pointer. Disabled for the time being though until I determine why that rule's not yielding the expected values for ESP in anything other than the top frame, though the other location offset rules work as expected. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39816 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/debugger/Jamfile | 1 + src/apps/debugger/arch/Architecture.cpp | 49 +++++++++++++++++++ src/apps/debugger/arch/Architecture.h | 2 + .../debugger/arch/x86/ArchitectureX86.cpp | 15 ++++++ src/apps/debugger/arch/x86/ArchitectureX86.h | 1 + .../debug_info/DwarfImageDebugInfo.cpp | 5 ++ src/apps/debugger/dwarf/DwarfFile.cpp | 17 ++----- .../debugger/dwarf/DwarfTargetInterface.h | 3 ++ 8 files changed, 80 insertions(+), 13 deletions(-) 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;