- 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
This commit is contained in:
Rene Gollent
2010-12-11 19:05:54 +00:00
parent 452c6bfade
commit 87d85ea382
8 changed files with 80 additions and 13 deletions
+1
View File
@@ -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 ] ;
+49
View File
@@ -10,11 +10,14 @@
#include <AutoDeleter.h>
#include <AutoLocker.h>
#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<RegisterMap> 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,
+2
View File
@@ -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;
@@ -12,6 +12,7 @@
#include <AutoDeleter.h>
#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
@@ -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;
@@ -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
{
+4 -13
View File
@@ -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);
}
@@ -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;