1 //===- DWARFDebugRangesList.cpp -------------------------------------------===//
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 "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
11 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
12 #include "llvm/Support/Format.h"
13 #include "llvm/Support/raw_ostream.h"
14 #include <cinttypes>
15 #include <cstdint>
16 #include <utility>
17 
18 using namespace llvm;
19 
20 void DWARFDebugRangeList::clear() {
21   Offset = -1U;
22   AddressSize = 0;
23   Entries.clear();
24 }
25 
26 bool DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
27                                   uint32_t *offset_ptr) {
28   clear();
29   if (!data.isValidOffset(*offset_ptr))
30     return false;
31   AddressSize = data.getAddressSize();
32   if (AddressSize != 4 && AddressSize != 8)
33     return false;
34   Offset = *offset_ptr;
35   while (true) {
36     RangeListEntry entry;
37     uint32_t prev_offset = *offset_ptr;
38     entry.StartAddress =
39         data.getRelocatedAddress(offset_ptr, &entry.SectionIndex);
40     entry.EndAddress = data.getRelocatedAddress(offset_ptr);
41 
42     // Check that both values were extracted correctly.
43     if (*offset_ptr != prev_offset + 2 * AddressSize) {
44       clear();
45       return false;
46     }
47     if (entry.isEndOfListEntry())
48       break;
49     Entries.push_back(entry);
50   }
51   return true;
52 }
53 
54 void DWARFDebugRangeList::dump(raw_ostream &OS) const {
55   for (const RangeListEntry &RLE : Entries) {
56     const char *format_str = (AddressSize == 4
57                               ? "%08x %08"  PRIx64 " %08"  PRIx64 "\n"
58                               : "%08x %016" PRIx64 " %016" PRIx64 "\n");
59     OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress);
60   }
61   OS << format("%08x <End of list>\n", Offset);
62 }
63 
64 DWARFAddressRangesVector
65 DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const {
66   DWARFAddressRangesVector Res;
67   for (const RangeListEntry &RLE : Entries) {
68     if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
69       BaseAddress = RLE.EndAddress;
70     } else {
71       Res.push_back({BaseAddress + RLE.StartAddress,
72                      BaseAddress + RLE.EndAddress, RLE.SectionIndex});
73     }
74   }
75   return Res;
76 }
77