File: | tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp |
Warning: | line 221, column 5 Value stored to 'isDwarf64' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- DWARFDebugRanges.cpp ------------------------------------*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #include "DWARFDebugRanges.h" |
11 | #include "DWARFUnit.h" |
12 | #include "SymbolFileDWARF.h" |
13 | #include "lldb/Utility/Stream.h" |
14 | #include <assert.h> |
15 | |
16 | using namespace lldb_private; |
17 | using namespace std; |
18 | |
19 | static dw_addr_t GetBaseAddressMarker(uint32_t addr_size) { |
20 | switch(addr_size) { |
21 | case 2: |
22 | return 0xffff; |
23 | case 4: |
24 | return 0xffffffff; |
25 | case 8: |
26 | return 0xffffffffffffffff; |
27 | } |
28 | llvm_unreachable("GetBaseAddressMarker unsupported address size.")::llvm::llvm_unreachable_internal("GetBaseAddressMarker unsupported address size." , "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp" , 28); |
29 | } |
30 | |
31 | DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {} |
32 | |
33 | void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) { |
34 | DWARFRangeList range_list; |
35 | lldb::offset_t offset = 0; |
36 | dw_offset_t debug_ranges_offset = offset; |
37 | while (Extract(dwarf2Data, &offset, range_list)) { |
38 | range_list.Sort(); |
39 | m_range_map[debug_ranges_offset] = range_list; |
40 | debug_ranges_offset = offset; |
41 | } |
42 | } |
43 | |
44 | bool DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data, |
45 | lldb::offset_t *offset_ptr, |
46 | DWARFRangeList &range_list) { |
47 | range_list.Clear(); |
48 | |
49 | lldb::offset_t range_offset = *offset_ptr; |
50 | const DWARFDataExtractor &debug_ranges_data = |
51 | dwarf2Data->get_debug_ranges_data(); |
52 | uint32_t addr_size = debug_ranges_data.GetAddressByteSize(); |
53 | dw_addr_t base_addr = 0; |
54 | dw_addr_t base_addr_marker = GetBaseAddressMarker(addr_size); |
55 | |
56 | while ( |
57 | debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) { |
58 | dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); |
59 | dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); |
60 | |
61 | if (!begin && !end) { |
62 | // End of range list |
63 | break; |
64 | } |
65 | |
66 | if (begin == base_addr_marker) { |
67 | base_addr = end; |
68 | continue; |
69 | } |
70 | |
71 | // Filter out empty ranges |
72 | if (begin < end) |
73 | range_list.Append(DWARFRangeList::Entry(begin + base_addr, end - begin)); |
74 | } |
75 | |
76 | // Make sure we consumed at least something |
77 | return range_offset != *offset_ptr; |
78 | } |
79 | |
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 | |
86 | dw_addr_t base_addr = cu_base_addr; |
87 | while ( |
88 | debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) { |
89 | dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); |
90 | dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); |
91 | // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits of |
92 | // ones |
93 | if (begin == 0xFFFFFFFFull && addr_size == 4) |
94 | begin = LLDB_INVALID_ADDRESS(18446744073709551615UL); |
95 | |
96 | s.Indent(); |
97 | if (begin == 0 && end == 0) { |
98 | s.PutCString(" End"); |
99 | break; |
100 | } else if (begin == LLDB_INVALID_ADDRESS(18446744073709551615UL)) { |
101 | // A base address selection entry |
102 | base_addr = end; |
103 | s.Address(base_addr, sizeof(dw_addr_t), " Base address = "); |
104 | } else { |
105 | // Convert from offset to an address |
106 | dw_addr_t begin_addr = begin + base_addr; |
107 | dw_addr_t end_addr = end + base_addr; |
108 | |
109 | s.AddressRange(begin_addr, end_addr, sizeof(dw_addr_t), NULL__null); |
110 | } |
111 | } |
112 | } |
113 | |
114 | bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu, |
115 | dw_offset_t debug_ranges_offset, |
116 | DWARFRangeList &range_list) const { |
117 | dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset; |
118 | range_map_const_iterator pos = m_range_map.find(debug_ranges_address); |
119 | if (pos != m_range_map.end()) { |
120 | range_list = pos->second; |
121 | |
122 | // All DW_AT_ranges are relative to the base address of the compile |
123 | // unit. We add the compile unit base address to make sure all the |
124 | // addresses are properly fixed up. |
125 | range_list.Slide(cu->GetBaseAddress()); |
126 | return true; |
127 | } |
128 | return false; |
129 | } |
130 | |
131 | bool DWARFDebugRngLists::ExtractRangeList( |
132 | const DWARFDataExtractor &data, uint8_t addrSize, |
133 | lldb::offset_t *offset_ptr, std::vector<RngListEntry> &rangeList) { |
134 | rangeList.clear(); |
135 | |
136 | bool error = false; |
137 | while (!error) { |
138 | switch (data.GetU8(offset_ptr)) { |
139 | case DW_RLE_end_of_list: |
140 | return true; |
141 | |
142 | case DW_RLE_start_length: { |
143 | dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize); |
144 | dw_addr_t len = data.GetULEB128(offset_ptr); |
145 | rangeList.push_back({DW_RLE_start_length, begin, len}); |
146 | break; |
147 | } |
148 | |
149 | case DW_RLE_start_end: { |
150 | dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize); |
151 | dw_addr_t end = data.GetMaxU64(offset_ptr, addrSize); |
152 | rangeList.push_back({DW_RLE_start_end, begin, end}); |
153 | break; |
154 | } |
155 | |
156 | case DW_RLE_base_address: { |
157 | dw_addr_t base = data.GetMaxU64(offset_ptr, addrSize); |
158 | rangeList.push_back({DW_RLE_base_address, base, 0}); |
159 | break; |
160 | } |
161 | |
162 | case DW_RLE_offset_pair: { |
163 | dw_addr_t begin = data.GetULEB128(offset_ptr); |
164 | dw_addr_t end = data.GetULEB128(offset_ptr); |
165 | rangeList.push_back({DW_RLE_offset_pair, begin, end}); |
166 | break; |
167 | } |
168 | |
169 | default: |
170 | // Next encodings are not yet supported: |
171 | // DW_RLE_base_addressx, DW_RLE_startx_endx, DW_RLE_startx_length, |
172 | // DW_RLE_offset_pair, DW_RLE_base_address. |
173 | lldbassert(0 && "unknown range list entry encoding")lldb_private::lldb_assert(static_cast<bool>(0 && "unknown range list entry encoding"), "0 && \"unknown range list entry encoding\"" , __FUNCTION__, "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp" , 173); |
174 | error = true; |
175 | } |
176 | } |
177 | |
178 | return false; |
179 | } |
180 | |
181 | bool DWARFDebugRngLists::FindRanges(const DWARFUnit *cu, |
182 | dw_offset_t debug_ranges_offset, |
183 | DWARFRangeList &range_list) const { |
184 | range_list.Clear(); |
185 | dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset; |
186 | auto pos = m_range_map.find(debug_ranges_address); |
187 | if (pos != m_range_map.end()) { |
188 | dw_addr_t BaseAddr = cu->GetBaseAddress(); |
189 | for (const RngListEntry &E : pos->second) { |
190 | switch (E.encoding) { |
191 | case DW_RLE_start_length: |
192 | range_list.Append(DWARFRangeList::Entry(E.value0, E.value1)); |
193 | break; |
194 | case DW_RLE_base_address: |
195 | BaseAddr = E.value0; |
196 | break; |
197 | case DW_RLE_start_end: |
198 | range_list.Append(DWARFRangeList::Entry(E.value0, E.value1 - E.value0)); |
199 | break; |
200 | case DW_RLE_offset_pair: |
201 | range_list.Append( |
202 | DWARFRangeList::Entry(BaseAddr + E.value0, E.value1 - E.value0)); |
203 | break; |
204 | default: |
205 | llvm_unreachable("unexpected encoding")::llvm::llvm_unreachable_internal("unexpected encoding", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp" , 205); |
206 | } |
207 | } |
208 | return true; |
209 | } |
210 | return false; |
211 | } |
212 | |
213 | void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) { |
214 | const DWARFDataExtractor &data = dwarf2Data->get_debug_rnglists_data(); |
215 | lldb::offset_t offset = 0; |
216 | |
217 | uint64_t length = data.GetU32(&offset); |
218 | bool isDwarf64 = false; |
219 | if (length == 0xffffffff) { |
220 | length = data.GetU64(&offset); |
221 | isDwarf64 = true; |
Value stored to 'isDwarf64' is never read | |
222 | } |
223 | lldb::offset_t end = offset + length; |
224 | |
225 | // Check version. |
226 | if (data.GetU16(&offset) < 5) |
227 | return; |
228 | |
229 | uint8_t addrSize = data.GetU8(&offset); |
230 | |
231 | // We do not support non-zero segment selector size. |
232 | if (data.GetU8(&offset) != 0) { |
233 | lldbassert(0 && "not implemented")lldb_private::lldb_assert(static_cast<bool>(0 && "not implemented"), "0 && \"not implemented\"", __FUNCTION__ , "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp" , 233); |
234 | return; |
235 | } |
236 | |
237 | uint32_t offsetsAmount = data.GetU32(&offset); |
238 | for (uint32_t i = 0; i < offsetsAmount; ++i) |
239 | Offsets.push_back(data.GetPointer(&offset)); |
240 | |
241 | lldb::offset_t listOffset = offset; |
242 | std::vector<RngListEntry> rangeList; |
243 | while (offset < end && ExtractRangeList(data, addrSize, &offset, rangeList)) { |
244 | m_range_map[listOffset] = rangeList; |
245 | listOffset = offset; |
246 | } |
247 | } |