diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index d5110bb21f..825c366501 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -57,6 +57,7 @@ Application Debugger : ThreadListView.cpp # model + DisassembledCode.cpp Image.cpp ImageInfo.cpp SourceCode.cpp diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.cpp b/src/apps/debugger/arch/x86/ArchitectureX86.cpp index c2dfc6f7ca..b51e0e3903 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.cpp +++ b/src/apps/debugger/arch/x86/ArchitectureX86.cpp @@ -13,8 +13,8 @@ #include "CpuStateX86.h" #include "DebuggerInterface.h" +#include "DisassembledCode.h" #include "FunctionDebugInfo.h" -#include "SourceCode.h" #include "StackFrame.h" #include "Statement.h" @@ -150,10 +150,10 @@ status_t ArchitectureX86::DisassembleCode(FunctionDebugInfo* function, const void* buffer, size_t bufferSize, SourceCode*& _sourceCode) { - SourceCode* source = new(std::nothrow) SourceCode; + DisassembledCode* source = new(std::nothrow) DisassembledCode; if (source == NULL) return B_NO_MEMORY; - Reference sourceReference(source, true); + Reference sourceReference(source, true); // init disassembler DisassemblerX86 disassembler; @@ -163,9 +163,8 @@ ArchitectureX86::DisassembleCode(FunctionDebugInfo* function, // add a function name line BString functionName(function->PrettyName()); - if (!source->AddLine((functionName << ':').String())) + if (!source->AddCommentLine((functionName << ':').String())) return B_NO_MEMORY; - uint32 lineIndex = 1; // disassemble the instructions BString line; @@ -174,16 +173,10 @@ ArchitectureX86::DisassembleCode(FunctionDebugInfo* function, bool breakpointAllowed; while (disassembler.GetNextInstruction(line, instructionAddress, instructionSize, breakpointAllowed) == B_OK) { - Statement* statement = new(std::nothrow) ContiguousStatement( - SourceLocation(lineIndex), SourceLocation(lineIndex + 1), - TargetAddressRange(instructionAddress, instructionSize)); - if (statement == NULL) + if (!source->AddInstructionLine(line, instructionAddress, + instructionSize, breakpointAllowed)) { return B_NO_MEMORY; - - if (!source->AddStatement(statement) || !source->AddLine(line.String())) - return B_NO_MEMORY; - - lineIndex++; + } } _sourceCode = sourceReference.Detach(); diff --git a/src/apps/debugger/model/DisassembledCode.cpp b/src/apps/debugger/model/DisassembledCode.cpp new file mode 100644 index 0000000000..68e92b9553 --- /dev/null +++ b/src/apps/debugger/model/DisassembledCode.cpp @@ -0,0 +1,147 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include "DisassembledCode.h" + +#include +#include + +#include + +#include + +#include "Statement.h" + + +struct DisassembledCode::Line { + BString line; + ContiguousStatement* statement; + + Line(const BString& line, ContiguousStatement* statement) + : + line(line), + statement(statement) + { + } +}; + + +DisassembledCode::DisassembledCode() + : + fLines(20, true) +{ +} + + +DisassembledCode::~DisassembledCode() +{ + for (int32 i = 0; Statement* statement = fStatements.ItemAt(i); i++) + statement->RemoveReference(); +} + + +int32 +DisassembledCode::CountLines() const +{ + return fLines.CountItems(); +} + + +const char* +DisassembledCode::LineAt(int32 index) const +{ + Line* line = fLines.ItemAt(index); + return line != NULL ? line->line.String() : NULL; +} + + +int32 +DisassembledCode::CountStatements() const +{ + return fStatements.CountItems(); +} + + +Statement* +DisassembledCode::StatementAt(int32 index) const +{ + return fStatements.ItemAt(index); +} + + +Statement* +DisassembledCode::StatementAtLine(int32 index) const +{ + Line* line = fLines.ItemAt(index); + return line != NULL ? line->statement : NULL; +} + + +Statement* +DisassembledCode::StatementAtAddress(target_addr_t address) const +{ + return fStatements.BinarySearchByKey(address, &_CompareAddressStatement); +} + + +bool +DisassembledCode::AddCommentLine(const BString& line) +{ + return _AddLine(line, NULL); +} + + +bool +DisassembledCode::AddInstructionLine(const BString& line, target_addr_t address, + target_size_t size, bool breakpointAllowed) +{ + int32 lineIndex = fLines.CountItems(); + + ContiguousStatement* statement = new(std::nothrow) ContiguousStatement( + SourceLocation(lineIndex), SourceLocation(lineIndex + 1), + TargetAddressRange(address, size)); + // TODO: breakpointAllowed! + if (statement == NULL) + return false; + + if (!fStatements.AddItem(statement)) { + delete statement; + return false; + } + + if (!_AddLine(line, statement)) + return false; + + return true; +} + + +bool +DisassembledCode::_AddLine(const BString& _line, ContiguousStatement* statement) +{ + Line* line = new(std::nothrow) Line(_line, statement); + if (line == NULL) + return false; + + if (!fLines.AddItem(line)) { + delete line; + return false; + } + + return true; +} + + +/*static*/ int +DisassembledCode::_CompareAddressStatement(const target_addr_t* address, + const ContiguousStatement* statement) +{ + const TargetAddressRange& range = statement->AddressRange(); + + if (*address < range.Start()) + return -1; + return *address < range.End() ? 0 : 1; +} + diff --git a/src/apps/debugger/model/DisassembledCode.h b/src/apps/debugger/model/DisassembledCode.h new file mode 100644 index 0000000000..031aafe29c --- /dev/null +++ b/src/apps/debugger/model/DisassembledCode.h @@ -0,0 +1,57 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef DISASSEMBLED_CODE_H +#define DISASSEMBLED_CODE_H + +#include + +#include "SourceCode.h" + + +class BString; +class ContiguousStatement; + + +class DisassembledCode : public SourceCode { +public: + DisassembledCode(); + ~DisassembledCode(); + + virtual int32 CountLines() const; + virtual const char* LineAt(int32 index) const; + + virtual int32 CountStatements() const; + virtual Statement* StatementAt(int32 index) const; + virtual Statement* StatementAtLine(int32 index) const; + virtual Statement* StatementAtAddress(target_addr_t address) const; + +public: + bool AddCommentLine(const BString& line); + bool AddInstructionLine(const BString& line, + target_addr_t address, target_size_t size, + bool breakpointAllowed); + // instructions must be added in + // ascending address order + +private: + struct Line; + + typedef BObjectList LineList; + typedef BObjectList StatementList; + +private: + bool _AddLine(const BString& line, + ContiguousStatement* statement); + static int _CompareAddressStatement( + const target_addr_t* address, + const ContiguousStatement* statement); + +private: + LineList fLines; + StatementList fStatements; +}; + + +#endif // DISASSEMBLED_CODE_H diff --git a/src/apps/debugger/model/SourceCode.cpp b/src/apps/debugger/model/SourceCode.cpp index f38bfe94e6..a06d6c1925 100644 --- a/src/apps/debugger/model/SourceCode.cpp +++ b/src/apps/debugger/model/SourceCode.cpp @@ -5,89 +5,7 @@ #include "SourceCode.h" -#include -#include - -#include "Statement.h" - - -SourceCode::SourceCode() -{ -} - SourceCode::~SourceCode() { - for (int32 i = 0; char* line = fLines.ItemAt(i); i++) - free(line); - for (int32 i = 0; Statement* statement = fStatements.ItemAt(i); i++) - statement->RemoveReference(); -} - - -int32 -SourceCode::CountLines() const -{ - return fLines.CountItems(); -} - - -const char* -SourceCode::LineAt(int32 index) const -{ - return fLines.ItemAt(index); -} - - -int32 -SourceCode::CountStatements() const -{ - return fStatements.CountItems(); -} - - -Statement* -SourceCode::StatementAt(int32 index) const -{ - return fStatements.ItemAt(index); -} - - -Statement* -SourceCode::StatementAtAddress(target_addr_t address) const -{ - // TODO: Optimize! - for (int32 i = 0; Statement* statement = fStatements.ItemAt(i); i++) { - if (statement->ContainsAddress(address)) - return statement; - } - - return NULL; -} - - -bool -SourceCode::AddLine(const char* _line) -{ - char* line = strdup(_line); - if (line == NULL) - return false; - if (!fLines.AddItem(line)) { - free(line); - return false; - } - - return true; -} - - -bool -SourceCode::AddStatement(Statement* statement) -{ - if (!fStatements.AddItem(statement)) { - statement->RemoveReference(); - return false; - } - - return true; } diff --git a/src/apps/debugger/model/SourceCode.h b/src/apps/debugger/model/SourceCode.h index c106283178..b9c24b3a6e 100644 --- a/src/apps/debugger/model/SourceCode.h +++ b/src/apps/debugger/model/SourceCode.h @@ -5,7 +5,6 @@ #ifndef SOURCE_CODE_H #define SOURCE_CODE_H -#include #include #include "ArchitectureTypes.h" @@ -16,28 +15,16 @@ class Statement; class SourceCode : public Referenceable { public: - SourceCode(); - ~SourceCode(); + virtual ~SourceCode(); - int32 CountLines() const; - const char* LineAt(int32 index) const; + virtual int32 CountLines() const = 0; + virtual const char* LineAt(int32 index) const = 0; - int32 CountStatements() const; - Statement* StatementAt(int32 index) const; - Statement* StatementAtAddress(target_addr_t address) const; - - bool AddLine(const char* line); - // clones - bool AddStatement(Statement* statement); - // takes over reference - -private: - typedef BObjectList LineList; - typedef BObjectList StatementList; - -private: - LineList fLines; - StatementList fStatements; + virtual int32 CountStatements() const = 0; + virtual Statement* StatementAt(int32 index) const = 0; + virtual Statement* StatementAtLine(int32 index) const = 0; + virtual Statement* StatementAtAddress(target_addr_t address) + const = 0; };