@@ -28,11 +28,10 @@ using namespace llvm;
2828// expression that LLVM doesn't produce. Guessing the wrong version means we
2929// won't be able to pretty print expressions in DWARF2 binaries produced by
3030// non-LLVM tools.
31- static void dumpExpression (raw_ostream &OS, ArrayRef<char > Data,
31+ static void dumpExpression (raw_ostream &OS, ArrayRef<uint8_t > Data,
3232 bool IsLittleEndian, unsigned AddressSize,
3333 const MCRegisterInfo *MRI, DWARFUnit *U) {
34- DWARFDataExtractor Extractor (StringRef (Data.data (), Data.size ()),
35- IsLittleEndian, AddressSize);
34+ DWARFDataExtractor Extractor (toStringRef (Data), IsLittleEndian, AddressSize);
3635 DWARFExpression (Extractor, dwarf::DWARF_VERSION, AddressSize).print (OS, MRI, U);
3736}
3837
@@ -83,47 +82,37 @@ void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
8382 }
8483}
8584
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) {
8888 LocationList LL;
8989 LL.Offset = *Offset;
90+ DataExtractor::Cursor C (*Offset);
9091
9192 // 2.6.2 Location Lists
9293 // A location list entry consists of:
9394 while (true ) {
9495 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- }
9996
10097 // 1. A beginning address offset. ...
101- E.Begin = Data.getRelocatedAddress (Offset );
98+ E.Begin = Data.getRelocatedAddress (C );
10299
103100 // 2. An ending address offset. ...
104- E.End = Data.getRelocatedAddress (Offset );
101+ E.End = Data.getRelocatedAddress (C );
105102
103+ if (Error Err = C.takeError ())
104+ return std::move (Err);
106105 // The end of any given location list is marked by an end of list entry,
107106 // which consists of a 0 for the beginning address offset and a 0 for the
108107 // ending address offset.
109- if (E.Begin == 0 && E.End == 0 )
108+ if (E.Begin == 0 && E.End == 0 ) {
109+ *Offset = C.tell ();
110110 return LL;
111-
112- if (!Data.isValidOffsetForDataOfSize (*Offset, 2 )) {
113- WithColor::error () << " location list overflows the debug_loc section.\n " ;
114- return None;
115111 }
116112
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);
122114 // 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);
127116 LL.Entries .push_back (std::move (E));
128117 }
129118}
@@ -133,67 +122,65 @@ void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
133122 AddressSize = data.getAddressSize ();
134123
135124 uint64_t Offset = 0 ;
136- while (data. isValidOffset ( Offset + data.getAddressSize () - 1 )) {
125+ while (Offset < data.getData (). size ( )) {
137126 if (auto LL = parseOneLocationList (data, &Offset))
138127 Locations.push_back (std::move (*LL));
139- else
128+ else {
129+ logAllUnhandledErrors (LL.takeError (), WithColor::error ());
140130 break ;
131+ }
141132 }
142- if (data.isValidOffset (Offset))
143- WithColor::error () << " failed to consume entire .debug_loc section\n " ;
144133}
145134
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) {
149138 LocationList LL;
150139 LL.Offset = *Offset;
140+ DataExtractor::Cursor C (*Offset);
151141
152142 // 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))) {
156144 Entry E;
157145 E.Kind = Kind;
158146 switch (Kind) {
159147 case dwarf::DW_LLE_startx_length:
160- E.Value0 = Data.getULEB128 (Offset );
148+ E.Value0 = Data.getULEB128 (C );
161149 // Pre-DWARF 5 has different interpretation of the length field. We have
162150 // to support both pre- and standartized styles for the compatibility.
163151 if (Version < 5 )
164- E.Value1 = Data.getU32 (Offset );
152+ E.Value1 = Data.getU32 (C );
165153 else
166- E.Value1 = Data.getULEB128 (Offset );
154+ E.Value1 = Data.getULEB128 (C );
167155 break ;
168156 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 );
171159 break ;
172160 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 );
175163 break ;
176164 case dwarf::DW_LLE_base_address:
177- E.Value0 = Data.getAddress (Offset );
165+ E.Value0 = Data.getAddress (C );
178166 break ;
179167 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) ;
183171 }
184172
185173 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);
188175 // 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);
193177 }
194178
195179 LL.Entries .push_back (std::move (E));
196180 }
181+ if (Error Err = C.takeError ())
182+ return std::move (Err);
183+ *Offset = C.tell ();
197184 return LL;
198185}
199186
@@ -202,11 +189,13 @@ void DWARFDebugLoclists::parse(DataExtractor data, unsigned Version) {
202189 AddressSize = data.getAddressSize ();
203190
204191 uint64_t Offset = 0 ;
205- while (data.isValidOffset (Offset )) {
192+ while (Offset < data.getData (). size ( )) {
206193 if (auto LL = parseOneLocationList (data, &Offset, Version))
207194 Locations.push_back (std::move (*LL));
208- else
195+ else {
196+ logAllUnhandledErrors (LL.takeError (), WithColor::error ());
209197 return ;
198+ }
210199 }
211200}
212201
0 commit comments