blob: 7738cba83f6a1c7ba59f12ff0dde9da55d9a1e68 [file] [log] [blame]
Jason Molenda3a4ea242010-09-10 07:49:16 +00001//===-- UnwindTable.cpp ----------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Greg Clayton412440a2010-09-23 01:09:21 +000010#include "lldb/Symbol/UnwindTable.h"
Jason Molenda3a4ea242010-09-10 07:49:16 +000011
Greg Clayton412440a2010-09-23 01:09:21 +000012#include <stdio.h>
13
14#include "lldb/lldb-forward.h"
15
16#include "lldb/Core/Module.h"
17#include "lldb/Core/Section.h"
18#include "lldb/Symbol/ObjectFile.h"
Jason Molenda3a4ea242010-09-10 07:49:16 +000019#include "lldb/Symbol/FuncUnwinders.h"
20#include "lldb/Symbol/SymbolContext.h"
Jason Molenda3a4ea242010-09-10 07:49:16 +000021#include "lldb/Symbol/DWARFCallFrameInfo.h"
Greg Clayton412440a2010-09-23 01:09:21 +000022#include "lldb/Utility/UnwindAssemblyProfiler.h"
Jason Molenda3a4ea242010-09-10 07:49:16 +000023
24// There is one UnwindTable object per ObjectFile.
25// It contains a list of Unwind objects -- one per function, populated lazily -- for the ObjectFile.
26// Each Unwind object has multiple UnwindPlans for different scenarios.
27
28using namespace lldb;
29using namespace lldb_private;
30
31UnwindTable::UnwindTable (ObjectFile& objfile) : m_object_file(objfile),
32 m_unwinds(),
33 m_initialized(false),
34 m_eh_frame(NULL),
35 m_assembly_profiler(NULL)
36{
37}
38
39// We can't do some of this initialization when the ObjectFile is running its ctor; delay doing it
40// until needed for something.
41
42void
43UnwindTable::initialize ()
44{
45 if (m_initialized)
46 return;
47
48 SectionList* sl = m_object_file.GetSectionList ();
49 if (sl)
50 {
51 SectionSP sect = sl->FindSectionByType (eSectionTypeEHFrame, true);
52 if (sect.get())
53 {
54 m_eh_frame = new DWARFCallFrameInfo(m_object_file, sect, eRegisterKindGCC, true);
55 }
56 }
57
58 ArchSpec arch;
59 ConstString str;
60 m_object_file.GetTargetTriple (str);
61 arch.SetArchFromTargetTriple (str.GetCString());
62 m_assembly_profiler = UnwindAssemblyProfiler::FindPlugin (arch);
63
64 m_initialized = true;
65}
66
67UnwindTable::~UnwindTable ()
68{
69 if (m_eh_frame)
70 delete m_eh_frame;
71}
72
73FuncUnwindersSP
74UnwindTable::GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc)
75{
76 FuncUnwindersSP no_unwind_found;
77
78 initialize();
79
Jason Molenda800d11d2010-11-04 00:53:20 +000080 if (m_eh_frame == NULL)
81 {
82 return no_unwind_found;
83 }
84
Jason Molenda3a4ea242010-09-10 07:49:16 +000085 // Create a FuncUnwinders object for the binary search below
86 AddressRange search_range(addr, 1);
87 FuncUnwindersSP search_unwind(new FuncUnwinders (*this, NULL, search_range));
88
89 const_iterator idx;
90 idx = std::lower_bound (m_unwinds.begin(), m_unwinds.end(), search_unwind);
91
92 bool found_match = true;
93 if (m_unwinds.size() == 0)
94 {
95 found_match = false;
96 }
97 else if (idx == m_unwinds.end())
98 {
99 --idx;
100 }
101 if (idx != m_unwinds.begin() && (*idx)->GetFunctionStartAddress().GetOffset() != addr.GetOffset())
102 {
103 --idx;
104 }
105 if (found_match && (*idx)->ContainsAddress (addr))
106 {
107 return *idx;
108 }
109
110 AddressRange range;
Jason Molenda800d11d2010-11-04 00:53:20 +0000111 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range) || !range.GetBaseAddress().IsValid())
Jason Molenda3a4ea242010-09-10 07:49:16 +0000112 {
Jason Molenda800d11d2010-11-04 00:53:20 +0000113 // Does the eh_frame unwind info has a function bounds for this addr?
114 if (!m_eh_frame->GetAddressRange (addr, range))
Jason Molenda3a4ea242010-09-10 07:49:16 +0000115 {
Jason Molenda800d11d2010-11-04 00:53:20 +0000116 return no_unwind_found;
Jason Molenda3a4ea242010-09-10 07:49:16 +0000117 }
118 }
Jason Molenda800d11d2010-11-04 00:53:20 +0000119
120 FuncUnwindersSP unw(new FuncUnwinders(*this, m_assembly_profiler, range));
121 m_unwinds.push_back (unw);
122 std::sort (m_unwinds.begin(), m_unwinds.end());
123 return unw;
Jason Molenda3a4ea242010-09-10 07:49:16 +0000124}
125
126DWARFCallFrameInfo *
127UnwindTable::GetEHFrameInfo ()
128{
129 initialize();
130 return m_eh_frame;
131}