headers/bsd: Add sys/queue.h.
[haiku.git] / src / kits / debugger / model / DisassembledCode.cpp
blobf2c3e8b813f0e61473d73aa912a06a3ee6801a8f
1 /*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "DisassembledCode.h"
9 #include <stdlib.h>
10 #include <string.h>
12 #include <new>
14 #include <String.h>
16 #include "SourceLanguage.h"
17 #include "Statement.h"
20 struct DisassembledCode::Line {
21 BString line;
22 ContiguousStatement* statement;
24 Line(const BString& line, ContiguousStatement* statement)
26 line(line),
27 statement(statement)
33 DisassembledCode::DisassembledCode(SourceLanguage* language)
35 fLanguage(language),
36 fLines(20, true)
38 fLanguage->AcquireReference();
42 DisassembledCode::~DisassembledCode()
44 for (int32 i = 0; Statement* statement = fStatements.ItemAt(i); i++)
45 statement->ReleaseReference();
47 fLanguage->ReleaseReference();
51 bool
52 DisassembledCode::Lock()
54 // We're immutable, so no locking required.
55 return true;
59 void
60 DisassembledCode::Unlock()
65 SourceLanguage*
66 DisassembledCode::GetSourceLanguage() const
68 return fLanguage;
72 int32
73 DisassembledCode::CountLines() const
75 return fLines.CountItems();
79 const char*
80 DisassembledCode::LineAt(int32 index) const
82 Line* line = fLines.ItemAt(index);
83 return line != NULL ? line->line.String() : NULL;
87 int32
88 DisassembledCode::LineLengthAt(int32 index) const
90 Line* line = fLines.ItemAt(index);
91 return line != NULL ? line->line.Length() : 0;
95 bool
96 DisassembledCode::GetStatementLocationRange(const SourceLocation& location,
97 SourceLocation& _start, SourceLocation& _end) const
99 Line* line = fLines.ItemAt(location.Line());
100 if (line == NULL || line->statement == NULL)
101 return false;
103 _start = line->statement->StartSourceLocation();
104 _end = SourceLocation(_start.Line() + 1);
105 // TODO: Multi-line instructions!
106 return true;
110 LocatableFile*
111 DisassembledCode::GetSourceFile() const
113 return NULL;
117 Statement*
118 DisassembledCode::StatementAtLocation(const SourceLocation& location) const
120 Line* line = fLines.ItemAt(location.Line());
121 return line != NULL ? line->statement : NULL;
125 Statement*
126 DisassembledCode::StatementAtAddress(target_addr_t address) const
128 return fStatements.BinarySearchByKey(address, &_CompareAddressStatement);
132 TargetAddressRange
133 DisassembledCode::StatementAddressRange() const
135 if (fStatements.IsEmpty())
136 return TargetAddressRange();
138 ContiguousStatement* first = fStatements.ItemAt(0);
139 ContiguousStatement* last
140 = fStatements.ItemAt(fStatements.CountItems() - 1);
141 return TargetAddressRange(first->AddressRange().Start(),
142 last->AddressRange().End());
146 bool
147 DisassembledCode::AddCommentLine(const BString& line)
149 return _AddLine(line, NULL);
153 bool
154 DisassembledCode::AddInstructionLine(const BString& line, target_addr_t address,
155 target_size_t size)
157 int32 lineIndex = fLines.CountItems();
159 ContiguousStatement* statement = new(std::nothrow) ContiguousStatement(
160 SourceLocation(lineIndex), TargetAddressRange(address, size));
161 if (statement == NULL)
162 return false;
164 if (!fStatements.AddItem(statement)) {
165 delete statement;
166 return false;
169 if (!_AddLine(line, statement))
170 return false;
172 return true;
176 bool
177 DisassembledCode::_AddLine(const BString& _line, ContiguousStatement* statement)
179 Line* line = new(std::nothrow) Line(_line, statement);
180 if (line == NULL)
181 return false;
183 if (!fLines.AddItem(line)) {
184 delete line;
185 return false;
188 return true;
192 /*static*/ int
193 DisassembledCode::_CompareAddressStatement(const target_addr_t* address,
194 const ContiguousStatement* statement)
196 const TargetAddressRange& range = statement->AddressRange();
198 if (*address < range.Start())
199 return -1;
200 return *address < range.End() ? 0 : 1;