Files
clang-p2996/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
Felipe de Azevedo Piovezan ab674234c4 [lldb][NFC] Prevent slicing when converting DataExtractors
LLDB's implementation of DWARFDataExtractor has a method that returns a
llvm::DWARFDataExtractor. In some cases, like DebugNamesDWARFIndex::Create, we
were passing an LLVM::DWARFDataExtractor to a function that expects a
LLVM:DataExtractor by value. This is causing slicing of the derived class.

While slicing is not inherently bad, it can be dangerous if the constructor of
the derived class mutates the base class in a way that leaves it in an invalid
state after slicing.

Differential Revision: https://reviews.llvm.org/D153913
2023-06-27 18:09:40 -04:00

56 lines
2.0 KiB
C++

//===-- DWARFDebugRanges.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DWARFDebugRanges.h"
#include "DWARFUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
using namespace lldb_private;
DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}
void DWARFDebugRanges::Extract(DWARFContext &context) {
llvm::DWARFDataExtractor extractor =
context.getOrLoadRangesData().GetAsLLVMDWARF();
llvm::DWARFDebugRangeList extracted_list;
uint64_t current_offset = 0;
auto extract_next_list = [&] {
if (auto error = extracted_list.extract(extractor, &current_offset)) {
consumeError(std::move(error));
return false;
}
return true;
};
uint64_t previous_offset = current_offset;
while (extractor.isValidOffset(current_offset) && extract_next_list()) {
DWARFRangeList &lldb_range_list = m_range_map[previous_offset];
lldb_range_list.Reserve(extracted_list.getEntries().size());
for (auto &range : extracted_list.getEntries())
lldb_range_list.Append(range.StartAddress,
range.EndAddress - range.StartAddress);
lldb_range_list.Sort();
previous_offset = current_offset;
}
}
DWARFRangeList
DWARFDebugRanges::FindRanges(const DWARFUnit *cu,
dw_offset_t debug_ranges_offset) const {
dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset;
auto pos = m_range_map.find(debug_ranges_address);
DWARFRangeList ans =
pos == m_range_map.end() ? DWARFRangeList() : pos->second;
// All DW_AT_ranges are relative to the base address of the compile
// unit. We add the compile unit base address to make sure all the
// addresses are properly fixed up.
ans.Slide(cu->GetBaseAddress());
return ans;
}