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