425 changes: 425 additions & 0 deletions lldb/source/Symbol/ArmUnwindInfo.cpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions lldb/source/Symbol/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_lldb_library(lldbSymbol
ArmUnwindInfo.cpp
Block.cpp
ClangASTContext.cpp
ClangASTImporter.cpp
Expand Down
43 changes: 38 additions & 5 deletions lldb/source/Symbol/FuncUnwinders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Address.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/ArmUnwindInfo.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/CompactUnwindInfo.h"
#include "lldb/Symbol/ObjectFile.h"
Expand Down Expand Up @@ -37,13 +38,15 @@ FuncUnwinders::FuncUnwinders (UnwindTable& unwind_table, AddressRange range) :
m_unwind_plan_eh_frame_sp (),
m_unwind_plan_eh_frame_augmented_sp (),
m_unwind_plan_compact_unwind (),
m_unwind_plan_arm_unwind_sp (),
m_unwind_plan_fast_sp (),
m_unwind_plan_arch_default_sp (),
m_unwind_plan_arch_default_at_func_entry_sp (),
m_tried_unwind_plan_assembly (false),
m_tried_unwind_plan_eh_frame (false),
m_tried_unwind_plan_eh_frame_augmented (false),
m_tried_unwind_plan_compact_unwind (false),
m_tried_unwind_plan_arm_unwind (false),
m_tried_unwind_fast (false),
m_tried_unwind_arch_default (false),
m_tried_unwind_arch_default_at_func_entry (false),
Expand All @@ -65,12 +68,18 @@ FuncUnwinders::GetUnwindPlanAtCallSite (Target &target, int current_offset)
Mutex::Locker locker (m_mutex);

UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan (target, current_offset);
if (unwind_plan_sp.get() == nullptr)
{
unwind_plan_sp = GetCompactUnwindUnwindPlan (target, current_offset);
}
if (unwind_plan_sp)
return unwind_plan_sp;

unwind_plan_sp = GetCompactUnwindUnwindPlan (target, current_offset);
if (unwind_plan_sp)
return unwind_plan_sp;

unwind_plan_sp = GetArmUnwindUnwindPlan (target, current_offset);
if (unwind_plan_sp)
return unwind_plan_sp;

return unwind_plan_sp;
return nullptr;
}

UnwindPlanSP
Expand Down Expand Up @@ -126,6 +135,30 @@ FuncUnwinders::GetEHFrameUnwindPlan (Target &target, int current_offset)
return m_unwind_plan_eh_frame_sp;
}

UnwindPlanSP
FuncUnwinders::GetArmUnwindUnwindPlan (Target &target, int current_offset)
{
if (m_unwind_plan_arm_unwind_sp.get() || m_tried_unwind_plan_arm_unwind)
return m_unwind_plan_arm_unwind_sp;

Mutex::Locker lock (m_mutex);
m_tried_unwind_plan_arm_unwind = true;
if (m_range.GetBaseAddress().IsValid())
{
Address current_pc (m_range.GetBaseAddress ());
if (current_offset != -1)
current_pc.SetOffset (current_pc.GetOffset() + current_offset);
ArmUnwindInfo *arm_unwind_info = m_unwind_table.GetArmUnwindInfo();
if (arm_unwind_info)
{
m_unwind_plan_arm_unwind_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
if (!arm_unwind_info->GetUnwindPlan (target, current_pc, *m_unwind_plan_arm_unwind_sp))
m_unwind_plan_arm_unwind_sp.reset();
}
}
return m_unwind_plan_arm_unwind_sp;
}

UnwindPlanSP
FuncUnwinders::GetEHFrameAugmentedUnwindPlan (Target &target, Thread &thread, int current_offset)
{
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Symbol/ObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ ObjectFile::GetAddressClass (addr_t file_addr)
case eSectionTypeDWARFAppleObjC:
return eAddressClassDebug;
case eSectionTypeEHFrame:
case eSectionTypeARMexidx:
case eSectionTypeARMextab:
case eSectionTypeCompactUnwind:
return eAddressClassRuntime;
case eSectionTypeELFSymbolTable:
Expand Down
36 changes: 26 additions & 10 deletions lldb/source/Symbol/UnwindTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/ArmUnwindInfo.h"
#include "lldb/Symbol/CompactUnwindInfo.h"

// There is one UnwindTable object per ObjectFile.
Expand All @@ -31,8 +32,9 @@ UnwindTable::UnwindTable (ObjectFile& objfile) :
m_unwinds (),
m_initialized (false),
m_mutex (),
m_eh_frame (nullptr),
m_compact_unwind (nullptr)
m_eh_frame_up (),
m_compact_unwind_up (),
m_arm_unwind_up ()
{
}

Expand All @@ -56,12 +58,21 @@ UnwindTable::Initialize ()
SectionSP sect = sl->FindSectionByType (eSectionTypeEHFrame, true);
if (sect.get())
{
m_eh_frame = new DWARFCallFrameInfo(m_object_file, sect, eRegisterKindEHFrame, true);
m_eh_frame_up.reset(new DWARFCallFrameInfo(m_object_file, sect, eRegisterKindEHFrame, true));
}
sect = sl->FindSectionByType (eSectionTypeCompactUnwind, true);
if (sect.get())
{
m_compact_unwind = new CompactUnwindInfo(m_object_file, sect);
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));
}
}
}

Expand All @@ -70,8 +81,6 @@ UnwindTable::Initialize ()

UnwindTable::~UnwindTable ()
{
if (m_eh_frame)
delete m_eh_frame;
}

FuncUnwindersSP
Expand Down Expand Up @@ -102,7 +111,7 @@ UnwindTable::GetFuncUnwindersContainingAddress (const Address& addr, SymbolConte
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 == nullptr || !m_eh_frame->GetAddressRange (addr, range))
if (m_eh_frame_up == nullptr || !m_eh_frame_up->GetAddressRange (addr, range))
{
return no_unwind_found;
}
Expand All @@ -129,7 +138,7 @@ UnwindTable::GetUncachedFuncUnwindersContainingAddress (const Address& addr, Sym
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 == nullptr || !m_eh_frame->GetAddressRange (addr, range))
if (m_eh_frame_up == nullptr || !m_eh_frame_up->GetAddressRange (addr, range))
{
return no_unwind_found;
}
Expand Down Expand Up @@ -158,14 +167,21 @@ DWARFCallFrameInfo *
UnwindTable::GetEHFrameInfo ()
{
Initialize();
return m_eh_frame;
return m_eh_frame_up.get();
}

CompactUnwindInfo *
UnwindTable::GetCompactUnwindInfo ()
{
Initialize();
return m_compact_unwind;
return m_compact_unwind_up.get();
}

ArmUnwindInfo *
UnwindTable::GetArmUnwindInfo ()
{
Initialize();
return m_arm_unwind_up.get();
}

bool
Expand Down
4 changes: 4 additions & 0 deletions lldb/source/Utility/ConvertEnum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ lldb_private::GetSectionTypeAsCString(lldb::SectionType sect_type)
return "apple-objc";
case eSectionTypeEHFrame:
return "eh-frame";
case eSectionTypeARMexidx:
return "ARM.exidx";
case eSectionTypeARMextab:
return "ARM.extab";
case eSectionTypeCompactUnwind:
return "compact-unwind";
case eSectionTypeGoSymtab:
Expand Down