Path: blob/main/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
39645 views
//===-- DWARFDebugAranges.cpp ---------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "DWARFDebugAranges.h"9#include "DWARFDebugArangeSet.h"10#include "DWARFUnit.h"11#include "LogChannelDWARF.h"12#include "lldb/Utility/Log.h"13#include "lldb/Utility/Timer.h"1415using namespace lldb;16using namespace lldb_private;17using namespace lldb_private::plugin::dwarf;1819// Constructor20DWARFDebugAranges::DWARFDebugAranges() : m_aranges() {}2122// CountArangeDescriptors23class CountArangeDescriptors {24public:25CountArangeDescriptors(uint32_t &count_ref) : count(count_ref) {26// printf("constructor CountArangeDescriptors()\n");27}28void operator()(const DWARFDebugArangeSet &set) {29count += set.NumDescriptors();30}31uint32_t &count;32};3334// Extract35void DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) {36lldb::offset_t offset = 0;3738DWARFDebugArangeSet set;39Range range;40while (debug_aranges_data.ValidOffset(offset)) {41const lldb::offset_t set_offset = offset;42if (llvm::Error error = set.extract(debug_aranges_data, &offset)) {43Log *log = GetLog(DWARFLog::DebugInfo);44LLDB_LOG_ERROR(log, std::move(error),45"DWARFDebugAranges::extract failed to extract "46".debug_aranges set at offset {1:x}: {0}",47set_offset);48} else {49const uint32_t num_descriptors = set.NumDescriptors();50if (num_descriptors > 0) {51const dw_offset_t cu_offset = set.GetHeader().cu_offset;5253for (uint32_t i = 0; i < num_descriptors; ++i) {54const DWARFDebugArangeSet::Descriptor &descriptor =55set.GetDescriptorRef(i);56m_aranges.Append(RangeToDIE::Entry(descriptor.address,57descriptor.length, cu_offset));58}59}60}61// Always use the previous DWARFDebugArangeSet's information to calculate62// the offset of the next DWARFDebugArangeSet in case we entouncter an63// error in the current DWARFDebugArangeSet and our offset position is64// still in the middle of the data. If we do this, we can parse all valid65// DWARFDebugArangeSet objects without returning invalid errors.66offset = set.GetNextOffset();67set.Clear();68}69}7071void DWARFDebugAranges::Dump(Log *log) const {72if (log == nullptr)73return;7475const size_t num_entries = m_aranges.GetSize();76for (size_t i = 0; i < num_entries; ++i) {77const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);78if (entry)79LLDB_LOG(log, "{0:x8}: [{1:x16} - {2:x16})", entry->data,80entry->GetRangeBase(), entry->GetRangeEnd());81}82}8384void DWARFDebugAranges::AppendRange(dw_offset_t offset, dw_addr_t low_pc,85dw_addr_t high_pc) {86if (high_pc > low_pc)87m_aranges.Append(RangeToDIE::Entry(low_pc, high_pc - low_pc, offset));88}8990void DWARFDebugAranges::Sort(bool minimize) {91LLDB_SCOPED_TIMER();9293m_aranges.Sort();94m_aranges.CombineConsecutiveEntriesWithEqualData();95}9697// FindAddress98dw_offset_t DWARFDebugAranges::FindAddress(dw_addr_t address) const {99const RangeToDIE::Entry *entry = m_aranges.FindEntryThatContains(address);100if (entry)101return entry->data;102return DW_INVALID_OFFSET;103}104105106