1 //===-- FuncUnwinders.cpp ----------------------------------*- C++ -*-===// 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 9 #include "lldb/Symbol/FuncUnwinders.h" 10 #include "lldb/Core/Address.h" 11 #include "lldb/Core/AddressRange.h" 12 #include "lldb/Symbol/ArmUnwindInfo.h" 13 #include "lldb/Symbol/CompactUnwindInfo.h" 14 #include "lldb/Symbol/DWARFCallFrameInfo.h" 15 #include "lldb/Symbol/ObjectFile.h" 16 #include "lldb/Symbol/SymbolFile.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/RegisterContext.h" 23 #include "lldb/Target/RegisterNumber.h" 24 #include "lldb/Target/Target.h" 25 #include "lldb/Target/Thread.h" 26 #include "lldb/Target/UnwindAssembly.h" 27 28 #include <memory> 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 /// constructor 34 35 FuncUnwinders::FuncUnwinders(UnwindTable &unwind_table, AddressRange range) 36 : m_unwind_table(unwind_table), m_range(range), m_mutex(), 37 m_unwind_plan_assembly_sp(), m_unwind_plan_eh_frame_sp(), 38 m_unwind_plan_eh_frame_augmented_sp(), m_unwind_plan_compact_unwind(), 39 m_unwind_plan_arm_unwind_sp(), m_unwind_plan_fast_sp(), 40 m_unwind_plan_arch_default_sp(), 41 m_unwind_plan_arch_default_at_func_entry_sp(), 42 m_tried_unwind_plan_assembly(false), m_tried_unwind_plan_eh_frame(false), 43 m_tried_unwind_plan_debug_frame(false), 44 m_tried_unwind_plan_eh_frame_augmented(false), 45 m_tried_unwind_plan_debug_frame_augmented(false), 46 m_tried_unwind_plan_compact_unwind(false), 47 m_tried_unwind_plan_arm_unwind(false), 48 m_tried_unwind_plan_symbol_file(false), m_tried_unwind_fast(false), 49 m_tried_unwind_arch_default(false), 50 m_tried_unwind_arch_default_at_func_entry(false), 51 m_first_non_prologue_insn() {} 52 53 /// destructor 54 55 FuncUnwinders::~FuncUnwinders() {} 56 57 UnwindPlanSP FuncUnwinders::GetUnwindPlanAtCallSite(Target &target) { 58 std::lock_guard<std::recursive_mutex> guard(m_mutex); 59 60 if (UnwindPlanSP plan_sp = GetEHFrameUnwindPlan(target)) 61 return plan_sp; 62 if (UnwindPlanSP plan_sp = GetDebugFrameUnwindPlan(target)) 63 return plan_sp; 64 if (UnwindPlanSP plan_sp = GetCompactUnwindUnwindPlan(target)) 65 return plan_sp; 66 if (UnwindPlanSP plan_sp = GetArmUnwindUnwindPlan(target)) 67 return plan_sp; 68 69 return nullptr; 70 } 71 72 UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target) { 73 std::lock_guard<std::recursive_mutex> guard(m_mutex); 74 if (m_unwind_plan_compact_unwind.size() > 0) 75 return m_unwind_plan_compact_unwind[0]; // FIXME support multiple compact 76 // unwind plans for one func 77 if (m_tried_unwind_plan_compact_unwind) 78 return UnwindPlanSP(); 79 80 m_tried_unwind_plan_compact_unwind = true; 81 if (m_range.GetBaseAddress().IsValid()) { 82 Address current_pc(m_range.GetBaseAddress()); 83 CompactUnwindInfo *compact_unwind = m_unwind_table.GetCompactUnwindInfo(); 84 if (compact_unwind) { 85 UnwindPlanSP unwind_plan_sp(new UnwindPlan(lldb::eRegisterKindGeneric)); 86 if (compact_unwind->GetUnwindPlan(target, current_pc, *unwind_plan_sp)) { 87 m_unwind_plan_compact_unwind.push_back(unwind_plan_sp); 88 return m_unwind_plan_compact_unwind[0]; // FIXME support multiple 89 // compact unwind plans for one 90 // func 91 } 92 } 93 } 94 return UnwindPlanSP(); 95 } 96 97 UnwindPlanSP FuncUnwinders::GetEHFrameUnwindPlan(Target &target) { 98 std::lock_guard<std::recursive_mutex> guard(m_mutex); 99 if (m_unwind_plan_eh_frame_sp.get() || m_tried_unwind_plan_eh_frame) 100 return m_unwind_plan_eh_frame_sp; 101 102 m_tried_unwind_plan_eh_frame = true; 103 if (m_range.GetBaseAddress().IsValid()) { 104 DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo(); 105 if (eh_frame) { 106 m_unwind_plan_eh_frame_sp = 107 std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 108 if (!eh_frame->GetUnwindPlan(m_range, *m_unwind_plan_eh_frame_sp)) 109 m_unwind_plan_eh_frame_sp.reset(); 110 } 111 } 112 return m_unwind_plan_eh_frame_sp; 113 } 114 115 UnwindPlanSP FuncUnwinders::GetDebugFrameUnwindPlan(Target &target) { 116 std::lock_guard<std::recursive_mutex> guard(m_mutex); 117 if (m_unwind_plan_debug_frame_sp || m_tried_unwind_plan_debug_frame) 118 return m_unwind_plan_debug_frame_sp; 119 120 m_tried_unwind_plan_debug_frame = true; 121 if (m_range.GetBaseAddress().IsValid()) { 122 DWARFCallFrameInfo *debug_frame = m_unwind_table.GetDebugFrameInfo(); 123 if (debug_frame) { 124 m_unwind_plan_debug_frame_sp = 125 std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 126 if (!debug_frame->GetUnwindPlan(m_range, *m_unwind_plan_debug_frame_sp)) 127 m_unwind_plan_debug_frame_sp.reset(); 128 } 129 } 130 return m_unwind_plan_debug_frame_sp; 131 } 132 133 UnwindPlanSP FuncUnwinders::GetArmUnwindUnwindPlan(Target &target) { 134 std::lock_guard<std::recursive_mutex> guard(m_mutex); 135 if (m_unwind_plan_arm_unwind_sp.get() || m_tried_unwind_plan_arm_unwind) 136 return m_unwind_plan_arm_unwind_sp; 137 138 m_tried_unwind_plan_arm_unwind = true; 139 if (m_range.GetBaseAddress().IsValid()) { 140 Address current_pc(m_range.GetBaseAddress()); 141 ArmUnwindInfo *arm_unwind_info = m_unwind_table.GetArmUnwindInfo(); 142 if (arm_unwind_info) { 143 m_unwind_plan_arm_unwind_sp = 144 std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 145 if (!arm_unwind_info->GetUnwindPlan(target, current_pc, 146 *m_unwind_plan_arm_unwind_sp)) 147 m_unwind_plan_arm_unwind_sp.reset(); 148 } 149 } 150 return m_unwind_plan_arm_unwind_sp; 151 } 152 153 namespace { 154 class RegisterContextToInfo: public SymbolFile::RegisterInfoResolver { 155 public: 156 RegisterContextToInfo(RegisterContext &ctx) : m_ctx(ctx) {} 157 158 const RegisterInfo *ResolveName(llvm::StringRef name) const { 159 return m_ctx.GetRegisterInfoByName(name); 160 } 161 const RegisterInfo *ResolveNumber(lldb::RegisterKind kind, 162 uint32_t number) const { 163 return m_ctx.GetRegisterInfo(kind, number); 164 } 165 166 private: 167 RegisterContext &m_ctx; 168 }; 169 } // namespace 170 171 UnwindPlanSP FuncUnwinders::GetSymbolFileUnwindPlan(Thread &thread) { 172 std::lock_guard<std::recursive_mutex> guard(m_mutex); 173 if (m_unwind_plan_symbol_file_sp.get() || m_tried_unwind_plan_symbol_file) 174 return m_unwind_plan_symbol_file_sp; 175 176 m_tried_unwind_plan_symbol_file = true; 177 if (SymbolFile *symfile = m_unwind_table.GetSymbolFile()) { 178 m_unwind_plan_symbol_file_sp = symfile->GetUnwindPlan( 179 m_range.GetBaseAddress(), 180 RegisterContextToInfo(*thread.GetRegisterContext())); 181 } 182 return m_unwind_plan_symbol_file_sp; 183 } 184 185 UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target, 186 Thread &thread) { 187 std::lock_guard<std::recursive_mutex> guard(m_mutex); 188 if (m_unwind_plan_eh_frame_augmented_sp.get() || 189 m_tried_unwind_plan_eh_frame_augmented) 190 return m_unwind_plan_eh_frame_augmented_sp; 191 192 // Only supported on x86 architectures where we get eh_frame from the 193 // compiler that describes the prologue instructions perfectly, and sometimes 194 // the epilogue instructions too. 195 if (target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_32_i386 && 196 target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64 && 197 target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64h) { 198 m_tried_unwind_plan_eh_frame_augmented = true; 199 return m_unwind_plan_eh_frame_augmented_sp; 200 } 201 202 m_tried_unwind_plan_eh_frame_augmented = true; 203 204 UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan(target); 205 if (!eh_frame_plan) 206 return m_unwind_plan_eh_frame_augmented_sp; 207 208 m_unwind_plan_eh_frame_augmented_sp = 209 std::make_shared<UnwindPlan>(*eh_frame_plan); 210 211 // Augment the eh_frame instructions with epilogue descriptions if necessary 212 // so the UnwindPlan can be used at any instruction in the function. 213 214 UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target)); 215 if (assembly_profiler_sp) { 216 if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite( 217 m_range, thread, *m_unwind_plan_eh_frame_augmented_sp)) { 218 m_unwind_plan_eh_frame_augmented_sp.reset(); 219 } 220 } else { 221 m_unwind_plan_eh_frame_augmented_sp.reset(); 222 } 223 return m_unwind_plan_eh_frame_augmented_sp; 224 } 225 226 UnwindPlanSP FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target, 227 Thread &thread) { 228 std::lock_guard<std::recursive_mutex> guard(m_mutex); 229 if (m_unwind_plan_debug_frame_augmented_sp.get() || 230 m_tried_unwind_plan_debug_frame_augmented) 231 return m_unwind_plan_debug_frame_augmented_sp; 232 233 // Only supported on x86 architectures where we get debug_frame from the 234 // compiler that describes the prologue instructions perfectly, and sometimes 235 // the epilogue instructions too. 236 if (target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_32_i386 && 237 target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64 && 238 target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64h) { 239 m_tried_unwind_plan_debug_frame_augmented = true; 240 return m_unwind_plan_debug_frame_augmented_sp; 241 } 242 243 m_tried_unwind_plan_debug_frame_augmented = true; 244 245 UnwindPlanSP debug_frame_plan = GetDebugFrameUnwindPlan(target); 246 if (!debug_frame_plan) 247 return m_unwind_plan_debug_frame_augmented_sp; 248 249 m_unwind_plan_debug_frame_augmented_sp = 250 std::make_shared<UnwindPlan>(*debug_frame_plan); 251 252 // Augment the debug_frame instructions with epilogue descriptions if 253 // necessary so the UnwindPlan can be used at any instruction in the 254 // function. 255 256 UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target)); 257 if (assembly_profiler_sp) { 258 if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite( 259 m_range, thread, *m_unwind_plan_debug_frame_augmented_sp)) { 260 m_unwind_plan_debug_frame_augmented_sp.reset(); 261 } 262 } else 263 m_unwind_plan_debug_frame_augmented_sp.reset(); 264 return m_unwind_plan_debug_frame_augmented_sp; 265 } 266 267 UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target, 268 Thread &thread) { 269 std::lock_guard<std::recursive_mutex> guard(m_mutex); 270 if (m_unwind_plan_assembly_sp.get() || m_tried_unwind_plan_assembly || 271 !m_unwind_table.GetAllowAssemblyEmulationUnwindPlans()) { 272 return m_unwind_plan_assembly_sp; 273 } 274 275 m_tried_unwind_plan_assembly = true; 276 277 UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target)); 278 if (assembly_profiler_sp) { 279 m_unwind_plan_assembly_sp = 280 std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 281 if (!assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly( 282 m_range, thread, *m_unwind_plan_assembly_sp)) { 283 m_unwind_plan_assembly_sp.reset(); 284 } 285 } 286 return m_unwind_plan_assembly_sp; 287 } 288 289 // This method compares the pc unwind rule in the first row of two UnwindPlans. 290 // If they have the same way of getting the pc value (e.g. "CFA - 8" + "CFA is 291 // sp"), then it will return LazyBoolTrue. 292 LazyBool FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation( 293 Thread &thread, const UnwindPlanSP &a, const UnwindPlanSP &b) { 294 LazyBool plans_are_identical = eLazyBoolCalculate; 295 296 RegisterNumber pc_reg(thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 297 uint32_t pc_reg_lldb_regnum = pc_reg.GetAsKind(eRegisterKindLLDB); 298 299 if (a.get() && b.get()) { 300 UnwindPlan::RowSP a_first_row = a->GetRowAtIndex(0); 301 UnwindPlan::RowSP b_first_row = b->GetRowAtIndex(0); 302 303 if (a_first_row.get() && b_first_row.get()) { 304 UnwindPlan::Row::RegisterLocation a_pc_regloc; 305 UnwindPlan::Row::RegisterLocation b_pc_regloc; 306 307 a_first_row->GetRegisterInfo(pc_reg_lldb_regnum, a_pc_regloc); 308 b_first_row->GetRegisterInfo(pc_reg_lldb_regnum, b_pc_regloc); 309 310 plans_are_identical = eLazyBoolYes; 311 312 if (a_first_row->GetCFAValue() != b_first_row->GetCFAValue()) { 313 plans_are_identical = eLazyBoolNo; 314 } 315 if (a_pc_regloc != b_pc_regloc) { 316 plans_are_identical = eLazyBoolNo; 317 } 318 } 319 } 320 return plans_are_identical; 321 } 322 323 UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target, 324 Thread &thread) { 325 UnwindPlanSP eh_frame_sp = GetEHFrameUnwindPlan(target); 326 if (!eh_frame_sp) 327 eh_frame_sp = GetDebugFrameUnwindPlan(target); 328 UnwindPlanSP arch_default_at_entry_sp = 329 GetUnwindPlanArchitectureDefaultAtFunctionEntry(thread); 330 UnwindPlanSP arch_default_sp = GetUnwindPlanArchitectureDefault(thread); 331 UnwindPlanSP assembly_sp = GetAssemblyUnwindPlan(target, thread); 332 333 // This point of this code is to detect when a function is using a non- 334 // standard ABI, and the eh_frame correctly describes that alternate ABI. 335 // This is addressing a specific situation on x86_64 linux systems where one 336 // function in a library pushes a value on the stack and jumps to another 337 // function. So using an assembly instruction based unwind will not work 338 // when you're in the second function - the stack has been modified in a non- 339 // ABI way. But we have eh_frame that correctly describes how to unwind from 340 // this location. So we're looking to see if the initial pc register save 341 // location from the eh_frame is different from the assembly unwind, the arch 342 // default unwind, and the arch default at initial function entry. 343 // 344 // We may have eh_frame that describes the entire function -- or we may have 345 // eh_frame that only describes the unwind after the prologue has executed -- 346 // so we need to check both the arch default (once the prologue has executed) 347 // and the arch default at initial function entry. And we may be running on 348 // a target where we have only some of the assembly/arch default unwind plans 349 // available. 350 351 if (CompareUnwindPlansForIdenticalInitialPCLocation( 352 thread, eh_frame_sp, arch_default_at_entry_sp) == eLazyBoolNo && 353 CompareUnwindPlansForIdenticalInitialPCLocation( 354 thread, eh_frame_sp, arch_default_sp) == eLazyBoolNo && 355 CompareUnwindPlansForIdenticalInitialPCLocation( 356 thread, assembly_sp, arch_default_sp) == eLazyBoolNo) { 357 return eh_frame_sp; 358 } 359 360 if (UnwindPlanSP plan_sp = GetEHFrameAugmentedUnwindPlan(target, thread)) 361 return plan_sp; 362 if (UnwindPlanSP plan_sp = GetDebugFrameAugmentedUnwindPlan(target, thread)) 363 return plan_sp; 364 365 return assembly_sp; 366 } 367 368 UnwindPlanSP FuncUnwinders::GetUnwindPlanFastUnwind(Target &target, 369 Thread &thread) { 370 std::lock_guard<std::recursive_mutex> guard(m_mutex); 371 if (m_unwind_plan_fast_sp.get() || m_tried_unwind_fast) 372 return m_unwind_plan_fast_sp; 373 374 m_tried_unwind_fast = true; 375 376 UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target)); 377 if (assembly_profiler_sp) { 378 m_unwind_plan_fast_sp = 379 std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 380 if (!assembly_profiler_sp->GetFastUnwindPlan(m_range, thread, 381 *m_unwind_plan_fast_sp)) { 382 m_unwind_plan_fast_sp.reset(); 383 } 384 } 385 return m_unwind_plan_fast_sp; 386 } 387 388 UnwindPlanSP FuncUnwinders::GetUnwindPlanArchitectureDefault(Thread &thread) { 389 std::lock_guard<std::recursive_mutex> guard(m_mutex); 390 if (m_unwind_plan_arch_default_sp.get() || m_tried_unwind_arch_default) 391 return m_unwind_plan_arch_default_sp; 392 393 m_tried_unwind_arch_default = true; 394 395 Address current_pc; 396 ProcessSP process_sp(thread.CalculateProcess()); 397 if (process_sp) { 398 ABI *abi = process_sp->GetABI().get(); 399 if (abi) { 400 m_unwind_plan_arch_default_sp = 401 std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 402 if (!abi->CreateDefaultUnwindPlan(*m_unwind_plan_arch_default_sp)) { 403 m_unwind_plan_arch_default_sp.reset(); 404 } 405 } 406 } 407 408 return m_unwind_plan_arch_default_sp; 409 } 410 411 UnwindPlanSP 412 FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry(Thread &thread) { 413 std::lock_guard<std::recursive_mutex> guard(m_mutex); 414 if (m_unwind_plan_arch_default_at_func_entry_sp.get() || 415 m_tried_unwind_arch_default_at_func_entry) 416 return m_unwind_plan_arch_default_at_func_entry_sp; 417 418 m_tried_unwind_arch_default_at_func_entry = true; 419 420 Address current_pc; 421 ProcessSP process_sp(thread.CalculateProcess()); 422 if (process_sp) { 423 ABI *abi = process_sp->GetABI().get(); 424 if (abi) { 425 m_unwind_plan_arch_default_at_func_entry_sp = 426 std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); 427 if (!abi->CreateFunctionEntryUnwindPlan( 428 *m_unwind_plan_arch_default_at_func_entry_sp)) { 429 m_unwind_plan_arch_default_at_func_entry_sp.reset(); 430 } 431 } 432 } 433 434 return m_unwind_plan_arch_default_at_func_entry_sp; 435 } 436 437 Address &FuncUnwinders::GetFirstNonPrologueInsn(Target &target) { 438 std::lock_guard<std::recursive_mutex> guard(m_mutex); 439 if (m_first_non_prologue_insn.IsValid()) 440 return m_first_non_prologue_insn; 441 442 ExecutionContext exe_ctx(target.shared_from_this(), false); 443 UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target)); 444 if (assembly_profiler_sp) 445 assembly_profiler_sp->FirstNonPrologueInsn(m_range, exe_ctx, 446 m_first_non_prologue_insn); 447 return m_first_non_prologue_insn; 448 } 449 450 const Address &FuncUnwinders::GetFunctionStartAddress() const { 451 return m_range.GetBaseAddress(); 452 } 453 454 lldb::UnwindAssemblySP 455 FuncUnwinders::GetUnwindAssemblyProfiler(Target &target) { 456 UnwindAssemblySP assembly_profiler_sp; 457 if (ArchSpec arch = m_unwind_table.GetArchitecture()) { 458 arch.MergeFrom(target.GetArchitecture()); 459 assembly_profiler_sp = UnwindAssembly::FindPlugin(arch); 460 } 461 return assembly_profiler_sp; 462 } 463 464 Address FuncUnwinders::GetLSDAAddress(Target &target) { 465 Address lsda_addr; 466 467 UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target); 468 if (unwind_plan_sp.get() == nullptr) { 469 unwind_plan_sp = GetCompactUnwindUnwindPlan(target); 470 } 471 if (unwind_plan_sp.get() && unwind_plan_sp->GetLSDAAddress().IsValid()) { 472 lsda_addr = unwind_plan_sp->GetLSDAAddress(); 473 } 474 return lsda_addr; 475 } 476 477 Address FuncUnwinders::GetPersonalityRoutinePtrAddress(Target &target) { 478 Address personality_addr; 479 480 UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target); 481 if (unwind_plan_sp.get() == nullptr) { 482 unwind_plan_sp = GetCompactUnwindUnwindPlan(target); 483 } 484 if (unwind_plan_sp.get() && 485 unwind_plan_sp->GetPersonalityFunctionPtr().IsValid()) { 486 personality_addr = unwind_plan_sp->GetPersonalityFunctionPtr(); 487 } 488 489 return personality_addr; 490 } 491