/* * Copyright (c) 2020, Itamar S. * * SPDX-License-Identifier: BSD-2-Clause */ #include "AbbreviationsMap.h" #include "DwarfInfo.h" #include #include namespace Debug::Dwarf { AbbreviationsMap::AbbreviationsMap(DwarfInfo const& dwarf_info, u32 offset) : m_dwarf_info(dwarf_info) , m_offset(offset) { populate_map().release_value_but_fixme_should_propagate_errors(); } ErrorOr AbbreviationsMap::populate_map() { auto abbreviation_stream = TRY(FixedMemoryStream::construct(m_dwarf_info.abbreviation_data())); TRY(abbreviation_stream->discard(m_offset)); while (!abbreviation_stream->is_eof()) { size_t abbreviation_code = 0; TRY(LEB128::read_unsigned(*abbreviation_stream, abbreviation_code)); // An abbreviation code of 0 marks the end of the // abbreviations for a given compilation unit if (abbreviation_code == 0) break; size_t tag {}; TRY(LEB128::read_unsigned(*abbreviation_stream, tag)); auto has_children = TRY(abbreviation_stream->read_value()); AbbreviationEntry abbreviation_entry {}; abbreviation_entry.tag = static_cast(tag); abbreviation_entry.has_children = (has_children == 1); AttributeSpecification current_attribute_specification {}; do { size_t attribute_value = 0; size_t form_value = 0; TRY(LEB128::read_unsigned(*abbreviation_stream, attribute_value)); TRY(LEB128::read_unsigned(*abbreviation_stream, form_value)); current_attribute_specification.attribute = static_cast(attribute_value); current_attribute_specification.form = static_cast(form_value); if (current_attribute_specification.form == AttributeDataForm::ImplicitConst) { ssize_t data_value; TRY(LEB128::read_signed(*abbreviation_stream, data_value)); current_attribute_specification.value = data_value; } if (current_attribute_specification.attribute != Attribute::None) { abbreviation_entry.attribute_specifications.append(current_attribute_specification); } } while (current_attribute_specification.attribute != Attribute::None || current_attribute_specification.form != AttributeDataForm::None); m_entries.set(static_cast(abbreviation_code), move(abbreviation_entry)); } return {}; } AbbreviationsMap::AbbreviationEntry const* AbbreviationsMap::get(u32 code) const { auto it = m_entries.find(code); if (it == m_entries.end()) { return nullptr; } return &it->value; } }