File: | tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp |
Location: | line 1727, column 17 |
Description: | Value stored to 'cfa_reg_contents' is never read |
1 | //===-- RegisterContextLLDB.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 | |
11 | #include "lldb/lldb-private.h" |
12 | #include "lldb/Core/Address.h" |
13 | #include "lldb/Core/AddressRange.h" |
14 | #include "lldb/Core/DataBufferHeap.h" |
15 | #include "lldb/Core/Log.h" |
16 | #include "lldb/Core/Module.h" |
17 | #include "lldb/Core/RegisterValue.h" |
18 | #include "lldb/Core/Value.h" |
19 | #include "lldb/Expression/DWARFExpression.h" |
20 | #include "lldb/Symbol/DWARFCallFrameInfo.h" |
21 | #include "lldb/Symbol/FuncUnwinders.h" |
22 | #include "lldb/Symbol/Function.h" |
23 | #include "lldb/Symbol/ObjectFile.h" |
24 | #include "lldb/Symbol/Symbol.h" |
25 | #include "lldb/Symbol/SymbolContext.h" |
26 | #include "lldb/Target/ABI.h" |
27 | #include "lldb/Target/DynamicLoader.h" |
28 | #include "lldb/Target/ExecutionContext.h" |
29 | #include "lldb/Target/Platform.h" |
30 | #include "lldb/Target/Process.h" |
31 | #include "lldb/Target/SectionLoadList.h" |
32 | #include "lldb/Target/StackFrame.h" |
33 | #include "lldb/Target/Target.h" |
34 | #include "lldb/Target/Thread.h" |
35 | |
36 | #include "RegisterContextLLDB.h" |
37 | |
38 | using namespace lldb; |
39 | using namespace lldb_private; |
40 | |
41 | RegisterContextLLDB::RegisterContextLLDB |
42 | ( |
43 | Thread& thread, |
44 | const SharedPtr &next_frame, |
45 | SymbolContext& sym_ctx, |
46 | uint32_t frame_number, |
47 | UnwindLLDB& unwind_lldb |
48 | ) : |
49 | RegisterContext (thread, frame_number), |
50 | m_thread(thread), |
51 | m_fast_unwind_plan_sp (), |
52 | m_full_unwind_plan_sp (), |
53 | m_fallback_unwind_plan_sp (), |
54 | m_all_registers_available(false), |
55 | m_frame_type (-1), |
56 | m_cfa (LLDB_INVALID_ADDRESS(18446744073709551615UL)), |
57 | m_start_pc (), |
58 | m_current_pc (), |
59 | m_current_offset (0), |
60 | m_current_offset_backed_up_one (0), |
61 | m_sym_ctx(sym_ctx), |
62 | m_sym_ctx_valid (false), |
63 | m_frame_number (frame_number), |
64 | m_registers(), |
65 | m_parent_unwind (unwind_lldb) |
66 | { |
67 | m_sym_ctx.Clear(false); |
68 | m_sym_ctx_valid = false; |
69 | |
70 | if (IsFrameZero ()) |
71 | { |
72 | InitializeZerothFrame (); |
73 | } |
74 | else |
75 | { |
76 | InitializeNonZerothFrame (); |
77 | } |
78 | |
79 | // This same code exists over in the GetFullUnwindPlanForFrame() but it may not have been executed yet |
80 | if (IsFrameZero() |
81 | || next_frame->m_frame_type == eTrapHandlerFrame |
82 | || next_frame->m_frame_type == eDebuggerFrame) |
83 | { |
84 | m_all_registers_available = true; |
85 | } |
86 | } |
87 | |
88 | bool |
89 | RegisterContextLLDB::IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset) |
90 | { |
91 | if (!unwind_plan_sp) |
92 | return false; |
93 | |
94 | // check if m_current_pc is valid |
95 | if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) |
96 | { |
97 | // yes - current offset can be used as is |
98 | valid_pc_offset = m_current_offset; |
99 | return true; |
100 | } |
101 | |
102 | // if m_current_offset <= 0, we've got nothing else to try |
103 | if (m_current_offset <= 0) |
104 | return false; |
105 | |
106 | // check pc - 1 to see if it's valid |
107 | Address pc_minus_one (m_current_pc); |
108 | pc_minus_one.SetOffset(m_current_pc.GetOffset() - 1); |
109 | if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one)) |
110 | { |
111 | // *valid_pc_offset = m_current_offset - 1; |
112 | valid_pc_offset = m_current_pc.GetOffset() - 1; |
113 | return true; |
114 | } |
115 | |
116 | return false; |
117 | } |
118 | |
119 | // Initialize a RegisterContextLLDB which is the first frame of a stack -- the zeroth frame or currently |
120 | // executing frame. |
121 | |
122 | void |
123 | RegisterContextLLDB::InitializeZerothFrame() |
124 | { |
125 | Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND(1u << 15))); |
126 | ExecutionContext exe_ctx(m_thread.shared_from_this()); |
127 | RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext(); |
128 | |
129 | if (reg_ctx_sp.get() == NULL__null) |
130 | { |
131 | m_frame_type = eNotAValidFrame; |
132 | UnwindLogMsg ("frame does not have a register context"); |
133 | return; |
134 | } |
135 | |
136 | addr_t current_pc = reg_ctx_sp->GetPC(); |
137 | |
138 | if (current_pc == LLDB_INVALID_ADDRESS(18446744073709551615UL)) |
139 | { |
140 | m_frame_type = eNotAValidFrame; |
141 | UnwindLogMsg ("frame does not have a pc"); |
142 | return; |
143 | } |
144 | |
145 | Process *process = exe_ctx.GetProcessPtr(); |
146 | |
147 | // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs |
148 | // this will strip bit zero in case we read a PC from memory or from the LR. |
149 | // (which would be a no-op in frame 0 where we get it from the register set, |
150 | // but still a good idea to make the call here for other ABIs that may exist.) |
151 | ABI *abi = process->GetABI().get(); |
152 | if (abi) |
153 | current_pc = abi->FixCodeAddress(current_pc); |
154 | |
155 | // Initialize m_current_pc, an Address object, based on current_pc, an addr_t. |
156 | m_current_pc.SetLoadAddress (current_pc, &process->GetTarget()); |
157 | |
158 | // If we don't have a Module for some reason, we're not going to find symbol/function information - just |
159 | // stick in some reasonable defaults and hope we can unwind past this frame. |
160 | ModuleSP pc_module_sp (m_current_pc.GetModule()); |
161 | if (!m_current_pc.IsValid() || !pc_module_sp) |
162 | { |
163 | UnwindLogMsg ("using architectural default unwind method"); |
164 | } |
165 | |
166 | // We require either a symbol or function in the symbols context to be successfully |
167 | // filled in or this context is of no use to us. |
168 | const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; |
169 | if (pc_module_sp.get() |
170 | && (pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, resolve_scope, m_sym_ctx) & resolve_scope)) |
171 | { |
172 | m_sym_ctx_valid = true; |
173 | } |
174 | |
175 | if (m_sym_ctx.symbol) |
176 | { |
177 | UnwindLogMsg ("with pc value of 0x%" PRIx64"l" "x" ", symbol name is '%s'", |
178 | current_pc, m_sym_ctx.symbol == NULL__null ? "" : m_sym_ctx.symbol->GetName().AsCString()); |
179 | } |
180 | else if (m_sym_ctx.function) |
181 | { |
182 | UnwindLogMsg ("with pc value of 0x%" PRIx64"l" "x" ", function name is '%s'", |
183 | current_pc, m_sym_ctx.symbol == NULL__null ? "" : m_sym_ctx.function->GetName().AsCString()); |
184 | } |
185 | else |
186 | { |
187 | UnwindLogMsg ("with pc value of 0x%" PRIx64"l" "x" ", no symbol/function name is known.", current_pc); |
188 | } |
189 | |
190 | AddressRange addr_range; |
191 | m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range); |
192 | |
193 | if (IsTrapHandlerSymbol (process, m_sym_ctx)) |
194 | { |
195 | m_frame_type = eTrapHandlerFrame; |
196 | } |
197 | else |
198 | { |
199 | // FIXME: Detect eDebuggerFrame here. |
200 | m_frame_type = eNormalFrame; |
201 | } |
202 | |
203 | // If we were able to find a symbol/function, set addr_range to the bounds of that symbol/function. |
204 | // else treat the current pc value as the start_pc and record no offset. |
205 | if (addr_range.GetBaseAddress().IsValid()) |
206 | { |
207 | m_start_pc = addr_range.GetBaseAddress(); |
208 | if (m_current_pc.GetSection() == m_start_pc.GetSection()) |
209 | { |
210 | m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset(); |
211 | } |
212 | else if (m_current_pc.GetModule() == m_start_pc.GetModule()) |
213 | { |
214 | // This means that whatever symbol we kicked up isn't really correct |
215 | // --- we should not cross section boundaries ... We really should NULL out |
216 | // the function/symbol in this case unless there is a bad assumption |
217 | // here due to inlined functions? |
218 | m_current_offset = m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress(); |
219 | } |
220 | m_current_offset_backed_up_one = m_current_offset; |
221 | } |
222 | else |
223 | { |
224 | m_start_pc = m_current_pc; |
225 | m_current_offset = -1; |
226 | m_current_offset_backed_up_one = -1; |
227 | } |
228 | |
229 | // We've set m_frame_type and m_sym_ctx before these calls. |
230 | |
231 | m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame (); |
232 | m_full_unwind_plan_sp = GetFullUnwindPlanForFrame (); |
233 | |
234 | UnwindPlan::RowSP active_row; |
235 | lldb::RegisterKind row_register_kind = eRegisterKindGeneric; |
236 | if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc)) |
237 | { |
238 | active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); |
239 | row_register_kind = m_full_unwind_plan_sp->GetRegisterKind (); |
240 | if (active_row.get() && log) |
241 | { |
242 | StreamString active_row_strm; |
243 | active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); |
244 | UnwindLogMsg ("%s", active_row_strm.GetString().c_str()); |
245 | } |
246 | } |
247 | |
248 | if (!active_row.get()) |
249 | { |
250 | UnwindLogMsg ("could not find an unwindplan row for this frame's pc"); |
251 | m_frame_type = eNotAValidFrame; |
252 | return; |
253 | } |
254 | |
255 | |
256 | if (!ReadCFAValueForRow (row_register_kind, active_row, m_cfa)) |
257 | { |
258 | UnwindLogMsg ("could not read CFA register for this frame."); |
259 | m_frame_type = eNotAValidFrame; |
260 | return; |
261 | } |
262 | |
263 | UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64"l" "x" " cfa is 0x%" PRIx64"l" "x" " using %s UnwindPlan", |
264 | (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), |
265 | (uint64_t) m_cfa, |
266 | m_full_unwind_plan_sp->GetSourceName().GetCString()); |
267 | } |
268 | |
269 | // Initialize a RegisterContextLLDB for the non-zeroth frame -- rely on the RegisterContextLLDB "below" it |
270 | // to provide things like its current pc value. |
271 | |
272 | void |
273 | RegisterContextLLDB::InitializeNonZerothFrame() |
274 | { |
275 | Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND(1u << 15))); |
276 | if (IsFrameZero ()) |
277 | { |
278 | m_frame_type = eNotAValidFrame; |
279 | UnwindLogMsg ("non-zeroth frame tests positive for IsFrameZero -- that shouldn't happen."); |
280 | return; |
281 | } |
282 | |
283 | if (!GetNextFrame().get() || !GetNextFrame()->IsValid()) |
284 | { |
285 | m_frame_type = eNotAValidFrame; |
286 | UnwindLogMsg ("Could not get next frame, marking this frame as invalid."); |
287 | return; |
288 | } |
289 | if (!m_thread.GetRegisterContext()) |
290 | { |
291 | m_frame_type = eNotAValidFrame; |
292 | UnwindLogMsg ("Could not get register context for this thread, marking this frame as invalid."); |
293 | return; |
294 | } |
295 | |
296 | addr_t pc; |
297 | if (!ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC0, pc)) |
298 | { |
299 | UnwindLogMsg ("could not get pc value"); |
300 | m_frame_type = eNotAValidFrame; |
301 | return; |
302 | } |
303 | |
304 | if (log) |
305 | { |
306 | UnwindLogMsg ("pc = 0x%" PRIx64"l" "x", pc); |
307 | addr_t reg_val; |
308 | if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP2, reg_val)) |
309 | UnwindLogMsg ("fp = 0x%" PRIx64"l" "x", reg_val); |
310 | if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP1, reg_val)) |
311 | UnwindLogMsg ("sp = 0x%" PRIx64"l" "x", reg_val); |
312 | } |
313 | |
314 | // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap handler function |
315 | bool above_trap_handler = false; |
316 | if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsTrapHandlerFrame()) |
317 | above_trap_handler = true; |
318 | |
319 | if (pc == 0 || pc == 0x1) |
320 | { |
321 | if (above_trap_handler == false) |
322 | { |
323 | m_frame_type = eNotAValidFrame; |
324 | UnwindLogMsg ("this frame has a pc of 0x0"); |
325 | return; |
326 | } |
327 | } |
328 | |
329 | ExecutionContext exe_ctx(m_thread.shared_from_this()); |
330 | Process *process = exe_ctx.GetProcessPtr(); |
331 | // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs |
332 | // this will strip bit zero in case we read a PC from memory or from the LR. |
333 | ABI *abi = process->GetABI().get(); |
334 | if (abi) |
335 | pc = abi->FixCodeAddress(pc); |
336 | |
337 | m_current_pc.SetLoadAddress (pc, &process->GetTarget()); |
338 | |
339 | // If we don't have a Module for some reason, we're not going to find symbol/function information - just |
340 | // stick in some reasonable defaults and hope we can unwind past this frame. |
341 | ModuleSP pc_module_sp (m_current_pc.GetModule()); |
342 | if (!m_current_pc.IsValid() || !pc_module_sp) |
343 | { |
344 | UnwindLogMsg ("using architectural default unwind method"); |
345 | |
346 | // Test the pc value to see if we know it's in an unmapped/non-executable region of memory. |
347 | uint32_t permissions; |
348 | if (process->GetLoadAddressPermissions(pc, permissions) |
349 | && (permissions & ePermissionsExecutable) == 0) |
350 | { |
351 | // If this is the second frame off the stack, we may have unwound the first frame |
352 | // incorrectly. But using the architecture default unwind plan may get us back on |
353 | // track -- albeit possibly skipping a real frame. Give this frame a clearly-invalid |
354 | // pc and see if we can get any further. |
355 | if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsFrameZero()) |
356 | { |
357 | UnwindLogMsg ("had a pc of 0x%" PRIx64"l" "x" " which is not in executable memory but on frame 1 -- allowing it once.", |
358 | (uint64_t) pc); |
359 | m_frame_type = eSkipFrame; |
360 | } |
361 | else |
362 | { |
363 | // anywhere other than the second frame, a non-executable pc means we're off in the weeds -- stop now. |
364 | m_frame_type = eNotAValidFrame; |
365 | UnwindLogMsg ("pc is in a non-executable section of memory and this isn't the 2nd frame in the stack walk."); |
366 | return; |
367 | } |
368 | } |
369 | |
370 | if (abi) |
371 | { |
372 | m_fast_unwind_plan_sp.reset (); |
373 | m_full_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); |
374 | abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp); |
375 | if (m_frame_type != eSkipFrame) // don't override eSkipFrame |
376 | { |
377 | m_frame_type = eNormalFrame; |
378 | } |
379 | m_all_registers_available = false; |
380 | m_current_offset = -1; |
381 | m_current_offset_backed_up_one = -1; |
382 | RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind (); |
383 | UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0); |
384 | if (row.get()) |
385 | { |
386 | if (!ReadCFAValueForRow (row_register_kind, row, m_cfa)) |
387 | { |
388 | UnwindLogMsg ("failed to get cfa value"); |
389 | if (m_frame_type != eSkipFrame) // don't override eSkipFrame |
390 | { |
391 | m_frame_type = eNotAValidFrame; |
392 | } |
393 | return; |
394 | } |
395 | |
396 | // A couple of sanity checks.. |
397 | if (m_cfa == LLDB_INVALID_ADDRESS(18446744073709551615UL) || m_cfa == 0 || m_cfa == 1) |
398 | { |
399 | UnwindLogMsg ("could not find a valid cfa address"); |
400 | m_frame_type = eNotAValidFrame; |
401 | return; |
402 | } |
403 | |
404 | // m_cfa should point into the stack memory; if we can query memory region permissions, |
405 | // see if the memory is allocated & readable. |
406 | if (process->GetLoadAddressPermissions(m_cfa, permissions) |
407 | && (permissions & ePermissionsReadable) == 0) |
408 | { |
409 | m_frame_type = eNotAValidFrame; |
410 | UnwindLogMsg ("the CFA points to a region of memory that is not readable"); |
411 | return; |
412 | } |
413 | } |
414 | else |
415 | { |
416 | UnwindLogMsg ("could not find a row for function offset zero"); |
417 | m_frame_type = eNotAValidFrame; |
418 | return; |
419 | } |
420 | |
421 | if (CheckIfLoopingStack ()) |
422 | { |
423 | TryFallbackUnwindPlan(); |
424 | if (CheckIfLoopingStack ()) |
425 | { |
426 | UnwindLogMsg ("same CFA address as next frame, assuming the unwind is looping - stopping"); |
427 | m_frame_type = eNotAValidFrame; |
428 | return; |
429 | } |
430 | } |
431 | |
432 | UnwindLogMsg ("initialized frame cfa is 0x%" PRIx64"l" "x", (uint64_t) m_cfa); |
433 | return; |
434 | } |
435 | m_frame_type = eNotAValidFrame; |
436 | UnwindLogMsg ("could not find any symbol for this pc, or a default unwind plan, to continue unwind."); |
437 | return; |
438 | } |
439 | |
440 | bool resolve_tail_call_address = true; // m_current_pc can be one past the address range of the function... |
441 | // This will handle the case where the saved pc does not point to |
442 | // a function/symbol because it is beyond the bounds of the correct |
443 | // function and there's no symbol there. ResolveSymbolContextForAddress |
444 | // will fail to find a symbol, back up the pc by 1 and re-search. |
445 | const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; |
446 | uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, |
447 | resolve_scope, |
448 | m_sym_ctx, resolve_tail_call_address); |
449 | |
450 | // We require either a symbol or function in the symbols context to be successfully |
451 | // filled in or this context is of no use to us. |
452 | if (resolve_scope & resolved_scope) |
453 | { |
454 | m_sym_ctx_valid = true; |
455 | } |
456 | |
457 | if (m_sym_ctx.symbol) |
458 | { |
459 | UnwindLogMsg ("with pc value of 0x%" PRIx64"l" "x" ", symbol name is '%s'", |
460 | pc, m_sym_ctx.symbol == NULL__null ? "" : m_sym_ctx.symbol->GetName().AsCString()); |
461 | } |
462 | else if (m_sym_ctx.function) |
463 | { |
464 | UnwindLogMsg ("with pc value of 0x%" PRIx64"l" "x" ", function name is '%s'", |
465 | pc, m_sym_ctx.symbol == NULL__null ? "" : m_sym_ctx.function->GetName().AsCString()); |
466 | } |
467 | else |
468 | { |
469 | UnwindLogMsg ("with pc value of 0x%" PRIx64"l" "x" ", no symbol/function name is known.", pc); |
470 | } |
471 | |
472 | AddressRange addr_range; |
473 | if (!m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range)) |
474 | { |
475 | m_sym_ctx_valid = false; |
476 | } |
477 | |
478 | bool decr_pc_and_recompute_addr_range = false; |
479 | |
480 | // If the symbol lookup failed... |
481 | if (m_sym_ctx_valid == false) |
482 | decr_pc_and_recompute_addr_range = true; |
483 | |
484 | // Or if we're in the middle of the stack (and not "above" an asynchronous event like sigtramp), |
485 | // and our "current" pc is the start of a function... |
486 | if (m_sym_ctx_valid |
487 | && GetNextFrame()->m_frame_type != eTrapHandlerFrame |
488 | && GetNextFrame()->m_frame_type != eDebuggerFrame |
489 | && addr_range.GetBaseAddress().IsValid() |
490 | && addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection() |
491 | && addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset()) |
492 | { |
493 | decr_pc_and_recompute_addr_range = true; |
494 | } |
495 | |
496 | // We need to back up the pc by 1 byte and re-search for the Symbol to handle the case where the "saved pc" |
497 | // value is pointing to the next function, e.g. if a function ends with a CALL instruction. |
498 | // FIXME this may need to be an architectural-dependent behavior; if so we'll need to add a member function |
499 | // to the ABI plugin and consult that. |
500 | if (decr_pc_and_recompute_addr_range) |
501 | { |
502 | UnwindLogMsg ("Backing up the pc value of 0x%" PRIx64"l" "x" " by 1 and re-doing symbol lookup; old symbol was %s", |
503 | pc, m_sym_ctx.symbol == NULL__null ? "" : m_sym_ctx.symbol->GetName().AsCString()); |
504 | Address temporary_pc; |
505 | temporary_pc.SetLoadAddress (pc - 1, &process->GetTarget()); |
506 | m_sym_ctx.Clear (false); |
507 | m_sym_ctx_valid = false; |
508 | uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; |
509 | |
510 | ModuleSP temporary_module_sp = temporary_pc.GetModule(); |
511 | if (temporary_module_sp && |
512 | temporary_module_sp->ResolveSymbolContextForAddress (temporary_pc, resolve_scope, m_sym_ctx) & resolve_scope) |
513 | { |
514 | if (m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range)) |
515 | m_sym_ctx_valid = true; |
516 | } |
517 | UnwindLogMsg ("Symbol is now %s", m_sym_ctx.symbol == NULL__null ? "" : m_sym_ctx.symbol->GetName().AsCString()); |
518 | } |
519 | |
520 | // If we were able to find a symbol/function, set addr_range_ptr to the bounds of that symbol/function. |
521 | // else treat the current pc value as the start_pc and record no offset. |
522 | if (addr_range.GetBaseAddress().IsValid()) |
523 | { |
524 | m_start_pc = addr_range.GetBaseAddress(); |
525 | m_current_offset = pc - m_start_pc.GetLoadAddress (&process->GetTarget()); |
526 | m_current_offset_backed_up_one = m_current_offset; |
527 | if (decr_pc_and_recompute_addr_range && m_current_offset_backed_up_one > 0) |
528 | { |
529 | m_current_offset_backed_up_one--; |
530 | if (m_sym_ctx_valid) |
531 | { |
532 | m_current_pc.SetLoadAddress (pc - 1, &process->GetTarget()); |
533 | } |
534 | } |
535 | } |
536 | else |
537 | { |
538 | m_start_pc = m_current_pc; |
539 | m_current_offset = -1; |
540 | m_current_offset_backed_up_one = -1; |
541 | } |
542 | |
543 | if (IsTrapHandlerSymbol (process, m_sym_ctx)) |
544 | { |
545 | m_frame_type = eTrapHandlerFrame; |
546 | } |
547 | else |
548 | { |
549 | // FIXME: Detect eDebuggerFrame here. |
550 | if (m_frame_type != eSkipFrame) // don't override eSkipFrame |
551 | { |
552 | m_frame_type = eNormalFrame; |
553 | } |
554 | } |
555 | |
556 | // We've set m_frame_type and m_sym_ctx before this call. |
557 | m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame (); |
558 | |
559 | UnwindPlan::RowSP active_row; |
560 | RegisterKind row_register_kind = eRegisterKindGeneric; |
561 | |
562 | // Try to get by with just the fast UnwindPlan if possible - the full UnwindPlan may be expensive to get |
563 | // (e.g. if we have to parse the entire eh_frame section of an ObjectFile for the first time.) |
564 | |
565 | if (m_fast_unwind_plan_sp && m_fast_unwind_plan_sp->PlanValidAtAddress (m_current_pc)) |
566 | { |
567 | active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); |
568 | row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind (); |
569 | if (active_row.get() && log) |
570 | { |
571 | StreamString active_row_strm; |
572 | active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); |
573 | UnwindLogMsg ("active row: %s", active_row_strm.GetString().c_str()); |
574 | } |
575 | } |
576 | else |
577 | { |
578 | m_full_unwind_plan_sp = GetFullUnwindPlanForFrame (); |
579 | int valid_offset = -1; |
580 | if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset)) |
581 | { |
582 | active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (valid_offset); |
583 | row_register_kind = m_full_unwind_plan_sp->GetRegisterKind (); |
584 | if (active_row.get() && log) |
585 | { |
586 | StreamString active_row_strm; |
587 | active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); |
588 | UnwindLogMsg ("active row: %s", active_row_strm.GetString().c_str()); |
589 | } |
590 | } |
591 | } |
592 | |
593 | if (!active_row.get()) |
594 | { |
595 | m_frame_type = eNotAValidFrame; |
596 | UnwindLogMsg ("could not find unwind row for this pc"); |
597 | return; |
598 | } |
599 | |
600 | if (!ReadCFAValueForRow (row_register_kind, active_row, m_cfa)) |
601 | { |
602 | UnwindLogMsg ("failed to get cfa reg %d/%d", row_register_kind, active_row->GetCFARegister()); |
603 | m_frame_type = eNotAValidFrame; |
604 | return; |
605 | } |
606 | |
607 | UnwindLogMsg ("m_cfa = 0x%" PRIx64"l" "x", m_cfa); |
608 | |
609 | if (CheckIfLoopingStack ()) |
610 | { |
611 | TryFallbackUnwindPlan(); |
612 | if (CheckIfLoopingStack ()) |
613 | { |
614 | UnwindLogMsg ("same CFA address as next frame, assuming the unwind is looping - stopping"); |
615 | m_frame_type = eNotAValidFrame; |
616 | return; |
617 | } |
618 | } |
619 | |
620 | UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64"l" "x" " cfa is 0x%" PRIx64"l" "x", |
621 | (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa); |
622 | } |
623 | |
624 | bool |
625 | RegisterContextLLDB::CheckIfLoopingStack () |
626 | { |
627 | // If we have a bad stack setup, we can get the same CFA value multiple times -- or even |
628 | // more devious, we can actually oscillate between two CFA values. Detect that here and |
629 | // break out to avoid a possible infinite loop in lldb trying to unwind the stack. |
630 | addr_t next_frame_cfa; |
631 | addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS(18446744073709551615UL); |
632 | if (GetNextFrame().get() && GetNextFrame()->GetCFA(next_frame_cfa)) |
633 | { |
634 | if (next_frame_cfa == m_cfa) |
635 | { |
636 | // We have a loop in the stack unwind |
637 | return true; |
638 | } |
639 | if (GetNextFrame()->GetNextFrame().get() && GetNextFrame()->GetNextFrame()->GetCFA(next_next_frame_cfa) |
640 | && next_next_frame_cfa == m_cfa) |
641 | { |
642 | // We have a loop in the stack unwind |
643 | return true; |
644 | } |
645 | } |
646 | return false; |
647 | } |
648 | |
649 | |
650 | bool |
651 | RegisterContextLLDB::IsFrameZero () const |
652 | { |
653 | return m_frame_number == 0; |
654 | } |
655 | |
656 | |
657 | // Find a fast unwind plan for this frame, if possible. |
658 | // |
659 | // On entry to this method, |
660 | // |
661 | // 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame if either of those are correct, |
662 | // 2. m_sym_ctx should already be filled in, and |
663 | // 3. m_current_pc should have the current pc value for this frame |
664 | // 4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown |
665 | |
666 | UnwindPlanSP |
667 | RegisterContextLLDB::GetFastUnwindPlanForFrame () |
668 | { |
669 | UnwindPlanSP unwind_plan_sp; |
670 | ModuleSP pc_module_sp (m_current_pc.GetModule()); |
671 | |
672 | if (!m_current_pc.IsValid() || !pc_module_sp || pc_module_sp->GetObjectFile() == NULL__null) |
673 | return unwind_plan_sp; |
674 | |
675 | if (IsFrameZero ()) |
676 | return unwind_plan_sp; |
677 | |
678 | FuncUnwindersSP func_unwinders_sp (pc_module_sp->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx)); |
679 | if (!func_unwinders_sp) |
680 | return unwind_plan_sp; |
681 | |
682 | // If we're in _sigtramp(), unwinding past this frame requires special knowledge. |
683 | if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame) |
684 | return unwind_plan_sp; |
685 | |
686 | unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind (m_thread); |
687 | if (unwind_plan_sp) |
688 | { |
689 | if (unwind_plan_sp->PlanValidAtAddress (m_current_pc)) |
690 | { |
691 | Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND(1u << 15))); |
692 | if (log && log->GetVerbose()) |
693 | { |
694 | if (m_fast_unwind_plan_sp) |
695 | UnwindLogMsgVerbose ("frame, and has a fast UnwindPlan"); |
696 | else |
697 | UnwindLogMsgVerbose ("frame"); |
698 | } |
699 | m_frame_type = eNormalFrame; |
700 | return unwind_plan_sp; |
701 | } |
702 | else |
703 | { |
704 | unwind_plan_sp.reset(); |
705 | } |
706 | } |
707 | return unwind_plan_sp; |
708 | } |
709 | |
710 | // On entry to this method, |
711 | // |
712 | // 1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame if either of those are correct, |
713 | // 2. m_sym_ctx should already be filled in, and |
714 | // 3. m_current_pc should have the current pc value for this frame |
715 | // 4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown |
716 | |
717 | UnwindPlanSP |
718 | RegisterContextLLDB::GetFullUnwindPlanForFrame () |
719 | { |
720 | UnwindPlanSP unwind_plan_sp; |
721 | UnwindPlanSP arch_default_unwind_plan_sp; |
722 | ExecutionContext exe_ctx(m_thread.shared_from_this()); |
723 | Process *process = exe_ctx.GetProcessPtr(); |
724 | ABI *abi = process ? process->GetABI().get() : NULL__null; |
725 | if (abi) |
726 | { |
727 | arch_default_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); |
728 | abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp); |
729 | } |
730 | else |
731 | { |
732 | UnwindLogMsg ("unable to get architectural default UnwindPlan from ABI plugin"); |
733 | } |
734 | |
735 | bool behaves_like_zeroth_frame = false; |
736 | if (IsFrameZero () |
737 | || GetNextFrame()->m_frame_type == eTrapHandlerFrame |
738 | || GetNextFrame()->m_frame_type == eDebuggerFrame) |
739 | { |
740 | behaves_like_zeroth_frame = true; |
741 | // If this frame behaves like a 0th frame (currently executing or |
742 | // interrupted asynchronously), all registers can be retrieved. |
743 | m_all_registers_available = true; |
744 | } |
745 | |
746 | // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer) so the pc is 0x0 |
747 | // in the zeroth frame, we need to use the "unwind at first instruction" arch default UnwindPlan |
748 | // Also, if this Process can report on memory region attributes, any non-executable region means |
749 | // we jumped through a bad function pointer - handle the same way as 0x0. |
750 | // Note, if we have a symbol context & a symbol, we don't want to follow this code path. This is |
751 | // for jumping to memory regions without any information available. |
752 | |
753 | if ((!m_sym_ctx_valid || (m_sym_ctx.function == NULL__null && m_sym_ctx.symbol == NULL__null)) && behaves_like_zeroth_frame && m_current_pc.IsValid()) |
754 | { |
755 | uint32_t permissions; |
756 | addr_t current_pc_addr = m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()); |
757 | if (current_pc_addr == 0 |
758 | || (process && |
759 | process->GetLoadAddressPermissions (current_pc_addr, permissions) |
760 | && (permissions & ePermissionsExecutable) == 0)) |
761 | { |
762 | if (abi) |
763 | { |
764 | unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); |
765 | abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp); |
766 | m_frame_type = eNormalFrame; |
767 | return unwind_plan_sp; |
768 | } |
769 | } |
770 | } |
771 | |
772 | // No Module for the current pc, try using the architecture default unwind. |
773 | ModuleSP pc_module_sp (m_current_pc.GetModule()); |
774 | if (!m_current_pc.IsValid() || !pc_module_sp || pc_module_sp->GetObjectFile() == NULL__null) |
775 | { |
776 | m_frame_type = eNormalFrame; |
777 | return arch_default_unwind_plan_sp; |
778 | } |
779 | |
780 | FuncUnwindersSP func_unwinders_sp; |
781 | if (m_sym_ctx_valid) |
782 | { |
783 | func_unwinders_sp = pc_module_sp->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx); |
784 | } |
785 | |
786 | // No FuncUnwinders available for this pc (i.e. a stripped function symbol and -fomit-frame-pointer). |
787 | // Try using the eh_frame information relative to the current PC, |
788 | // and finally fall back on the architectural default unwind. |
789 | if (!func_unwinders_sp) |
790 | { |
791 | DWARFCallFrameInfo *eh_frame = pc_module_sp && pc_module_sp->GetObjectFile() ? |
792 | pc_module_sp->GetObjectFile()->GetUnwindTable().GetEHFrameInfo() : nullptr; |
793 | |
794 | m_frame_type = eNormalFrame; |
795 | if (eh_frame && m_current_pc.IsValid()) |
796 | { |
797 | unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); |
798 | // Even with -fomit-frame-pointer, we can try eh_frame to get back on track. |
799 | if (eh_frame->GetUnwindPlan (m_current_pc, *unwind_plan_sp)) |
800 | return unwind_plan_sp; |
801 | else |
802 | unwind_plan_sp.reset(); |
803 | } |
804 | return arch_default_unwind_plan_sp; |
805 | } |
806 | |
807 | // If we're in _sigtramp(), unwinding past this frame requires special knowledge. On Mac OS X this knowledge |
808 | // is properly encoded in the eh_frame section, so prefer that if available. |
809 | // On other platforms we may need to provide a platform-specific UnwindPlan which encodes the details of |
810 | // how to unwind out of sigtramp. |
811 | if (m_frame_type == eTrapHandlerFrame && process) |
812 | { |
813 | m_fast_unwind_plan_sp.reset(); |
814 | unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one); |
815 | if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc) && unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) |
816 | { |
817 | return unwind_plan_sp; |
818 | } |
819 | } |
820 | |
821 | // Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame even when it's frame zero |
822 | // This comes up if we have hand-written functions in a Module and hand-written eh_frame. The assembly |
823 | // instruction inspection may fail and the eh_frame CFI were probably written with some care to do the |
824 | // right thing. It'd be nice if there was a way to ask the eh_frame directly if it is asynchronous |
825 | // (can be trusted at every instruction point) or synchronous (the normal case - only at call sites). |
826 | // But there is not. |
827 | if (process && process->GetDynamicLoader() && process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo (m_sym_ctx)) |
828 | { |
829 | // We must specifically call the GetEHFrameUnwindPlan() method here -- normally we would |
830 | // call GetUnwindPlanAtCallSite() -- because CallSite may return an unwind plan sourced from |
831 | // either eh_frame (that's what we intend) or compact unwind (this won't work) |
832 | unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one); |
833 | if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) |
834 | { |
835 | UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan because the DynamicLoader suggested we prefer it", |
836 | unwind_plan_sp->GetSourceName().GetCString()); |
837 | return unwind_plan_sp; |
838 | } |
839 | } |
840 | |
841 | // Typically the NonCallSite UnwindPlan is the unwind created by inspecting the assembly language instructions |
842 | if (behaves_like_zeroth_frame && process) |
843 | { |
844 | unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (process->GetTarget(), m_thread, m_current_offset_backed_up_one); |
845 | if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) |
846 | { |
847 | if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) |
848 | { |
849 | // We probably have an UnwindPlan created by inspecting assembly instructions, and we probably |
850 | // don't have any eh_frame instructions available. |
851 | // The assembly profilers work really well with compiler-generated functions but hand-written |
852 | // assembly can be problematic. We'll set the architecture default UnwindPlan as our fallback |
853 | // UnwindPlan in case this doesn't work out when we try to unwind. |
854 | m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; |
855 | } |
856 | UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString()); |
857 | return unwind_plan_sp; |
858 | } |
859 | } |
860 | |
861 | // Typically this is unwind info from an eh_frame section intended for exception handling; only valid at call sites |
862 | if (process) |
863 | { |
864 | unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (process->GetTarget(), m_current_offset_backed_up_one); |
865 | } |
866 | int valid_offset = -1; |
867 | if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) |
868 | { |
869 | UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString()); |
870 | return unwind_plan_sp; |
871 | } |
872 | |
873 | // We'd prefer to use an UnwindPlan intended for call sites when we're at a call site but if we've |
874 | // struck out on that, fall back to using the non-call-site assembly inspection UnwindPlan if possible. |
875 | if (process) |
876 | { |
877 | unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (process->GetTarget(), m_thread, m_current_offset_backed_up_one); |
878 | } |
879 | if (unwind_plan_sp && unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) |
880 | { |
881 | // We probably have an UnwindPlan created by inspecting assembly instructions, and we probably |
882 | // don't have any eh_frame instructions available. |
883 | // The assembly profilers work really well with compiler-generated functions but hand-written |
884 | // assembly can be problematic. We'll set the architecture default UnwindPlan as our fallback |
885 | // UnwindPlan in case this doesn't work out when we try to unwind. |
886 | m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp; |
887 | } |
888 | |
889 | if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) |
890 | { |
891 | UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString()); |
892 | return unwind_plan_sp; |
893 | } |
894 | |
895 | // If we're on the first instruction of a function, and we have an architectural default UnwindPlan |
896 | // for the initial instruction of a function, use that. |
897 | if (m_current_offset_backed_up_one == 0) |
898 | { |
899 | unwind_plan_sp = func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry (m_thread); |
900 | if (unwind_plan_sp) |
901 | { |
902 | UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString()); |
903 | return unwind_plan_sp; |
904 | } |
905 | } |
906 | |
907 | // If nothing else, use the architectural default UnwindPlan and hope that does the job. |
908 | if (arch_default_unwind_plan_sp) |
909 | UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", arch_default_unwind_plan_sp->GetSourceName().GetCString()); |
910 | else |
911 | UnwindLogMsg ("Unable to find any UnwindPlan for full unwind of this frame."); |
912 | |
913 | return arch_default_unwind_plan_sp; |
914 | } |
915 | |
916 | |
917 | void |
918 | RegisterContextLLDB::InvalidateAllRegisters () |
919 | { |
920 | m_frame_type = eNotAValidFrame; |
921 | } |
922 | |
923 | size_t |
924 | RegisterContextLLDB::GetRegisterCount () |
925 | { |
926 | return m_thread.GetRegisterContext()->GetRegisterCount(); |
927 | } |
928 | |
929 | const RegisterInfo * |
930 | RegisterContextLLDB::GetRegisterInfoAtIndex (size_t reg) |
931 | { |
932 | return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex (reg); |
933 | } |
934 | |
935 | size_t |
936 | RegisterContextLLDB::GetRegisterSetCount () |
937 | { |
938 | return m_thread.GetRegisterContext()->GetRegisterSetCount (); |
939 | } |
940 | |
941 | const RegisterSet * |
942 | RegisterContextLLDB::GetRegisterSet (size_t reg_set) |
943 | { |
944 | return m_thread.GetRegisterContext()->GetRegisterSet (reg_set); |
945 | } |
946 | |
947 | uint32_t |
948 | RegisterContextLLDB::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num) |
949 | { |
950 | return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num); |
951 | } |
952 | |
953 | bool |
954 | RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc, |
955 | const RegisterInfo *reg_info, |
956 | RegisterValue &value) |
957 | { |
958 | if (!IsValid()) |
959 | return false; |
960 | bool success = false; |
961 | |
962 | switch (regloc.type) |
963 | { |
964 | case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: |
965 | { |
966 | const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number); |
967 | |
968 | if (!other_reg_info) |
969 | return false; |
970 | |
971 | success = m_thread.GetRegisterContext()->ReadRegister (other_reg_info, value); |
972 | } |
973 | break; |
974 | case UnwindLLDB::RegisterLocation::eRegisterInRegister: |
975 | { |
976 | const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number); |
977 | |
978 | if (!other_reg_info) |
979 | return false; |
980 | |
981 | if (IsFrameZero ()) |
982 | { |
983 | success = m_thread.GetRegisterContext()->ReadRegister (other_reg_info, value); |
984 | } |
985 | else |
986 | { |
987 | success = GetNextFrame()->ReadRegister (other_reg_info, value); |
988 | } |
989 | } |
990 | break; |
991 | case UnwindLLDB::RegisterLocation::eRegisterValueInferred: |
992 | success = value.SetUInt (regloc.location.inferred_value, reg_info->byte_size); |
993 | break; |
994 | |
995 | case UnwindLLDB::RegisterLocation::eRegisterNotSaved: |
996 | break; |
997 | case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation: |
998 | assert ("FIXME debugger inferior function call unwind")(("FIXME debugger inferior function call unwind") ? static_cast <void> (0) : __assert_fail ("\"FIXME debugger inferior function call unwind\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230168/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp" , 998, __PRETTY_FUNCTION__)); |
999 | break; |
1000 | case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: |
1001 | { |
1002 | Error error (ReadRegisterValueFromMemory(reg_info, |
1003 | regloc.location.target_memory_location, |
1004 | reg_info->byte_size, |
1005 | value)); |
1006 | success = error.Success(); |
1007 | } |
1008 | break; |
1009 | default: |
1010 | assert ("Unknown RegisterLocation type.")(("Unknown RegisterLocation type.") ? static_cast<void> (0) : __assert_fail ("\"Unknown RegisterLocation type.\"", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230168/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp" , 1010, __PRETTY_FUNCTION__)); |
1011 | break; |
1012 | } |
1013 | return success; |
1014 | } |
1015 | |
1016 | bool |
1017 | RegisterContextLLDB::WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc, |
1018 | const RegisterInfo *reg_info, |
1019 | const RegisterValue &value) |
1020 | { |
1021 | if (!IsValid()) |
1022 | return false; |
1023 | |
1024 | bool success = false; |
1025 | |
1026 | switch (regloc.type) |
1027 | { |
1028 | case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: |
1029 | { |
1030 | const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number); |
1031 | success = m_thread.GetRegisterContext()->WriteRegister (other_reg_info, value); |
1032 | } |
1033 | break; |
1034 | case UnwindLLDB::RegisterLocation::eRegisterInRegister: |
1035 | { |
1036 | const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number); |
1037 | if (IsFrameZero ()) |
1038 | { |
1039 | success = m_thread.GetRegisterContext()->WriteRegister (other_reg_info, value); |
1040 | } |
1041 | else |
1042 | { |
1043 | success = GetNextFrame()->WriteRegister (other_reg_info, value); |
1044 | } |
1045 | } |
1046 | break; |
1047 | case UnwindLLDB::RegisterLocation::eRegisterValueInferred: |
1048 | case UnwindLLDB::RegisterLocation::eRegisterNotSaved: |
1049 | break; |
1050 | case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation: |
1051 | assert ("FIXME debugger inferior function call unwind")(("FIXME debugger inferior function call unwind") ? static_cast <void> (0) : __assert_fail ("\"FIXME debugger inferior function call unwind\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230168/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp" , 1051, __PRETTY_FUNCTION__)); |
1052 | break; |
1053 | case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: |
1054 | { |
1055 | Error error (WriteRegisterValueToMemory (reg_info, |
1056 | regloc.location.target_memory_location, |
1057 | reg_info->byte_size, |
1058 | value)); |
1059 | success = error.Success(); |
1060 | } |
1061 | break; |
1062 | default: |
1063 | assert ("Unknown RegisterLocation type.")(("Unknown RegisterLocation type.") ? static_cast<void> (0) : __assert_fail ("\"Unknown RegisterLocation type.\"", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230168/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp" , 1063, __PRETTY_FUNCTION__)); |
1064 | break; |
1065 | } |
1066 | return success; |
1067 | } |
1068 | |
1069 | |
1070 | bool |
1071 | RegisterContextLLDB::IsValid () const |
1072 | { |
1073 | return m_frame_type != eNotAValidFrame; |
1074 | } |
1075 | |
1076 | // After the final stack frame in a stack walk we'll get one invalid (eNotAValidFrame) stack frame -- |
1077 | // one past the end of the stack walk. But higher-level code will need to tell the differnece between |
1078 | // "the unwind plan below this frame failed" versus "we successfully completed the stack walk" so |
1079 | // this method helps to disambiguate that. |
1080 | |
1081 | bool |
1082 | RegisterContextLLDB::IsTrapHandlerFrame () const |
1083 | { |
1084 | return m_frame_type == eTrapHandlerFrame; |
1085 | } |
1086 | |
1087 | // A skip frame is a bogus frame on the stack -- but one where we're likely to find a real frame farther |
1088 | // up the stack if we keep looking. It's always the second frame in an unwind (i.e. the first frame after |
1089 | // frame zero) where unwinding can be the trickiest. Ideally we'll mark up this frame in some way so the |
1090 | // user knows we're displaying bad data and we may have skipped one frame of their real program in the |
1091 | // process of getting back on track. |
1092 | |
1093 | bool |
1094 | RegisterContextLLDB::IsSkipFrame () const |
1095 | { |
1096 | return m_frame_type == eSkipFrame; |
1097 | } |
1098 | |
1099 | bool |
1100 | RegisterContextLLDB::IsTrapHandlerSymbol (lldb_private::Process *process, const lldb_private::SymbolContext &m_sym_ctx) const |
1101 | { |
1102 | PlatformSP platform_sp (process->GetTarget().GetPlatform()); |
1103 | if (platform_sp) |
1104 | { |
1105 | const std::vector<ConstString> trap_handler_names (platform_sp->GetTrapHandlerSymbolNames()); |
1106 | for (ConstString name : trap_handler_names) |
1107 | { |
1108 | if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) || |
1109 | (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) |
1110 | { |
1111 | return true; |
1112 | } |
1113 | } |
1114 | } |
1115 | const std::vector<ConstString> user_specified_trap_handler_names (m_parent_unwind.GetUserSpecifiedTrapHandlerFunctionNames()); |
1116 | for (ConstString name : user_specified_trap_handler_names) |
1117 | { |
1118 | if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) || |
1119 | (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) |
1120 | { |
1121 | return true; |
1122 | } |
1123 | } |
1124 | |
1125 | return false; |
1126 | } |
1127 | |
1128 | // Answer the question: Where did THIS frame save the CALLER frame ("previous" frame)'s register value? |
1129 | |
1130 | enum UnwindLLDB::RegisterSearchResult |
1131 | RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc) |
1132 | { |
1133 | RegisterNumber regnum (m_thread, eRegisterKindLLDB, lldb_regnum); |
1134 | |
1135 | // Have we already found this register location? |
1136 | if (!m_registers.empty()) |
1137 | { |
1138 | std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation>::const_iterator iterator; |
1139 | iterator = m_registers.find (regnum.GetAsKind (eRegisterKindLLDB)); |
1140 | if (iterator != m_registers.end()) |
1141 | { |
1142 | regloc = iterator->second; |
1143 | UnwindLogMsg ("supplying caller's saved %s (%d)'s location, cached", |
1144 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1145 | return UnwindLLDB::RegisterSearchResult::eRegisterFound; |
1146 | } |
1147 | } |
1148 | |
1149 | // Look through the available UnwindPlans for the register location. |
1150 | |
1151 | UnwindPlan::Row::RegisterLocation unwindplan_regloc; |
1152 | bool have_unwindplan_regloc = false; |
1153 | RegisterKind unwindplan_registerkind = kNumRegisterKinds; |
1154 | |
1155 | if (m_fast_unwind_plan_sp) |
1156 | { |
1157 | UnwindPlan::RowSP active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); |
1158 | unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind (); |
1159 | if (regnum.GetAsKind (unwindplan_registerkind) == LLDB_INVALID_REGNUM(4294967295U)) |
1160 | { |
1161 | UnwindLogMsg ("could not convert lldb regnum %s (%d) into %d RegisterKind reg numbering scheme", |
1162 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), (int) unwindplan_registerkind); |
1163 | return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; |
1164 | } |
1165 | if (active_row->GetRegisterInfo (regnum.GetAsKind (unwindplan_registerkind), unwindplan_regloc)) |
1166 | { |
1167 | UnwindLogMsg ("supplying caller's saved %s (%d)'s location using FastUnwindPlan", |
1168 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1169 | have_unwindplan_regloc = true; |
1170 | } |
1171 | } |
1172 | |
1173 | if (!have_unwindplan_regloc) |
1174 | { |
1175 | // m_full_unwind_plan_sp being NULL means that we haven't tried to find a full UnwindPlan yet |
1176 | if (!m_full_unwind_plan_sp) |
1177 | m_full_unwind_plan_sp = GetFullUnwindPlanForFrame (); |
1178 | |
1179 | if (m_full_unwind_plan_sp) |
1180 | { |
1181 | RegisterNumber pc_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC0); |
1182 | |
1183 | UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); |
1184 | unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind (); |
1185 | |
1186 | RegisterNumber return_address_reg; |
1187 | |
1188 | // If we're fetching the saved pc and this UnwindPlan defines a ReturnAddress register (e.g. lr on arm), |
1189 | // look for the return address register number in the UnwindPlan's row. |
1190 | if (pc_regnum.IsValid() |
1191 | && pc_regnum == regnum |
1192 | && m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM(4294967295U)) |
1193 | { |
1194 | |
1195 | return_address_reg.init (m_thread, m_full_unwind_plan_sp->GetRegisterKind(), m_full_unwind_plan_sp->GetReturnAddressRegister()); |
1196 | regnum = return_address_reg; |
1197 | UnwindLogMsg ("requested caller's saved PC but this UnwindPlan uses a RA reg; getting %s (%d) instead", |
1198 | return_address_reg.GetName(), return_address_reg.GetAsKind (eRegisterKindLLDB)); |
1199 | } |
1200 | else |
1201 | { |
1202 | if (regnum.GetAsKind (unwindplan_registerkind) == LLDB_INVALID_REGNUM(4294967295U)) |
1203 | { |
1204 | if (unwindplan_registerkind == eRegisterKindGeneric) |
1205 | { |
1206 | UnwindLogMsg ("could not convert lldb regnum %s (%d) into eRegisterKindGeneric reg numbering scheme", |
1207 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1208 | } |
1209 | else |
1210 | { |
1211 | UnwindLogMsg ("could not convert lldb regnum %s (%d) into %d RegisterKind reg numbering scheme", |
1212 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), (int) unwindplan_registerkind); |
1213 | } |
1214 | return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; |
1215 | } |
1216 | } |
1217 | |
1218 | if (regnum.IsValid() |
1219 | && active_row->GetRegisterInfo (regnum.GetAsKind (unwindplan_registerkind), unwindplan_regloc)) |
1220 | { |
1221 | have_unwindplan_regloc = true; |
1222 | UnwindLogMsg ("supplying caller's saved %s (%d)'s location using %s UnwindPlan", |
1223 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), |
1224 | m_full_unwind_plan_sp->GetSourceName().GetCString()); |
1225 | } |
1226 | |
1227 | // This is frame 0 and we're retrieving the PC and it's saved in a Return Address register and |
1228 | // it hasn't been saved anywhere yet -- that is, it's still live in the actual register. |
1229 | // Handle this specially. |
1230 | |
1231 | if (have_unwindplan_regloc == false |
1232 | && return_address_reg.IsValid() |
1233 | && IsFrameZero()) |
1234 | { |
1235 | if (return_address_reg.GetAsKind (eRegisterKindLLDB) != LLDB_INVALID_REGNUM(4294967295U)) |
1236 | { |
1237 | lldb_private::UnwindLLDB::RegisterLocation new_regloc; |
1238 | new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext; |
1239 | new_regloc.location.register_number = return_address_reg.GetAsKind (eRegisterKindLLDB); |
1240 | m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc; |
1241 | regloc = new_regloc; |
1242 | UnwindLogMsg ("supplying caller's register %s (%d) from the live RegisterContext at frame 0, saved in %d", |
1243 | return_address_reg.GetName(), return_address_reg.GetAsKind (eRegisterKindLLDB), |
1244 | return_address_reg.GetAsKind (eRegisterKindLLDB)); |
1245 | return UnwindLLDB::RegisterSearchResult::eRegisterFound; |
1246 | } |
1247 | } |
1248 | |
1249 | // If this architecture stores the return address in a register (it defines a Return Address register) |
1250 | // and we're on a non-zero stack frame and the Full UnwindPlan says that the pc is stored in the |
1251 | // RA registers (e.g. lr on arm), then we know that the full unwindplan is not trustworthy -- this |
1252 | // is an impossible situation and the instruction emulation code has likely been misled. |
1253 | // If this stack frame meets those criteria, we need to throw away the Full UnwindPlan that the |
1254 | // instruction emulation came up with and fall back to the architecture's Default UnwindPlan so |
1255 | // the stack walk can get past this point. |
1256 | |
1257 | // Special note: If the Full UnwindPlan was generated from the compiler, don't second-guess it |
1258 | // when we're at a call site location. |
1259 | |
1260 | // arch_default_ra_regnum is the return address register # in the Full UnwindPlan register numbering |
1261 | RegisterNumber arch_default_ra_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA3); |
1262 | |
1263 | if (arch_default_ra_regnum.GetAsKind (unwindplan_registerkind) != LLDB_INVALID_REGNUM(4294967295U) |
1264 | && pc_regnum == regnum |
1265 | && unwindplan_regloc.IsInOtherRegister() |
1266 | && unwindplan_regloc.GetRegisterNumber() == arch_default_ra_regnum.GetAsKind (unwindplan_registerkind) |
1267 | && m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes |
1268 | && !m_all_registers_available) |
1269 | { |
1270 | UnwindLogMsg ("%s UnwindPlan tried to restore the pc from the link register but this is a non-zero frame", |
1271 | m_full_unwind_plan_sp->GetSourceName().GetCString()); |
1272 | |
1273 | // Throw away the full unwindplan; install the arch default unwindplan |
1274 | if (ForceSwitchToFallbackUnwindPlan()) |
1275 | { |
1276 | // Update for the possibly new unwind plan |
1277 | unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind (); |
1278 | UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); |
1279 | |
1280 | // Sanity check: Verify that we can fetch a pc value and CFA value with this unwind plan |
1281 | |
1282 | RegisterNumber arch_default_pc_reg (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC0); |
1283 | bool can_fetch_pc_value = false; |
1284 | bool can_fetch_cfa = false; |
1285 | addr_t cfa_value; |
1286 | if (active_row) |
1287 | { |
1288 | if (arch_default_pc_reg.GetAsKind (unwindplan_registerkind) != LLDB_INVALID_REGNUM(4294967295U) |
1289 | && active_row->GetRegisterInfo (arch_default_pc_reg.GetAsKind (unwindplan_registerkind), unwindplan_regloc)) |
1290 | { |
1291 | can_fetch_pc_value = true; |
1292 | } |
1293 | if (ReadCFAValueForRow (unwindplan_registerkind, active_row, cfa_value)) |
1294 | { |
1295 | can_fetch_cfa = true; |
1296 | } |
1297 | } |
1298 | |
1299 | if (can_fetch_pc_value && can_fetch_cfa) |
1300 | { |
1301 | have_unwindplan_regloc = true; |
1302 | } |
1303 | else |
1304 | { |
1305 | have_unwindplan_regloc = false; |
1306 | } |
1307 | } |
1308 | else |
1309 | { |
1310 | // We were unable to fall back to another unwind plan |
1311 | have_unwindplan_regloc = false; |
1312 | } |
1313 | } |
1314 | } |
1315 | } |
1316 | |
1317 | if (have_unwindplan_regloc == false) |
1318 | { |
1319 | // Did the UnwindPlan fail to give us the caller's stack pointer? |
1320 | // The stack pointer is defined to be the same as THIS frame's CFA, so return the CFA value as |
1321 | // the caller's stack pointer. This is true on x86-32/x86-64 at least. |
1322 | |
1323 | RegisterNumber sp_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP1); |
1324 | if (sp_regnum.GetAsKind (eRegisterKindLLDB) != LLDB_INVALID_REGNUM(4294967295U) |
1325 | && sp_regnum.GetAsKind (eRegisterKindLLDB) == regnum.GetAsKind (eRegisterKindLLDB)) |
1326 | { |
1327 | // make sure we won't lose precision copying an addr_t (m_cfa) into a uint64_t (.inferred_value) |
1328 | assert (sizeof (addr_t) <= sizeof (uint64_t))((sizeof (addr_t) <= sizeof (uint64_t)) ? static_cast<void > (0) : __assert_fail ("sizeof (addr_t) <= sizeof (uint64_t)" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn230168/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp" , 1328, __PRETTY_FUNCTION__)); |
1329 | regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; |
1330 | regloc.location.inferred_value = m_cfa; |
1331 | m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc; |
1332 | UnwindLogMsg ("supplying caller's stack pointer %s (%d) value, computed from CFA", |
1333 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1334 | return UnwindLLDB::RegisterSearchResult::eRegisterFound; |
1335 | } |
1336 | } |
1337 | |
1338 | ExecutionContext exe_ctx(m_thread.shared_from_this()); |
1339 | Process *process = exe_ctx.GetProcessPtr(); |
1340 | if (have_unwindplan_regloc == false) |
1341 | { |
1342 | // If a volatile register is being requested, we don't want to forward the next frame's register contents |
1343 | // up the stack -- the register is not retrievable at this frame. |
1344 | ABI *abi = process ? process->GetABI().get() : NULL__null; |
1345 | if (abi) |
1346 | { |
1347 | const RegisterInfo *reg_info = GetRegisterInfoAtIndex(regnum.GetAsKind (eRegisterKindLLDB)); |
1348 | if (reg_info && abi->RegisterIsVolatile (reg_info)) |
1349 | { |
1350 | UnwindLogMsg ("did not supply reg location for %s (%d) because it is volatile", |
1351 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1352 | return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile; |
1353 | } |
1354 | } |
1355 | |
1356 | if (IsFrameZero ()) |
1357 | { |
1358 | // This is frame 0 - we should return the actual live register context value |
1359 | lldb_private::UnwindLLDB::RegisterLocation new_regloc; |
1360 | new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext; |
1361 | new_regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB); |
1362 | m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc; |
1363 | regloc = new_regloc; |
1364 | UnwindLogMsg ("supplying caller's register %s (%d) from the live RegisterContext at frame 0", |
1365 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1366 | return UnwindLLDB::RegisterSearchResult::eRegisterFound; |
1367 | } |
1368 | else |
1369 | { |
1370 | std::string unwindplan_name (""); |
1371 | if (m_full_unwind_plan_sp) |
1372 | { |
1373 | unwindplan_name += "via '"; |
1374 | unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString(); |
1375 | unwindplan_name += "'"; |
1376 | } |
1377 | UnwindLogMsg ("no save location for %s (%d) %s", |
1378 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), |
1379 | unwindplan_name.c_str()); |
1380 | } |
1381 | return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; |
1382 | } |
1383 | |
1384 | // unwindplan_regloc has valid contents about where to retrieve the register |
1385 | if (unwindplan_regloc.IsUnspecified()) |
1386 | { |
1387 | lldb_private::UnwindLLDB::RegisterLocation new_regloc; |
1388 | new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved; |
1389 | m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc; |
1390 | UnwindLogMsg ("save location for %s (%d) is unspecified, continue searching", |
1391 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1392 | return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; |
1393 | } |
1394 | |
1395 | if (unwindplan_regloc.IsSame()) |
1396 | { |
1397 | if (IsFrameZero ()) |
1398 | { |
1399 | UnwindLogMsg ("could not supply caller's %s (%d) location, IsSame", |
1400 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1401 | return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; |
1402 | } |
1403 | else |
1404 | { |
1405 | return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; |
1406 | } |
1407 | } |
1408 | |
1409 | if (unwindplan_regloc.IsCFAPlusOffset()) |
1410 | { |
1411 | int offset = unwindplan_regloc.GetOffset(); |
1412 | regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; |
1413 | regloc.location.inferred_value = m_cfa + offset; |
1414 | m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc; |
1415 | UnwindLogMsg ("supplying caller's register %s (%d), value is CFA plus offset %d [value is 0x%" PRIx64"l" "x" "]", |
1416 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), |
1417 | offset, regloc.location.inferred_value); |
1418 | return UnwindLLDB::RegisterSearchResult::eRegisterFound; |
1419 | } |
1420 | |
1421 | if (unwindplan_regloc.IsAtCFAPlusOffset()) |
1422 | { |
1423 | int offset = unwindplan_regloc.GetOffset(); |
1424 | regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation; |
1425 | regloc.location.target_memory_location = m_cfa + offset; |
1426 | m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc; |
1427 | UnwindLogMsg ("supplying caller's register %s (%d) from the stack, saved at CFA plus offset %d [saved at 0x%" PRIx64"l" "x" "]", |
1428 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), |
1429 | offset, regloc.location.target_memory_location); |
1430 | return UnwindLLDB::RegisterSearchResult::eRegisterFound; |
1431 | } |
1432 | |
1433 | if (unwindplan_regloc.IsInOtherRegister()) |
1434 | { |
1435 | uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber(); |
1436 | RegisterNumber row_regnum (m_thread, unwindplan_registerkind, unwindplan_regnum); |
1437 | if (row_regnum.GetAsKind (eRegisterKindLLDB) == LLDB_INVALID_REGNUM(4294967295U)) |
1438 | { |
1439 | UnwindLogMsg ("could not supply caller's %s (%d) location - was saved in another reg but couldn't convert that regnum", |
1440 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1441 | return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; |
1442 | } |
1443 | regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister; |
1444 | regloc.location.register_number = row_regnum.GetAsKind (eRegisterKindLLDB); |
1445 | m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc; |
1446 | UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)", |
1447 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), |
1448 | row_regnum.GetName(), row_regnum.GetAsKind (eRegisterKindLLDB)); |
1449 | return UnwindLLDB::RegisterSearchResult::eRegisterFound; |
1450 | } |
1451 | |
1452 | if (unwindplan_regloc.IsDWARFExpression() || unwindplan_regloc.IsAtDWARFExpression()) |
1453 | { |
1454 | DataExtractor dwarfdata (unwindplan_regloc.GetDWARFExpressionBytes(), |
1455 | unwindplan_regloc.GetDWARFExpressionLength(), |
1456 | process->GetByteOrder(), process->GetAddressByteSize()); |
1457 | ModuleSP opcode_ctx; |
1458 | DWARFExpression dwarfexpr (opcode_ctx, dwarfdata, 0, unwindplan_regloc.GetDWARFExpressionLength()); |
1459 | dwarfexpr.SetRegisterKind (unwindplan_registerkind); |
1460 | Value result; |
1461 | Error error; |
1462 | if (dwarfexpr.Evaluate (&exe_ctx, NULL__null, NULL__null, this, 0, NULL__null, result, &error)) |
1463 | { |
1464 | addr_t val; |
1465 | val = result.GetScalar().ULongLong(); |
1466 | if (unwindplan_regloc.IsDWARFExpression()) |
1467 | { |
1468 | regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; |
1469 | regloc.location.inferred_value = val; |
1470 | m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc; |
1471 | UnwindLogMsg ("supplying caller's register %s (%d) via DWARF expression (IsDWARFExpression)", |
1472 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1473 | return UnwindLLDB::RegisterSearchResult::eRegisterFound; |
1474 | } |
1475 | else |
1476 | { |
1477 | regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation; |
1478 | regloc.location.target_memory_location = val; |
1479 | m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc; |
1480 | UnwindLogMsg ("supplying caller's register %s (%d) via DWARF expression (IsAtDWARFExpression)", |
1481 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1482 | return UnwindLLDB::RegisterSearchResult::eRegisterFound; |
1483 | } |
1484 | } |
1485 | UnwindLogMsg ("tried to use IsDWARFExpression or IsAtDWARFExpression for %s (%d) but failed", |
1486 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1487 | return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; |
1488 | } |
1489 | |
1490 | UnwindLogMsg ("no save location for %s (%d) in this stack frame", |
1491 | regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); |
1492 | |
1493 | // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are unsupported. |
1494 | |
1495 | return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; |
1496 | } |
1497 | |
1498 | // TryFallbackUnwindPlan() -- this method is a little tricky. |
1499 | // |
1500 | // When this is called, the frame above -- the caller frame, the "previous" frame -- |
1501 | // is invalid or bad. |
1502 | // |
1503 | // Instead of stopping the stack walk here, we'll try a different UnwindPlan and see |
1504 | // if we can get a valid frame above us. |
1505 | // |
1506 | // This most often happens when an unwind plan based on assembly instruction inspection |
1507 | // is not correct -- mostly with hand-written assembly functions or functions where the |
1508 | // stack frame is set up "out of band", e.g. the kernel saved the register context and |
1509 | // then called an asynchronous trap handler like _sigtramp. |
1510 | // |
1511 | // Often in these cases, if we just do a dumb stack walk we'll get past this tricky |
1512 | // frame and our usual techniques can continue to be used. |
1513 | |
1514 | bool |
1515 | RegisterContextLLDB::TryFallbackUnwindPlan () |
1516 | { |
1517 | if (m_fallback_unwind_plan_sp.get() == nullptr) |
1518 | return false; |
1519 | |
1520 | if (m_full_unwind_plan_sp.get() == nullptr) |
1521 | return false; |
1522 | |
1523 | if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() |
1524 | || m_full_unwind_plan_sp->GetSourceName() == m_fallback_unwind_plan_sp->GetSourceName()) |
1525 | { |
1526 | return false; |
1527 | } |
1528 | |
1529 | // If a compiler generated unwind plan failed, trying the arch default unwindplan |
1530 | // isn't going to do any better. |
1531 | if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) |
1532 | return false; |
1533 | |
1534 | |
1535 | // Get the caller's pc value and our own CFA value. |
1536 | // Swap in the fallback unwind plan, re-fetch the caller's pc value and CFA value. |
1537 | // If they're the same, then the fallback unwind plan provides no benefit. |
1538 | |
1539 | RegisterNumber pc_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC0); |
1540 | |
1541 | addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS(18446744073709551615UL); |
1542 | addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS(18446744073709551615UL); |
1543 | addr_t old_this_frame_cfa_value = m_cfa; |
1544 | UnwindLLDB::RegisterLocation regloc; |
1545 | if (SavedLocationForRegister (pc_regnum.GetAsKind (eRegisterKindLLDB), regloc) == UnwindLLDB::RegisterSearchResult::eRegisterFound) |
1546 | { |
1547 | const RegisterInfo *reg_info = GetRegisterInfoAtIndex(pc_regnum.GetAsKind (eRegisterKindLLDB)); |
1548 | if (reg_info) |
1549 | { |
1550 | RegisterValue reg_value; |
1551 | if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value)) |
1552 | { |
1553 | old_caller_pc_value = reg_value.GetAsUInt64(); |
1554 | } |
1555 | } |
1556 | } |
1557 | |
1558 | // This is a tricky wrinkle! If SavedLocationForRegister() detects a really impossible |
1559 | // register location for the full unwind plan, it may call ForceSwitchToFallbackUnwindPlan() |
1560 | // which in turn replaces the full unwindplan with the fallback... in short, we're done, |
1561 | // we're using the fallback UnwindPlan. |
1562 | // We checked if m_fallback_unwind_plan_sp was nullptr at the top -- the only way it |
1563 | // became nullptr since then is via SavedLocationForRegister(). |
1564 | if (m_fallback_unwind_plan_sp.get() == nullptr) |
1565 | return true; |
1566 | |
1567 | |
1568 | // Switch the full UnwindPlan to be the fallback UnwindPlan. If we decide this isn't |
1569 | // working, we need to restore. |
1570 | // We'll also need to save & restore the value of the m_cfa ivar. Save is down below a bit in 'old_cfa'. |
1571 | UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp; |
1572 | addr_t old_cfa = m_cfa; |
1573 | |
1574 | m_registers.clear(); |
1575 | |
1576 | m_full_unwind_plan_sp = m_fallback_unwind_plan_sp; |
1577 | |
1578 | UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); |
1579 | |
1580 | if (active_row && active_row->GetCFARegister() != LLDB_INVALID_REGNUM(4294967295U)) |
1581 | { |
1582 | addr_t new_cfa; |
1583 | if (!ReadCFAValueForRow (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row, new_cfa) |
1584 | || new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS(18446744073709551615UL)) |
1585 | { |
1586 | UnwindLogMsg ("failed to get cfa with fallback unwindplan"); |
1587 | m_fallback_unwind_plan_sp.reset(); |
1588 | m_full_unwind_plan_sp = original_full_unwind_plan_sp; |
1589 | m_cfa = old_cfa; |
1590 | return false; |
1591 | } |
1592 | m_cfa = new_cfa; |
1593 | |
1594 | if (SavedLocationForRegister (pc_regnum.GetAsKind (eRegisterKindLLDB), regloc) == UnwindLLDB::RegisterSearchResult::eRegisterFound) |
1595 | { |
1596 | const RegisterInfo *reg_info = GetRegisterInfoAtIndex(pc_regnum.GetAsKind (eRegisterKindLLDB)); |
1597 | if (reg_info) |
1598 | { |
1599 | RegisterValue reg_value; |
1600 | if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value)) |
1601 | { |
1602 | new_caller_pc_value = reg_value.GetAsUInt64(); |
1603 | } |
1604 | } |
1605 | } |
1606 | |
1607 | |
1608 | if (new_caller_pc_value == LLDB_INVALID_ADDRESS(18446744073709551615UL)) |
1609 | { |
1610 | UnwindLogMsg ("failed to get a pc value for the caller frame with the fallback unwind plan"); |
1611 | m_fallback_unwind_plan_sp.reset(); |
1612 | m_full_unwind_plan_sp = original_full_unwind_plan_sp; |
1613 | m_cfa = old_cfa; |
1614 | return false; |
1615 | } |
1616 | |
1617 | if (old_caller_pc_value != LLDB_INVALID_ADDRESS(18446744073709551615UL)) |
1618 | { |
1619 | if (old_caller_pc_value == new_caller_pc_value && new_cfa == old_this_frame_cfa_value) |
1620 | { |
1621 | UnwindLogMsg ("fallback unwind plan got the same values for this frame CFA and caller frame pc, not using"); |
1622 | m_fallback_unwind_plan_sp.reset(); |
1623 | m_full_unwind_plan_sp = original_full_unwind_plan_sp; |
1624 | m_cfa = old_cfa; |
1625 | return false; |
1626 | } |
1627 | } |
1628 | |
1629 | UnwindLogMsg ("trying to unwind from this function with the UnwindPlan '%s' because UnwindPlan '%s' failed.", |
1630 | m_fallback_unwind_plan_sp->GetSourceName().GetCString(), |
1631 | original_full_unwind_plan_sp->GetSourceName().GetCString()); |
1632 | |
1633 | // We've copied the fallback unwind plan into the full - now clear the fallback. |
1634 | m_fallback_unwind_plan_sp.reset(); |
1635 | } |
1636 | |
1637 | return true; |
1638 | } |
1639 | |
1640 | bool |
1641 | RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan () |
1642 | { |
1643 | if (m_fallback_unwind_plan_sp.get() == NULL__null) |
1644 | return false; |
1645 | |
1646 | if (m_full_unwind_plan_sp.get() == NULL__null) |
1647 | return false; |
1648 | |
1649 | if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() |
1650 | || m_full_unwind_plan_sp->GetSourceName() == m_fallback_unwind_plan_sp->GetSourceName()) |
1651 | { |
1652 | return false; |
1653 | } |
1654 | |
1655 | UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); |
1656 | |
1657 | if (active_row && active_row->GetCFARegister() != LLDB_INVALID_REGNUM(4294967295U)) |
1658 | { |
1659 | addr_t new_cfa; |
1660 | if (!ReadCFAValueForRow (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row, new_cfa) |
1661 | || new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS(18446744073709551615UL)) |
1662 | { |
1663 | UnwindLogMsg ("failed to get cfa with fallback unwindplan"); |
1664 | m_fallback_unwind_plan_sp.reset(); |
1665 | return false; |
1666 | } |
1667 | |
1668 | m_full_unwind_plan_sp = m_fallback_unwind_plan_sp; |
1669 | m_fallback_unwind_plan_sp.reset(); |
1670 | |
1671 | m_registers.clear(); |
1672 | |
1673 | m_cfa = new_cfa; |
1674 | |
1675 | UnwindLogMsg ("switched unconditionally to the fallback unwindplan %s", m_full_unwind_plan_sp->GetSourceName().GetCString()); |
1676 | return true; |
1677 | } |
1678 | return false; |
1679 | } |
1680 | |
1681 | bool |
1682 | RegisterContextLLDB::ReadCFAValueForRow (lldb::RegisterKind row_register_kind, |
1683 | const UnwindPlan::RowSP &row, |
1684 | addr_t &cfa_value) |
1685 | { |
1686 | RegisterNumber cfa_reg (m_thread, row_register_kind, row->GetCFARegister()); |
1687 | RegisterValue reg_value; |
1688 | |
1689 | cfa_value = LLDB_INVALID_ADDRESS(18446744073709551615UL); |
1690 | addr_t cfa_reg_contents; |
1691 | |
1692 | if (ReadGPRValue (cfa_reg, cfa_reg_contents)) |
1693 | { |
1694 | if (row->GetCFAType() == UnwindPlan::Row::CFAIsRegisterDereferenced) |
1695 | { |
1696 | const RegisterInfo *reg_info = GetRegisterInfoAtIndex (cfa_reg.GetAsKind (eRegisterKindLLDB)); |
1697 | RegisterValue reg_value; |
1698 | if (reg_info) |
1699 | { |
1700 | Error error = ReadRegisterValueFromMemory(reg_info, |
1701 | cfa_reg_contents, |
1702 | reg_info->byte_size, |
1703 | reg_value); |
1704 | if (error.Success ()) |
1705 | { |
1706 | cfa_value = reg_value.GetAsUInt64(); |
1707 | UnwindLogMsg ("CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64"l" "x" ", CFA value is 0x%" PRIx64"l" "x", |
1708 | cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB), |
1709 | cfa_reg_contents, cfa_value); |
1710 | return true; |
1711 | } |
1712 | else |
1713 | { |
1714 | UnwindLogMsg ("Tried to deref reg %s (%d) [0x%" PRIx64"l" "x" "] but memory read failed.", |
1715 | cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB), |
1716 | cfa_reg_contents); |
1717 | } |
1718 | } |
1719 | } |
1720 | else |
1721 | { |
1722 | if (cfa_reg_contents == LLDB_INVALID_ADDRESS(18446744073709551615UL) || cfa_reg_contents == 0 || cfa_reg_contents == 1) |
1723 | { |
1724 | UnwindLogMsg ("Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64"l" "x", |
1725 | cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB), |
1726 | cfa_reg_contents); |
1727 | cfa_reg_contents = LLDB_INVALID_ADDRESS(18446744073709551615UL); |
Value stored to 'cfa_reg_contents' is never read | |
1728 | return false; |
1729 | } |
1730 | cfa_value = cfa_reg_contents + row->GetCFAOffset (); |
1731 | UnwindLogMsg ("CFA is 0x%" PRIx64"l" "x" ": Register %s (%d) contents are 0x%" PRIx64"l" "x" ", offset is %d", |
1732 | cfa_value, |
1733 | cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB), |
1734 | cfa_reg_contents, row->GetCFAOffset ()); |
1735 | return true; |
1736 | } |
1737 | } |
1738 | return false; |
1739 | } |
1740 | |
1741 | // Retrieve a general purpose register value for THIS frame, as saved by the NEXT frame, i.e. the frame that |
1742 | // this frame called. e.g. |
1743 | // |
1744 | // foo () { } |
1745 | // bar () { foo (); } |
1746 | // main () { bar (); } |
1747 | // |
1748 | // stopped in foo() so |
1749 | // frame 0 - foo |
1750 | // frame 1 - bar |
1751 | // frame 2 - main |
1752 | // and this RegisterContext is for frame 1 (bar) - if we want to get the pc value for frame 1, we need to ask |
1753 | // where frame 0 (the "next" frame) saved that and retrieve the value. |
1754 | |
1755 | bool |
1756 | RegisterContextLLDB::ReadGPRValue (lldb::RegisterKind register_kind, uint32_t regnum, addr_t &value) |
1757 | { |
1758 | if (!IsValid()) |
1759 | return false; |
1760 | |
1761 | uint32_t lldb_regnum; |
1762 | if (register_kind == eRegisterKindLLDB) |
1763 | { |
1764 | lldb_regnum = regnum; |
1765 | } |
1766 | else if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (register_kind, regnum, eRegisterKindLLDB, lldb_regnum)) |
1767 | { |
1768 | return false; |
1769 | } |
1770 | |
1771 | const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum); |
1772 | RegisterValue reg_value; |
1773 | // if this is frame 0 (currently executing frame), get the requested reg contents from the actual thread registers |
1774 | if (IsFrameZero ()) |
1775 | { |
1776 | if (m_thread.GetRegisterContext()->ReadRegister (reg_info, reg_value)) |
1777 | { |
1778 | value = reg_value.GetAsUInt64(); |
1779 | return true; |
1780 | } |
1781 | return false; |
1782 | } |
1783 | |
1784 | bool pc_register = false; |
1785 | uint32_t generic_regnum; |
1786 | if (register_kind == eRegisterKindGeneric && regnum == LLDB_REGNUM_GENERIC_PC0) |
1787 | { |
1788 | pc_register = true; |
1789 | } |
1790 | else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (register_kind, regnum, eRegisterKindGeneric, generic_regnum) |
1791 | && generic_regnum == LLDB_REGNUM_GENERIC_PC0) |
1792 | { |
1793 | pc_register = true; |
1794 | } |
1795 | |
1796 | lldb_private::UnwindLLDB::RegisterLocation regloc; |
1797 | if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, pc_register)) |
1798 | { |
1799 | return false; |
1800 | } |
1801 | if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value)) |
1802 | { |
1803 | value = reg_value.GetAsUInt64(); |
1804 | return true; |
1805 | } |
1806 | return false; |
1807 | } |
1808 | |
1809 | bool |
1810 | RegisterContextLLDB::ReadGPRValue (const RegisterNumber ®num, addr_t &value) |
1811 | { |
1812 | return ReadGPRValue (regnum.GetRegisterKind(), regnum.GetRegisterNumber(), value); |
1813 | } |
1814 | |
1815 | // Find the value of a register in THIS frame |
1816 | |
1817 | bool |
1818 | RegisterContextLLDB::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) |
1819 | { |
1820 | if (!IsValid()) |
1821 | return false; |
1822 | |
1823 | const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB]; |
1824 | UnwindLogMsgVerbose ("looking for register saved location for reg %d", lldb_regnum); |
1825 | |
1826 | // If this is the 0th frame, hand this over to the live register context |
1827 | if (IsFrameZero ()) |
1828 | { |
1829 | UnwindLogMsgVerbose ("passing along to the live register context for reg %d", lldb_regnum); |
1830 | return m_thread.GetRegisterContext()->ReadRegister (reg_info, value); |
1831 | } |
1832 | |
1833 | lldb_private::UnwindLLDB::RegisterLocation regloc; |
1834 | // Find out where the NEXT frame saved THIS frame's register contents |
1835 | if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, false)) |
1836 | return false; |
1837 | |
1838 | return ReadRegisterValueFromRegisterLocation (regloc, reg_info, value); |
1839 | } |
1840 | |
1841 | bool |
1842 | RegisterContextLLDB::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &value) |
1843 | { |
1844 | if (!IsValid()) |
1845 | return false; |
1846 | |
1847 | const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB]; |
1848 | UnwindLogMsgVerbose ("looking for register saved location for reg %d", lldb_regnum); |
1849 | |
1850 | // If this is the 0th frame, hand this over to the live register context |
1851 | if (IsFrameZero ()) |
1852 | { |
1853 | UnwindLogMsgVerbose ("passing along to the live register context for reg %d", lldb_regnum); |
1854 | return m_thread.GetRegisterContext()->WriteRegister (reg_info, value); |
1855 | } |
1856 | |
1857 | lldb_private::UnwindLLDB::RegisterLocation regloc; |
1858 | // Find out where the NEXT frame saved THIS frame's register contents |
1859 | if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, false)) |
1860 | return false; |
1861 | |
1862 | return WriteRegisterValueToRegisterLocation (regloc, reg_info, value); |
1863 | } |
1864 | |
1865 | // Don't need to implement this one |
1866 | bool |
1867 | RegisterContextLLDB::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) |
1868 | { |
1869 | return false; |
1870 | } |
1871 | |
1872 | // Don't need to implement this one |
1873 | bool |
1874 | RegisterContextLLDB::WriteAllRegisterValues (const lldb::DataBufferSP& data_sp) |
1875 | { |
1876 | return false; |
1877 | } |
1878 | |
1879 | // Retrieve the pc value for THIS from |
1880 | |
1881 | bool |
1882 | RegisterContextLLDB::GetCFA (addr_t& cfa) |
1883 | { |
1884 | if (!IsValid()) |
1885 | { |
1886 | return false; |
1887 | } |
1888 | if (m_cfa == LLDB_INVALID_ADDRESS(18446744073709551615UL)) |
1889 | { |
1890 | return false; |
1891 | } |
1892 | cfa = m_cfa; |
1893 | return true; |
1894 | } |
1895 | |
1896 | |
1897 | RegisterContextLLDB::SharedPtr |
1898 | RegisterContextLLDB::GetNextFrame () const |
1899 | { |
1900 | RegisterContextLLDB::SharedPtr regctx; |
1901 | if (m_frame_number == 0) |
1902 | return regctx; |
1903 | return m_parent_unwind.GetRegisterContextForFrameNum (m_frame_number - 1); |
1904 | } |
1905 | |
1906 | RegisterContextLLDB::SharedPtr |
1907 | RegisterContextLLDB::GetPrevFrame () const |
1908 | { |
1909 | RegisterContextLLDB::SharedPtr regctx; |
1910 | return m_parent_unwind.GetRegisterContextForFrameNum (m_frame_number + 1); |
1911 | } |
1912 | |
1913 | // Retrieve the address of the start of the function of THIS frame |
1914 | |
1915 | bool |
1916 | RegisterContextLLDB::GetStartPC (addr_t& start_pc) |
1917 | { |
1918 | if (!IsValid()) |
1919 | return false; |
1920 | |
1921 | if (!m_start_pc.IsValid()) |
1922 | { |
1923 | return ReadPC (start_pc); |
1924 | } |
1925 | start_pc = m_start_pc.GetLoadAddress (CalculateTarget().get()); |
1926 | return true; |
1927 | } |
1928 | |
1929 | // Retrieve the current pc value for THIS frame, as saved by the NEXT frame. |
1930 | |
1931 | bool |
1932 | RegisterContextLLDB::ReadPC (addr_t& pc) |
1933 | { |
1934 | if (!IsValid()) |
1935 | return false; |
1936 | |
1937 | bool above_trap_handler = false; |
1938 | if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsTrapHandlerFrame()) |
1939 | above_trap_handler = true; |
1940 | |
1941 | if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC0, pc)) |
1942 | { |
1943 | // A pc value of 0 or 1 is impossible in the middle of the stack -- it indicates the end of a stack walk. |
1944 | // On the currently executing frame (or such a frame interrupted asynchronously by sigtramp et al) this may |
1945 | // occur if code has jumped through a NULL pointer -- we want to be able to unwind past that frame to help |
1946 | // find the bug. |
1947 | |
1948 | if (m_all_registers_available == false |
1949 | && above_trap_handler == false |
1950 | && (pc == 0 || pc == 1)) |
1951 | { |
1952 | return false; |
1953 | } |
1954 | else |
1955 | { |
1956 | return true; |
1957 | } |
1958 | } |
1959 | else |
1960 | { |
1961 | return false; |
1962 | } |
1963 | } |
1964 | |
1965 | |
1966 | void |
1967 | RegisterContextLLDB::UnwindLogMsg (const char *fmt, ...) |
1968 | { |
1969 | Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND(1u << 15))); |
1970 | if (log) |
1971 | { |
1972 | va_list args; |
1973 | va_start (args, fmt)__builtin_va_start(args, fmt); |
1974 | |
1975 | char *logmsg; |
1976 | if (vasprintf (&logmsg, fmt, args) == -1 || logmsg == NULL__null) |
1977 | { |
1978 | if (logmsg) |
1979 | free (logmsg); |
1980 | va_end (args)__builtin_va_end(args); |
1981 | return; |
1982 | } |
1983 | va_end (args)__builtin_va_end(args); |
1984 | |
1985 | log->Printf ("%*sth%d/fr%u %s", |
1986 | m_frame_number < 100 ? m_frame_number : 100, "", m_thread.GetIndexID(), m_frame_number, |
1987 | logmsg); |
1988 | free (logmsg); |
1989 | } |
1990 | } |
1991 | |
1992 | void |
1993 | RegisterContextLLDB::UnwindLogMsgVerbose (const char *fmt, ...) |
1994 | { |
1995 | Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND(1u << 15))); |
1996 | if (log && log->GetVerbose()) |
1997 | { |
1998 | va_list args; |
1999 | va_start (args, fmt)__builtin_va_start(args, fmt); |
2000 | |
2001 | char *logmsg; |
2002 | if (vasprintf (&logmsg, fmt, args) == -1 || logmsg == NULL__null) |
2003 | { |
2004 | if (logmsg) |
2005 | free (logmsg); |
2006 | va_end (args)__builtin_va_end(args); |
2007 | return; |
2008 | } |
2009 | va_end (args)__builtin_va_end(args); |
2010 | |
2011 | log->Printf ("%*sth%d/fr%u %s", |
2012 | m_frame_number < 100 ? m_frame_number : 100, "", m_thread.GetIndexID(), m_frame_number, |
2013 | logmsg); |
2014 | free (logmsg); |
2015 | } |
2016 | } |
2017 | |
2018 |