* Virtualized SourceCode and implemented a derived class DisassembledCode, which
allows to implement StatementAtAddress() in O(log(n). * Added SourceCode::StatementAtLine(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31174 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -57,6 +57,7 @@ Application Debugger :
|
||||
ThreadListView.cpp
|
||||
|
||||
# model
|
||||
DisassembledCode.cpp
|
||||
Image.cpp
|
||||
ImageInfo.cpp
|
||||
SourceCode.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<SourceCode> sourceReference(source, true);
|
||||
Reference<DisassembledCode> 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();
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "DisassembledCode.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <String.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef DISASSEMBLED_CODE_H
|
||||
#define DISASSEMBLED_CODE_H
|
||||
|
||||
#include <ObjectList.h>
|
||||
|
||||
#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<Line> LineList;
|
||||
typedef BObjectList<ContiguousStatement> 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
|
||||
@@ -5,89 +5,7 @@
|
||||
|
||||
#include "SourceCode.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#ifndef SOURCE_CODE_H
|
||||
#define SOURCE_CODE_H
|
||||
|
||||
#include <ObjectList.h>
|
||||
#include <Referenceable.h>
|
||||
|
||||
#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<char> LineList;
|
||||
typedef BObjectList<Statement> 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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user