- 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:
@@ -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 ] ;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user