@@ -28,11 +28,10 @@ using namespace llvm;
28
28
// expression that LLVM doesn't produce. Guessing the wrong version means we
29
29
// won't be able to pretty print expressions in DWARF2 binaries produced by
30
30
// non-LLVM tools.
31
- static void dumpExpression (raw_ostream &OS, ArrayRef<char > Data,
31
+ static void dumpExpression (raw_ostream &OS, ArrayRef<uint8_t > Data,
32
32
bool IsLittleEndian, unsigned AddressSize,
33
33
const MCRegisterInfo *MRI, DWARFUnit *U) {
34
- DWARFDataExtractor Extractor (StringRef (Data.data (), Data.size ()),
35
- IsLittleEndian, AddressSize);
34
+ DWARFDataExtractor Extractor (toStringRef (Data), IsLittleEndian, AddressSize);
36
35
DWARFExpression (Extractor, dwarf::DWARF_VERSION, AddressSize).print (OS, MRI, U);
37
36
}
38
37
@@ -83,47 +82,37 @@ void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
83
82
}
84
83
}
85
84
86
- Optional<DWARFDebugLoc::LocationList>
87
- DWARFDebugLoc::parseOneLocationList (DWARFDataExtractor Data, uint64_t *Offset) {
85
+ Expected<DWARFDebugLoc::LocationList>
86
+ DWARFDebugLoc::parseOneLocationList (const DWARFDataExtractor &Data,
87
+ uint64_t *Offset) {
88
88
LocationList LL;
89
89
LL.Offset = *Offset;
90
+ DataExtractor::Cursor C (*Offset);
90
91
91
92
// 2.6.2 Location Lists
92
93
// A location list entry consists of:
93
94
while (true ) {
94
95
Entry E;
95
- if (!Data.isValidOffsetForDataOfSize (*Offset, 2 * Data.getAddressSize ())) {
96
- WithColor::error () << " location list overflows the debug_loc section.\n " ;
97
- return None;
98
- }
99
96
100
97
// 1. A beginning address offset. ...
101
- E.Begin = Data.getRelocatedAddress (Offset );
98
+ E.Begin = Data.getRelocatedAddress (C );
102
99
103
100
// 2. An ending address offset. ...
104
- E.End = Data.getRelocatedAddress (Offset );
101
+ E.End = Data.getRelocatedAddress (C );
105
102
103
+ if (Error Err = C.takeError ())
104
+ return std::move (Err);
106
105
// The end of any given location list is marked by an end of list entry,
107
106
// which consists of a 0 for the beginning address offset and a 0 for the
108
107
// ending address offset.
109
- if (E.Begin == 0 && E.End == 0 )
108
+ if (E.Begin == 0 && E.End == 0 ) {
109
+ *Offset = C.tell ();
110
110
return LL;
111
-
112
- if (!Data.isValidOffsetForDataOfSize (*Offset, 2 )) {
113
- WithColor::error () << " location list overflows the debug_loc section.\n " ;
114
- return None;
115
111
}
116
112
117
- unsigned Bytes = Data.getU16 (Offset);
118
- if (!Data.isValidOffsetForDataOfSize (*Offset, Bytes)) {
119
- WithColor::error () << " location list overflows the debug_loc section.\n " ;
120
- return None;
121
- }
113
+ unsigned Bytes = Data.getU16 (C);
122
114
// A single location description describing the location of the object...
123
- StringRef str = Data.getData ().substr (*Offset, Bytes);
124
- *Offset += Bytes;
125
- E.Loc .reserve (str.size ());
126
- llvm::copy (str, std::back_inserter (E.Loc ));
115
+ Data.getU8 (C, E.Loc , Bytes);
127
116
LL.Entries .push_back (std::move (E));
128
117
}
129
118
}
@@ -133,67 +122,65 @@ void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
133
122
AddressSize = data.getAddressSize ();
134
123
135
124
uint64_t Offset = 0 ;
136
- while (data. isValidOffset ( Offset + data.getAddressSize () - 1 )) {
125
+ while (Offset < data.getData (). size ( )) {
137
126
if (auto LL = parseOneLocationList (data, &Offset))
138
127
Locations.push_back (std::move (*LL));
139
- else
128
+ else {
129
+ logAllUnhandledErrors (LL.takeError (), WithColor::error ());
140
130
break ;
131
+ }
141
132
}
142
- if (data.isValidOffset (Offset))
143
- WithColor::error () << " failed to consume entire .debug_loc section\n " ;
144
133
}
145
134
146
- Optional <DWARFDebugLoclists::LocationList>
147
- DWARFDebugLoclists::parseOneLocationList (DataExtractor Data, uint64_t *Offset ,
148
- unsigned Version) {
135
+ Expected <DWARFDebugLoclists::LocationList>
136
+ DWARFDebugLoclists::parseOneLocationList (const DataExtractor & Data,
137
+ uint64_t *Offset, unsigned Version) {
149
138
LocationList LL;
150
139
LL.Offset = *Offset;
140
+ DataExtractor::Cursor C (*Offset);
151
141
152
142
// dwarf::DW_LLE_end_of_list_entry is 0 and indicates the end of the list.
153
- while (auto Kind =
154
- static_cast <dwarf::LocationListEntry>(Data.getU8 (Offset))) {
155
-
143
+ while (auto Kind = static_cast <dwarf::LocationListEntry>(Data.getU8 (C))) {
156
144
Entry E;
157
145
E.Kind = Kind;
158
146
switch (Kind) {
159
147
case dwarf::DW_LLE_startx_length:
160
- E.Value0 = Data.getULEB128 (Offset );
148
+ E.Value0 = Data.getULEB128 (C );
161
149
// Pre-DWARF 5 has different interpretation of the length field. We have
162
150
// to support both pre- and standartized styles for the compatibility.
163
151
if (Version < 5 )
164
- E.Value1 = Data.getU32 (Offset );
152
+ E.Value1 = Data.getU32 (C );
165
153
else
166
- E.Value1 = Data.getULEB128 (Offset );
154
+ E.Value1 = Data.getULEB128 (C );
167
155
break ;
168
156
case dwarf::DW_LLE_start_length:
169
- E.Value0 = Data.getAddress (Offset );
170
- E.Value1 = Data.getULEB128 (Offset );
157
+ E.Value0 = Data.getAddress (C );
158
+ E.Value1 = Data.getULEB128 (C );
171
159
break ;
172
160
case dwarf::DW_LLE_offset_pair:
173
- E.Value0 = Data.getULEB128 (Offset );
174
- E.Value1 = Data.getULEB128 (Offset );
161
+ E.Value0 = Data.getULEB128 (C );
162
+ E.Value1 = Data.getULEB128 (C );
175
163
break ;
176
164
case dwarf::DW_LLE_base_address:
177
- E.Value0 = Data.getAddress (Offset );
165
+ E.Value0 = Data.getAddress (C );
178
166
break ;
179
167
default :
180
- WithColor::error () << " dumping support for LLE of kind " << ( int )Kind
181
- << " not implemented \n " ;
182
- return None ;
168
+ cantFail (C. takeError ());
169
+ return createStringError (errc::illegal_byte_sequence,
170
+ " LLE of kind %x not supported " , ( int )Kind) ;
183
171
}
184
172
185
173
if (Kind != dwarf::DW_LLE_base_address) {
186
- unsigned Bytes =
187
- Version >= 5 ? Data.getULEB128 (Offset) : Data.getU16 (Offset);
174
+ unsigned Bytes = Version >= 5 ? Data.getULEB128 (C) : Data.getU16 (C);
188
175
// A single location description describing the location of the object...
189
- StringRef str = Data.getData ().substr (*Offset, Bytes);
190
- *Offset += Bytes;
191
- E.Loc .resize (str.size ());
192
- llvm::copy (str, E.Loc .begin ());
176
+ Data.getU8 (C, E.Loc , Bytes);
193
177
}
194
178
195
179
LL.Entries .push_back (std::move (E));
196
180
}
181
+ if (Error Err = C.takeError ())
182
+ return std::move (Err);
183
+ *Offset = C.tell ();
197
184
return LL;
198
185
}
199
186
@@ -202,11 +189,13 @@ void DWARFDebugLoclists::parse(DataExtractor data, unsigned Version) {
202
189
AddressSize = data.getAddressSize ();
203
190
204
191
uint64_t Offset = 0 ;
205
- while (data.isValidOffset (Offset )) {
192
+ while (Offset < data.getData (). size ( )) {
206
193
if (auto LL = parseOneLocationList (data, &Offset, Version))
207
194
Locations.push_back (std::move (*LL));
208
- else
195
+ else {
196
+ logAllUnhandledErrors (LL.takeError (), WithColor::error ());
209
197
return ;
198
+ }
210
199
}
211
200
}
212
201
0 commit comments