blob: 5356e9493e4b94260780c6ee15755028599d39b8 [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
80 // Create a FuncUnwinders object for the binary search below
81 AddressRange search_range(addr, 1);
82 FuncUnwindersSP search_unwind(new FuncUnwinders (*this, NULL, search_range));
83
84 const_iterator idx;
85 idx = std::lower_bound (m_unwinds.begin(), m_unwinds.end(), search_unwind);
86
87 bool found_match = true;
88 if (m_unwinds.size() == 0)
89 {
90 found_match = false;
91 }
92 else if (idx == m_unwinds.end())
93 {
94 --idx;
95 }
96 if (idx != m_unwinds.begin() && (*idx)->GetFunctionStartAddress().GetOffset() != addr.GetOffset())
97 {
98 --idx;
99 }
100 if (found_match && (*idx)->ContainsAddress (addr))
101 {
102 return *idx;
103 }
104
105 AddressRange range;
Jason Molenda800d11d2010-11-04 00:53:20 +0000106 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range) || !range.GetBaseAddress().IsValid())
Jason Molenda3a4ea242010-09-10 07:49:16 +0000107 {
Jason Molenda800d11d2010-11-04 00:53:20 +0000108 // Does the eh_frame unwind info has a function bounds for this addr?
Jason Molendad6ef16a2010-11-09 01:21:22 +0000109 if (m_eh_frame == NULL || !m_eh_frame->GetAddressRange (addr, range))
Jason Molenda3a4ea242010-09-10 07:49:16 +0000110 {
Jason Molenda800d11d2010-11-04 00:53:20 +0000111 return no_unwind_found;
Jason Molenda3a4ea242010-09-10 07:49:16 +0000112 }
113 }
Jason Molenda800d11d2010-11-04 00:53:20 +0000114
115 FuncUnwindersSP unw(new FuncUnwinders(*this, m_assembly_profiler, range));
116 m_unwinds.push_back (unw);
117 std::sort (m_unwinds.begin(), m_unwinds.end());
118 return unw;
Jason Molenda3a4ea242010-09-10 07:49:16 +0000119}
120
121DWARFCallFrameInfo *
122UnwindTable::GetEHFrameInfo ()
123{
124 initialize();
125 return m_eh_frame;
126}