Coverage Report

Created: 2022-01-15 10:30

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- DWARFDebugRanges.cpp ----------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "DWARFDebugRanges.h"
10
#include "DWARFUnit.h"
11
#include "lldb/Utility/Stream.h"
12
13
using namespace lldb_private;
14
15
937
static dw_addr_t GetBaseAddressMarker(uint32_t addr_size) {
16
937
  switch(addr_size) {
17
0
    case 2:
18
0
      return 0xffff;
19
0
    case 4:
20
0
      return 0xffffffff;
21
937
    case 8:
22
937
      return 0xffffffffffffffff;
23
937
  }
24
0
  llvm_unreachable("GetBaseAddressMarker unsupported address size.");
25
0
}
26
27
246
DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}
28
29
246
void DWARFDebugRanges::Extract(DWARFContext &context) {
30
246
  DWARFRangeList range_list;
31
246
  lldb::offset_t offset = 0;
32
246
  dw_offset_t debug_ranges_offset = offset;
33
937
  while (Extract(context, &offset, range_list)) {
34
691
    range_list.Sort();
35
691
    m_range_map[debug_ranges_offset] = range_list;
36
691
    debug_ranges_offset = offset;
37
691
  }
38
246
}
39
40
bool DWARFDebugRanges::Extract(DWARFContext &context,
41
                               lldb::offset_t *offset_ptr,
42
937
                               DWARFRangeList &range_list) {
43
937
  range_list.Clear();
44
45
937
  lldb::offset_t range_offset = *offset_ptr;
46
937
  const DWARFDataExtractor &debug_ranges_data = context.getOrLoadRangesData();
47
937
  uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
48
937
  dw_addr_t base_addr = 0;
49
937
  dw_addr_t base_addr_marker = GetBaseAddressMarker(addr_size);
50
51
937
  while (
52
4.31k
      debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
53
4.06k
    dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
54
4.06k
    dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
55
56
4.06k
    if (!begin && 
!end870
) {
57
      // End of range list
58
691
      break;
59
691
    }
60
61
3.37k
    if (begin == base_addr_marker) {
62
0
      base_addr = end;
63
0
      continue;
64
0
    }
65
66
    // Filter out empty ranges
67
3.37k
    if (begin < end)
68
3.37k
      range_list.Append(DWARFRangeList::Entry(begin + base_addr, end - begin));
69
3.37k
  }
70
71
  // Make sure we consumed at least something
72
937
  return range_offset != *offset_ptr;
73
937
}
74
75
void DWARFDebugRanges::Dump(Stream &s,
76
                            const DWARFDataExtractor &debug_ranges_data,
77
                            lldb::offset_t *offset_ptr,
78
0
                            dw_addr_t cu_base_addr) {
79
0
  uint32_t addr_size = s.GetAddressByteSize();
80
81
0
  dw_addr_t base_addr = cu_base_addr;
82
0
  while (
83
0
      debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
84
0
    dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
85
0
    dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
86
    // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits of
87
    // ones
88
0
    if (begin == 0xFFFFFFFFull && addr_size == 4)
89
0
      begin = LLDB_INVALID_ADDRESS;
90
91
0
    s.Indent();
92
0
    if (begin == 0 && end == 0) {
93
0
      s.PutCString(" End");
94
0
      break;
95
0
    } else if (begin == LLDB_INVALID_ADDRESS) {
96
      // A base address selection entry
97
0
      base_addr = end;
98
0
      DumpAddress(s.AsRawOstream(), base_addr, sizeof(dw_addr_t),
99
0
                  " Base address = ");
100
0
    } else {
101
      // Convert from offset to an address
102
0
      dw_addr_t begin_addr = begin + base_addr;
103
0
      dw_addr_t end_addr = end + base_addr;
104
105
0
      DumpAddressRange(s.AsRawOstream(), begin_addr, end_addr,
106
0
                       sizeof(dw_addr_t), nullptr);
107
0
    }
108
0
  }
109
0
}
110
111
bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu,
112
                                  dw_offset_t debug_ranges_offset,
113
1.17k
                                  DWARFRangeList &range_list) const {
114
1.17k
  dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset;
115
1.17k
  range_map_const_iterator pos = m_range_map.find(debug_ranges_address);
116
1.17k
  if (pos != m_range_map.end()) {
117
1.17k
    range_list = pos->second;
118
119
    // All DW_AT_ranges are relative to the base address of the compile
120
    // unit. We add the compile unit base address to make sure all the
121
    // addresses are properly fixed up.
122
1.17k
    range_list.Slide(cu->GetBaseAddress());
123
1.17k
    return true;
124
1.17k
  }
125
0
  return false;
126
1.17k
}