LLDB  mainline
UnwindTable.cpp
Go to the documentation of this file.
1 //===-- UnwindTable.cpp ---------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include <cstdio>
12 
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/Section.h"
20 #include "lldb/Symbol/ObjectFile.h"
23 
24 // There is one UnwindTable object per ObjectFile. It contains a list of Unwind
25 // objects -- one per function, populated lazily -- for the ObjectFile. Each
26 // Unwind object has multiple UnwindPlans for different scenarios.
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 UnwindTable::UnwindTable(Module &module)
32  : m_module(module), m_unwinds(), m_initialized(false), m_mutex(),
33  m_object_file_unwind_up(), m_eh_frame_up(), m_compact_unwind_up(),
34  m_arm_unwind_up() {}
35 
36 // We can't do some of this initialization when the ObjectFile is running its
37 // ctor; delay doing it until needed for something.
38 
40  if (m_initialized)
41  return;
42 
43  std::lock_guard<std::mutex> guard(m_mutex);
44 
45  if (m_initialized) // check again once we've acquired the lock
46  return;
47  m_initialized = true;
48  ObjectFile *object_file = m_module.GetObjectFile();
49  if (!object_file)
50  return;
51 
53 
55  if (!sl)
56  return;
57 
58  SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true);
59  if (sect.get()) {
60  m_eh_frame_up = std::make_unique<DWARFCallFrameInfo>(
61  *object_file, sect, DWARFCallFrameInfo::EH);
62  }
63 
65  if (sect) {
66  m_debug_frame_up = std::make_unique<DWARFCallFrameInfo>(
67  *object_file, sect, DWARFCallFrameInfo::DWARF);
68  }
69 
71  if (sect) {
73  std::make_unique<CompactUnwindInfo>(*object_file, sect);
74  }
75 
76  sect = sl->FindSectionByType(eSectionTypeARMexidx, true);
77  if (sect) {
78  SectionSP sect_extab = sl->FindSectionByType(eSectionTypeARMextab, true);
79  if (sect_extab.get()) {
81  std::make_unique<ArmUnwindInfo>(*object_file, sect, sect_extab);
82  }
83  }
84 }
85 
86 UnwindTable::~UnwindTable() = default;
87 
88 llvm::Optional<AddressRange> UnwindTable::GetAddressRange(const Address &addr,
89  SymbolContext &sc) {
90  AddressRange range;
91 
92  // First check the unwind info from the object file plugin
94  m_object_file_unwind_up->GetAddressRange(addr, range))
95  return range;
96 
97  // Check the symbol context
98  if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
99  false, range) &&
100  range.GetBaseAddress().IsValid())
101  return range;
102 
103  // Does the eh_frame unwind info has a function bounds for this addr?
104  if (m_eh_frame_up && m_eh_frame_up->GetAddressRange(addr, range))
105  return range;
106 
107  // Try debug_frame as well
108  if (m_debug_frame_up && m_debug_frame_up->GetAddressRange(addr, range))
109  return range;
110 
111  return llvm::None;
112 }
113 
114 FuncUnwindersSP
116  SymbolContext &sc) {
117  Initialize();
118 
119  std::lock_guard<std::mutex> guard(m_mutex);
120 
121  // There is an UnwindTable per object file, so we can safely use file handles
122  addr_t file_addr = addr.GetFileAddress();
123  iterator end = m_unwinds.end();
124  iterator insert_pos = end;
125  if (!m_unwinds.empty()) {
126  insert_pos = m_unwinds.lower_bound(file_addr);
127  iterator pos = insert_pos;
128  if ((pos == m_unwinds.end()) ||
129  (pos != m_unwinds.begin() &&
130  pos->second->GetFunctionStartAddress() != addr))
131  --pos;
132 
133  if (pos->second->ContainsAddress(addr))
134  return pos->second;
135  }
136 
137  auto range_or = GetAddressRange(addr, sc);
138  if (!range_or)
139  return nullptr;
140 
141  FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, *range_or));
142  m_unwinds.insert(insert_pos,
143  std::make_pair(range_or->GetBaseAddress().GetFileAddress(),
144  func_unwinder_sp));
145  return func_unwinder_sp;
146 }
147 
148 // Ignore any existing FuncUnwinders for this function, create a new one and
149 // don't add it to the UnwindTable. This is intended for use by target modules
150 // show-unwind where we want to create new UnwindPlans, not re-use existing
151 // ones.
152 FuncUnwindersSP
154  SymbolContext &sc) {
155  Initialize();
156 
157  auto range_or = GetAddressRange(addr, sc);
158  if (!range_or)
159  return nullptr;
160 
161  return std::make_shared<FuncUnwinders>(*this, *range_or);
162 }
163 
165  std::lock_guard<std::mutex> guard(m_mutex);
166  s.Format("UnwindTable for '{0}':\n", m_module.GetFileSpec());
167  const_iterator begin = m_unwinds.begin();
168  const_iterator end = m_unwinds.end();
169  for (const_iterator pos = begin; pos != end; ++pos) {
170  s.Printf("[%u] 0x%16.16" PRIx64 "\n", (unsigned)std::distance(begin, pos),
171  pos->first);
172  }
173  s.EOL();
174 }
175 
177  Initialize();
178  return m_object_file_unwind_up.get();
179 }
180 
182  Initialize();
183  return m_eh_frame_up.get();
184 }
185 
187  Initialize();
188  return m_debug_frame_up.get();
189 }
190 
192  Initialize();
193  return m_compact_unwind_up.get();
194 }
195 
197  Initialize();
198  return m_arm_unwind_up.get();
199 }
200 
202 
204 
206  if (ObjectFile *object_file = m_module.GetObjectFile())
207  return object_file->AllowAssemblyEmulationUnwindPlans();
208  return false;
209 }
lldb_private::UnwindTable::GetSymbolFile
SymbolFile * GetSymbolFile()
Definition: UnwindTable.cpp:201
lldb_private::AddressRange::GetBaseAddress
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:209
lldb_private::Stream::Format
void Format(const char *format, Args &&... args)
Definition: Stream.h:309
lldb_private::UnwindTable::GetUncachedFuncUnwindersContainingAddress
lldb::FuncUnwindersSP GetUncachedFuncUnwindersContainingAddress(const Address &addr, SymbolContext &sc)
Definition: UnwindTable.cpp:153
lldb_private::Module::GetObjectFile
virtual ObjectFile * GetObjectFile()
Get the object file representation for the current architecture.
Definition: Module.cpp:1238
lldb_private::SymbolFile
Definition: SymbolFile.h:38
lldb_private::UnwindTable::GetEHFrameInfo
lldb_private::DWARFCallFrameInfo * GetEHFrameInfo()
Definition: UnwindTable.cpp:181
lldb_private::ArchSpec
Definition: ArchSpec.h:33
lldb_private::UnwindTable::GetDebugFrameInfo
lldb_private::DWARFCallFrameInfo * GetDebugFrameInfo()
Definition: UnwindTable.cpp:186
lldb_private::Address::IsValid
bool IsValid() const
Check if the object state is valid.
Definition: Address.h:336
lldb_private::UnwindTable::GetArchitecture
ArchSpec GetArchitecture()
Definition: UnwindTable.cpp:203
lldb_private::SymbolContext::GetAddressRange
bool GetAddressRange(uint32_t scope, uint32_t range_idx, bool use_inline_block_range, AddressRange &range) const
Get the address range contained within a symbol context.
Definition: SymbolContext.cpp:379
lldb_private::UnwindTable::const_iterator
collection::const_iterator const_iterator
Definition: UnwindTable.h:68
lldb_private::UnwindTable::GetAddressRange
llvm::Optional< AddressRange > GetAddressRange(const Address &addr, SymbolContext &sc)
Definition: UnwindTable.cpp:88
lldb_private::UnwindTable::Initialize
void Initialize()
Definition: UnwindTable.cpp:39
lldb::eSectionTypeDWARFDebugFrame
@ eSectionTypeDWARFDebugFrame
Definition: lldb-enumerations.h:667
Module.h
lldb_private::UnwindTable::m_module
Module & m_module
Definition: UnwindTable.h:70
lldb_private::ArmUnwindInfo
Definition: ArmUnwindInfo.h:30
lldb_private::Module::GetSymbolFile
virtual SymbolFile * GetSymbolFile(bool can_create=true, Stream *feedback_strm=nullptr)
Get the module's symbol file.
Definition: Module.cpp:1035
lldb_private::Module
Definition: Module.h:85
lldb_private::SectionList
Definition: Section.h:34
lldb_private::UnwindTable::GetAllowAssemblyEmulationUnwindPlans
bool GetAllowAssemblyEmulationUnwindPlans()
Definition: UnwindTable.cpp:205
lldb_private::Stream
Definition: Stream.h:28
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::UnwindTable::~UnwindTable
~UnwindTable()
lldb_private::SymbolContext
Definition: SymbolContext.h:33
Section.h
lldb_private::CompactUnwindInfo
Definition: CompactUnwindInfo.h:36
lldb_private::UnwindTable::m_mutex
std::mutex m_mutex
Definition: UnwindTable.h:74
lldb_private::Module::GetFileSpec
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition: Module.h:477
lldb_private::UnwindTable::iterator
collection::iterator iterator
Definition: UnwindTable.h:67
CompactUnwindInfo.h
lldb_private::FuncUnwinders
Definition: FuncUnwinders.h:13
lldb_private::UnwindTable::m_eh_frame_up
std::unique_ptr< DWARFCallFrameInfo > m_eh_frame_up
Definition: UnwindTable.h:77
lldb_private::DWARFCallFrameInfo::EH
@ EH
Definition: DWARFCallFrameInfo.h:35
lldb::eSectionTypeCompactUnwind
@ eSectionTypeCompactUnwind
compact unwind section in Mach-O, __TEXT,__unwind_info
Definition: lldb-enumerations.h:689
lldb_private::UnwindTable::m_arm_unwind_up
std::unique_ptr< ArmUnwindInfo > m_arm_unwind_up
Definition: UnwindTable.h:80
lldb_private::Address::GetFileAddress
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:290
ArmUnwindInfo.h
lldb_private::UnwindTable::GetCompactUnwindInfo
lldb_private::CompactUnwindInfo * GetCompactUnwindInfo()
Definition: UnwindTable.cpp:191
DWARFCallFrameInfo.h
UnwindTable.h
lldb_private::UnwindTable::m_debug_frame_up
std::unique_ptr< DWARFCallFrameInfo > m_debug_frame_up
Definition: UnwindTable.h:78
lldb_private::AddressRange
Definition: AddressRange.h:25
lldb_private::DWARFCallFrameInfo::DWARF
@ DWARF
Definition: DWARFCallFrameInfo.h:35
lldb_private::UnwindTable::m_initialized
bool m_initialized
Definition: UnwindTable.h:73
lldb_private::CallFrameInfo
Definition: CallFrameInfo.h:16
lldb_private::UnwindTable::GetObjectFileUnwindInfo
lldb_private::CallFrameInfo * GetObjectFileUnwindInfo()
Definition: UnwindTable.cpp:176
lldb_private::UnwindTable::GetArmUnwindInfo
ArmUnwindInfo * GetArmUnwindInfo()
Definition: UnwindTable.cpp:196
lldb_private::UnwindTable::GetFuncUnwindersContainingAddress
lldb::FuncUnwindersSP GetFuncUnwindersContainingAddress(const Address &addr, SymbolContext &sc)
Definition: UnwindTable.cpp:115
ObjectFile.h
lldb_private::Module::GetSectionList
virtual SectionList * GetSectionList()
Get the unified section list for the module.
Definition: Module.cpp:1277
FuncUnwinders.h
lldb_private::SectionList::FindSectionByType
lldb::SectionSP FindSectionByType(lldb::SectionType sect_type, bool check_children, size_t start_idx=0) const
Definition: Section.cpp:594
lldb::eSectionTypeEHFrame
@ eSectionTypeEHFrame
Definition: lldb-enumerations.h:686
lldb_private::Address
Definition: Address.h:59
lldb_private::Stream::EOL
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:128
lldb::eSectionTypeARMextab
@ eSectionTypeARMextab
Definition: lldb-enumerations.h:688
CallFrameInfo.h
lldb_private::DWARFCallFrameInfo
Definition: DWARFCallFrameInfo.h:33
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
SymbolContext.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::Module::GetArchitecture
const ArchSpec & GetArchitecture() const
Get const accessor for the module architecture.
Definition: Module.cpp:1066
SymbolVendor.h
lldb::eSectionTypeARMexidx
@ eSectionTypeARMexidx
Definition: lldb-enumerations.h:687
lldb_private::UnwindTable::m_compact_unwind_up
std::unique_ptr< CompactUnwindInfo > m_compact_unwind_up
Definition: UnwindTable.h:79
lldb_private::ObjectFile::CreateCallFrameInfo
virtual std::unique_ptr< CallFrameInfo > CreateCallFrameInfo()
Creates a plugin-specific call frame info.
Definition: ObjectFile.cpp:646
lldb
Definition: SBAddress.h:15
lldb_private::UnwindTable::Dump
void Dump(Stream &s)
Definition: UnwindTable.cpp:164
lldb_private::ObjectFile
Definition: ObjectFile.h:58
lldb_private::UnwindTable::m_unwinds
collection m_unwinds
Definition: UnwindTable.h:71
lldb_private::UnwindTable::m_object_file_unwind_up
std::unique_ptr< CallFrameInfo > m_object_file_unwind_up
Definition: UnwindTable.h:76