1 //===-- DWARFDebugRanges.cpp ------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "DWARFDebugRanges.h"
11 #include "SymbolFileDWARF.h"
12 #include "lldb/Core/Stream.h"
15 using namespace lldb_private;
18 DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}
20 DWARFDebugRanges::~DWARFDebugRanges() {}
22 void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) {
23 DWARFRangeList range_list;
24 lldb::offset_t offset = 0;
25 dw_offset_t debug_ranges_offset = offset;
26 while (Extract(dwarf2Data, &offset, range_list)) {
28 m_range_map[debug_ranges_offset] = range_list;
29 debug_ranges_offset = offset;
33 bool DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data,
34 lldb::offset_t *offset_ptr,
35 DWARFRangeList &range_list) {
38 lldb::offset_t range_offset = *offset_ptr;
39 const DWARFDataExtractor &debug_ranges_data =
40 dwarf2Data->get_debug_ranges_data();
41 uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
44 debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
45 dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
46 dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
51 // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
55 if (begin == 0xFFFFull)
56 begin = LLDB_INVALID_ADDRESS;
60 if (begin == 0xFFFFFFFFull)
61 begin = LLDB_INVALID_ADDRESS;
68 llvm_unreachable("DWARFRangeList::Extract() unsupported address size.");
71 // Filter out empty ranges
73 range_list.Append(DWARFRangeList::Entry(begin, end - begin));
76 // Make sure we consumed at least something
77 return range_offset != *offset_ptr;
80 void DWARFDebugRanges::Dump(Stream &s,
81 const DWARFDataExtractor &debug_ranges_data,
82 lldb::offset_t *offset_ptr,
83 dw_addr_t cu_base_addr) {
84 uint32_t addr_size = s.GetAddressByteSize();
85 bool verbose = s.GetVerbose();
87 dw_addr_t base_addr = cu_base_addr;
89 debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
90 dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
91 dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
92 // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
94 if (begin == 0xFFFFFFFFull && addr_size == 4)
95 begin = LLDB_INVALID_ADDRESS;
99 s.AddressRange(begin, end, sizeof(dw_addr_t), " offsets = ");
102 if (begin == 0 && end == 0) {
103 s.PutCString(" End");
105 } else if (begin == LLDB_INVALID_ADDRESS) {
106 // A base address selection entry
108 s.Address(base_addr, sizeof(dw_addr_t), " Base address = ");
110 // Convert from offset to an address
111 dw_addr_t begin_addr = begin + base_addr;
112 dw_addr_t end_addr = end + base_addr;
114 s.AddressRange(begin_addr, end_addr, sizeof(dw_addr_t),
115 verbose ? " ==> addrs = " : NULL);
120 bool DWARFDebugRanges::FindRanges(dw_addr_t debug_ranges_base,
121 dw_offset_t debug_ranges_offset,
122 DWARFRangeList &range_list) const {
123 dw_addr_t debug_ranges_address = debug_ranges_base + debug_ranges_offset;
124 range_map_const_iterator pos = m_range_map.find(debug_ranges_address);
125 if (pos != m_range_map.end()) {
126 range_list = pos->second;