1515#include " lldb/Utility/ConstString.h"
1616#include " lldb/Utility/LLDBLog.h"
1717#include " lldb/Utility/Log.h"
18+ #include " llvm/ADT/STLExtras.h"
1819#include " llvm/DebugInfo/DIContext.h"
1920#include " llvm/DebugInfo/DWARF/DWARFExpression.h"
2021#include < optional>
@@ -397,36 +398,35 @@ void UnwindPlan::AppendRow(const UnwindPlan::RowSP &row_sp) {
397398 m_row_list.back () = row_sp;
398399}
399400
401+ struct RowLess {
402+ bool operator ()(addr_t a, const UnwindPlan::RowSP &b) const {
403+ return a < b->GetOffset ();
404+ }
405+ bool operator ()(const UnwindPlan::RowSP &a, addr_t b) const {
406+ return a->GetOffset () < b;
407+ }
408+ };
409+
400410void UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp,
401411 bool replace_existing) {
402- collection::iterator it = m_row_list.begin ();
403- while (it != m_row_list.end ()) {
404- RowSP row = *it;
405- if (row->GetOffset () >= row_sp->GetOffset ())
406- break ;
407- it++;
408- }
409- if (it == m_row_list.end () || (*it)->GetOffset () != row_sp->GetOffset ())
412+ auto it = llvm::lower_bound (m_row_list, row_sp->GetOffset (), RowLess ());
413+ if (it == m_row_list.end () || it->get ()->GetOffset () > row_sp->GetOffset ())
410414 m_row_list.insert (it, row_sp);
411- else if (replace_existing)
412- *it = row_sp;
415+ else {
416+ assert (it->get ()->GetOffset () == row_sp->GetOffset ());
417+ if (replace_existing)
418+ *it = row_sp;
419+ }
413420}
414421
415422const UnwindPlan::Row *UnwindPlan::GetRowForFunctionOffset (int offset) const {
416- if (m_row_list.empty ())
423+ auto it = offset == -1 ? m_row_list.end ()
424+ : llvm::upper_bound (m_row_list, offset, RowLess ());
425+ if (it == m_row_list.begin ())
417426 return nullptr ;
418- if (offset == -1 )
419- return m_row_list.back ().get ();
420-
421- RowSP row;
422- collection::const_iterator pos, end = m_row_list.end ();
423- for (pos = m_row_list.begin (); pos != end; ++pos) {
424- if ((*pos)->GetOffset () <= static_cast <lldb::offset_t >(offset))
425- row = *pos;
426- else
427- break ;
428- }
429- return row.get ();
427+ // upper_bound returns the row strictly greater than our desired offset, which
428+ // means that the row before it is a match.
429+ return std::prev (it)->get ();
430430}
431431
432432bool UnwindPlan::IsValidRowIndex (uint32_t idx) const {
@@ -445,20 +445,13 @@ const UnwindPlan::Row *UnwindPlan::GetRowAtIndex(uint32_t idx) const {
445445
446446const UnwindPlan::Row *UnwindPlan::GetLastRow () const {
447447 if (m_row_list.empty ()) {
448- Log *log = GetLog (LLDBLog::Unwind);
449- LLDB_LOGF (log, " UnwindPlan::GetLastRow() when rows are empty" );
448+ LLDB_LOG ( GetLog (LLDBLog::Unwind),
449+ " UnwindPlan::GetLastRow() when rows are empty" );
450450 return nullptr ;
451451 }
452452 return m_row_list.back ().get ();
453453}
454454
455- int UnwindPlan::GetRowCount () const { return m_row_list.size (); }
456-
457- void UnwindPlan::SetPlanValidAddressRange (const AddressRange &range) {
458- if (range.GetBaseAddress ().IsValid () && range.GetByteSize () != 0 )
459- m_plan_valid_address_range = range;
460- }
461-
462455bool UnwindPlan::PlanValidAtAddress (Address addr) {
463456 // If this UnwindPlan has no rows, it is an invalid UnwindPlan.
464457 if (GetRowCount () == 0 ) {
@@ -482,9 +475,9 @@ bool UnwindPlan::PlanValidAtAddress(Address addr) {
482475 // If the 0th Row of unwind instructions is missing, or if it doesn't provide
483476 // a register to use to find the Canonical Frame Address, this is not a valid
484477 // UnwindPlan.
485- if ( GetRowAtIndex ( 0 ) == nullptr ||
486- GetRowAtIndex ( 0 )-> GetCFAValue (). GetValueType () ==
487- Row::FAValue::unspecified) {
478+ const Row *row0 = GetRowForFunctionOffset ( 0 );
479+ if (!row0 ||
480+ row0-> GetCFAValue (). GetValueType () == Row::FAValue::unspecified) {
488481 Log *log = GetLog (LLDBLog::Unwind);
489482 if (log) {
490483 StreamString s;
@@ -503,17 +496,15 @@ bool UnwindPlan::PlanValidAtAddress(Address addr) {
503496 return false ;
504497 }
505498
506- if (!m_plan_valid_address_range.GetBaseAddress ().IsValid () ||
507- m_plan_valid_address_range.GetByteSize () == 0 )
499+ if (m_plan_valid_ranges.empty ())
508500 return true ;
509501
510502 if (!addr.IsValid ())
511503 return true ;
512504
513- if (m_plan_valid_address_range.ContainsFileAddress (addr))
514- return true ;
515-
516- return false ;
505+ return llvm::any_of (m_plan_valid_ranges, [&](const AddressRange &range) {
506+ return range.ContainsFileAddress (addr);
507+ });
517508}
518509
519510void UnwindPlan::Dump (Stream &s, Thread *thread, lldb::addr_t base_addr) const {
@@ -570,20 +561,17 @@ void UnwindPlan::Dump(Stream &s, Thread *thread, lldb::addr_t base_addr) const {
570561 s.Printf (" not specified.\n " );
571562 break ;
572563 }
573- if (m_plan_valid_address_range.GetBaseAddress ().IsValid () &&
574- m_plan_valid_address_range.GetByteSize () > 0 ) {
564+ if (!m_plan_valid_ranges.empty ()) {
575565 s.PutCString (" Address range of this UnwindPlan: " );
576566 TargetSP target_sp (thread->CalculateTarget ());
577- m_plan_valid_address_range. Dump (&s, target_sp. get (),
578- Address::DumpStyleSectionNameOffset);
567+ for ( const AddressRange &range : m_plan_valid_ranges)
568+ range. Dump (&s, target_sp. get (), Address::DumpStyleSectionNameOffset);
579569 s.EOL ();
580570 }
581- collection::const_iterator pos, begin = m_row_list.begin (),
582- end = m_row_list.end ();
583- for (pos = begin; pos != end; ++pos) {
584- s.Printf (" row[%u]: " , (uint32_t )std::distance (begin, pos));
585- (*pos)->Dump (s, this , thread, base_addr);
586- s.Printf (" \n " );
571+ for (const auto &[index, row_sp] : llvm::enumerate (m_row_list)) {
572+ s.Format (" row[{0}]: " , index);
573+ row_sp->Dump (s, this , thread, base_addr);
574+ s << " \n " ;
587575 }
588576}
589577
0 commit comments