19
19
#include " llvm/Support/Compiler.h"
20
20
#include " llvm/Support/DataExtractor.h"
21
21
#include " llvm/Support/Errc.h"
22
+ #include " llvm/Support/Error.h"
22
23
#include " llvm/Support/ErrorHandling.h"
23
24
#include " llvm/Support/Format.h"
24
25
#include " llvm/Support/raw_ostream.h"
@@ -204,7 +205,7 @@ raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, const UnwindTable &Rows) {
204
205
return OS;
205
206
}
206
207
207
- Expected<UnwindTable> UnwindTable::create (const FDE *Fde) {
208
+ Expected<UnwindTable> llvm::dwarf::createUnwindTable (const FDE *Fde) {
208
209
const CIE *Cie = Fde->getLinkedCIE ();
209
210
if (Cie == nullptr )
210
211
return createStringError (errc::invalid_argument,
@@ -213,46 +214,56 @@ Expected<UnwindTable> UnwindTable::create(const FDE *Fde) {
213
214
214
215
// Rows will be empty if there are no CFI instructions.
215
216
if (Cie->cfis ().empty () && Fde->cfis ().empty ())
216
- return UnwindTable ();
217
+ return UnwindTable ({} );
217
218
218
- UnwindTable UT ;
219
+ UnwindTable::RowContainer CieRows ;
219
220
UnwindRow Row;
220
221
Row.setAddress (Fde->getInitialLocation ());
221
- UT.EndAddress = Fde->getInitialLocation () + Fde->getAddressRange ();
222
- if (Error CieError = UT.parseRows (Cie->cfis (), Row, nullptr ))
222
+ if (Error CieError = parseRows (Cie->cfis (), Row, nullptr ).moveInto (CieRows))
223
223
return std::move (CieError);
224
224
// We need to save the initial locations of registers from the CIE parsing
225
225
// in case we run into DW_CFA_restore or DW_CFA_restore_extended opcodes.
226
+ UnwindTable::RowContainer FdeRows;
226
227
const RegisterLocations InitialLocs = Row.getRegisterLocations ();
227
- if (Error FdeError = UT.parseRows (Fde->cfis (), Row, &InitialLocs))
228
+ if (Error FdeError =
229
+ parseRows (Fde->cfis (), Row, &InitialLocs).moveInto (FdeRows))
228
230
return std::move (FdeError);
231
+
232
+ UnwindTable::RowContainer AllRows;
233
+ AllRows.insert (AllRows.end (), CieRows.begin (), CieRows.end ());
234
+ AllRows.insert (AllRows.end (), FdeRows.begin (), FdeRows.end ());
235
+
229
236
// May be all the CFI instructions were DW_CFA_nop amd Row becomes empty.
230
237
// Do not add that to the unwind table.
231
238
if (Row.getRegisterLocations ().hasLocations () ||
232
239
Row.getCFAValue ().getLocation () != UnwindLocation::Unspecified)
233
- UT. Rows .push_back (Row);
234
- return UT ;
240
+ AllRows .push_back (Row);
241
+ return UnwindTable ( std::move (AllRows)) ;
235
242
}
236
243
237
- Expected<UnwindTable> UnwindTable::create (const CIE *Cie) {
244
+ Expected<UnwindTable> llvm::dwarf::createUnwindTable (const CIE *Cie) {
238
245
// Rows will be empty if there are no CFI instructions.
239
246
if (Cie->cfis ().empty ())
240
- return UnwindTable ();
247
+ return UnwindTable ({} );
241
248
242
- UnwindTable UT ;
249
+ UnwindTable::RowContainer Rows ;
243
250
UnwindRow Row;
244
- if (Error CieError = UT. parseRows (Cie->cfis (), Row, nullptr ))
251
+ if (Error CieError = parseRows (Cie->cfis (), Row, nullptr ). moveInto (Rows ))
245
252
return std::move (CieError);
246
253
// May be all the CFI instructions were DW_CFA_nop amd Row becomes empty.
247
254
// Do not add that to the unwind table.
248
255
if (Row.getRegisterLocations ().hasLocations () ||
249
256
Row.getCFAValue ().getLocation () != UnwindLocation::Unspecified)
250
- UT. Rows .push_back (Row);
251
- return UT ;
257
+ Rows.push_back (Row);
258
+ return UnwindTable ( std::move (Rows)) ;
252
259
}
253
260
254
- Error UnwindTable::parseRows (const CFIProgram &CFIP, UnwindRow &Row,
255
- const RegisterLocations *InitialLocs) {
261
+ Expected<UnwindTable::RowContainer>
262
+ llvm::dwarf::parseRows (const CFIProgram &CFIP, UnwindRow &Row,
263
+ const RegisterLocations *InitialLocs) {
264
+ // All the unwinding rows parsed during processing of the CFI program.
265
+ UnwindTable::RowContainer Rows;
266
+
256
267
// State consists of CFA value and register locations.
257
268
std::vector<std::pair<UnwindLocation, RegisterLocations>> States;
258
269
for (const CFIProgram::Instruction &Inst : CFIP) {
@@ -554,7 +565,7 @@ Error UnwindTable::parseRows(const CFIProgram &CFIP, UnwindRow &Row,
554
565
break ;
555
566
}
556
567
}
557
- return Error::success () ;
568
+ return Rows ;
558
569
}
559
570
560
571
// Returns the CIE identifier to be used by the requested format.
@@ -607,7 +618,7 @@ void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
607
618
/* InitialLocation=*/ {});
608
619
OS << " \n " ;
609
620
610
- if (Expected<UnwindTable> RowsOrErr = UnwindTable::create (this ))
621
+ if (Expected<UnwindTable> RowsOrErr = createUnwindTable (this ))
611
622
RowsOrErr->dump (OS, DumpOpts, 1 );
612
623
else {
613
624
DumpOpts.RecoverableErrorHandler (joinErrors (
@@ -635,7 +646,7 @@ void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
635
646
printCFIProgram (CFIs, OS, DumpOpts, /* IndentLevel=*/ 1 , InitialLocation);
636
647
OS << " \n " ;
637
648
638
- if (Expected<UnwindTable> RowsOrErr = UnwindTable::create (this ))
649
+ if (Expected<UnwindTable> RowsOrErr = createUnwindTable (this ))
639
650
RowsOrErr->dump (OS, DumpOpts, 1 );
640
651
else {
641
652
DumpOpts.RecoverableErrorHandler (joinErrors (
0 commit comments