diff options
Diffstat (limited to 'source/Symbol/UnwindTable.cpp')
| -rw-r--r-- | source/Symbol/UnwindTable.cpp | 110 | 
1 files changed, 61 insertions, 49 deletions
diff --git a/source/Symbol/UnwindTable.cpp b/source/Symbol/UnwindTable.cpp index 336f0c3e04a7..405d57754ea5 100644 --- a/source/Symbol/UnwindTable.cpp +++ b/source/Symbol/UnwindTable.cpp @@ -44,38 +44,64 @@ void UnwindTable::Initialize() {    if (m_initialized) // check again once we've acquired the lock      return; +  m_initialized = true;    SectionList *sl = m_object_file.GetSectionList(); -  if (sl) { -    SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true); -    if (sect.get()) { -      m_eh_frame_up.reset(new DWARFCallFrameInfo(m_object_file, sect, -                                                 eRegisterKindEHFrame, true)); -    } -    sect = sl->FindSectionByType(eSectionTypeCompactUnwind, true); -    if (sect.get()) { -      m_compact_unwind_up.reset(new CompactUnwindInfo(m_object_file, sect)); -    } -    sect = sl->FindSectionByType(eSectionTypeARMexidx, true); -    if (sect.get()) { -      SectionSP sect_extab = sl->FindSectionByType(eSectionTypeARMextab, true); -      if (sect_extab.get()) { -        m_arm_unwind_up.reset( -            new ArmUnwindInfo(m_object_file, sect, sect_extab)); -      } -    } +  if (!sl) +    return; + +  SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true); +  if (sect.get()) { +    m_eh_frame_up.reset( +        new DWARFCallFrameInfo(m_object_file, sect, DWARFCallFrameInfo::EH));    } -  m_initialized = true; +  sect = sl->FindSectionByType(eSectionTypeDWARFDebugFrame, true); +  if (sect) { +    m_debug_frame_up.reset( +        new DWARFCallFrameInfo(m_object_file, sect, DWARFCallFrameInfo::DWARF)); +  } + +  sect = sl->FindSectionByType(eSectionTypeCompactUnwind, true); +  if (sect) { +    m_compact_unwind_up.reset(new CompactUnwindInfo(m_object_file, sect)); +  } + +  sect = sl->FindSectionByType(eSectionTypeARMexidx, true); +  if (sect) { +    SectionSP sect_extab = sl->FindSectionByType(eSectionTypeARMextab, true); +    if (sect_extab.get()) { +      m_arm_unwind_up.reset(new ArmUnwindInfo(m_object_file, sect, sect_extab)); +    } +  }  }  UnwindTable::~UnwindTable() {} +llvm::Optional<AddressRange> UnwindTable::GetAddressRange(const Address &addr, +                                                          SymbolContext &sc) { +  AddressRange range; + +  // First check the symbol context +  if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, +                         false, range) && +      range.GetBaseAddress().IsValid()) +    return range; + +  // Does the eh_frame unwind info has a function bounds for this addr? +  if (m_eh_frame_up && m_eh_frame_up->GetAddressRange(addr, range)) +    return range; + +  // Try debug_frame as well +  if (m_debug_frame_up && m_debug_frame_up->GetAddressRange(addr, range)) +    return range; + +  return llvm::None; +} +  FuncUnwindersSP  UnwindTable::GetFuncUnwindersContainingAddress(const Address &addr,                                                 SymbolContext &sc) { -  FuncUnwindersSP no_unwind_found; -    Initialize();    std::lock_guard<std::mutex> guard(m_mutex); @@ -96,23 +122,14 @@ UnwindTable::GetFuncUnwindersContainingAddress(const Address &addr,        return pos->second;    } -  AddressRange range; -  if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, -                          false, range) || -      !range.GetBaseAddress().IsValid()) { -    // Does the eh_frame unwind info has a function bounds for this addr? -    if (m_eh_frame_up == nullptr || -        !m_eh_frame_up->GetAddressRange(addr, range)) { -      return no_unwind_found; -    } -  } +  auto range_or = GetAddressRange(addr, sc); +  if (!range_or) +    return nullptr; -  FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, range)); +  FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, *range_or));    m_unwinds.insert(insert_pos, -                   std::make_pair(range.GetBaseAddress().GetFileAddress(), +                   std::make_pair(range_or->GetBaseAddress().GetFileAddress(),                                    func_unwinder_sp)); -  //    StreamFile s(stdout, false); -  //    Dump (s);    return func_unwinder_sp;  } @@ -121,26 +138,16 @@ UnwindTable::GetFuncUnwindersContainingAddress(const Address &addr,  // UnwindTable.  This is intended for use by target modules show-unwind where we  // want to create  // new UnwindPlans, not re-use existing ones. -  FuncUnwindersSP  UnwindTable::GetUncachedFuncUnwindersContainingAddress(const Address &addr,                                                         SymbolContext &sc) { -  FuncUnwindersSP no_unwind_found;    Initialize(); -  AddressRange range; -  if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, -                          false, range) || -      !range.GetBaseAddress().IsValid()) { -    // Does the eh_frame unwind info has a function bounds for this addr? -    if (m_eh_frame_up == nullptr || -        !m_eh_frame_up->GetAddressRange(addr, range)) { -      return no_unwind_found; -    } -  } +  auto range_or = GetAddressRange(addr, sc); +  if (!range_or) +    return nullptr; -  FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, range)); -  return func_unwinder_sp; +  return std::make_shared<FuncUnwinders>(*this, *range_or);  }  void UnwindTable::Dump(Stream &s) { @@ -161,6 +168,11 @@ DWARFCallFrameInfo *UnwindTable::GetEHFrameInfo() {    return m_eh_frame_up.get();  } +DWARFCallFrameInfo *UnwindTable::GetDebugFrameInfo() { +  Initialize(); +  return m_debug_frame_up.get(); +} +  CompactUnwindInfo *UnwindTable::GetCompactUnwindInfo() {    Initialize();    return m_compact_unwind_up.get();  | 
