Beginnings of the architecture abstraction.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31104 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1f2a566cd6
commit
a81bb42a93
|
@ -6,6 +6,8 @@ C++FLAGS += -Werror ;
|
|||
UsePrivateHeaders debug interface kernel shared ;
|
||||
UsePrivateSystemHeaders ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) arch ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) arch x86 ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) debugger_interface ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) gui team_window ] ;
|
||||
|
||||
|
@ -17,7 +19,6 @@ SubDirHdrs [ FDirName $(debugAnalyzerSources) gui ] ;
|
|||
SubDirHdrs [ FDirName $(debugAnalyzerSources) util ] ;
|
||||
|
||||
Application Debugger :
|
||||
CpuState.cpp
|
||||
Debugger.cpp
|
||||
# ElfFile.cpp
|
||||
Image.cpp
|
||||
|
@ -28,17 +29,27 @@ Application Debugger :
|
|||
Thread.cpp
|
||||
ThreadInfo.cpp
|
||||
|
||||
# DebugAnalyzer:util
|
||||
Variant.cpp
|
||||
# arch
|
||||
Architecture.cpp
|
||||
CpuState.cpp
|
||||
StackFrame.cpp
|
||||
StackTrace.cpp
|
||||
|
||||
# arch/x86
|
||||
ArchitectureX86.cpp
|
||||
CpuStateX86.cpp
|
||||
|
||||
# debugger_interface
|
||||
DebugEvent.cpp
|
||||
DebuggerInterface.cpp
|
||||
|
||||
# gui/team_window
|
||||
ImageListView.cpp
|
||||
TeamWindow.cpp
|
||||
ThreadListView.cpp
|
||||
|
||||
# debugger_interface
|
||||
DebugEvent.cpp
|
||||
DebuggerInterface.cpp
|
||||
# DebugAnalyzer:util
|
||||
Variant.cpp
|
||||
|
||||
# DWARF
|
||||
# attribute_classes.cpp
|
||||
|
|
|
@ -337,4 +337,5 @@ TeamDebugger::_UpdateThreadState(::Thread* thread)
|
|||
newState = THREAD_STATE_RUNNING;
|
||||
|
||||
thread->SetState(newState);
|
||||
thread->SetCpuState(state);
|
||||
}
|
||||
|
|
|
@ -5,18 +5,27 @@
|
|||
|
||||
#include "Thread.h"
|
||||
|
||||
#include "CpuState.h"
|
||||
#include "StackTrace.h"
|
||||
|
||||
|
||||
Thread::Thread(Team* team, thread_id threadID)
|
||||
:
|
||||
fTeam(team),
|
||||
fID(threadID),
|
||||
fState(THREAD_STATE_UNKNOWN)
|
||||
fState(THREAD_STATE_UNKNOWN),
|
||||
fCpuState(NULL),
|
||||
fStackTrace(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
if (fCpuState != NULL)
|
||||
fCpuState->RemoveReference();
|
||||
if (fStackTrace != NULL)
|
||||
fStackTrace->RemoveReference();
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,5 +46,45 @@ Thread::SetName(const BString& name)
|
|||
void
|
||||
Thread::SetState(uint32 state)
|
||||
{
|
||||
if (state == fState)
|
||||
return;
|
||||
|
||||
fState = state;
|
||||
|
||||
// unset CPU state and stack trace, if the thread isn't stopped
|
||||
if (fState != THREAD_STATE_STOPPED) {
|
||||
SetCpuState(NULL);
|
||||
SetStackTrace(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Thread::SetCpuState(CpuState* state)
|
||||
{
|
||||
if (state == fCpuState)
|
||||
return;
|
||||
|
||||
if (fCpuState != NULL)
|
||||
fCpuState->RemoveReference();
|
||||
|
||||
fCpuState = state;
|
||||
|
||||
if (fCpuState != NULL)
|
||||
fCpuState->AddReference();
|
||||
}
|
||||
|
||||
void
|
||||
Thread::SetStackTrace(StackTrace* trace)
|
||||
{
|
||||
if (trace == fStackTrace)
|
||||
return;
|
||||
|
||||
if (fStackTrace != NULL)
|
||||
fStackTrace->RemoveReference();
|
||||
|
||||
fStackTrace = trace;
|
||||
|
||||
if (fStackTrace != NULL)
|
||||
fStackTrace->AddReference();
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <util/DoublyLinkedList.h>
|
||||
|
||||
|
||||
class CpuState;
|
||||
class StackTrace;
|
||||
class Team;
|
||||
|
||||
|
||||
|
@ -38,11 +40,19 @@ public:
|
|||
uint32 State() const { return fState; }
|
||||
void SetState(uint32 state);
|
||||
|
||||
CpuState* GetCpuState() const { return fCpuState; }
|
||||
void SetCpuState(CpuState* state);
|
||||
|
||||
StackTrace* GetStackTrace() const { return fStackTrace; }
|
||||
void SetStackTrace(StackTrace* trace);
|
||||
|
||||
private:
|
||||
Team* fTeam;
|
||||
thread_id fID;
|
||||
BString fName;
|
||||
uint32 fState;
|
||||
CpuState* fCpuState;
|
||||
StackTrace* fStackTrace;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "Architecture.h"
|
||||
|
||||
|
||||
Architecture::Architecture(DebuggerInterface* debuggerInterface)
|
||||
:
|
||||
fDebuggerInterface(debuggerInterface)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Architecture::~Architecture()
|
||||
{
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ARCHITECTURE_H
|
||||
#define ARCHITECTURE_H
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <Referenceable.h>
|
||||
|
||||
|
||||
class CpuState;
|
||||
class DebuggerInterface;
|
||||
|
||||
|
||||
class Architecture : public Referenceable {
|
||||
public:
|
||||
Architecture(
|
||||
DebuggerInterface* debuggerInterface);
|
||||
virtual ~Architecture();
|
||||
|
||||
virtual status_t CreateCpuState(const void* cpuStateData,
|
||||
size_t size, CpuState*& _state) = 0;
|
||||
|
||||
protected:
|
||||
DebuggerInterface* fDebuggerInterface;
|
||||
};
|
||||
|
||||
|
||||
#endif // ARCHITECTURE_H
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ARCHITECTURE_TYPES_H
|
||||
#define ARCHITECTURE_TYPES_H
|
||||
|
||||
|
||||
typedef uint64 target_addr_t;
|
||||
|
||||
|
||||
|
||||
#endif // ARCHITECTURE_TYPES_H
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "StackFrame.h"
|
||||
|
||||
|
||||
StackFrame::~StackFrame()
|
||||
{
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef STACK_FRAME_H
|
||||
#define STACK_FRAME_H
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <Referenceable.h>
|
||||
#include <util/DoublyLinkedList.h>
|
||||
|
||||
#include "ArchitectureTypes.h"
|
||||
|
||||
|
||||
class CpuState;
|
||||
|
||||
|
||||
class StackFrame : public Referenceable,
|
||||
public DoublyLinkedListLinkImpl<StackFrame> {
|
||||
public:
|
||||
virtual ~StackFrame();
|
||||
|
||||
virtual CpuState* GetCpuState() const = 0;
|
||||
|
||||
virtual target_addr_t FrameAddress() const = 0;
|
||||
virtual target_addr_t ReturnAddress() const = 0;
|
||||
virtual target_addr_t PreviousFrameAddress() const = 0;
|
||||
};
|
||||
|
||||
|
||||
typedef DoublyLinkedList<StackFrame> StackFrameList;
|
||||
|
||||
|
||||
#endif // STACK_FRAME_H
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "StackTrace.h"
|
||||
|
||||
|
||||
StackTrace::StackTrace()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StackTrace::~StackTrace()
|
||||
{
|
||||
while (StackFrame* frame = fStackFrames.RemoveHead())
|
||||
frame->RemoveReference();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StackTrace::AddFrame(StackFrame* frame)
|
||||
{
|
||||
fStackFrames.Add(frame);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef STACK_TRACE_H
|
||||
#define STACK_TRACE_H
|
||||
|
||||
#include "StackFrame.h"
|
||||
|
||||
|
||||
class StackTrace : public Referenceable {
|
||||
public:
|
||||
StackTrace();
|
||||
virtual ~StackTrace();
|
||||
|
||||
void AddFrame(StackFrame* frame);
|
||||
// takes over reference
|
||||
|
||||
const StackFrameList& Frames() const { return fStackFrames; }
|
||||
|
||||
StackFrame* TopFrame() const
|
||||
{ return fStackFrames.Head(); }
|
||||
StackFrame* BottomFrame() const
|
||||
{ return fStackFrames.Tail(); }
|
||||
|
||||
private:
|
||||
StackFrameList fStackFrames;
|
||||
};
|
||||
|
||||
|
||||
#endif // STACK_TRACE_H
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "ArchitectureX86.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "CpuStateX86.h"
|
||||
|
||||
|
||||
ArchitectureX86::ArchitectureX86(DebuggerInterface* debuggerInterface)
|
||||
:
|
||||
Architecture(debuggerInterface)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ArchitectureX86::~ArchitectureX86()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ArchitectureX86::CreateCpuState(const void* cpuStateData, size_t size,
|
||||
CpuState*& _state)
|
||||
{
|
||||
if (size != sizeof(debug_cpu_state_x86))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
CpuStateX86* state = new(std::nothrow) CpuStateX86(
|
||||
*(const debug_cpu_state_x86*)cpuStateData);
|
||||
if (state == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
_state = state;
|
||||
return B_OK;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ARCHITECTURE_X86_H
|
||||
#define ARCHITECTURE_X86_H
|
||||
|
||||
#include "Architecture.h"
|
||||
|
||||
|
||||
class ArchitectureX86 : public Architecture {
|
||||
public:
|
||||
ArchitectureX86(
|
||||
DebuggerInterface* debuggerInterface);
|
||||
virtual ~ArchitectureX86();
|
||||
|
||||
virtual status_t CreateCpuState(const void* cpuStateData,
|
||||
size_t size, CpuState*& _state);
|
||||
};
|
||||
|
||||
|
||||
#endif // ARCHITECTURE_X86_H
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "CpuStateX86.h"
|
||||
|
||||
|
||||
CpuStateX86::CpuStateX86(const debug_cpu_state_x86& state)
|
||||
:
|
||||
fState(state)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CpuStateX86::~CpuStateX86()
|
||||
{
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef CPU_STATE_X86_H
|
||||
#define CPU_STATE_X86_H
|
||||
|
||||
#include <debugger.h>
|
||||
|
||||
#include "CpuState.h"
|
||||
|
||||
|
||||
typedef debug_cpu_state debug_cpu_state_x86;
|
||||
// TODO: Should be defined by <debugger.h>!
|
||||
|
||||
|
||||
class CpuStateX86 : public CpuState {
|
||||
public:
|
||||
CpuStateX86(const debug_cpu_state_x86& state);
|
||||
virtual ~CpuStateX86();
|
||||
|
||||
const debug_cpu_state_x86 State() const { return fState; }
|
||||
|
||||
private:
|
||||
debug_cpu_state_x86 fState;
|
||||
};
|
||||
|
||||
|
||||
#endif // CPU_STATE_X86_H
|
|
@ -7,12 +7,10 @@
|
|||
|
||||
#include <debugger.h>
|
||||
|
||||
#include "ArchitectureTypes.h"
|
||||
#include "ImageInfo.h"
|
||||
|
||||
|
||||
typedef uint64 target_addr_t;
|
||||
// TODO: Define elsewhere!
|
||||
|
||||
class CpuState;
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "debug_utils.h"
|
||||
|
||||
#include "ArchitectureX86.h"
|
||||
#include "CpuState.h"
|
||||
#include "DebugEvent.h"
|
||||
#include "ImageInfo.h"
|
||||
|
@ -21,7 +22,8 @@ DebuggerInterface::DebuggerInterface(team_id teamID)
|
|||
:
|
||||
fTeamID(teamID),
|
||||
fDebuggerPort(-1),
|
||||
fNubPort(-1)
|
||||
fNubPort(-1),
|
||||
fArchitecture(NULL)
|
||||
{
|
||||
fDebugContext.reply_port = -1;
|
||||
}
|
||||
|
@ -29,6 +31,8 @@ DebuggerInterface::DebuggerInterface(team_id teamID)
|
|||
|
||||
DebuggerInterface::~DebuggerInterface()
|
||||
{
|
||||
fArchitecture->RemoveReference();
|
||||
|
||||
destroy_debug_context(&fDebugContext);
|
||||
|
||||
Close();
|
||||
|
@ -38,6 +42,16 @@ DebuggerInterface::~DebuggerInterface()
|
|||
status_t
|
||||
DebuggerInterface::Init()
|
||||
{
|
||||
// create the architecture
|
||||
#ifdef ARCH_x86
|
||||
fArchitecture = new(std::nothrow) ArchitectureX86(this);
|
||||
#else
|
||||
return B_UNSUPPORTED;
|
||||
#endif
|
||||
|
||||
if (fArchitecture == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
// create debugger port
|
||||
char buffer[128];
|
||||
snprintf(buffer, sizeof(buffer), "team %ld debugger", fTeamID);
|
||||
|
@ -211,20 +225,47 @@ DebuggerInterface::_CreateDebugEvent(int32 messageCode,
|
|||
(target_addr_t)message.debugger_call.message);
|
||||
break;
|
||||
case B_DEBUGGER_MESSAGE_BREAKPOINT_HIT:
|
||||
{
|
||||
CpuState* state = NULL;
|
||||
status_t error = fArchitecture->CreateCpuState(
|
||||
&message.breakpoint_hit.cpu_state,
|
||||
sizeof(debug_cpu_state), state);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
event = new(std::nothrow) BreakpointHitEvent(message.origin.team,
|
||||
message.origin.thread, NULL);
|
||||
// TODO: CpuState!
|
||||
message.origin.thread, state);
|
||||
state->RemoveReference();
|
||||
break;
|
||||
}
|
||||
case B_DEBUGGER_MESSAGE_WATCHPOINT_HIT:
|
||||
{
|
||||
CpuState* state = NULL;
|
||||
status_t error = fArchitecture->CreateCpuState(
|
||||
&message.watchpoint_hit.cpu_state,
|
||||
sizeof(debug_cpu_state), state);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
event = new(std::nothrow) WatchpointHitEvent(message.origin.team,
|
||||
message.origin.thread, NULL);
|
||||
// TODO: CpuState!
|
||||
message.origin.thread, state);
|
||||
state->RemoveReference();
|
||||
break;
|
||||
}
|
||||
case B_DEBUGGER_MESSAGE_SINGLE_STEP:
|
||||
{
|
||||
CpuState* state = NULL;
|
||||
status_t error = fArchitecture->CreateCpuState(
|
||||
&message.single_step.cpu_state,
|
||||
sizeof(debug_cpu_state), state);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
event = new(std::nothrow) SingleStepEvent(message.origin.team,
|
||||
message.origin.thread, NULL);
|
||||
// TODO: CpuState!
|
||||
message.origin.thread, state);
|
||||
state->RemoveReference();
|
||||
break;
|
||||
}
|
||||
case B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED:
|
||||
event = new(std::nothrow) ExceptionOccurredEvent(
|
||||
message.origin.team, message.origin.thread,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <ObjectList.h>
|
||||
|
||||
|
||||
class Architecture;
|
||||
class CpuState;
|
||||
class DebugEvent;
|
||||
class ImageInfo;
|
||||
|
@ -25,6 +26,9 @@ public:
|
|||
status_t Init();
|
||||
void Close();
|
||||
|
||||
Architecture* GetArchitecture() const
|
||||
{ return fArchitecture; }
|
||||
|
||||
virtual status_t GetNextDebugEvent(DebugEvent*& _event);
|
||||
|
||||
virtual status_t SetTeamDebuggingFlags(uint32 flags);
|
||||
|
@ -50,6 +54,8 @@ private:
|
|||
port_id fDebuggerPort;
|
||||
port_id fNubPort;
|
||||
debug_context fDebugContext;
|
||||
// TODO: Use a debug context pool!
|
||||
Architecture* fArchitecture;
|
||||
};
|
||||
|
||||
#endif // DEBUGGER_INTERFACE_H
|
||||
|
|
Loading…
Reference in New Issue