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 }
DWARFDebugRanges::DWARFDebugRanges
DWARFDebugRanges()
Definition: DWARFDebugRanges.cpp:27
lldb_private::DumpAddressRange
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:93
lldb_private::Stream::GetAddressByteSize
uint32_t GetAddressByteSize() const
Get the address size in bytes.
Definition: Stream.cpp:179
DWARFDebugRanges::range_map_const_iterator
range_map::const_iterator range_map_const_iterator
Definition: DWARFDebugRanges.h:38
lldb_private::RangeVector::Sort
void Sort()
Definition: RangeMap.h:174
DWARFDebugRanges::FindRanges
bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const
Definition: DWARFDebugRanges.cpp:111
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
lldb_private::Stream
Definition: Stream.h:28
lldb_private::DWARFDataExtractor
Definition: DWARFDataExtractor.h:18
lldb_private::RangeVector::Clear
void Clear()
Definition: RangeMap.h:246
lldb_private::DWARFContext
Definition: DWARFContext.h:20
lldb_private::RangeVector::Append
void Append(const Entry &entry)
Definition: RangeMap.h:136
DWARFUnit
Definition: DWARFUnit.h:80
DWARFDebugRanges::Extract
void Extract(lldb_private::DWARFContext &context)
Definition: DWARFDebugRanges.cpp:29
lldb_private::Stream::Indent
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition: Stream.cpp:130
lldb_private::DataExtractor::GetAddressByteSize
uint32_t GetAddressByteSize() const
Get the current address size.
Definition: DataExtractor.h:253
GetBaseAddressMarker
static dw_addr_t GetBaseAddressMarker(uint32_t addr_size)
Definition: DWARFDebugRanges.cpp:15
DumpAddress
static void DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, Stream &strm)
Definition: CommandObjectTarget.cpp:1464
lldb_private::RangeVector::Slide
void Slide(BaseType slide)
Definition: RangeMap.h:240
lldb_private::Range
Definition: Process.h:60
DWARFUnit.h
lldb_private::RangeVector
Definition: RangeMap.h:125
DWARFUnit::GetBaseAddress
dw_addr_t GetBaseAddress() const
Definition: DWARFUnit.h:155
lldb_private::DWARFContext::getOrLoadRangesData
const DWARFDataExtractor & getOrLoadRangesData()
Definition: DWARFContext.cpp:99
uint32_t
lldb_private::DataExtractor::GetMaxU64
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
Definition: DataExtractor.cpp:527
DWARFDebugRanges.h
lldb_private::Stream::AsRawOstream
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition: Stream.h:357
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
DWARFDebugRanges::Dump
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)
Definition: DWARFDebugRanges.cpp:75
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
Stream.h
DWARFUnit::GetRangesBase
dw_addr_t GetRangesBase() const
Definition: DWARFUnit.h:157
lldb_private::Stream::PutCString
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
dw_addr_t
uint64_t dw_addr_t
Definition: dwarf.h:26
lldb_private::DataExtractor::ValidOffsetForDataOfSize
bool ValidOffsetForDataOfSize(lldb::offset_t offset, lldb::offset_t length) const
Test the availability of length bytes of data from offset.
Definition: DataExtractor.h:954
DWARFDebugRanges::m_range_map
range_map m_range_map
Definition: DWARFDebugRanges.h:39