summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AK/BufferStream.h44
-rw-r--r--AK/Stream.h61
-rw-r--r--Libraries/LibDebug/DebugInfo.cpp7
-rw-r--r--Libraries/LibDebug/Dwarf/AbbreviationsMap.cpp8
-rw-r--r--Libraries/LibDebug/Dwarf/DIE.cpp38
-rw-r--r--Libraries/LibDebug/Dwarf/DIE.h3
-rw-r--r--Libraries/LibDebug/Dwarf/DwarfInfo.cpp15
-rw-r--r--Libraries/LibDebug/Dwarf/DwarfInfo.h1
-rw-r--r--Libraries/LibDebug/Dwarf/Expression.cpp17
-rw-r--r--Libraries/LibDebug/Dwarf/Expression.h6
-rw-r--r--Libraries/LibDebug/Dwarf/LineProgram.cpp24
-rw-r--r--Libraries/LibDebug/Dwarf/LineProgram.h7
12 files changed, 125 insertions, 106 deletions
diff --git a/AK/BufferStream.h b/AK/BufferStream.h
index b39b88339c..ca07dd102b 100644
--- a/AK/BufferStream.h
+++ b/AK/BufferStream.h
@@ -352,50 +352,6 @@ public:
return *this;
}
- // LEB128 is a variable-length encoding for integers
- BufferStream& read_LEB128_unsigned(size_t& result)
- {
- result = 0;
- size_t num_bytes = 0;
- while (true) {
- if (m_offset > m_buffer.size()) {
- m_read_failure = true;
- break;
- }
- const u8 byte = m_buffer[m_offset];
- result = (result) | (static_cast<size_t>(byte & ~(1 << 7)) << (num_bytes * 7));
- ++m_offset;
- if (!(byte & (1 << 7)))
- break;
- ++num_bytes;
- }
-
- return *this;
- }
-
- // LEB128 is a variable-length encoding for integers
- BufferStream& read_LEB128_signed(ssize_t& result)
- {
- result = 0;
- size_t num_bytes = 0;
- u8 byte = 0;
- do {
- if (m_offset > m_buffer.size()) {
- m_read_failure = true;
- break;
- }
- byte = m_buffer[m_offset];
- result = (result) | (static_cast<size_t>(byte & ~(1 << 7)) << (num_bytes * 7));
- ++m_offset;
- ++num_bytes;
- } while (byte & (1 << 7));
- if (num_bytes * 7 < sizeof(size_t) * 4 && (byte & 0x40)) {
- // sign extend
- result |= ((size_t)(-1) << (num_bytes * 7));
- }
- return *this;
- }
-
BufferStream& advance(size_t amount)
{
if (m_offset + amount > m_buffer.size()) {
diff --git a/AK/Stream.h b/AK/Stream.h
index 6875578683..7a59b9b551 100644
--- a/AK/Stream.h
+++ b/AK/Stream.h
@@ -154,6 +154,67 @@ public:
return m_bytes[m_offset];
}
+ // FIXME: Duplicated from AK::BufferStream::read_LEB128_unsigned.
+ // LEB128 is a variable-length encoding for integers
+ bool read_LEB128_unsigned(size_t& result)
+ {
+ const auto backup = m_offset;
+
+ result = 0;
+ size_t num_bytes = 0;
+ while (true) {
+ // Note. The implementation in AK::BufferStream::read_LEB128_unsigned read one
+ // past the end, this is fixed here.
+ if (eof()) {
+ m_offset = backup;
+ m_error = true;
+ return false;
+ }
+
+ const u8 byte = m_bytes[m_offset];
+ result = (result) | (static_cast<size_t>(byte & ~(1 << 7)) << (num_bytes * 7));
+ ++m_offset;
+ if (!(byte & (1 << 7)))
+ break;
+ ++num_bytes;
+ }
+
+ return true;
+ }
+
+ // FIXME: Duplicated from AK::BufferStream::read_LEB128_signed.
+ // LEB128 is a variable-length encoding for integers
+ bool read_LEB128_signed(ssize_t& result)
+ {
+ const auto backup = m_offset;
+
+ result = 0;
+ size_t num_bytes = 0;
+ u8 byte = 0;
+
+ do {
+ // Note. The implementation in AK::BufferStream::read_LEB128_unsigned read one
+ // past the end, this is fixed here.
+ if (eof()) {
+ m_offset = backup;
+ m_error = true;
+ return false;
+ }
+
+ byte = m_bytes[m_offset];
+ result = (result) | (static_cast<size_t>(byte & ~(1 << 7)) << (num_bytes * 7));
+ ++m_offset;
+ ++num_bytes;
+ } while (byte & (1 << 7));
+
+ if (num_bytes * 7 < sizeof(size_t) * 4 && (byte & 0x40)) {
+ // sign extend
+ result |= ((size_t)(-1) << (num_bytes * 7));
+ }
+
+ return true;
+ }
+
ReadonlyBytes bytes() const { return m_bytes; }
size_t offset() const { return m_offset; }
size_t remaining() const { return m_bytes.size() - m_offset; }
diff --git a/Libraries/LibDebug/DebugInfo.cpp b/Libraries/LibDebug/DebugInfo.cpp
index bd6755f66e..16ee6131e4 100644
--- a/Libraries/LibDebug/DebugInfo.cpp
+++ b/Libraries/LibDebug/DebugInfo.cpp
@@ -26,6 +26,7 @@
#include "DebugInfo.h"
#include <AK/QuickSort.h>
+#include <AK/Stream.h>
#include <LibDebug/Dwarf/CompilationUnit.h>
#include <LibDebug/Dwarf/DwarfInfo.h>
#include <LibDebug/Dwarf/Expression.h>
@@ -104,10 +105,10 @@ void DebugInfo::prepare_lines()
return;
auto buffer = section.wrapping_byte_buffer();
- BufferStream stream(buffer);
+ InputMemoryStream stream { buffer.span() };
Vector<LineProgram::LineInfo> all_lines;
- while (!stream.at_end()) {
+ while (!stream.eof()) {
LineProgram program(stream);
all_lines.append(program.lines());
}
@@ -204,7 +205,7 @@ static void parse_variable_location(const Dwarf::DIE& variable_die, DebugInfo::V
}
if (location_info.value().type == Dwarf::DIE::AttributeValue::Type::DwarfExpression) {
- auto expression_bytes = ByteBuffer::wrap(location_info.value().data.as_raw_bytes.bytes, location_info.value().data.as_raw_bytes.length);
+ auto expression_bytes = ReadonlyBytes { location_info.value().data.as_raw_bytes.bytes, location_info.value().data.as_raw_bytes.length };
auto value = Dwarf::Expression::evaluate(expression_bytes, regs);
if (value.type != Dwarf::Expression::Type::None) {
diff --git a/Libraries/LibDebug/Dwarf/AbbreviationsMap.cpp b/Libraries/LibDebug/Dwarf/AbbreviationsMap.cpp
index 78c76caf1e..dadd9d97ed 100644
--- a/Libraries/LibDebug/Dwarf/AbbreviationsMap.cpp
+++ b/Libraries/LibDebug/Dwarf/AbbreviationsMap.cpp
@@ -27,6 +27,8 @@
#include "AbbreviationsMap.h"
#include "DwarfInfo.h"
+#include <AK/Stream.h>
+
namespace Dwarf {
AbbreviationsMap::AbbreviationsMap(const DwarfInfo& dwarf_info, u32 offset)
@@ -38,10 +40,10 @@ AbbreviationsMap::AbbreviationsMap(const DwarfInfo& dwarf_info, u32 offset)
void AbbreviationsMap::populate_map()
{
- BufferStream abbreviation_stream(const_cast<ByteBuffer&>(m_dwarf_info.abbreviation_data()));
- abbreviation_stream.advance(m_offset);
+ InputMemoryStream abbreviation_stream(m_dwarf_info.abbreviation_data().span());
+ abbreviation_stream.discard_or_error(m_offset);
- while (!abbreviation_stream.at_end()) {
+ while (!abbreviation_stream.eof()) {
size_t abbreviation_code = 0;
abbreviation_stream.read_LEB128_unsigned(abbreviation_code);
// An abbrevation code of 0 marks the end of the
diff --git a/Libraries/LibDebug/Dwarf/DIE.cpp b/Libraries/LibDebug/Dwarf/DIE.cpp
index 2afab92920..c487f42c96 100644
--- a/Libraries/LibDebug/Dwarf/DIE.cpp
+++ b/Libraries/LibDebug/Dwarf/DIE.cpp
@@ -27,8 +27,8 @@
#include "DIE.h"
#include "CompilationUnit.h"
#include "DwarfInfo.h"
-#include <AK/BufferStream.h>
#include <AK/ByteBuffer.h>
+#include <AK/Stream.h>
namespace Dwarf {
@@ -36,8 +36,8 @@ DIE::DIE(const CompilationUnit& unit, u32 offset)
: m_compilation_unit(unit)
, m_offset(offset)
{
- BufferStream stream(const_cast<ByteBuffer&>(m_compilation_unit.dwarf_info().debug_info_data()));
- stream.advance(m_offset);
+ InputMemoryStream stream(m_compilation_unit.dwarf_info().debug_info_data().span());
+ stream.discard_or_error(m_offset);
stream.read_LEB128_unsigned(m_abbreviation_code);
m_data_offset = stream.offset();
@@ -60,7 +60,7 @@ DIE::DIE(const CompilationUnit& unit, u32 offset)
}
DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
- BufferStream& debug_info_stream) const
+ InputMemoryStream& debug_info_stream) const
{
AttributeValue value;
@@ -69,12 +69,12 @@ DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
value.data.as_raw_bytes.bytes = reinterpret_cast<const u8*>(m_compilation_unit.dwarf_info().debug_info_data().data()
+ debug_info_stream.offset());
- debug_info_stream.advance(length);
+ debug_info_stream.discard_or_error(length);
};
switch (form) {
case AttributeDataForm::StringPointer: {
- u32 offset = 0;
+ u32 offset;
debug_info_stream >> offset;
value.type = AttributeValue::Type::String;
@@ -83,42 +83,42 @@ DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
break;
}
case AttributeDataForm::Data1: {
- u8 data = 0;
+ u8 data;
debug_info_stream >> data;
value.type = AttributeValue::Type::UnsignedNumber;
value.data.as_u32 = data;
break;
}
case AttributeDataForm::Data2: {
- u16 data = 0;
+ u16 data;
debug_info_stream >> data;
value.type = AttributeValue::Type::UnsignedNumber;
value.data.as_u32 = data;
break;
}
case AttributeDataForm::Addr: {
- u32 address = 0;
+ u32 address;
debug_info_stream >> address;
value.type = AttributeValue::Type::UnsignedNumber;
value.data.as_u32 = address;
break;
}
case AttributeDataForm::SecOffset: {
- u32 data = 0;
+ u32 data;
debug_info_stream >> data;
value.type = AttributeValue::Type::SecOffset;
value.data.as_u32 = data;
break;
}
case AttributeDataForm::Data4: {
- u32 data = 0;
+ u32 data;
debug_info_stream >> data;
value.type = AttributeValue::Type::UnsignedNumber;
value.data.as_u32 = data;
break;
}
case AttributeDataForm::Ref4: {
- u32 data = 0;
+ u32 data;
debug_info_stream >> data;
value.type = AttributeValue::Type::DieReference;
value.data.as_u32 = data + m_compilation_unit.offset();
@@ -130,7 +130,7 @@ DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
break;
}
case AttributeDataForm::ExprLoc: {
- size_t length = 0;
+ size_t length;
debug_info_stream.read_LEB128_unsigned(length);
value.type = AttributeValue::Type::DwarfExpression;
assign_raw_bytes_value(length);
@@ -146,28 +146,28 @@ DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
}
case AttributeDataForm::Block1: {
value.type = AttributeValue::Type::RawBytes;
- u8 length = 0;
+ u8 length;
debug_info_stream >> length;
assign_raw_bytes_value(length);
break;
}
case AttributeDataForm::Block2: {
value.type = AttributeValue::Type::RawBytes;
- u16 length = 0;
+ u16 length;
debug_info_stream >> length;
assign_raw_bytes_value(length);
break;
}
case AttributeDataForm::Block4: {
value.type = AttributeValue::Type::RawBytes;
- u32 length = 0;
+ u32 length;
debug_info_stream >> length;
assign_raw_bytes_value(length);
break;
}
case AttributeDataForm::Block: {
value.type = AttributeValue::Type::RawBytes;
- size_t length = 0;
+ size_t length;
debug_info_stream.read_LEB128_unsigned(length);
assign_raw_bytes_value(length);
break;
@@ -181,8 +181,8 @@ DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
Optional<DIE::AttributeValue> DIE::get_attribute(const Attribute& attribute) const
{
- BufferStream stream(const_cast<ByteBuffer&>(m_compilation_unit.dwarf_info().debug_info_data()));
- stream.advance(m_data_offset);
+ InputMemoryStream stream { m_compilation_unit.dwarf_info().debug_info_data().span() };
+ stream.discard_or_error(m_data_offset);
auto abbreviation_info = m_compilation_unit.abbreviations_map().get(m_abbreviation_code);
ASSERT(abbreviation_info.has_value());
diff --git a/Libraries/LibDebug/Dwarf/DIE.h b/Libraries/LibDebug/Dwarf/DIE.h
index 85ac01a67c..2d2da9ea4f 100644
--- a/Libraries/LibDebug/Dwarf/DIE.h
+++ b/Libraries/LibDebug/Dwarf/DIE.h
@@ -28,7 +28,6 @@
#include "CompilationUnit.h"
#include "DwarfTypes.h"
-#include <AK/BufferStream.h>
#include <AK/Function.h>
#include <AK/NonnullOwnPtr.h>
#include <AK/Optional.h>
@@ -82,7 +81,7 @@ public:
private:
AttributeValue get_attribute_value(AttributeDataForm form,
- BufferStream& debug_info_stream) const;
+ InputMemoryStream& debug_info_stream) const;
const CompilationUnit& m_compilation_unit;
u32 m_offset { 0 };
diff --git a/Libraries/LibDebug/Dwarf/DwarfInfo.cpp b/Libraries/LibDebug/Dwarf/DwarfInfo.cpp
index e105099b4c..2c81e3e059 100644
--- a/Libraries/LibDebug/Dwarf/DwarfInfo.cpp
+++ b/Libraries/LibDebug/Dwarf/DwarfInfo.cpp
@@ -26,6 +26,8 @@
#include "DwarfInfo.h"
+#include <AK/Stream.h>
+
namespace Dwarf {
DwarfInfo::DwarfInfo(NonnullRefPtr<const ELF::Loader> elf)
@@ -50,22 +52,19 @@ void DwarfInfo::populate_compilation_units()
{
if (m_debug_info_data.is_null())
return;
- // We have to const_cast here because there isn't a version of
- // BufferStream that accepts a const ByteStream
- // We take care not to use BufferStream operations that modify the underlying buffer
- // TOOD: Add a variant of BufferStream that operates on a const ByteBuffer to AK
- BufferStream stream(const_cast<ByteBuffer&>(m_debug_info_data));
- while (!stream.at_end()) {
+
+ InputMemoryStream stream(m_debug_info_data.span());
+ while (!stream.eof()) {
auto unit_offset = stream.offset();
CompilationUnitHeader compilation_unit_header {};
- stream.read_raw(reinterpret_cast<u8*>(&compilation_unit_header), sizeof(CompilationUnitHeader));
+ stream >> Bytes { &compilation_unit_header, sizeof(compilation_unit_header) };
ASSERT(compilation_unit_header.address_size == sizeof(u32));
ASSERT(compilation_unit_header.version == 4);
u32 length_after_header = compilation_unit_header.length - (sizeof(CompilationUnitHeader) - offsetof(CompilationUnitHeader, version));
m_compilation_units.empend(*this, unit_offset, compilation_unit_header);
- stream.advance(length_after_header);
+ stream.discard_or_error(length_after_header);
}
}
diff --git a/Libraries/LibDebug/Dwarf/DwarfInfo.h b/Libraries/LibDebug/Dwarf/DwarfInfo.h
index f39d168790..e3927c2e61 100644
--- a/Libraries/LibDebug/Dwarf/DwarfInfo.h
+++ b/Libraries/LibDebug/Dwarf/DwarfInfo.h
@@ -28,7 +28,6 @@
#include "CompilationUnit.h"
#include "DwarfTypes.h"
-#include <AK/BufferStream.h>
#include <AK/ByteBuffer.h>
#include <AK/NonnullRefPtr.h>
#include <AK/RefCounted.h>
diff --git a/Libraries/LibDebug/Dwarf/Expression.cpp b/Libraries/LibDebug/Dwarf/Expression.cpp
index ddc1dfcde4..a38b0fd2bd 100644
--- a/Libraries/LibDebug/Dwarf/Expression.cpp
+++ b/Libraries/LibDebug/Dwarf/Expression.cpp
@@ -24,18 +24,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Expression.h"
-#include <AK/BufferStream.h>
+
+#include <AK/Stream.h>
+
#include <sys/arch/i386/regs.h>
-namespace Dwarf {
-namespace Expression {
+namespace Dwarf::Expression {
-Value evaluate(const ByteBuffer& bytes, const PtraceRegisters& regs)
+Value evaluate(ReadonlyBytes bytes, const PtraceRegisters& regs)
{
- // TODO: we need a BufferStream variant that takes a const ByteBuffer
- BufferStream stream(const_cast<ByteBuffer&>(bytes));
+ InputMemoryStream stream(bytes);
- while (!stream.at_end()) {
+ while (!stream.eof()) {
u8 opcode = 0;
stream >> opcode;
@@ -61,5 +61,4 @@ Value evaluate(const ByteBuffer& bytes, const PtraceRegisters& regs)
ASSERT_NOT_REACHED();
}
-};
-};
+}
diff --git a/Libraries/LibDebug/Dwarf/Expression.h b/Libraries/LibDebug/Dwarf/Expression.h
index 235efdea8f..de9463901d 100644
--- a/Libraries/LibDebug/Dwarf/Expression.h
+++ b/Libraries/LibDebug/Dwarf/Expression.h
@@ -31,8 +31,7 @@
class PtraceRegisters;
-namespace Dwarf {
-namespace Expression {
+namespace Dwarf::Expression {
enum class Type {
None,
@@ -52,7 +51,6 @@ enum class Operations : u8 {
FbReg = 0x91,
};
-Value evaluate(const ByteBuffer&, const PtraceRegisters&);
+Value evaluate(ReadonlyBytes, const PtraceRegisters&);
}
-}
diff --git a/Libraries/LibDebug/Dwarf/LineProgram.cpp b/Libraries/LibDebug/Dwarf/LineProgram.cpp
index 2bc629daff..66d72e31bd 100644
--- a/Libraries/LibDebug/Dwarf/LineProgram.cpp
+++ b/Libraries/LibDebug/Dwarf/LineProgram.cpp
@@ -26,7 +26,9 @@
#include "LineProgram.h"
-LineProgram::LineProgram(BufferStream& stream)
+#include <AK/String.h>
+
+LineProgram::LineProgram(InputMemoryStream& stream)
: m_stream(stream)
{
m_unit_offset = m_stream.offset();
@@ -38,7 +40,7 @@ LineProgram::LineProgram(BufferStream& stream)
void LineProgram::parse_unit_header()
{
- m_stream.read_raw((u8*)&m_unit_header, sizeof(m_unit_header));
+ m_stream >> Bytes { &m_unit_header, sizeof(m_unit_header) };
ASSERT(m_unit_header.version == DWARF_VERSION);
ASSERT(m_unit_header.opcode_base == SPECIAL_OPCODES_BASE);
@@ -51,21 +53,23 @@ void LineProgram::parse_unit_header()
void LineProgram::parse_source_directories()
{
m_source_directories.append(".");
- while (m_stream.peek()) {
- String directory;
- m_stream >> directory;
+
+ String directory;
+ while (m_stream >> directory) {
#ifdef DWARF_DEBUG
dbg() << "directory: " << directory;
#endif
m_source_directories.append(move(directory));
}
- m_stream.advance(1);
+ m_stream.handle_error();
+ m_stream.discard_or_error(1);
+ ASSERT(!m_stream.handle_error());
}
void LineProgram::parse_source_files()
{
m_source_files.append({ ".", 0 });
- while (m_stream.peek()) {
+ while (!m_stream.eof() && m_stream.peek_or_error()) {
String file_name;
m_stream >> file_name;
size_t directory_index = 0;
@@ -78,8 +82,8 @@ void LineProgram::parse_source_files()
#endif
m_source_files.append({ file_name, directory_index });
}
- m_stream.advance(1);
- ASSERT(!m_stream.handle_read_failure());
+ m_stream.discard_or_error(1);
+ ASSERT(!m_stream.handle_error());
}
void LineProgram::append_to_line_info()
@@ -129,7 +133,7 @@ void LineProgram::handle_extended_opcode()
#ifdef DWARF_DEBUG
dbg() << "SetDiscriminator";
#endif
- m_stream.advance(1);
+ m_stream.discard_or_error(1);
break;
}
default:
diff --git a/Libraries/LibDebug/Dwarf/LineProgram.h b/Libraries/LibDebug/Dwarf/LineProgram.h
index f49ec17390..092b2deba8 100644
--- a/Libraries/LibDebug/Dwarf/LineProgram.h
+++ b/Libraries/LibDebug/Dwarf/LineProgram.h
@@ -26,12 +26,13 @@
#pragma once
-#include <AK/BufferStream.h>
+#include <AK/Stream.h>
+#include <AK/String.h>
#include <AK/Vector.h>
class LineProgram {
public:
- explicit LineProgram(BufferStream& stream);
+ explicit LineProgram(InputMemoryStream& stream);
struct LineInfo {
u32 address { 0 };
@@ -97,7 +98,7 @@ private:
static constexpr u16 DWARF_VERSION = 3;
static constexpr u8 SPECIAL_OPCODES_BASE = 13;
- BufferStream& m_stream;
+ InputMemoryStream& m_stream;
size_t m_unit_offset { 0 };
UnitHeader32 m_unit_header {};