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:
Ingo Weinhold 2009-06-18 19:57:46 +00:00
parent 1f2a566cd6
commit a81bb42a93
20 changed files with 405 additions and 17 deletions

View File

@ -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

View File

@ -337,4 +337,5 @@ TeamDebugger::_UpdateThreadState(::Thread* thread)
newState = THREAD_STATE_RUNNING;
thread->SetState(newState);
thread->SetCpuState(state);
}

View File

@ -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();
}

View File

@ -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;
};

View File

@ -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()
{
}

View File

@ -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

View File

@ -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

View File

@ -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()
{
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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()
{
}

View File

@ -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

View File

@ -7,12 +7,10 @@
#include <debugger.h>
#include "ArchitectureTypes.h"
#include "ImageInfo.h"
typedef uint64 target_addr_t;
// TODO: Define elsewhere!
class CpuState;

View File

@ -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,

View File

@ -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