|
7 | 7 | //===----------------------------------------------------------------------===//
|
8 | 8 |
|
9 | 9 | #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
|
| 10 | +#include "llvm/BinaryFormat/Dwarf.h" |
10 | 11 | #include "llvm/Support/Errc.h"
|
11 | 12 | #include "llvm/Support/Format.h"
|
12 | 13 | #include "llvm/Support/raw_ostream.h"
|
@@ -35,28 +36,51 @@ Error DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) {
|
35 | 36 | ArangeDescriptors.clear();
|
36 | 37 | Offset = *offset_ptr;
|
37 | 38 |
|
38 |
| - // 7.20 Address Range Table |
39 |
| - // |
| 39 | + // 7.21 Address Range Table (extract) |
40 | 40 | // Each set of entries in the table of address ranges contained in
|
41 |
| - // the .debug_aranges section begins with a header consisting of: a |
42 |
| - // 4-byte length containing the length of the set of entries for this |
43 |
| - // compilation unit, not including the length field itself; a 2-byte |
44 |
| - // version identifier containing the value 2 for DWARF Version 2; a |
45 |
| - // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer |
46 |
| - // containing the size in bytes of an address (or the offset portion of |
47 |
| - // an address for segmented addressing) on the target system; and a |
48 |
| - // 1-byte unsigned integer containing the size in bytes of a segment |
49 |
| - // descriptor on the target system. This header is followed by a series |
50 |
| - // of tuples. Each tuple consists of an address and a length, each in |
51 |
| - // the size appropriate for an address on the target architecture. |
| 41 | + // the .debug_aranges section begins with a header containing: |
| 42 | + // 1. unit_length (initial length) |
| 43 | + // A 4-byte (32-bit DWARF) or 12-byte (64-bit DWARF) length containing |
| 44 | + // the length of the set of entries for this compilation unit, |
| 45 | + // not including the length field itself. |
| 46 | + // 2. version (uhalf) |
| 47 | + // The value in this field is 2. |
| 48 | + // 3. debug_info_offset (section offset) |
| 49 | + // A 4-byte (32-bit DWARF) or 8-byte (64-bit DWARF) offset into the |
| 50 | + // .debug_info section of the compilation unit header. |
| 51 | + // 4. address_size (ubyte) |
| 52 | + // 5. segment_selector_size (ubyte) |
| 53 | + // This header is followed by a series of tuples. Each tuple consists of |
| 54 | + // a segment, an address and a length. The segment selector size is given by |
| 55 | + // the segment_selector_size field of the header; the address and length |
| 56 | + // size are each given by the address_size field of the header. Each set of |
| 57 | + // tuples is terminated by a 0 for the segment, a 0 for the address and 0 |
| 58 | + // for the length. If the segment_selector_size field in the header is zero, |
| 59 | + // the segment selectors are omitted from all tuples, including |
| 60 | + // the terminating tuple. |
| 61 | + |
| 62 | + dwarf::DwarfFormat format = dwarf::DWARF32; |
52 | 63 | HeaderData.Length = data.getU32(offset_ptr);
|
| 64 | + if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) { |
| 65 | + HeaderData.Length = data.getU64(offset_ptr); |
| 66 | + format = dwarf::DWARF64; |
| 67 | + } else if (HeaderData.Length >= dwarf::DW_LENGTH_lo_reserved) { |
| 68 | + return createStringError( |
| 69 | + errc::invalid_argument, |
| 70 | + "address range table at offset 0x%" PRIx64 |
| 71 | + " has unsupported reserved unit length of value 0x%8.8" PRIx64, |
| 72 | + Offset, HeaderData.Length); |
| 73 | + } |
53 | 74 | HeaderData.Version = data.getU16(offset_ptr);
|
54 |
| - HeaderData.CuOffset = data.getU32(offset_ptr); |
| 75 | + HeaderData.CuOffset = |
| 76 | + data.getUnsigned(offset_ptr, dwarf::getDwarfOffsetByteSize(format)); |
55 | 77 | HeaderData.AddrSize = data.getU8(offset_ptr);
|
56 | 78 | HeaderData.SegSize = data.getU8(offset_ptr);
|
57 | 79 |
|
58 | 80 | // Perform basic validation of the header fields.
|
59 |
| - if (!data.isValidOffsetForDataOfSize(Offset, HeaderData.Length + 4)) |
| 81 | + uint64_t full_length = |
| 82 | + dwarf::getUnitLengthFieldByteSize(format) + HeaderData.Length; |
| 83 | + if (!data.isValidOffsetForDataOfSize(Offset, full_length)) |
60 | 84 | return createStringError(errc::invalid_argument,
|
61 | 85 | "the length of address range table at offset "
|
62 | 86 | "0x%" PRIx64 " exceeds section size",
|
@@ -105,10 +129,12 @@ Error DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) {
|
105 | 129 | }
|
106 | 130 |
|
107 | 131 | void DWARFDebugArangeSet::dump(raw_ostream &OS) const {
|
108 |
| - OS << format("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, ", |
109 |
| - HeaderData.Length, HeaderData.Version) |
110 |
| - << format("cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n", |
111 |
| - HeaderData.CuOffset, HeaderData.AddrSize, HeaderData.SegSize); |
| 132 | + OS << "Address Range Header: " |
| 133 | + << format("length = 0x%8.8" PRIx64 ", ", HeaderData.Length) |
| 134 | + << format("version = 0x%4.4x, ", HeaderData.Version) |
| 135 | + << format("cu_offset = 0x%8.8" PRIx64 ", ", HeaderData.CuOffset) |
| 136 | + << format("addr_size = 0x%2.2x, ", HeaderData.AddrSize) |
| 137 | + << format("seg_size = 0x%2.2x\n", HeaderData.SegSize); |
112 | 138 |
|
113 | 139 | for (const auto &Desc : ArangeDescriptors) {
|
114 | 140 | Desc.dump(OS, HeaderData.AddrSize);
|
|
0 commit comments