1 //===-- FuncUnwinders.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 10 #include "lldb/Core/AddressRange.h" 11 #include "lldb/Core/Address.h" 12 #include "lldb/Symbol/FuncUnwinders.h" 13 #include "lldb/Symbol/DWARFCallFrameInfo.h" 14 #include "lldb/Symbol/ObjectFile.h" 15 #include "lldb/Symbol/UnwindPlan.h" 16 #include "lldb/Symbol/UnwindTable.h" 17 #include "lldb/Target/ABI.h" 18 #include "lldb/Target/ExecutionContext.h" 19 #include "lldb/Target/Process.h" 20 #include "lldb/Target/Thread.h" 21 #include "lldb/Target/Target.h" 22 #include "lldb/Target/UnwindAssembly.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 28 FuncUnwinders::FuncUnwinders 29 ( 30 UnwindTable& unwind_table, 31 AddressRange range 32 ) : 33 m_unwind_table(unwind_table), 34 m_range(range), 35 m_mutex (Mutex::eMutexTypeRecursive), 36 m_unwind_plan_call_site_sp (), 37 m_unwind_plan_non_call_site_sp (), 38 m_unwind_plan_fast_sp (), 39 m_unwind_plan_arch_default_sp (), 40 m_tried_unwind_at_call_site (false), 41 m_tried_unwind_at_non_call_site (false), 42 m_tried_unwind_fast (false), 43 m_tried_unwind_arch_default (false), 44 m_tried_unwind_arch_default_at_func_entry (false), 45 m_first_non_prologue_insn() 46 { 47 } 48 49 FuncUnwinders::~FuncUnwinders () 50 { 51 } 52 53 UnwindPlanSP 54 FuncUnwinders::GetUnwindPlanAtCallSite (int current_offset) 55 { 56 // Lock the mutex to ensure we can always give out the most appropriate 57 // information. We want to make sure if someone requests a call site unwind 58 // plan, that they get one and don't run into a race condition where one 59 // thread has started to create the unwind plan and has put it into 60 // m_unwind_plan_call_site_sp, and have another thread enter this function 61 // and return the partially filled in m_unwind_plan_call_site_sp pointer. 62 // We also want to make sure that we lock out other unwind plans from 63 // being accessed until this one is done creating itself in case someone 64 // had some code like: 65 // UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...) 66 // if (best_unwind_plan == NULL) 67 // best_unwind_plan = GetUnwindPlanAtNonCallSite (...) 68 Mutex::Locker locker (m_mutex); 69 if (m_tried_unwind_at_call_site == false && m_unwind_plan_call_site_sp.get() == nullptr) 70 { 71 m_tried_unwind_at_call_site = true; 72 // We have cases (e.g. with _sigtramp on Mac OS X) where the hand-written eh_frame unwind info for a 73 // function does not cover the entire range of the function and so the FDE only lists a subset of the 74 // address range. If we try to look up the unwind info by the starting address of the function 75 // (i.e. m_range.GetBaseAddress()) we may not find the eh_frame FDE. We need to use the actual byte offset 76 // into the function when looking it up. 77 78 if (m_range.GetBaseAddress().IsValid()) 79 { 80 Address current_pc (m_range.GetBaseAddress ()); 81 if (current_offset != -1) 82 current_pc.SetOffset (current_pc.GetOffset() + current_offset); 83 84 DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo(); 85 if (eh_frame) 86 { 87 m_unwind_plan_call_site_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); 88 if (!eh_frame->GetUnwindPlan (current_pc, *m_unwind_plan_call_site_sp)) 89 m_unwind_plan_call_site_sp.reset(); 90 } 91 } 92 } 93 return m_unwind_plan_call_site_sp; 94 } 95 96 UnwindPlanSP 97 FuncUnwinders::GetUnwindPlanAtNonCallSite (Target& target, Thread& thread, int current_offset) 98 { 99 // Lock the mutex to ensure we can always give out the most appropriate 100 // information. We want to make sure if someone requests an unwind 101 // plan, that they get one and don't run into a race condition where one 102 // thread has started to create the unwind plan and has put it into 103 // the unique pointer member variable, and have another thread enter this function 104 // and return the partially filled pointer contained in the unique pointer. 105 // We also want to make sure that we lock out other unwind plans from 106 // being accessed until this one is done creating itself in case someone 107 // had some code like: 108 // UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...) 109 // if (best_unwind_plan == NULL) 110 // best_unwind_plan = GetUnwindPlanAtNonCallSite (...) 111 Mutex::Locker locker (m_mutex); 112 if (m_tried_unwind_at_non_call_site == false && m_unwind_plan_non_call_site_sp.get() == nullptr) 113 { 114 UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler()); 115 if (assembly_profiler_sp) 116 { 117 if (target.GetArchitecture().GetCore() == ArchSpec::eCore_x86_32_i386 118 || target.GetArchitecture().GetCore() == ArchSpec::eCore_x86_64_x86_64 119 || target.GetArchitecture().GetCore() == ArchSpec::eCore_x86_64_x86_64h) 120 { 121 // For 0th frame on i386 & x86_64, we fetch eh_frame and try using assembly profiler 122 // to augment it into asynchronous unwind table. 123 GetUnwindPlanAtCallSite(current_offset); 124 if (m_unwind_plan_call_site_sp) { 125 UnwindPlan* plan = new UnwindPlan (*m_unwind_plan_call_site_sp); 126 if (assembly_profiler_sp->AugmentUnwindPlanFromCallSite (m_range, thread, *plan)) { 127 m_unwind_plan_non_call_site_sp.reset (plan); 128 return m_unwind_plan_non_call_site_sp; 129 } 130 } 131 } 132 133 m_unwind_plan_non_call_site_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); 134 if (!assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *m_unwind_plan_non_call_site_sp)) 135 m_unwind_plan_non_call_site_sp.reset(); 136 } 137 } 138 return m_unwind_plan_non_call_site_sp; 139 } 140 141 UnwindPlanSP 142 FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread) 143 { 144 // Lock the mutex to ensure we can always give out the most appropriate 145 // information. We want to make sure if someone requests an unwind 146 // plan, that they get one and don't run into a race condition where one 147 // thread has started to create the unwind plan and has put it into 148 // the unique pointer member variable, and have another thread enter this function 149 // and return the partially filled pointer contained in the unique pointer. 150 // We also want to make sure that we lock out other unwind plans from 151 // being accessed until this one is done creating itself in case someone 152 // had some code like: 153 // UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...) 154 // if (best_unwind_plan == NULL) 155 // best_unwind_plan = GetUnwindPlanAtNonCallSite (...) 156 Mutex::Locker locker (m_mutex); 157 if (m_tried_unwind_fast == false && m_unwind_plan_fast_sp.get() == nullptr) 158 { 159 m_tried_unwind_fast = true; 160 UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler()); 161 if (assembly_profiler_sp) 162 { 163 m_unwind_plan_fast_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); 164 if (!assembly_profiler_sp->GetFastUnwindPlan (m_range, thread, *m_unwind_plan_fast_sp)) 165 m_unwind_plan_fast_sp.reset(); 166 } 167 } 168 return m_unwind_plan_fast_sp; 169 } 170 171 UnwindPlanSP 172 FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread) 173 { 174 // Lock the mutex to ensure we can always give out the most appropriate 175 // information. We want to make sure if someone requests an unwind 176 // plan, that they get one and don't run into a race condition where one 177 // thread has started to create the unwind plan and has put it into 178 // the unique pointer member variable, and have another thread enter this function 179 // and return the partially filled pointer contained in the unique pointer. 180 // We also want to make sure that we lock out other unwind plans from 181 // being accessed until this one is done creating itself in case someone 182 // had some code like: 183 // UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...) 184 // if (best_unwind_plan == NULL) 185 // best_unwind_plan = GetUnwindPlanAtNonCallSite (...) 186 Mutex::Locker locker (m_mutex); 187 if (m_tried_unwind_arch_default == false && m_unwind_plan_arch_default_sp.get() == nullptr) 188 { 189 m_tried_unwind_arch_default = true; 190 Address current_pc; 191 ProcessSP process_sp (thread.CalculateProcess()); 192 if (process_sp) 193 { 194 ABI *abi = process_sp->GetABI().get(); 195 if (abi) 196 { 197 m_unwind_plan_arch_default_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); 198 if (m_unwind_plan_arch_default_sp) 199 abi->CreateDefaultUnwindPlan(*m_unwind_plan_arch_default_sp); 200 } 201 } 202 } 203 204 return m_unwind_plan_arch_default_sp; 205 } 206 207 UnwindPlanSP 208 FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry (Thread& thread) 209 { 210 // Lock the mutex to ensure we can always give out the most appropriate 211 // information. We want to make sure if someone requests an unwind 212 // plan, that they get one and don't run into a race condition where one 213 // thread has started to create the unwind plan and has put it into 214 // the unique pointer member variable, and have another thread enter this function 215 // and return the partially filled pointer contained in the unique pointer. 216 // We also want to make sure that we lock out other unwind plans from 217 // being accessed until this one is done creating itself in case someone 218 // had some code like: 219 // UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...) 220 // if (best_unwind_plan == NULL) 221 // best_unwind_plan = GetUnwindPlanAtNonCallSite (...) 222 Mutex::Locker locker (m_mutex); 223 if (m_tried_unwind_arch_default_at_func_entry == false && m_unwind_plan_arch_default_at_func_entry_sp.get() == nullptr) 224 { 225 m_tried_unwind_arch_default_at_func_entry = true; 226 Address current_pc; 227 ProcessSP process_sp (thread.CalculateProcess()); 228 if (process_sp) 229 { 230 ABI *abi = process_sp->GetABI().get(); 231 if (abi) 232 { 233 m_unwind_plan_arch_default_at_func_entry_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); 234 if (m_unwind_plan_arch_default_at_func_entry_sp) 235 abi->CreateFunctionEntryUnwindPlan(*m_unwind_plan_arch_default_at_func_entry_sp); 236 } 237 } 238 } 239 240 return m_unwind_plan_arch_default_at_func_entry_sp; 241 } 242 243 244 Address& 245 FuncUnwinders::GetFirstNonPrologueInsn (Target& target) 246 { 247 if (m_first_non_prologue_insn.IsValid()) 248 return m_first_non_prologue_insn; 249 ExecutionContext exe_ctx (target.shared_from_this(), false); 250 UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler()); 251 if (assembly_profiler_sp) 252 if (assembly_profiler_sp) 253 assembly_profiler_sp->FirstNonPrologueInsn (m_range, exe_ctx, m_first_non_prologue_insn); 254 return m_first_non_prologue_insn; 255 } 256 257 const Address& 258 FuncUnwinders::GetFunctionStartAddress () const 259 { 260 return m_range.GetBaseAddress(); 261 } 262 263 void 264 FuncUnwinders::InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& thread) 265 { 266 UnwindPlanSP arch_default = GetUnwindPlanArchitectureDefault (thread); 267 if (arch_default && m_tried_unwind_at_call_site) 268 { 269 m_unwind_plan_call_site_sp = arch_default; 270 } 271 } 272 273 lldb::UnwindAssemblySP 274 FuncUnwinders::GetUnwindAssemblyProfiler () 275 { 276 UnwindAssemblySP assembly_profiler_sp; 277 ArchSpec arch; 278 if (m_unwind_table.GetArchitecture (arch)) 279 { 280 assembly_profiler_sp = UnwindAssembly::FindPlugin (arch); 281 } 282 return assembly_profiler_sp; 283 } 284