1 //===-- DWARFDebugArangeSet.cpp -------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/DebugInfo/DWARFDebugArangeSet.h"
11 #include "llvm/Support/Format.h"
12 #include "llvm/Support/raw_ostream.h"
17 void DWARFDebugArangeSet::clear() {
19 std::memset(&HeaderData
, 0, sizeof(Header
));
20 ArangeDescriptors
.clear();
24 DWARFDebugArangeSet::extract(DataExtractor data
, uint32_t *offset_ptr
) {
25 if (data
.isValidOffset(*offset_ptr
)) {
26 ArangeDescriptors
.clear();
29 // 7.20 Address Range Table
31 // Each set of entries in the table of address ranges contained in
32 // the .debug_aranges section begins with a header consisting of: a
33 // 4-byte length containing the length of the set of entries for this
34 // compilation unit, not including the length field itself; a 2-byte
35 // version identifier containing the value 2 for DWARF Version 2; a
36 // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer
37 // containing the size in bytes of an address (or the offset portion of
38 // an address for segmented addressing) on the target system; and a
39 // 1-byte unsigned integer containing the size in bytes of a segment
40 // descriptor on the target system. This header is followed by a series
41 // of tuples. Each tuple consists of an address and a length, each in
42 // the size appropriate for an address on the target architecture.
43 HeaderData
.Length
= data
.getU32(offset_ptr
);
44 HeaderData
.Version
= data
.getU16(offset_ptr
);
45 HeaderData
.CuOffset
= data
.getU32(offset_ptr
);
46 HeaderData
.AddrSize
= data
.getU8(offset_ptr
);
47 HeaderData
.SegSize
= data
.getU8(offset_ptr
);
49 // Perform basic validation of the header fields.
50 if (!data
.isValidOffsetForDataOfSize(Offset
, HeaderData
.Length
) ||
51 (HeaderData
.AddrSize
!= 4 && HeaderData
.AddrSize
!= 8)) {
56 // The first tuple following the header in each set begins at an offset
57 // that is a multiple of the size of a single tuple (that is, twice the
58 // size of an address). The header is padded, if necessary, to the
59 // appropriate boundary.
60 const uint32_t header_size
= *offset_ptr
- Offset
;
61 const uint32_t tuple_size
= HeaderData
.AddrSize
* 2;
62 uint32_t first_tuple_offset
= 0;
63 while (first_tuple_offset
< header_size
)
64 first_tuple_offset
+= tuple_size
;
66 *offset_ptr
= Offset
+ first_tuple_offset
;
68 Descriptor arangeDescriptor
;
70 static_assert(sizeof(arangeDescriptor
.Address
) ==
71 sizeof(arangeDescriptor
.Length
),
72 "Different datatypes for addresses and sizes!");
73 assert(sizeof(arangeDescriptor
.Address
) >= HeaderData
.AddrSize
);
75 while (data
.isValidOffset(*offset_ptr
)) {
76 arangeDescriptor
.Address
= data
.getUnsigned(offset_ptr
, HeaderData
.AddrSize
);
77 arangeDescriptor
.Length
= data
.getUnsigned(offset_ptr
, HeaderData
.AddrSize
);
79 // Each set of tuples is terminated by a 0 for the address and 0
81 if (arangeDescriptor
.Address
|| arangeDescriptor
.Length
)
82 ArangeDescriptors
.push_back(arangeDescriptor
);
84 break; // We are done if we get a zero address and length
87 return !ArangeDescriptors
.empty();
92 void DWARFDebugArangeSet::dump(raw_ostream
&OS
) const {
93 OS
<< format("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, ",
94 HeaderData
.Length
, HeaderData
.Version
)
95 << format("cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n",
96 HeaderData
.CuOffset
, HeaderData
.AddrSize
, HeaderData
.SegSize
);
98 const uint32_t hex_width
= HeaderData
.AddrSize
* 2;
99 for (const auto &Desc
: ArangeDescriptors
) {
100 OS
<< format("[0x%*.*" PRIx64
" -", hex_width
, hex_width
, Desc
.Address
)
101 << format(" 0x%*.*" PRIx64
")\n",
102 hex_width
, hex_width
, Desc
.getEndAddress());