1 //===- DWARFDebugRangesList.cpp -------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
10 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
11 #include "llvm/Support/Errc.h"
12 #include "llvm/Support/Format.h"
13 #include "llvm/Support/raw_ostream.h"
19 void DWARFDebugRangeList::clear() {
25 Error
DWARFDebugRangeList::extract(const DWARFDataExtractor
&data
,
26 uint64_t *offset_ptr
) {
28 if (!data
.isValidOffset(*offset_ptr
))
29 return createStringError(errc::invalid_argument
,
30 "invalid range list offset 0x%" PRIx64
, *offset_ptr
);
32 AddressSize
= data
.getAddressSize();
33 if (AddressSize
!= 4 && AddressSize
!= 8)
34 return createStringError(errc::invalid_argument
,
35 "invalid address size: %" PRIu8
, AddressSize
);
39 Entry
.SectionIndex
= -1ULL;
41 uint64_t prev_offset
= *offset_ptr
;
42 Entry
.StartAddress
= data
.getRelocatedAddress(offset_ptr
);
44 data
.getRelocatedAddress(offset_ptr
, &Entry
.SectionIndex
);
46 // Check that both values were extracted correctly.
47 if (*offset_ptr
!= prev_offset
+ 2 * AddressSize
) {
49 return createStringError(errc::invalid_argument
,
50 "invalid range list entry at offset 0x%" PRIx64
,
53 if (Entry
.isEndOfListEntry())
55 Entries
.push_back(Entry
);
57 return Error::success();
60 void DWARFDebugRangeList::dump(raw_ostream
&OS
) const {
61 for (const RangeListEntry
&RLE
: Entries
) {
62 const char *format_str
=
63 (AddressSize
== 4 ? "%08" PRIx64
" %08" PRIx64
" %08" PRIx64
"\n"
64 : "%08" PRIx64
" %016" PRIx64
" %016" PRIx64
"\n");
65 OS
<< format(format_str
, Offset
, RLE
.StartAddress
, RLE
.EndAddress
);
67 OS
<< format("%08" PRIx64
" <End of list>\n", Offset
);
70 DWARFAddressRangesVector
DWARFDebugRangeList::getAbsoluteRanges(
71 llvm::Optional
<object::SectionedAddress
> BaseAddr
) const {
72 DWARFAddressRangesVector Res
;
73 for (const RangeListEntry
&RLE
: Entries
) {
74 if (RLE
.isBaseAddressSelectionEntry(AddressSize
)) {
75 BaseAddr
= {RLE
.EndAddress
, RLE
.SectionIndex
};
80 E
.LowPC
= RLE
.StartAddress
;
81 E
.HighPC
= RLE
.EndAddress
;
82 E
.SectionIndex
= RLE
.SectionIndex
;
83 // Base address of a range list entry is determined by the closest preceding
84 // base address selection entry in the same range list. It defaults to the
85 // base address of the compilation unit if there is no such entry.
87 E
.LowPC
+= BaseAddr
->Address
;
88 E
.HighPC
+= BaseAddr
->Address
;
89 if (E
.SectionIndex
== -1ULL)
90 E
.SectionIndex
= BaseAddr
->SectionIndex
;