1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 15:57:35 +00:00

LibDebug: Parse line number information from DWARF format

DWARF line number information, if generated, is stored  in the
.debug_line section of an object file.

The information is encoded as instructions for a VM that is defined in
the DWARF specification.
By executing these instructions, we can extract the encoded line number
information.
This commit is contained in:
Itamar 2020-04-19 23:04:43 +03:00 committed by Andreas Kling
parent edaa9c06d9
commit 8a886e0e96
5 changed files with 596 additions and 0 deletions

View file

@ -317,6 +317,95 @@ public:
return *this;
}
BufferStream& read_raw(u8* raw_data, size_t size)
{
if (m_offset + size > m_buffer.size()) {
m_read_failure = true;
return *this;
}
__builtin_memcpy(raw_data, m_buffer.data() + m_offset, size);
m_offset += size;
return *this;
};
u8 peek()
{
if (m_offset >= m_buffer.size()) {
m_read_failure = true;
return 0;
}
return m_buffer[m_offset];
}
BufferStream& operator>>(String& str)
{
if (m_offset >= m_buffer.size()) {
m_read_failure = true;
return *this;
}
size_t string_size = 0;
while (m_offset + string_size < m_buffer.size() && m_buffer[m_offset + string_size]) {
++string_size;
}
str = String(reinterpret_cast<const char*>(&m_buffer[m_offset]), string_size);
m_offset += string_size + 1;
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()) {
m_read_failure = true;
} else {
m_offset += amount;
}
return *this;
}
bool at_end() const
{
return m_offset == m_buffer.size();