LLDB  mainline
DWARFDebugRanges.cpp
Go to the documentation of this file.
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 
16  switch(addr_size) {
17  case 2:
18  return 0xffff;
19  case 4:
20  return 0xffffffff;
21  case 8:
22  return 0xffffffffffffffff;
23  }
24  llvm_unreachable("GetBaseAddressMarker unsupported address size.");
25 }
26 
28 
30  DWARFRangeList range_list;
31  lldb::offset_t offset = 0;
32  dw_offset_t debug_ranges_offset = offset;
33  while (Extract(context, &offset, range_list)) {
34  range_list.Sort();
35  m_range_map[debug_ranges_offset] = range_list;
36  debug_ranges_offset = offset;
37  }
38 }
39 
41  lldb::offset_t *offset_ptr,
42  DWARFRangeList &range_list) {
43  range_list.Clear();
44 
45  lldb::offset_t range_offset = *offset_ptr;
46  const DWARFDataExtractor &debug_ranges_data = context.getOrLoadRangesData();
47  uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
48  dw_addr_t base_addr = 0;
49  dw_addr_t base_addr_marker = GetBaseAddressMarker(addr_size);
50 
51  while (
52  debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
53  dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
54  dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
55 
56  if (!begin && !end) {
57  // End of range list
58  break;
59  }
60 
61  if (begin == base_addr_marker) {
62  base_addr = end;
63  continue;
64  }
65 
66  // Filter out empty ranges
67  if (begin < end)
68  range_list.Append(DWARFRangeList::Entry(begin + base_addr, end - begin));
69  }
70 
71  // Make sure we consumed at least something
72  return range_offset != *offset_ptr;
73 }
74 
76  const DWARFDataExtractor &debug_ranges_data,
77  lldb::offset_t *offset_ptr,
78  dw_addr_t cu_base_addr) {
79  uint32_t addr_size = s.GetAddressByteSize();
80 
81  dw_addr_t base_addr = cu_base_addr;
82  while (
83  debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
84  dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
85  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  if (begin == 0xFFFFFFFFull && addr_size == 4)
89  begin = LLDB_INVALID_ADDRESS;
90 
91  s.Indent();
92  if (begin == 0 && end == 0) {
93  s.PutCString(" End");
94  break;
95  } else if (begin == LLDB_INVALID_ADDRESS) {
96  // A base address selection entry
97  base_addr = end;
98  DumpAddress(s.AsRawOstream(), base_addr, sizeof(dw_addr_t),
99  " Base address = ");
100  } else {
101  // Convert from offset to an address
102  dw_addr_t begin_addr = begin + base_addr;
103  dw_addr_t end_addr = end + base_addr;
104 
105  DumpAddressRange(s.AsRawOstream(), begin_addr, end_addr,
106  sizeof(dw_addr_t), nullptr);
107  }
108  }
109 }
110 
112  dw_offset_t debug_ranges_offset,
113  DWARFRangeList &range_list) const {
114  dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset;
115  range_map_const_iterator pos = m_range_map.find(debug_ranges_address);
116  if (pos != m_range_map.end()) {
117  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  range_list.Slide(cu->GetBaseAddress());
123  return true;
124  }
125  return false;
126 }
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:62
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition: Stream.h:356
dw_addr_t GetBaseAddress() const
Definition: DWARFUnit.h:153
A class that represents a running process on the host machine.
void DumpAddressRange(llvm::raw_ostream &s, uint64_t lo_addr, uint64_t hi_addr, uint32_t addr_size, const char *prefix=nullptr, const char *suffix=nullptr)
Output an address range to this stream.
Definition: Stream.cpp:92
void Slide(BaseType slide)
Definition: RangeMap.h:256
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
const DWARFDataExtractor & getOrLoadRangesData()
void Extract(lldb_private::DWARFContext &context)
uint64_t dw_addr_t
Definition: dwarf.h:26
static dw_addr_t GetBaseAddressMarker(uint32_t addr_size)
dw_addr_t GetRangesBase() const
Definition: DWARFUnit.h:155
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition: Stream.cpp:129
uint64_t offset_t
Definition: lldb-types.h:87
range_map::const_iterator range_map_const_iterator
bool ValidOffsetForDataOfSize(lldb::offset_t offset, lldb::offset_t length) const
Test the availability of length bytes of data from offset.
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const
static void DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, Stream &strm)
uint32_t GetAddressByteSize() const
Get the address size in bytes.
Definition: Stream.cpp:178
static void Dump(lldb_private::Stream &s, const lldb_private::DWARFDataExtractor &debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr)
uint32_t GetAddressByteSize() const
Get the current address size.
void Append(const Entry &entry)
Definition: RangeMap.h:136