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/ArmUnwindInfo.h" 14 #include "lldb/Symbol/DWARFCallFrameInfo.h" 15 #include "lldb/Symbol/CompactUnwindInfo.h" 16 #include "lldb/Symbol/ObjectFile.h" 17 #include "lldb/Symbol/UnwindPlan.h" 18 #include "lldb/Symbol/UnwindTable.h" 19 #include "lldb/Target/ABI.h" 20 #include "lldb/Target/ExecutionContext.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/Thread.h" 23 #include "lldb/Target/Target.h" 24 #include "lldb/Target/UnwindAssembly.h" 25 26 using namespace lldb; 27 using namespace lldb_private; 28 29 //------------------------------------------------ 30 /// constructor 31 //------------------------------------------------ 32 33 FuncUnwinders::FuncUnwinders(UnwindTable &unwind_table, AddressRange range) 34 : m_unwind_table(unwind_table), 35 m_range(range), 36 m_mutex(), 37 m_unwind_plan_assembly_sp(), 38 m_unwind_plan_eh_frame_sp(), 39 m_unwind_plan_eh_frame_augmented_sp(), 40 m_unwind_plan_compact_unwind(), 41 m_unwind_plan_arm_unwind_sp(), 42 m_unwind_plan_fast_sp(), 43 m_unwind_plan_arch_default_sp(), 44 m_unwind_plan_arch_default_at_func_entry_sp(), 45 m_tried_unwind_plan_assembly(false), 46 m_tried_unwind_plan_eh_frame(false), 47 m_tried_unwind_plan_eh_frame_augmented(false), 48 m_tried_unwind_plan_compact_unwind(false), 49 m_tried_unwind_plan_arm_unwind(false), 50 m_tried_unwind_fast(false), 51 m_tried_unwind_arch_default(false), 52 m_tried_unwind_arch_default_at_func_entry(false), 53 m_first_non_prologue_insn() 54 { 55 } 56 57 //------------------------------------------------ 58 /// destructor 59 //------------------------------------------------ 60 61 FuncUnwinders::~FuncUnwinders () 62 { 63 } 64 65 UnwindPlanSP 66 FuncUnwinders::GetUnwindPlanAtCallSite (Target &target, int current_offset) 67 { 68 std::lock_guard<std::recursive_mutex> guard(m_mutex); 69 70 UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan (target, current_offset); 71 if (unwind_plan_sp) 72 return unwind_plan_sp; 73 74 unwind_plan_sp = GetCompactUnwindUnwindPlan (target, current_offset); 75 if (unwind_plan_sp) 76 return unwind_plan_sp; 77 78 unwind_plan_sp = GetArmUnwindUnwindPlan (target, current_offset); 79 if (unwind_plan_sp) 80 return unwind_plan_sp; 81 82 return nullptr; 83 } 84 85 UnwindPlanSP 86 FuncUnwinders::GetCompactUnwindUnwindPlan (Target &target, int current_offset) 87 { 88 if (m_unwind_plan_compact_unwind.size() > 0) 89 return m_unwind_plan_compact_unwind[0]; // FIXME support multiple compact unwind plans for one func 90 if (m_tried_unwind_plan_compact_unwind) 91 return UnwindPlanSP(); 92 93 std::lock_guard<std::recursive_mutex> guard(m_mutex); 94 m_tried_unwind_plan_compact_unwind = true; 95 if (m_range.GetBaseAddress().IsValid()) 96 { 97 Address current_pc (m_range.GetBaseAddress ()); 98 if (current_offset != -1) 99 current_pc.SetOffset (current_pc.GetOffset() + current_offset); 100 CompactUnwindInfo *compact_unwind = m_unwind_table.GetCompactUnwindInfo(); 101 if (compact_unwind) 102 { 103 UnwindPlanSP unwind_plan_sp (new UnwindPlan (lldb::eRegisterKindGeneric)); 104 if (compact_unwind->GetUnwindPlan (target, current_pc, *unwind_plan_sp)) 105 { 106 m_unwind_plan_compact_unwind.push_back (unwind_plan_sp); 107 return m_unwind_plan_compact_unwind[0]; // FIXME support multiple compact unwind plans for one func 108 } 109 } 110 } 111 return UnwindPlanSP(); 112 } 113 114 UnwindPlanSP 115 FuncUnwinders::GetEHFrameUnwindPlan (Target &target, int current_offset) 116 { 117 if (m_unwind_plan_eh_frame_sp.get() || m_tried_unwind_plan_eh_frame) 118 return m_unwind_plan_eh_frame_sp; 119 120 std::lock_guard<std::recursive_mutex> guard(m_mutex); 121 m_tried_unwind_plan_eh_frame = true; 122 if (m_range.GetBaseAddress().IsValid()) 123 { 124 Address current_pc (m_range.GetBaseAddress ()); 125 if (current_offset != -1) 126 current_pc.SetOffset (current_pc.GetOffset() + current_offset); 127 DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo(); 128 if (eh_frame) 129 { 130 m_unwind_plan_eh_frame_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); 131 if (!eh_frame->GetUnwindPlan (current_pc, *m_unwind_plan_eh_frame_sp)) 132 m_unwind_plan_eh_frame_sp.reset(); 133 } 134 } 135 return m_unwind_plan_eh_frame_sp; 136 } 137 138 UnwindPlanSP 139 FuncUnwinders::GetArmUnwindUnwindPlan (Target &target, int current_offset) 140 { 141 if (m_unwind_plan_arm_unwind_sp.get() || m_tried_unwind_plan_arm_unwind) 142 return m_unwind_plan_arm_unwind_sp; 143 144 std::lock_guard<std::recursive_mutex> guard(m_mutex); 145 m_tried_unwind_plan_arm_unwind = true; 146 if (m_range.GetBaseAddress().IsValid()) 147 { 148 Address current_pc (m_range.GetBaseAddress ()); 149 if (current_offset != -1) 150 current_pc.SetOffset (current_pc.GetOffset() + current_offset); 151 ArmUnwindInfo *arm_unwind_info = m_unwind_table.GetArmUnwindInfo(); 152 if (arm_unwind_info) 153 { 154 m_unwind_plan_arm_unwind_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); 155 if (!arm_unwind_info->GetUnwindPlan (target, current_pc, *m_unwind_plan_arm_unwind_sp)) 156 m_unwind_plan_arm_unwind_sp.reset(); 157 } 158 } 159 return m_unwind_plan_arm_unwind_sp; 160 } 161 162 UnwindPlanSP 163 FuncUnwinders::GetEHFrameAugmentedUnwindPlan (Target &target, Thread &thread, int current_offset) 164 { 165 if (m_unwind_plan_eh_frame_augmented_sp.get() || m_tried_unwind_plan_eh_frame_augmented) 166 return m_unwind_plan_eh_frame_augmented_sp; 167 168 // Only supported on x86 architectures where we get eh_frame from the compiler that describes 169 // the prologue instructions perfectly, and sometimes the epilogue instructions too. 170 if (target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_32_i386 171 && target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64 172 && target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64h) 173 { 174 m_tried_unwind_plan_eh_frame_augmented = true; 175 return m_unwind_plan_eh_frame_augmented_sp; 176 } 177 178 std::lock_guard<std::recursive_mutex> guard(m_mutex); 179 m_tried_unwind_plan_eh_frame_augmented = true; 180 181 UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan (target, current_offset); 182 if (!eh_frame_plan) 183 return m_unwind_plan_eh_frame_augmented_sp; 184 185 m_unwind_plan_eh_frame_augmented_sp.reset(new UnwindPlan(*eh_frame_plan)); 186 187 // Augment the eh_frame instructions with epilogue descriptions if necessary so the 188 // UnwindPlan can be used at any instruction in the function. 189 190 UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target)); 191 if (assembly_profiler_sp) 192 { 193 if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite (m_range, thread, *m_unwind_plan_eh_frame_augmented_sp)) 194 { 195 m_unwind_plan_eh_frame_augmented_sp.reset(); 196 } 197 } 198 else 199 { 200 m_unwind_plan_eh_frame_augmented_sp.reset(); 201 } 202 return m_unwind_plan_eh_frame_augmented_sp; 203 } 204 205 206 UnwindPlanSP 207 FuncUnwinders::GetAssemblyUnwindPlan (Target &target, Thread &thread, int current_offset) 208 { 209 if (m_unwind_plan_assembly_sp.get() 210 || m_tried_unwind_plan_assembly 211 || m_unwind_table.GetAllowAssemblyEmulationUnwindPlans () == false) 212 { 213 return m_unwind_plan_assembly_sp; 214 } 215 216 std::lock_guard<std::recursive_mutex> guard(m_mutex); 217 m_tried_unwind_plan_assembly = true; 218 219 UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target)); 220 if (assembly_profiler_sp) 221 { 222 m_unwind_plan_assembly_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); 223 if (!assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *m_unwind_plan_assembly_sp)) 224 { 225 m_unwind_plan_assembly_sp.reset(); 226 } 227 } 228 return m_unwind_plan_assembly_sp; 229 } 230 231 232 UnwindPlanSP 233 FuncUnwinders::GetUnwindPlanAtNonCallSite (Target& target, Thread& thread, int current_offset) 234 { 235 UnwindPlanSP non_call_site_unwindplan_sp = GetEHFrameAugmentedUnwindPlan (target, thread, current_offset); 236 if (non_call_site_unwindplan_sp.get() == nullptr) 237 { 238 non_call_site_unwindplan_sp = GetAssemblyUnwindPlan (target, thread, current_offset); 239 } 240 return non_call_site_unwindplan_sp; 241 } 242 243 UnwindPlanSP 244 FuncUnwinders::GetUnwindPlanFastUnwind (Target& target, Thread& thread) 245 { 246 if (m_unwind_plan_fast_sp.get() || m_tried_unwind_fast) 247 return m_unwind_plan_fast_sp; 248 249 std::lock_guard<std::recursive_mutex> guard(m_mutex); 250 m_tried_unwind_fast = true; 251 252 UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target)); 253 if (assembly_profiler_sp) 254 { 255 m_unwind_plan_fast_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); 256 if (!assembly_profiler_sp->GetFastUnwindPlan (m_range, thread, *m_unwind_plan_fast_sp)) 257 { 258 m_unwind_plan_fast_sp.reset(); 259 } 260 } 261 return m_unwind_plan_fast_sp; 262 } 263 264 UnwindPlanSP 265 FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread) 266 { 267 if (m_unwind_plan_arch_default_sp.get() || m_tried_unwind_arch_default) 268 return m_unwind_plan_arch_default_sp; 269 270 std::lock_guard<std::recursive_mutex> guard(m_mutex); 271 m_tried_unwind_arch_default = true; 272 273 Address current_pc; 274 ProcessSP process_sp (thread.CalculateProcess()); 275 if (process_sp) 276 { 277 ABI *abi = process_sp->GetABI().get(); 278 if (abi) 279 { 280 m_unwind_plan_arch_default_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); 281 if (!abi->CreateDefaultUnwindPlan(*m_unwind_plan_arch_default_sp)) 282 { 283 m_unwind_plan_arch_default_sp.reset(); 284 } 285 } 286 } 287 288 return m_unwind_plan_arch_default_sp; 289 } 290 291 UnwindPlanSP 292 FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry (Thread& thread) 293 { 294 if (m_unwind_plan_arch_default_at_func_entry_sp.get() || m_tried_unwind_arch_default_at_func_entry) 295 return m_unwind_plan_arch_default_at_func_entry_sp; 296 297 std::lock_guard<std::recursive_mutex> guard(m_mutex); 298 m_tried_unwind_arch_default_at_func_entry = true; 299 300 Address current_pc; 301 ProcessSP process_sp (thread.CalculateProcess()); 302 if (process_sp) 303 { 304 ABI *abi = process_sp->GetABI().get(); 305 if (abi) 306 { 307 m_unwind_plan_arch_default_at_func_entry_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); 308 if (!abi->CreateFunctionEntryUnwindPlan(*m_unwind_plan_arch_default_at_func_entry_sp)) 309 { 310 m_unwind_plan_arch_default_at_func_entry_sp.reset(); 311 } 312 } 313 } 314 315 return m_unwind_plan_arch_default_at_func_entry_sp; 316 } 317 318 319 Address& 320 FuncUnwinders::GetFirstNonPrologueInsn (Target& target) 321 { 322 if (m_first_non_prologue_insn.IsValid()) 323 return m_first_non_prologue_insn; 324 325 std::lock_guard<std::recursive_mutex> guard(m_mutex); 326 ExecutionContext exe_ctx (target.shared_from_this(), false); 327 UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target)); 328 if (assembly_profiler_sp) 329 assembly_profiler_sp->FirstNonPrologueInsn (m_range, exe_ctx, m_first_non_prologue_insn); 330 return m_first_non_prologue_insn; 331 } 332 333 const Address& 334 FuncUnwinders::GetFunctionStartAddress () const 335 { 336 return m_range.GetBaseAddress(); 337 } 338 339 lldb::UnwindAssemblySP 340 FuncUnwinders::GetUnwindAssemblyProfiler (Target& target) 341 { 342 UnwindAssemblySP assembly_profiler_sp; 343 ArchSpec arch; 344 if (m_unwind_table.GetArchitecture (arch)) 345 { 346 arch.MergeFrom (target.GetArchitecture ()); 347 assembly_profiler_sp = UnwindAssembly::FindPlugin (arch); 348 } 349 return assembly_profiler_sp; 350 } 351 352 Address 353 FuncUnwinders::GetLSDAAddress (Target &target) 354 { 355 Address lsda_addr; 356 357 UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan (target, -1); 358 if (unwind_plan_sp.get() == nullptr) 359 { 360 unwind_plan_sp = GetCompactUnwindUnwindPlan (target, -1); 361 } 362 if (unwind_plan_sp.get() && unwind_plan_sp->GetLSDAAddress().IsValid()) 363 { 364 lsda_addr = unwind_plan_sp->GetLSDAAddress(); 365 } 366 return lsda_addr; 367 } 368 369 370 Address 371 FuncUnwinders::GetPersonalityRoutinePtrAddress (Target &target) 372 { 373 Address personality_addr; 374 375 UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan (target, -1); 376 if (unwind_plan_sp.get() == nullptr) 377 { 378 unwind_plan_sp = GetCompactUnwindUnwindPlan (target, -1); 379 } 380 if (unwind_plan_sp.get() && unwind_plan_sp->GetPersonalityFunctionPtr().IsValid()) 381 { 382 personality_addr = unwind_plan_sp->GetPersonalityFunctionPtr(); 383 } 384 385 return personality_addr; 386 } 387