Pārlūkot izejas kodu

LibDebug: Use InputMemoryStream instead of BufferStream.

This removes another call to ByteBuffer::wrap(const void*, size_t).
asynts 4 gadi atpakaļ
vecāks
revīzija
ac9f6fd1f8

+ 0 - 44
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()) {

+ 61 - 0
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; }

+ 4 - 3
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) {

+ 5 - 3
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

+ 19 - 19
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());

+ 1 - 2
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 };

+ 7 - 8
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);
     }
 }
 

+ 0 - 1
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>

+ 8 - 9
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();
 }
 
-};
-};
+}

+ 2 - 4
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&);
 
 }
-}

+ 14 - 10
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:

+ 4 - 3
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 {};