mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 22:44:58 +00:00
LibDebug: Use InputMemoryStream instead of BufferStream.
This removes another call to ByteBuffer::wrap(const void*, size_t).
This commit is contained in:
parent
5bfa7749c3
commit
ac9f6fd1f8
12 changed files with 125 additions and 106 deletions
|
@ -352,50 +352,6 @@ public:
|
||||||
return *this;
|
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)
|
BufferStream& advance(size_t amount)
|
||||||
{
|
{
|
||||||
if (m_offset + amount > m_buffer.size()) {
|
if (m_offset + amount > m_buffer.size()) {
|
||||||
|
|
61
AK/Stream.h
61
AK/Stream.h
|
@ -154,6 +154,67 @@ public:
|
||||||
return m_bytes[m_offset];
|
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; }
|
ReadonlyBytes bytes() const { return m_bytes; }
|
||||||
size_t offset() const { return m_offset; }
|
size_t offset() const { return m_offset; }
|
||||||
size_t remaining() const { return m_bytes.size() - m_offset; }
|
size_t remaining() const { return m_bytes.size() - m_offset; }
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "DebugInfo.h"
|
#include "DebugInfo.h"
|
||||||
#include <AK/QuickSort.h>
|
#include <AK/QuickSort.h>
|
||||||
|
#include <AK/Stream.h>
|
||||||
#include <LibDebug/Dwarf/CompilationUnit.h>
|
#include <LibDebug/Dwarf/CompilationUnit.h>
|
||||||
#include <LibDebug/Dwarf/DwarfInfo.h>
|
#include <LibDebug/Dwarf/DwarfInfo.h>
|
||||||
#include <LibDebug/Dwarf/Expression.h>
|
#include <LibDebug/Dwarf/Expression.h>
|
||||||
|
@ -104,10 +105,10 @@ void DebugInfo::prepare_lines()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto buffer = section.wrapping_byte_buffer();
|
auto buffer = section.wrapping_byte_buffer();
|
||||||
BufferStream stream(buffer);
|
InputMemoryStream stream { buffer.span() };
|
||||||
|
|
||||||
Vector<LineProgram::LineInfo> all_lines;
|
Vector<LineProgram::LineInfo> all_lines;
|
||||||
while (!stream.at_end()) {
|
while (!stream.eof()) {
|
||||||
LineProgram program(stream);
|
LineProgram program(stream);
|
||||||
all_lines.append(program.lines());
|
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) {
|
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);
|
auto value = Dwarf::Expression::evaluate(expression_bytes, regs);
|
||||||
|
|
||||||
if (value.type != Dwarf::Expression::Type::None) {
|
if (value.type != Dwarf::Expression::Type::None) {
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include "AbbreviationsMap.h"
|
#include "AbbreviationsMap.h"
|
||||||
#include "DwarfInfo.h"
|
#include "DwarfInfo.h"
|
||||||
|
|
||||||
|
#include <AK/Stream.h>
|
||||||
|
|
||||||
namespace Dwarf {
|
namespace Dwarf {
|
||||||
|
|
||||||
AbbreviationsMap::AbbreviationsMap(const DwarfInfo& dwarf_info, u32 offset)
|
AbbreviationsMap::AbbreviationsMap(const DwarfInfo& dwarf_info, u32 offset)
|
||||||
|
@ -38,10 +40,10 @@ AbbreviationsMap::AbbreviationsMap(const DwarfInfo& dwarf_info, u32 offset)
|
||||||
|
|
||||||
void AbbreviationsMap::populate_map()
|
void AbbreviationsMap::populate_map()
|
||||||
{
|
{
|
||||||
BufferStream abbreviation_stream(const_cast<ByteBuffer&>(m_dwarf_info.abbreviation_data()));
|
InputMemoryStream abbreviation_stream(m_dwarf_info.abbreviation_data().span());
|
||||||
abbreviation_stream.advance(m_offset);
|
abbreviation_stream.discard_or_error(m_offset);
|
||||||
|
|
||||||
while (!abbreviation_stream.at_end()) {
|
while (!abbreviation_stream.eof()) {
|
||||||
size_t abbreviation_code = 0;
|
size_t abbreviation_code = 0;
|
||||||
abbreviation_stream.read_LEB128_unsigned(abbreviation_code);
|
abbreviation_stream.read_LEB128_unsigned(abbreviation_code);
|
||||||
// An abbrevation code of 0 marks the end of the
|
// An abbrevation code of 0 marks the end of the
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
#include "DIE.h"
|
#include "DIE.h"
|
||||||
#include "CompilationUnit.h"
|
#include "CompilationUnit.h"
|
||||||
#include "DwarfInfo.h"
|
#include "DwarfInfo.h"
|
||||||
#include <AK/BufferStream.h>
|
|
||||||
#include <AK/ByteBuffer.h>
|
#include <AK/ByteBuffer.h>
|
||||||
|
#include <AK/Stream.h>
|
||||||
|
|
||||||
namespace Dwarf {
|
namespace Dwarf {
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@ DIE::DIE(const CompilationUnit& unit, u32 offset)
|
||||||
: m_compilation_unit(unit)
|
: m_compilation_unit(unit)
|
||||||
, m_offset(offset)
|
, m_offset(offset)
|
||||||
{
|
{
|
||||||
BufferStream stream(const_cast<ByteBuffer&>(m_compilation_unit.dwarf_info().debug_info_data()));
|
InputMemoryStream stream(m_compilation_unit.dwarf_info().debug_info_data().span());
|
||||||
stream.advance(m_offset);
|
stream.discard_or_error(m_offset);
|
||||||
stream.read_LEB128_unsigned(m_abbreviation_code);
|
stream.read_LEB128_unsigned(m_abbreviation_code);
|
||||||
m_data_offset = stream.offset();
|
m_data_offset = stream.offset();
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ DIE::DIE(const CompilationUnit& unit, u32 offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
|
DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
|
||||||
BufferStream& debug_info_stream) const
|
InputMemoryStream& debug_info_stream) const
|
||||||
{
|
{
|
||||||
AttributeValue value;
|
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()
|
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.offset());
|
||||||
|
|
||||||
debug_info_stream.advance(length);
|
debug_info_stream.discard_or_error(length);
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (form) {
|
switch (form) {
|
||||||
case AttributeDataForm::StringPointer: {
|
case AttributeDataForm::StringPointer: {
|
||||||
u32 offset = 0;
|
u32 offset;
|
||||||
debug_info_stream >> offset;
|
debug_info_stream >> offset;
|
||||||
value.type = AttributeValue::Type::String;
|
value.type = AttributeValue::Type::String;
|
||||||
|
|
||||||
|
@ -83,42 +83,42 @@ DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttributeDataForm::Data1: {
|
case AttributeDataForm::Data1: {
|
||||||
u8 data = 0;
|
u8 data;
|
||||||
debug_info_stream >> data;
|
debug_info_stream >> data;
|
||||||
value.type = AttributeValue::Type::UnsignedNumber;
|
value.type = AttributeValue::Type::UnsignedNumber;
|
||||||
value.data.as_u32 = data;
|
value.data.as_u32 = data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttributeDataForm::Data2: {
|
case AttributeDataForm::Data2: {
|
||||||
u16 data = 0;
|
u16 data;
|
||||||
debug_info_stream >> data;
|
debug_info_stream >> data;
|
||||||
value.type = AttributeValue::Type::UnsignedNumber;
|
value.type = AttributeValue::Type::UnsignedNumber;
|
||||||
value.data.as_u32 = data;
|
value.data.as_u32 = data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttributeDataForm::Addr: {
|
case AttributeDataForm::Addr: {
|
||||||
u32 address = 0;
|
u32 address;
|
||||||
debug_info_stream >> address;
|
debug_info_stream >> address;
|
||||||
value.type = AttributeValue::Type::UnsignedNumber;
|
value.type = AttributeValue::Type::UnsignedNumber;
|
||||||
value.data.as_u32 = address;
|
value.data.as_u32 = address;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttributeDataForm::SecOffset: {
|
case AttributeDataForm::SecOffset: {
|
||||||
u32 data = 0;
|
u32 data;
|
||||||
debug_info_stream >> data;
|
debug_info_stream >> data;
|
||||||
value.type = AttributeValue::Type::SecOffset;
|
value.type = AttributeValue::Type::SecOffset;
|
||||||
value.data.as_u32 = data;
|
value.data.as_u32 = data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttributeDataForm::Data4: {
|
case AttributeDataForm::Data4: {
|
||||||
u32 data = 0;
|
u32 data;
|
||||||
debug_info_stream >> data;
|
debug_info_stream >> data;
|
||||||
value.type = AttributeValue::Type::UnsignedNumber;
|
value.type = AttributeValue::Type::UnsignedNumber;
|
||||||
value.data.as_u32 = data;
|
value.data.as_u32 = data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttributeDataForm::Ref4: {
|
case AttributeDataForm::Ref4: {
|
||||||
u32 data = 0;
|
u32 data;
|
||||||
debug_info_stream >> data;
|
debug_info_stream >> data;
|
||||||
value.type = AttributeValue::Type::DieReference;
|
value.type = AttributeValue::Type::DieReference;
|
||||||
value.data.as_u32 = data + m_compilation_unit.offset();
|
value.data.as_u32 = data + m_compilation_unit.offset();
|
||||||
|
@ -130,7 +130,7 @@ DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttributeDataForm::ExprLoc: {
|
case AttributeDataForm::ExprLoc: {
|
||||||
size_t length = 0;
|
size_t length;
|
||||||
debug_info_stream.read_LEB128_unsigned(length);
|
debug_info_stream.read_LEB128_unsigned(length);
|
||||||
value.type = AttributeValue::Type::DwarfExpression;
|
value.type = AttributeValue::Type::DwarfExpression;
|
||||||
assign_raw_bytes_value(length);
|
assign_raw_bytes_value(length);
|
||||||
|
@ -146,28 +146,28 @@ DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
|
||||||
}
|
}
|
||||||
case AttributeDataForm::Block1: {
|
case AttributeDataForm::Block1: {
|
||||||
value.type = AttributeValue::Type::RawBytes;
|
value.type = AttributeValue::Type::RawBytes;
|
||||||
u8 length = 0;
|
u8 length;
|
||||||
debug_info_stream >> length;
|
debug_info_stream >> length;
|
||||||
assign_raw_bytes_value(length);
|
assign_raw_bytes_value(length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttributeDataForm::Block2: {
|
case AttributeDataForm::Block2: {
|
||||||
value.type = AttributeValue::Type::RawBytes;
|
value.type = AttributeValue::Type::RawBytes;
|
||||||
u16 length = 0;
|
u16 length;
|
||||||
debug_info_stream >> length;
|
debug_info_stream >> length;
|
||||||
assign_raw_bytes_value(length);
|
assign_raw_bytes_value(length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttributeDataForm::Block4: {
|
case AttributeDataForm::Block4: {
|
||||||
value.type = AttributeValue::Type::RawBytes;
|
value.type = AttributeValue::Type::RawBytes;
|
||||||
u32 length = 0;
|
u32 length;
|
||||||
debug_info_stream >> length;
|
debug_info_stream >> length;
|
||||||
assign_raw_bytes_value(length);
|
assign_raw_bytes_value(length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttributeDataForm::Block: {
|
case AttributeDataForm::Block: {
|
||||||
value.type = AttributeValue::Type::RawBytes;
|
value.type = AttributeValue::Type::RawBytes;
|
||||||
size_t length = 0;
|
size_t length;
|
||||||
debug_info_stream.read_LEB128_unsigned(length);
|
debug_info_stream.read_LEB128_unsigned(length);
|
||||||
assign_raw_bytes_value(length);
|
assign_raw_bytes_value(length);
|
||||||
break;
|
break;
|
||||||
|
@ -181,8 +181,8 @@ DIE::AttributeValue DIE::get_attribute_value(AttributeDataForm form,
|
||||||
|
|
||||||
Optional<DIE::AttributeValue> DIE::get_attribute(const Attribute& attribute) const
|
Optional<DIE::AttributeValue> DIE::get_attribute(const Attribute& attribute) const
|
||||||
{
|
{
|
||||||
BufferStream stream(const_cast<ByteBuffer&>(m_compilation_unit.dwarf_info().debug_info_data()));
|
InputMemoryStream stream { m_compilation_unit.dwarf_info().debug_info_data().span() };
|
||||||
stream.advance(m_data_offset);
|
stream.discard_or_error(m_data_offset);
|
||||||
|
|
||||||
auto abbreviation_info = m_compilation_unit.abbreviations_map().get(m_abbreviation_code);
|
auto abbreviation_info = m_compilation_unit.abbreviations_map().get(m_abbreviation_code);
|
||||||
ASSERT(abbreviation_info.has_value());
|
ASSERT(abbreviation_info.has_value());
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#include "CompilationUnit.h"
|
#include "CompilationUnit.h"
|
||||||
#include "DwarfTypes.h"
|
#include "DwarfTypes.h"
|
||||||
#include <AK/BufferStream.h>
|
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
#include <AK/NonnullOwnPtr.h>
|
#include <AK/NonnullOwnPtr.h>
|
||||||
#include <AK/Optional.h>
|
#include <AK/Optional.h>
|
||||||
|
@ -82,7 +81,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AttributeValue get_attribute_value(AttributeDataForm form,
|
AttributeValue get_attribute_value(AttributeDataForm form,
|
||||||
BufferStream& debug_info_stream) const;
|
InputMemoryStream& debug_info_stream) const;
|
||||||
|
|
||||||
const CompilationUnit& m_compilation_unit;
|
const CompilationUnit& m_compilation_unit;
|
||||||
u32 m_offset { 0 };
|
u32 m_offset { 0 };
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#include "DwarfInfo.h"
|
#include "DwarfInfo.h"
|
||||||
|
|
||||||
|
#include <AK/Stream.h>
|
||||||
|
|
||||||
namespace Dwarf {
|
namespace Dwarf {
|
||||||
|
|
||||||
DwarfInfo::DwarfInfo(NonnullRefPtr<const ELF::Loader> elf)
|
DwarfInfo::DwarfInfo(NonnullRefPtr<const ELF::Loader> elf)
|
||||||
|
@ -50,22 +52,19 @@ void DwarfInfo::populate_compilation_units()
|
||||||
{
|
{
|
||||||
if (m_debug_info_data.is_null())
|
if (m_debug_info_data.is_null())
|
||||||
return;
|
return;
|
||||||
// We have to const_cast here because there isn't a version of
|
|
||||||
// BufferStream that accepts a const ByteStream
|
InputMemoryStream stream(m_debug_info_data.span());
|
||||||
// We take care not to use BufferStream operations that modify the underlying buffer
|
while (!stream.eof()) {
|
||||||
// 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()) {
|
|
||||||
auto unit_offset = stream.offset();
|
auto unit_offset = stream.offset();
|
||||||
CompilationUnitHeader compilation_unit_header {};
|
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.address_size == sizeof(u32));
|
||||||
ASSERT(compilation_unit_header.version == 4);
|
ASSERT(compilation_unit_header.version == 4);
|
||||||
|
|
||||||
u32 length_after_header = compilation_unit_header.length - (sizeof(CompilationUnitHeader) - offsetof(CompilationUnitHeader, version));
|
u32 length_after_header = compilation_unit_header.length - (sizeof(CompilationUnitHeader) - offsetof(CompilationUnitHeader, version));
|
||||||
m_compilation_units.empend(*this, unit_offset, compilation_unit_header);
|
m_compilation_units.empend(*this, unit_offset, compilation_unit_header);
|
||||||
stream.advance(length_after_header);
|
stream.discard_or_error(length_after_header);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#include "CompilationUnit.h"
|
#include "CompilationUnit.h"
|
||||||
#include "DwarfTypes.h"
|
#include "DwarfTypes.h"
|
||||||
#include <AK/BufferStream.h>
|
|
||||||
#include <AK/ByteBuffer.h>
|
#include <AK/ByteBuffer.h>
|
||||||
#include <AK/NonnullRefPtr.h>
|
#include <AK/NonnullRefPtr.h>
|
||||||
#include <AK/RefCounted.h>
|
#include <AK/RefCounted.h>
|
||||||
|
|
|
@ -24,18 +24,18 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include "Expression.h"
|
#include "Expression.h"
|
||||||
#include <AK/BufferStream.h>
|
|
||||||
|
#include <AK/Stream.h>
|
||||||
|
|
||||||
#include <sys/arch/i386/regs.h>
|
#include <sys/arch/i386/regs.h>
|
||||||
|
|
||||||
namespace Dwarf {
|
namespace Dwarf::Expression {
|
||||||
namespace 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
|
InputMemoryStream stream(bytes);
|
||||||
BufferStream stream(const_cast<ByteBuffer&>(bytes));
|
|
||||||
|
|
||||||
while (!stream.at_end()) {
|
while (!stream.eof()) {
|
||||||
u8 opcode = 0;
|
u8 opcode = 0;
|
||||||
stream >> opcode;
|
stream >> opcode;
|
||||||
|
|
||||||
|
@ -61,5 +61,4 @@ Value evaluate(const ByteBuffer& bytes, const PtraceRegisters& regs)
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
}
|
||||||
};
|
|
||||||
|
|
|
@ -31,8 +31,7 @@
|
||||||
|
|
||||||
class PtraceRegisters;
|
class PtraceRegisters;
|
||||||
|
|
||||||
namespace Dwarf {
|
namespace Dwarf::Expression {
|
||||||
namespace Expression {
|
|
||||||
|
|
||||||
enum class Type {
|
enum class Type {
|
||||||
None,
|
None,
|
||||||
|
@ -52,7 +51,6 @@ enum class Operations : u8 {
|
||||||
FbReg = 0x91,
|
FbReg = 0x91,
|
||||||
};
|
};
|
||||||
|
|
||||||
Value evaluate(const ByteBuffer&, const PtraceRegisters&);
|
Value evaluate(ReadonlyBytes, const PtraceRegisters&);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -26,7 +26,9 @@
|
||||||
|
|
||||||
#include "LineProgram.h"
|
#include "LineProgram.h"
|
||||||
|
|
||||||
LineProgram::LineProgram(BufferStream& stream)
|
#include <AK/String.h>
|
||||||
|
|
||||||
|
LineProgram::LineProgram(InputMemoryStream& stream)
|
||||||
: m_stream(stream)
|
: m_stream(stream)
|
||||||
{
|
{
|
||||||
m_unit_offset = m_stream.offset();
|
m_unit_offset = m_stream.offset();
|
||||||
|
@ -38,7 +40,7 @@ LineProgram::LineProgram(BufferStream& stream)
|
||||||
|
|
||||||
void LineProgram::parse_unit_header()
|
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.version == DWARF_VERSION);
|
||||||
ASSERT(m_unit_header.opcode_base == SPECIAL_OPCODES_BASE);
|
ASSERT(m_unit_header.opcode_base == SPECIAL_OPCODES_BASE);
|
||||||
|
@ -51,21 +53,23 @@ void LineProgram::parse_unit_header()
|
||||||
void LineProgram::parse_source_directories()
|
void LineProgram::parse_source_directories()
|
||||||
{
|
{
|
||||||
m_source_directories.append(".");
|
m_source_directories.append(".");
|
||||||
while (m_stream.peek()) {
|
|
||||||
String directory;
|
String directory;
|
||||||
m_stream >> directory;
|
while (m_stream >> directory) {
|
||||||
#ifdef DWARF_DEBUG
|
#ifdef DWARF_DEBUG
|
||||||
dbg() << "directory: " << directory;
|
dbg() << "directory: " << directory;
|
||||||
#endif
|
#endif
|
||||||
m_source_directories.append(move(directory));
|
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()
|
void LineProgram::parse_source_files()
|
||||||
{
|
{
|
||||||
m_source_files.append({ ".", 0 });
|
m_source_files.append({ ".", 0 });
|
||||||
while (m_stream.peek()) {
|
while (!m_stream.eof() && m_stream.peek_or_error()) {
|
||||||
String file_name;
|
String file_name;
|
||||||
m_stream >> file_name;
|
m_stream >> file_name;
|
||||||
size_t directory_index = 0;
|
size_t directory_index = 0;
|
||||||
|
@ -78,8 +82,8 @@ void LineProgram::parse_source_files()
|
||||||
#endif
|
#endif
|
||||||
m_source_files.append({ file_name, directory_index });
|
m_source_files.append({ file_name, directory_index });
|
||||||
}
|
}
|
||||||
m_stream.advance(1);
|
m_stream.discard_or_error(1);
|
||||||
ASSERT(!m_stream.handle_read_failure());
|
ASSERT(!m_stream.handle_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineProgram::append_to_line_info()
|
void LineProgram::append_to_line_info()
|
||||||
|
@ -129,7 +133,7 @@ void LineProgram::handle_extended_opcode()
|
||||||
#ifdef DWARF_DEBUG
|
#ifdef DWARF_DEBUG
|
||||||
dbg() << "SetDiscriminator";
|
dbg() << "SetDiscriminator";
|
||||||
#endif
|
#endif
|
||||||
m_stream.advance(1);
|
m_stream.discard_or_error(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -26,12 +26,13 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/BufferStream.h>
|
#include <AK/Stream.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
class LineProgram {
|
class LineProgram {
|
||||||
public:
|
public:
|
||||||
explicit LineProgram(BufferStream& stream);
|
explicit LineProgram(InputMemoryStream& stream);
|
||||||
|
|
||||||
struct LineInfo {
|
struct LineInfo {
|
||||||
u32 address { 0 };
|
u32 address { 0 };
|
||||||
|
@ -97,7 +98,7 @@ private:
|
||||||
static constexpr u16 DWARF_VERSION = 3;
|
static constexpr u16 DWARF_VERSION = 3;
|
||||||
static constexpr u8 SPECIAL_OPCODES_BASE = 13;
|
static constexpr u8 SPECIAL_OPCODES_BASE = 13;
|
||||||
|
|
||||||
BufferStream& m_stream;
|
InputMemoryStream& m_stream;
|
||||||
|
|
||||||
size_t m_unit_offset { 0 };
|
size_t m_unit_offset { 0 };
|
||||||
UnitHeader32 m_unit_header {};
|
UnitHeader32 m_unit_header {};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue