From a81bb42a9321a3b8ccf7f92623237826ff8767f4 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 18 Jun 2009 19:57:46 +0000 Subject: [PATCH] Beginnings of the architecture abstraction. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31104 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/debugger/Jamfile | 23 ++++++-- src/apps/debugger/TeamDebugger.cpp | 1 + src/apps/debugger/Thread.cpp | 51 ++++++++++++++++- src/apps/debugger/Thread.h | 10 ++++ src/apps/debugger/arch/Architecture.cpp | 18 ++++++ src/apps/debugger/arch/Architecture.h | 31 +++++++++++ src/apps/debugger/arch/ArchitectureTypes.h | 13 +++++ src/apps/debugger/{ => arch}/CpuState.cpp | 0 src/apps/debugger/{ => arch}/CpuState.h | 0 src/apps/debugger/arch/StackFrame.cpp | 11 ++++ src/apps/debugger/arch/StackFrame.h | 35 ++++++++++++ src/apps/debugger/arch/StackTrace.cpp | 25 +++++++++ src/apps/debugger/arch/StackTrace.h | 31 +++++++++++ .../debugger/arch/x86/ArchitectureX86.cpp | 39 +++++++++++++ src/apps/debugger/arch/x86/ArchitectureX86.h | 22 ++++++++ src/apps/debugger/arch/x86/CpuStateX86.cpp | 18 ++++++ src/apps/debugger/arch/x86/CpuStateX86.h | 29 ++++++++++ .../debugger/debugger_interface/DebugEvent.h | 4 +- .../debugger_interface/DebuggerInterface.cpp | 55 ++++++++++++++++--- .../debugger_interface/DebuggerInterface.h | 6 ++ 20 files changed, 405 insertions(+), 17 deletions(-) create mode 100644 src/apps/debugger/arch/Architecture.cpp create mode 100644 src/apps/debugger/arch/Architecture.h create mode 100644 src/apps/debugger/arch/ArchitectureTypes.h rename src/apps/debugger/{ => arch}/CpuState.cpp (100%) rename src/apps/debugger/{ => arch}/CpuState.h (100%) create mode 100644 src/apps/debugger/arch/StackFrame.cpp create mode 100644 src/apps/debugger/arch/StackFrame.h create mode 100644 src/apps/debugger/arch/StackTrace.cpp create mode 100644 src/apps/debugger/arch/StackTrace.h create mode 100644 src/apps/debugger/arch/x86/ArchitectureX86.cpp create mode 100644 src/apps/debugger/arch/x86/ArchitectureX86.h create mode 100644 src/apps/debugger/arch/x86/CpuStateX86.cpp create mode 100644 src/apps/debugger/arch/x86/CpuStateX86.h diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 3d73271148..d0b633127c 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -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 diff --git a/src/apps/debugger/TeamDebugger.cpp b/src/apps/debugger/TeamDebugger.cpp index a20b3932c1..831c41cc94 100644 --- a/src/apps/debugger/TeamDebugger.cpp +++ b/src/apps/debugger/TeamDebugger.cpp @@ -337,4 +337,5 @@ TeamDebugger::_UpdateThreadState(::Thread* thread) newState = THREAD_STATE_RUNNING; thread->SetState(newState); + thread->SetCpuState(state); } diff --git a/src/apps/debugger/Thread.cpp b/src/apps/debugger/Thread.cpp index b3c83a8140..64c7072bb3 100644 --- a/src/apps/debugger/Thread.cpp +++ b/src/apps/debugger/Thread.cpp @@ -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(); } diff --git a/src/apps/debugger/Thread.h b/src/apps/debugger/Thread.h index b0d4f9ab6a..7b5f8da105 100644 --- a/src/apps/debugger/Thread.h +++ b/src/apps/debugger/Thread.h @@ -12,6 +12,8 @@ #include +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; }; diff --git a/src/apps/debugger/arch/Architecture.cpp b/src/apps/debugger/arch/Architecture.cpp new file mode 100644 index 0000000000..c2ba10eb51 --- /dev/null +++ b/src/apps/debugger/arch/Architecture.cpp @@ -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() +{ +} diff --git a/src/apps/debugger/arch/Architecture.h b/src/apps/debugger/arch/Architecture.h new file mode 100644 index 0000000000..dec7a6b943 --- /dev/null +++ b/src/apps/debugger/arch/Architecture.h @@ -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 + +#include + + +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 diff --git a/src/apps/debugger/arch/ArchitectureTypes.h b/src/apps/debugger/arch/ArchitectureTypes.h new file mode 100644 index 0000000000..7e1db1d7c2 --- /dev/null +++ b/src/apps/debugger/arch/ArchitectureTypes.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 diff --git a/src/apps/debugger/CpuState.cpp b/src/apps/debugger/arch/CpuState.cpp similarity index 100% rename from src/apps/debugger/CpuState.cpp rename to src/apps/debugger/arch/CpuState.cpp diff --git a/src/apps/debugger/CpuState.h b/src/apps/debugger/arch/CpuState.h similarity index 100% rename from src/apps/debugger/CpuState.h rename to src/apps/debugger/arch/CpuState.h diff --git a/src/apps/debugger/arch/StackFrame.cpp b/src/apps/debugger/arch/StackFrame.cpp new file mode 100644 index 0000000000..f84ec2a37d --- /dev/null +++ b/src/apps/debugger/arch/StackFrame.cpp @@ -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() +{ +} diff --git a/src/apps/debugger/arch/StackFrame.h b/src/apps/debugger/arch/StackFrame.h new file mode 100644 index 0000000000..f600dc4a2a --- /dev/null +++ b/src/apps/debugger/arch/StackFrame.h @@ -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 + +#include +#include + +#include "ArchitectureTypes.h" + + +class CpuState; + + +class StackFrame : public Referenceable, + public DoublyLinkedListLinkImpl { +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 StackFrameList; + + +#endif // STACK_FRAME_H diff --git a/src/apps/debugger/arch/StackTrace.cpp b/src/apps/debugger/arch/StackTrace.cpp new file mode 100644 index 0000000000..34eb3ad8a2 --- /dev/null +++ b/src/apps/debugger/arch/StackTrace.cpp @@ -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); +} diff --git a/src/apps/debugger/arch/StackTrace.h b/src/apps/debugger/arch/StackTrace.h new file mode 100644 index 0000000000..59516e7e9f --- /dev/null +++ b/src/apps/debugger/arch/StackTrace.h @@ -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 diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.cpp b/src/apps/debugger/arch/x86/ArchitectureX86.cpp new file mode 100644 index 0000000000..2189839bd8 --- /dev/null +++ b/src/apps/debugger/arch/x86/ArchitectureX86.cpp @@ -0,0 +1,39 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include "ArchitectureX86.h" + +#include + +#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; +} diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.h b/src/apps/debugger/arch/x86/ArchitectureX86.h new file mode 100644 index 0000000000..98592ba5b5 --- /dev/null +++ b/src/apps/debugger/arch/x86/ArchitectureX86.h @@ -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 diff --git a/src/apps/debugger/arch/x86/CpuStateX86.cpp b/src/apps/debugger/arch/x86/CpuStateX86.cpp new file mode 100644 index 0000000000..f31773fdca --- /dev/null +++ b/src/apps/debugger/arch/x86/CpuStateX86.cpp @@ -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() +{ +} diff --git a/src/apps/debugger/arch/x86/CpuStateX86.h b/src/apps/debugger/arch/x86/CpuStateX86.h new file mode 100644 index 0000000000..e25e095439 --- /dev/null +++ b/src/apps/debugger/arch/x86/CpuStateX86.h @@ -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 + +#include "CpuState.h" + + +typedef debug_cpu_state debug_cpu_state_x86; + // TODO: Should be defined by ! + + +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 diff --git a/src/apps/debugger/debugger_interface/DebugEvent.h b/src/apps/debugger/debugger_interface/DebugEvent.h index 0cbcb2eef8..47fdc6f0fd 100644 --- a/src/apps/debugger/debugger_interface/DebugEvent.h +++ b/src/apps/debugger/debugger_interface/DebugEvent.h @@ -7,12 +7,10 @@ #include +#include "ArchitectureTypes.h" #include "ImageInfo.h" -typedef uint64 target_addr_t; - // TODO: Define elsewhere! - class CpuState; diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp index d44fe7a3fd..df3d8b2192 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp @@ -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, diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.h b/src/apps/debugger/debugger_interface/DebuggerInterface.h index 7a5f3600e0..ec830a42c7 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.h +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.h @@ -11,6 +11,7 @@ #include +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