Mercurial > hg > CbC > CbC_llvm
comparison lib/DebugInfo/DWARFDebugArangeSet.cpp @ 3:9ad51c7bc036
1st commit. remove git dir and add all files.
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 15 May 2013 06:43:32 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 3:9ad51c7bc036 |
---|---|
1 //===-- DWARFDebugArangeSet.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 "DWARFDebugArangeSet.h" | |
11 #include "llvm/Support/Format.h" | |
12 #include "llvm/Support/raw_ostream.h" | |
13 #include <algorithm> | |
14 #include <cassert> | |
15 using namespace llvm; | |
16 | |
17 void DWARFDebugArangeSet::clear() { | |
18 Offset = -1U; | |
19 std::memset(&HeaderData, 0, sizeof(Header)); | |
20 ArangeDescriptors.clear(); | |
21 } | |
22 | |
23 void DWARFDebugArangeSet::compact() { | |
24 if (ArangeDescriptors.empty()) | |
25 return; | |
26 | |
27 // Iterate through all arange descriptors and combine any ranges that | |
28 // overlap or have matching boundaries. The ArangeDescriptors are assumed | |
29 // to be in ascending order. | |
30 uint32_t i = 0; | |
31 while (i + 1 < ArangeDescriptors.size()) { | |
32 if (ArangeDescriptors[i].getEndAddress() >= ArangeDescriptors[i+1].Address){ | |
33 // The current range ends at or exceeds the start of the next address | |
34 // range. Compute the max end address between the two and use that to | |
35 // make the new length. | |
36 const uint64_t max_end_addr = | |
37 std::max(ArangeDescriptors[i].getEndAddress(), | |
38 ArangeDescriptors[i+1].getEndAddress()); | |
39 ArangeDescriptors[i].Length = max_end_addr - ArangeDescriptors[i].Address; | |
40 // Now remove the next entry as it was just combined with the previous one | |
41 ArangeDescriptors.erase(ArangeDescriptors.begin()+i+1); | |
42 } else { | |
43 // Discontiguous address range, just proceed to the next one. | |
44 ++i; | |
45 } | |
46 } | |
47 } | |
48 | |
49 bool | |
50 DWARFDebugArangeSet::extract(DataExtractor data, uint32_t *offset_ptr) { | |
51 if (data.isValidOffset(*offset_ptr)) { | |
52 ArangeDescriptors.clear(); | |
53 Offset = *offset_ptr; | |
54 | |
55 // 7.20 Address Range Table | |
56 // | |
57 // Each set of entries in the table of address ranges contained in | |
58 // the .debug_aranges section begins with a header consisting of: a | |
59 // 4-byte length containing the length of the set of entries for this | |
60 // compilation unit, not including the length field itself; a 2-byte | |
61 // version identifier containing the value 2 for DWARF Version 2; a | |
62 // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer | |
63 // containing the size in bytes of an address (or the offset portion of | |
64 // an address for segmented addressing) on the target system; and a | |
65 // 1-byte unsigned integer containing the size in bytes of a segment | |
66 // descriptor on the target system. This header is followed by a series | |
67 // of tuples. Each tuple consists of an address and a length, each in | |
68 // the size appropriate for an address on the target architecture. | |
69 HeaderData.Length = data.getU32(offset_ptr); | |
70 HeaderData.Version = data.getU16(offset_ptr); | |
71 HeaderData.CuOffset = data.getU32(offset_ptr); | |
72 HeaderData.AddrSize = data.getU8(offset_ptr); | |
73 HeaderData.SegSize = data.getU8(offset_ptr); | |
74 | |
75 // Perform basic validation of the header fields. | |
76 if (!data.isValidOffsetForDataOfSize(Offset, HeaderData.Length) || | |
77 (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)) { | |
78 clear(); | |
79 return false; | |
80 } | |
81 | |
82 // The first tuple following the header in each set begins at an offset | |
83 // that is a multiple of the size of a single tuple (that is, twice the | |
84 // size of an address). The header is padded, if necessary, to the | |
85 // appropriate boundary. | |
86 const uint32_t header_size = *offset_ptr - Offset; | |
87 const uint32_t tuple_size = HeaderData.AddrSize * 2; | |
88 uint32_t first_tuple_offset = 0; | |
89 while (first_tuple_offset < header_size) | |
90 first_tuple_offset += tuple_size; | |
91 | |
92 *offset_ptr = Offset + first_tuple_offset; | |
93 | |
94 Descriptor arangeDescriptor; | |
95 | |
96 assert(sizeof(arangeDescriptor.Address) == sizeof(arangeDescriptor.Length)); | |
97 assert(sizeof(arangeDescriptor.Address) >= HeaderData.AddrSize); | |
98 | |
99 while (data.isValidOffset(*offset_ptr)) { | |
100 arangeDescriptor.Address = data.getUnsigned(offset_ptr, HeaderData.AddrSize); | |
101 arangeDescriptor.Length = data.getUnsigned(offset_ptr, HeaderData.AddrSize); | |
102 | |
103 // Each set of tuples is terminated by a 0 for the address and 0 | |
104 // for the length. | |
105 if (arangeDescriptor.Address || arangeDescriptor.Length) | |
106 ArangeDescriptors.push_back(arangeDescriptor); | |
107 else | |
108 break; // We are done if we get a zero address and length | |
109 } | |
110 | |
111 return !ArangeDescriptors.empty(); | |
112 } | |
113 return false; | |
114 } | |
115 | |
116 void DWARFDebugArangeSet::dump(raw_ostream &OS) const { | |
117 OS << format("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, ", | |
118 HeaderData.Length, HeaderData.Version) | |
119 << format("cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n", | |
120 HeaderData.CuOffset, HeaderData.AddrSize, HeaderData.SegSize); | |
121 | |
122 const uint32_t hex_width = HeaderData.AddrSize * 2; | |
123 for (DescriptorConstIter pos = ArangeDescriptors.begin(), | |
124 end = ArangeDescriptors.end(); pos != end; ++pos) | |
125 OS << format("[0x%*.*" PRIx64 " -", hex_width, hex_width, pos->Address) | |
126 << format(" 0x%*.*" PRIx64 ")\n", | |
127 hex_width, hex_width, pos->getEndAddress()); | |
128 } | |
129 | |
130 | |
131 namespace { | |
132 class DescriptorContainsAddress { | |
133 const uint64_t Address; | |
134 public: | |
135 DescriptorContainsAddress(uint64_t address) : Address(address) {} | |
136 bool operator()(const DWARFDebugArangeSet::Descriptor &desc) const { | |
137 return Address >= desc.Address && Address < (desc.Address + desc.Length); | |
138 } | |
139 }; | |
140 } | |
141 | |
142 uint32_t DWARFDebugArangeSet::findAddress(uint64_t address) const { | |
143 DescriptorConstIter end = ArangeDescriptors.end(); | |
144 DescriptorConstIter pos = | |
145 std::find_if(ArangeDescriptors.begin(), end, // Range | |
146 DescriptorContainsAddress(address)); // Predicate | |
147 if (pos != end) | |
148 return HeaderData.CuOffset; | |
149 | |
150 return -1U; | |
151 } |